Wer mehrere CentOS-Systeme betreut kennt das Problem bestimmt - die Verteilung von Updates. Klassisch telefoniert CentOS zu einem Mirror-Server in der Nähe im Internet um die aktuellen Updates zu beziehen. Wenn man mehrere Systeme betreut ist das eine unschöne Lösung, da unnötig Bandbreite und Plattenplatz verschenkt wird.
Abhilfe schafft ein zentraler kleiner CentOS-Server, der nichts anderes tut als mittels RSync die CentOS-Repositories zu synchronisieren und mittels HTTP zur Verfügung zu stellen.
Die Synchronisation kann per Cronjob gesteuert werden um immer „up2date“ zu sein.
Ich setze einfach mal voraus, dass ein CentOS Standard-Server installiert wurde - eine grafische Oberfläche ist nicht zwingend notwendig.
Benötigt werden darüber hinaus noch Rsync sowie der große Indianer:
# yum install httpd rsync
Ich persönlich lege die Files auf eine eigene Volume-Group, damit ich erstens mein System „sauber“ halte und zweitens verhindere, dass vollaufende Updates mein System zum Absturz bringen. Ein weiterer Vorteil beim Einsatz einer dedizierten Volumegroup ist, dass ich später die Möglichkeit habe mangelnden Speicherplatz in der Volumegroup mit zusätzlichen Festplatten zu kaschieren. Eine dedizierte Volumegroup lässt sich ganz einfach implementieren - zuerst wird eine zusätzliche Festplatte entsprechend partioniert (LVM-Partition anlegen), danach werden mittels pvcreate, vgcreate und lvcreate das Laufwerk vorbereitet, eine Volumegroup und ein Volume angelegt. Nach der Formatierung und Konfiguration der FSTAB steht das Filesystem zur Verfügung:
# fdisk /dev/sdb << EOF n p 1 t 8e w EOF # pvcreate /dev/sdb1 Writing physical volume data to disk "/dev/sdb1" Physical volume "/dev/sdb1" successfully created # vgcreate vg_updates /dev/sdb1 Volume group "updates" successfully created # lvcreate -n lv_upd_centos -l 100%FREE vg_updates Logical volume "centos_updates" created # mkfs.ext4 /dev/vg_updates/lv_upd_centos ... # echo "/dev/mapper/vg_updates-lv_upd_centos /var/mirror ext4 defaults 0 0" >> /etc/fstab # mkdir /var/mirror # mount -a # df -h | grep mirror 79G 184M 75G 1% /var/mirror
Für die CentOS-Releases, die später mit Updates versorgt werden sollen, werden Ordner und Symlinks angelegt. Für das 5.x Release beispielsweise wird ein Ordner für das letzte Release 5.7 angelegt. Da die älteren Releases (5.1-5.6) ohnehin durch Updates auf das letzte Release 5.7 gebracht werden, genügen Symlinks. Ähnlich verhält es sich bei den Releases 3 und 4.
# cd /var/mirror # mkdir CentOS && cd CentOS # mkdir 5.7 # ln -s 5.7 5 # ln -s 5.7 5.1 # ln -s 5.7 5.2 # ln -s 5.7 5.3 # ln -s 5.7 5.4 # ln -s 5.7 5.5 # ln -s 5.7 5.6 ...
Die Updates werden dann für das 5.x Release beispielsweise wie folgt bezogen:
# rsync -avSHP --delete --exclude "local*" --exclude "isos" rsync://mirror.netcologne.de/centos/5.7/ /var/mirror/CentOS/5.7/ ... receiving incremental file list 5.7/ 5.7/addons/ 5.7/addons/SRPMS/ 5.7/addons/SRPMS/repodata/ 5.7/addons/i386/ 5.7/addons/i386/RPMS/ 5.7/addons/i386/repodata/ 5.7/addons/x86_64/ 5.7/addons/x86_64/RPMS/ 5.7/addons/x86_64/repodata/ ...
Dieser Vorgang kann - je nach Leitung - mehrere Stunden bis Tage in Anspruch nehmen, da hier alle Dateien (außer ISO-Abbilder) für alle Architekturen (derzeit i386 und X86_64) bezogen werden. Bei CentOS 5.7 stehen derzeit ca. 15 GB Pakete zur Verfügung.
Für nicht mehr supportete Releases gibt es auf den aktuellen Mirror-Servern keine Updates mehr. Hierzu zählen derzeit (Dezember 2011) CentOS 2.x und 3.x. Für diese Releases gibt es die letzten Updates auf einem Archiv-Server - allerdings ohne Rsync. Kernel.org bietet glücklicherweise einen Rsync-Mirror für Museumsfreunde:
# rsync -avSHP --delete --exclude "local*" --exclude "isos" --exclude "s390*" --exclude "ia64" rsync://archive.kernel.org/centos-vault/3.9/ /var/mirror/CentOS/3.9/ ... receiving incremental file list Readme.txt 2582 100% 2.46MB/s 0:00:00 (xfer#1, to-check=1013/1015) HEADER.images/ HEADER.images/HEADER.html -> ../../HEADER.html HEADER.images/HEADER.images -> ../../HEADER.images HEADER.images/centos_icon_60.png ...
Damit man die ganzen RSync-Kommandos nicht immer manuell eingeben muss, kann man hierfür Cronjobs anlegen, die dann bequem alle 6 Stunden ausgeführt werden:
# vi /etc/crontab ... * */6 * * * root rsync -avSHP --delete --exclude "local*" --exclude "isos" --exclude "s390*" --exclude "ia64" rsync://archive.kernel.org/centos-vault/3.9/ /var/mirror/CentOS/3.9/ * */6 * * * root rsync -avSHP --delete --exclude "local*" --exclude "isos" rsync://mirror.netcologne.de/centos/5.7/ /var/mirror/CentOS/5.7 * */6 * * * root rsync -avSHP --delete --exclude "local*" --exclude "isos" rsync://mirror.netcologne.de/centos/6.2/ /var/mirror/CentOS/6.2
Damit dritte Hosts später an die bezogenen Updates gelangen können, muss der große Indianer dahingehend konfiguriert werden, dass er die Dateien unterhalb /var/mirror über einen Alias /centos bereitstellt. Hierfür wird eine Konfigurationsdatei angelegt:
# vi /etc/httpd/conf.d/repo.conf #CentOS repositories Alias /centos /var/mirror/CentOS <Directory /var/mirror/CentOS> Options +Indexes Order allow,deny Allow from all </Directory>
Wer möchte, kann der Zugriff hier auf bestimmte Subnetze beschränken.
Zur Integritätsvalidierung prüft YUM die bezogenen Pakete mit einem signierten GPG-Key. Dieser muss noch in das CentOS-Verzeichnis auf dem Webserver kopiert werden:
# cd /var/mirror/CentOS # wget http://mirror.centos.org/centos/RPM-GPG-KEY-CentOS-{3,5,6}
Wird dieser Key nicht kopiert, wird die Installation von Paketen verhindert:
warning: rpmts_HdrFromFdno: Header V3 DSA signature: NOKEY, key ID e8562897 GPG key retrieval failed: [Errno 14] HTTP Error 404: Not Found
Nach erneutem Einlesen der Apache-Konfiguration sollte der Zugriff über http://IP-Adresse/centos sollte nun die bezogenen Pakete über HTTP bereitstellen:
# service httpd reload httpd neu laden: #
Damit ein Host die Updates auch vom aufgesetzten Update-Server bezieht, muss die YUM-Konfigurationsdatei (CentOS 2.x/3.x) bzw. die YUM Repository-Konfigurationsdatei (CentOS 5.x/6.x) angepasst werden. In aller Regel werden dort Internet-Mirrors konfiguriert, die durch den lokalen Update-Server ersetzt werden:
# cd /etc/yum.repos.d # vi CentOS-Base.repo :%s/mirrorlist/#mirrorlist/g :%s/#baseurl/baseurl/g :%s/mirror.centos.org/192.168.1.52/g :wq
Nachdem die Änderungen gespeichert wurden sollte YUM in der Lage sein die Updates mit wesentlich höherer Bandbreite vom lokalen Server zu beziehen:
# yum update ... Added 2705 new packages, deleted 0 old in 21.28 seconds Added 413 new packages, deleted 0 old in 8.18 seconds Added 0 new packages, deleted 0 old in 0.09 seconds Added 282 new packages, deleted 0 old in 0.89 seconds ... Transaction Summary ============================================================================= Install 41 Package(s) Update 426 Package(s) Remove 0 Package(s) Total download size: 695 M ... (1/317): openoffice.org-c 80% |==================== | 87 MB 00:00 ETA ...
Bei älteren Releases (CentOS 3.x) gibt es kein dediziertes Verzeichnis für die Repository-Konfigurationsdateien. Die Konfiguration erfolgt hier in der YUM-Hauptkonfigurationsdatei (/etc/yum.conf) - mithilfe eines vi-Kommandos werden alle baseurl-Parameter umgestellt:
:%s/mirror.centos.org/192.168.1.52/g :wq
# cat /etc/yum.conf ... [base] name=CentOS-$releasever - Base baseurl=http://192.168.1.52/centos/$releasever/os/$basearch/ ... [update] name=CentOS-$releasever - Updates baseurl=http://192.168.1.52/centos/$releasever/updates/$basearch/ ...
Wenn (obowhl die Dateiberechtigungen stimmen) immer noch kein Zugriff über den Webserver auf die Dateien möglich sind und diese Fehlermeldung im Apache Error-Log (/var/log/httpd/error_log) auftaucht:
[Tue Dec 27 13:48:22 2011] [error] [client 192.168.1.23] (13)Permission denied: access to /centos denied
…dann ist vermutlich SELinux hieran schuld. SELinux erkennt den Zugriff auf den externen Pfad /var/mirror und weiß, dass die Webserver-Dateien normalerweise unterhalb von /var/www/html liegen - der Zugriff wird daher erstmal blockiert. Um dennoch den Zugriff zu ermöglichen muss entweder SELinux entschärft/deaktiviert oder eine Ausnahme definiert werden:
# setenforce 0 # vi /etc/selinux/config ... SELINUX=disabled