In diesem Beitrag beschreibe ich, wie ich in meinem virtualisierten Netzwerk Bandbreite und Zeit sparen, indem ich Pakete für Debian und Ubuntu zentral in einem Cache hinterlege und apt auf den VMs diesen Cache beim Download der Pakete verwenden lasse. So muss nicht mehr jedes System einzeln das selbe Paket herunterladen.

Bisherige Beiträge in der Reihe:

Vorüberlegungen

So ein Zwischenspeicher spart Bandbreite und Zeit. Gerade, wenn man eine sehr homogene Struktur mit virtuellen Maschinen und Containern einsetzt, kann sich der Einsatz lohnen. Dadurch bekommt man noch keine zentrale Verwaltung nach dem Beispiel von WSUS, zumindest das Vermeiden überflüssiger Downloads bekommt man so aber schon mal hin.

Die eingesetzte Software apt-cacher-ng stellt einen Proxy-Server bereit, der sich mit Debian-Paketquellen auskennt und deren Zwischenspeicherung einigermaßen intelligent durchführen kann. Die VMs nutzen diesen Server entweder direkt als Paketquelle, wobei auch Aliase definiert werden können, falls später mal für das ganze Netzwerk gültig der verwendete Ubuntu-Mirror gewechselt werden soll oder so, oder als Proxyserver für apt auf den VMs, was die Konfiguration der Paketquellen unverändert lässt und daher keinen zu großen Einfluss auf die restliche Konfiguration nimmt. Beides hat seine Vor- und Nachteile, ich habe mich für die Konfiguration als Proxyserver entschieden.

Server aufsetzen

Der apt-cacher-ng hat keine großen Anforderungen. Als Grundlage braucht er ein Debian-basiertes System und etwas Platz für seine Pakete. Ich habe für „Kleinkrust” einen Linux-Container angelegt, der einige nicht-kritische Infrastruktur bereitstellt, die nicht von anderen Diensten isoliert sein muss. Daher im Folgenden der Hostname infra.domain.tld. Wie Ihr das umsetzt, ist egal.

Ich mache alles mit Puppet, also verwende ich für die Installation ein Manifest:

# Datei /etc/puppetlabs/code/modules/profiles/aptcache.pp
# cache apt packages for the local network
class profiles::aptcache {

  packages { 'apt-cacher-ng':
    ensure => present,
    name   => 'apt-cacher-ng',
  }

  file { 'acng.conf':
    ensure => present,
    path   => '/etc/apt-cacher-ng/acng.conf',
    owner  => 'root',
    group  => 'root',
    mode   => '0644',
    source => 'puppet:///modules/profiles/acng.conf',
    notify => Service['apt-cacher-ng.conf'],
  }

  service { 'apt-cacher-ng':
    ensure => 'running',
    enable => true,
  }
}

Viel zu erklären gibt es nicht: Es wird das notwendige Paket installiert und seine Konfigurationsdatei übertragen:

CacheDir: /var/cache/apt-cacher-ng
LogDir: /var/log/apt-cacher-ng
SupportDir: /usr/lib/apt-cacher-ng
Remap-uburep: file:ubuntu_mirrors /ubuntu ; file:backends_ubuntu # Ubuntu Archives
ReportPage: acng-report.html
ExTreshold: 4
LocalDirs: acng-doc /usr/share/doc/apt-cacher-ng

Das Profil muss noch der VM zugewiesen werden:

# Datei /etc/puppetlabs/code/environments/production/data/nodes/infra.domain.tld.yaml
classes:
# [...]
  - profiles::aptcache

Clients aufsetzen

In meiner Konfiguration wird jede VM ein Client des Proxy-Servers. Nachdem ich nur VMs mit Ubuntu oder Debian einsetze, ist das kein Problem. pfSense läuft zwar auch als VM auf meinem Server, das wird aber nicht über Puppet verwaltet, also gilt das nicht. Daher habe ich es recht einfach und muss keine OS-spezifische Hierarchieebene in meiner hiera.yaml hinzufügen und brauche nur die common.yaml ergänzen:

# Datei /etc/puppetlabs/code/environments/production/data/common.yaml
classes: [...]
  - profiles::aptcacheclient

Das notwendige Profil muss auch noch angelegt werden:

# Datei /etc/puppetlabs/code/modules/profiles/aptcacheclient.pp
# use local apt cache
class profiles::aptcacheclient {
  $apt_proxy = lookup('profiles::aptcacheclient::apt_proxy')
  $proxy_lines = @("PROXYLINES"/L)
    Acquire::http { Proxy "http://${apt_proxy}:3142"; };
    Acquire::https { Proxy "https://"; };
    | PROXYLINES

  if $apt_proxy {
    apt::conf { 'proxy':
      ensure   => present,
      content  => $proxy_lines,
      priority => '10',
    }
  }

}

Kurze Erklärung:

  1. Aus Hiera wird die URl zum Proxyserver abgeholt. Ist keine definiert, macht das nichts, siehe Zeile 10.
  2. In Zeile 5 kommt ein recht hässliches Konstrukt, ein Heredoc. Im Grunde sagt man am Anfang, dass jetzt ein mehrzeiliger String kommt, der bis PROXYLINES geht. Dann kommt tatsächlich der mehrzeilige String und mit PROXYLINES (was nicht Teil des Strings ist), wird er beendet. Das spart das Anlegen einer sehr kurzen Template-Datei wegen zweier nicht komplexer Zeilen.
  3. Falls $apt_proxy gefunden wurde, wird die Datei /etc/apt/apt.conf.d/10proxy angelegt, mit dem Inhalt von oben.

Verwendung

Die Verwendung ist mit der angegebenen Konfiguration recht transparent. Die Systeme sollten davon nichts merken. Sobald Puppet die Konfiguration verteilt hat und einige Systeme den Cache genutzt haben, kann man unter http://infra.domain.tld:3142/acng-report.html eine kleine Statistik anschauen, ob sich der Einsatz lohnt.