So fügen Sie Ihrem Konfigurationsverwaltungssystem automatisch neue Tröpfchen hinzu

Einführung

Mithilfe des DigitalOcean-Metadatendienstes können Administratoren Anweisungen bereitstellen, mit denen neue Server sich automatisch konfigurieren können. Dies ist zwar nützlich, aber viele Organisationen möchten die gesamte Infrastrukturkonfiguration in einem Konfigurationsverwaltungstool wie Chef oder Puppet verwalten.

In diesem Handbuch wird gezeigt, wie ein DigitalOcean-Server mit dem Metadatendienst und CloudInit gebootet wird, um eine Verbindung zu einer vorhandenen Configuration Management-Bereitstellung herzustellen. Die eigentliche Konfiguration des Servers kann dann vom Konfigurationsverwaltungsdienst übernommen werden. Wir werden zeigen, wie man sowohl Chef- als auch Puppet-Knoten bootet.

Voraussetzungen

Um dieses Handbuch zu vervollständigen, müssen Sie mit dem DigitalOcean-Metadatendienst vertraut sein. Weitere Informationen zum Eingeben und Abrufen von Informationen vom Metadatendienst inthis guide finden Sie hier.

In diesem Handbuch wird ein Skripttyp namenscloud-config verwendet, der beim ersten Start vom CloudInit-Dienst auf Ihrem Droplet verwendet wird, um die Erstkonfiguration durchzuführen. Sie sollten sich mit den Skripten voncloud-config, ihrer Syntax und ihrem Verhalten vertraut machen, um besser zu verstehen, wie die in diesem Handbuch vorgestellten Skripte geändert werden. Sie finden eine Einführung in das Cloud-Konfigurationsskripthere. Ein praktischeres Beispiel (zusammen mit einigen Erläuterungen zu den Einschränkungen des Formats) finden Sie in unserem Handbuch zur Ausführung einiger grundlegender Aufgaben mit cloud-confighere.

Verwenden von Cloud-Config-Skripten zum Booten eines Chef-Knotens

Mit dem DigitalOcean-Metadatendienst können Sie Ihre neuen Server mitcloud-config Scripting problemlos in eine vorhandene, vom Chef kontrollierte Infrastruktur einbinden.

Um Ihren neuen Server zu diesem System hinzuzufügen, muss bereits ein Chef-Server konfiguriert sein, an den sich Ihr neuer Server wenden kann, um Konfigurationsanweisungen zu erhalten. Wenn Sie Hilfe beim Bereitstellen eines Chef-Servers und einer Verwaltungsarbeitsstation benötigen, können Siethis guide folgen, um loszulegen.

Genereller Plan

Wenn ein neuer Server online geschaltet wird, muss er unter die Kontrolle des Chef-Servers gebracht werden. In der Regel kann dies erreicht werden, indem mit dem Verwaltungsbefehlknifeeine Verbindung zum neuen Server hergestellt und der Unterbefehlbootstrapverwendet wird. Dies würde eine Verbindung zum neuen Server herstellen, den Chef-Client und die Validierungsdaten installieren, mit denen der neue Knoten eine Verbindung zum Chef-Server herstellen kann. Anschließend stellt der Chef-Client eine Verbindung zum Server her, überprüft sich selbst, erhält neue Client-Anmeldeinformationen, ruft seine Konfiguration vom Server ab und führt alle erforderlichen Aktionen aus, um sich in den gewünschten Zustand zu versetzen.

In diesem Handbuch wird eincloud-config-Skript verwendet, um den manuellen Bootstrapping-Schritt zu ersetzen. Dadurch kann der neue Knoten automatisch eine Verbindung zum Chef-Server herstellen, sich selbst validieren, Client-Anmeldeinformationen erhalten und einen ersten Chef-Client-Lauf ausführen. Der Server führt dies beim ersten Start automatisch aus, ohne dass der Administrator Sie manuell unterstützt.

Sammeln der erforderlichen Daten aus der Messerkonfigurationsdatei

Damit unsercloud-config-Skript erfolgreich booten kann, muss es auf die Anmeldeinformationen zugreifen können, die normalerweise für den Befehlknife verfügbar sind. Im Einzelnen benötigen wir folgende Informationen:

  • Der Chef-Validierungsname

  • Der Validierungsschlüssel

  • Die URL, unter der der Chef-Server erreichbar ist

Alle diese Informationen sind im richtigen Format in der Konfigurationsdateiknifeauf der Workstation verfügbar, die zur Verwaltung der Chef-Infrastruktur verwendet wird. Innerhalb des Chef Repo sollte sich ein verstecktes Verzeichnis namens.chef befinden, das diese Datei enthält.

Angenommen, Ihr Chef-Repo befindet sich in Ihrem Home-Verzeichnis auf der Workstation und heißtchef-repo. Sie können den Inhalt der Datei ausgeben, indem Sie Folgendes eingeben:

cat ~/chef-repo/.chef/knife.rb

Die Informationen, die Sie benötigen, sind nachfolgend hervorgehoben:

current_dir = File.dirname(__FILE__)
log_level                :info
log_location             STDOUT
node_name                "jellingwood"
client_key               "#{current_dir}/jellingwood.pem"
validation_client_name   "digitalocean-validator"
validation_key           "#{current_dir}/digitalocean-validator.pem"
chef_server_url          "https://your_server.com/organizations/digitalocean"
syntax_check_cache_path  "#{ENV['HOME']}/.chef/syntaxcache"
cookbook_path            ["#{current_dir}/../cookbooks"]

Der Validierungsname und die Chef-Server-URL können direkt wie sie sind aus der Datei entnommen werden. Kopieren Sie diese Werte, damit Sie sie in der Dateicloud-configverwenden können.

Dasvalidation_key zeigt auf den Ort, an dem der eigentliche Schlüssel aufbewahrt wird. Im obigen Beispiel bedeutet dies, dass es sich im selben Verzeichnis wie die Dateiknife.rbbefindet und alsdigitalocean-validator.pem bezeichnet wird. Dies wird wahrscheinlich für Ihre Konfiguration anders sein.

Wir müssen den Inhalt dieser Datei verwenden, verwenden Sie also erneut den Befehlcat. Ändern Sie den Befehl, um ihn auf den Speicherort zu verweisen, der für Ihren Validierungsschlüssel angegeben wurde:

cat ~/chef-repo/.chef/digitalocean-validator.pem

Sie sehen einen privaten RSA-Schlüssel:

-----BEGIN RSA PRIVATE KEY-----
MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU

. . .

sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
-----END RSA PRIVATE KEY-----

Kopieren Sie den gesamten Validierungsschlüssel, damit Sie ihn vorübergehend im Skriptcloud-configverwenden können.

Grundlegende Cloud-Config Chef Client-Installation

Sobald Sie die obigen Daten haben, können Sie das Skript ausbauen. Die Chef-Konfiguration kann über ein dediziertescloud-config-Modul namenschef erfolgen. Diecloud-config müssen eine gültige YAML enthalten und#cloud-config als erste Zeile des Skripts haben.

Zu Beginn sieht Ihr Skript folgendermaßen aus:

#cloud-config
chef:

In der Dokumentation voncloud-configwird behauptet, dass der Chef-Client entweder von einem Ruby-Juwel, einem Paket oder mit der herkömmlichen Omnibus-Installationsmethode installiert werden kann. In der Praxis neigen jedoch sowohl die Gem- als auch die Package-Methode zum Scheitern, weshalb wir die "Omnibus" -Methode verwenden. Obwohl dies normalerweise nicht erforderlich ist, listen wir auch den Speicherort des Omnibus-Installationsprogramms explizit auf.

Wir setzenforce_install auf "false". Auf diese Weise wird der Client nicht erneut installiert, wenn der Chef-Client aus irgendeinem Grund bereits auf dem Image installiert ist (z. B. wenn Sie von einem Snapshot aus bereitstellen). Bisher sieht unser Skript so aus:

#cloud-config
chef:
  install_type: "omnibus"
  omnibus_url: "https://www.opscode.com/chef/install.sh"
  force_install: false

Als Nächstes haben wir die Möglichkeit, mithilfe der Direktivenode_nameeinen Namen für den neuen Server in der Chef-Infrastruktur auszuwählen. Wenn Sie dies nicht einstellen, verwendet Chef den Hostnamen des Servers. Dies ist also optional. Dies muss jedoch in Ihrer Chef-Umgebung einzigartig sein.

Anschließend können wir alle Verbindungsinformationen hinzufügen, die wir von unserer Chef-Workstation übernommen haben. Wir setzen die Optionserver_url genau so auf den Speicherort des Chef-Servers wie in der Dateiknife.rb. Gleiches gilt für die Optionvalidation_name.

Für den Validierungsschlüssel verwenden wir das YAML-Pipe-Symbol (|), um den gesamten Validierungsschlüssel einzugeben, den wir auf der Workstation gefunden haben:

#cloud-config
chef:
  install_type: "omnibus"
  omnibus_url: "https://www.opscode.com/chef/install.sh"
  force_install: false
  node_name: "new_node"
  server_url: "https://your_server.com/organizations/digitalocean"
  validation_name: "digitalocean-validator"
  validation_key: |
    -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
    V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
    vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU

    . . .

    sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
    Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
    eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
    -----END RSA PRIVATE KEY-----

Zu diesem Zeitpunkt verfügt Ihr Skript über die gesamte Authentifizierung, die erforderlich ist, um eine Verbindung zu Ihrem Chef-Server herzustellen und Client-Anmeldeinformationen zu erstellen.

Chef Environment, run_list und Attribute konfigurieren

Während die obigen Details genügend Informationen für den Client bereitstellen, um eine Verbindung zum Chef-Server herzustellen, haben wir dem Knoten keine Informationen zur tatsächlichen Konfiguration gegeben. Wir können diese Informationen auch im Skriptcloud-configbereitstellen.

Verwenden Sie die Optionenvironment, um die Umgebung anzugeben, in der der neue Knoten platziert werden soll. Wenn dies nicht festgelegt ist, wird die_default-Umgebung festgelegt. Dies ist die generische Standardeinstellung für Chef-Knoten, denen keine andere Umgebung zugewiesen wurde.

chef:
  environment: "staging"

Unsererun_list können als einfache Liste von Elementen angegeben werden, die der Kunde in der richtigen Reihenfolge anwenden sollte. Dies können entweder Rezepte oder Rollen sein.

chef:
  run_list:
    - "recipe[lamp]"
    - "role[backend-web]"

Sie können die Anfangsattribute des neuen Knotens mithilfe derinitial_attributes-Hierarchie angeben. Dadurch werden die anfänglichen Attribute festgelegt, die sich auf die Anwendung vonrun_list auswirken:

chef:
  initial_attributes:
    lamp:
      apache:
        port: 80
      mysql:
        username: webclient
        pass: $#fjeaiop34S

Wenn es mit dem vorherigencloud-config-Skript verbunden ist, sieht es möglicherweise so aus:

#cloud-config
chef:
  install_type: "omnibus"
  omnibus_url: "https://www.opscode.com/chef/install.sh"
  force_install: false
  node_name: "new_node"
  server_url: "https://your_server.com/organizations/digitalocean"
  validation_name: "digitalocean-validator"
  validation_key: |
    -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
    V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
    vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU

    . . .

    sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
    Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
    eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
    -----END RSA PRIVATE KEY-----
  environment: "staging"
  run_list:
    - "recipe[lamp]"
    - "role[backend-web]"
  initial_attributes:
    lamp:
      apache:
        port: 80
      mysql:
        username: webclient
        pass: $#fjeaiop34S

Ausgabe umleiten und Chef Client Run konfigurieren

Das obige Skript enthält alle Informationen, die im Abschnittchef: benötigt werden. Es gibt jedoch noch einige andere Dinge, die wir mit einigen anderencloud-config-Modulen tun sollten.

Zunächst sollten wir festlegen, dass die Ausgabe von jedem Befehl und Unterbefehl in das Ausgabeprotokoll des CloudInit-Prozesses umgeleitet werden soll. Dies ist standardmäßig bei/var/log/cloud-init-output.log. Wir können dies mit demoutput-Modul wie folgt tun:

output: {all: '| tee -a /var/log/cloud-init-output.log'}

Das andere, was wir tun möchten, ist, den Chef-Client so einzurichten, dass er tatsächlich ausgeführt wird, sobald er installiert und konfiguriert wurde. Zum Zeitpunkt dieses Schreibens führt die Omnibus-Installationsmethode dies nicht automatisch aus.

Wir können dieses Verhalten erzwingen, indem wir warten, bis die ausführbare Datei vonchef-clientauf dem Server installiert ist, bevor wir den Befehl aufrufen. Mit einer einfachenbash-Schleife überprüfen wir alle fünf Sekunden, ob diese Datei vorhanden ist. Wenn es gefunden wird, führen wirchef-client aus, um die von uns angegebene Erstkonfiguration zu implementieren.

Das Modulruncmd kann verwendet werden, um beliebige Befehle auszugeben. Es ist der ideale Ort für unserebash-Schleife:

runcmd:
  - while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client

Optional können Sie auch eine weiterecloud-config-Direktive hinzufügen, um den Metadatenendpunkt nach dem ersten Start auf Null zu routen. Dies ist nützlich, da wir einen privaten Schlüssel in unsere Benutzerdaten einfügen. Ohne Null-Routing des Metadatenendpunkts kann jeder Benutzer auf dem Server darauf zugreifen. Implementieren Sie dies, indem Sie Folgendes hinzufügen:

disable_ec2_metadata: true

Wenn wir diese mit dem Skript kombinieren, das wir bisher erstellt haben, erhalten wir das komplette Skript, das erforderlich ist, um unseren Knoten zu booten und ihn mit unserer Chef-Infrastruktur zu verbinden:

#cloud-config
chef:
  install_type: "omnibus"
  omnibus_url: "https://www.opscode.com/chef/install.sh"
  force_install: false
  node_name: "new_node"
  server_url: "https://your_server.com/organizations/digitalocean"
  validation_name: "digitalocean-validator"
  validation_key: |
    -----BEGIN RSA PRIVATE KEY-----
    MIIEowIBAAKCAQEA3O60HT5pwEo6xUwcZ8WtExBUhoL3bTjlsvHVXg1JVmBUES+f
    V9jLu2N00uSZEDZneCIQyHLBXnqD/UNvWEPNvPzt1ecXzmw2BytB7lPDW4/F/8tJ
    vAVrKqC7B04VFGmcFY2zC8gf8BWmX8CNRDQooM7UO5OWe/H6GDGPPRIITerO3GrU

    . . .

    sWyRAoGBAKNc/ZUM8ljRV0UJxQ9nbdozXRZjtUaNgXMNiw+oP2HYYdHrlkKnGHYJ
    Js63rvjpq8pocjE8YI+2H0v4/4uWqW8GEBfrWbLMzGsYPnRyiHR5+hgjCUU50RB3
    eFoNbURwLYcq2Z/IAQZpDpJWpofz3OVMpMXtei1cIflrAAd2wtWO
    -----END RSA PRIVATE KEY-----
  environment: "staging"
  run_list:
    - "recipe[lamp]"
    - "role[backend-web]"
  initial_attributes:
    lamp:
      apache:
        port: 80
      mysql:
        username: webclient
        pass: $#fjeaiop34S
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
  - while [ ! -e /usr/bin/chef-client ]; do sleep 5; done; chef-client
disable_ec2_metadata: true

Das obige Skript kann für jeden neuen Server in Ihrer Infrastruktur nach Bedarf angepasst werden.

Verwenden von Cloud-Config-Skripten zum Booten eines Puppet-Knotens

Wenn Ihre Infrastruktur für das Konfigurationsmanagement auf Puppet basiert, können Sie stattdessen das Modulpuppetverwenden. Wie im Chef-Beispiel umfasst das Bootstrapping eines Puppet-Knotens die Verwendung voncloud-config, um den neuen Server an die vorhandene Konfigurationsverwaltungsinfrastruktur anzuschließen.

Bevor Sie beginnen, sollten Sie einen Puppet-Masterserver für Ihre Infrastruktur konfiguriert haben. Wenn Sie Hilfe benötigen, um einen Puppet-Server zum Laufen zu bringen, lesen Siethis guide.

Genereller Plan

Wenn ein neuer Puppet-Server online geschaltet wird, wird ein Puppet-Agent installiert, der mit dem Puppet-Masterserver kommunizieren kann. Dieser Agent ist dafür verantwortlich, die Informationen zu empfangen und anzuwenden, die den gewünschten Zustand des Knotens vorgeben. Zu diesem Zweck stellt der Agent eine Verbindung zum Master her, lädt Daten über sich selbst hoch, ruft den aktuellen Katalog mit der Beschreibung seines gewünschten Status ab und führt die erforderlichen Aktionen aus, um diesen Status zu erreichen.

Bevor dies jedoch geschieht, muss sich der Agent beim ersten Start beim Master-Server registrieren. Es erstellt eine Zertifikatsignierungsanforderung und sendet sie zum Signieren an den Master. In der Regel stellt der Agent die Verbindung zum Master in regelmäßigen Abständen wieder her, bis das Zertifikat signiert ist. Sie können Ihr Puppet jedoch so konfigurieren, dass eingehende Anforderungen mit bestimmten Merkmalen automatisch signiert werden, sofern dies für Ihre Umgebung geeignet ist (dies wird später behandelt).

Mit unseremcloud-config-Skript konfigurieren wir unseren neuen Server mit den Informationen, die er benötigt, um zum ersten Mal eine Verbindung zum Master herzustellen. Zu diesem Zeitpunkt kann es Konfigurationsdetails vom Puppet-Masterserver in Form eines Katalogs abrufen.

Sammeln der erforderlichen Daten vom Puppenmeister

Das erste, was wir tun müssen, bevor wir unserecloud-config-Datei erstellen, ist, die Daten von unserem Puppet-Master-Server zu sammeln, die wir verbinden müssen. Wir brauchen nur ein paar Informationen.

Zunächst müssen Sie den vollqualifizierten Domänennamen (FQDN) des Puppet-Masterservers abrufen. Sie können dies tun, indem Sie Folgendes eingeben:

hostname -f

In den meisten Fällen sollte es ungefähr so ​​aussehen:

puppet.example.com

Sie können auch in Ihrer Puppet Master-Konfigurationsdatei überprüfen, ob die Optiondns_alt_names aktiviert ist:

cat /etc/puppet/puppet.conf
. . .

dns_alt_names = puppet,puppet.example.com

. . .

Wenn die SSL-Zertifikate Ihres Puppet-Masters nach dem Festlegen dieser Optionen erstellt wurden, können sie möglicherweise ebenfalls verwendet werden.

Der andere Gegenstand, den wir sammeln müssen, ist das Zertifikat der Zertifizierungsstelle des Puppenmeisters. Dies kann entweder in/var/lib/puppet/ssl/certs/ca.pem oder/var/lib/puppet/ssl/ca/ca_crt.pem gefunden werden:

sudo cat /var/lib/puppet/ssl/certs/ca.pem

Die Ergebnisse sehen ungefähr so ​​aus:

-----BEGIN CERTIFICATE-----
MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

. . .

arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
-----END CERTIFICATE-----

Kopieren Sie das Zertifikat vollständig. Wir werden dies in unserecloud-config-Datei aufnehmen, damit unsere neuen Server überprüfen können, ob sie eine Verbindung zum richtigen Puppet-Master herstellen.

Sobald Sie über diese Informationen verfügen, können Sie mit dem Erstellen dercloud-config-Datei beginnen, damit sich der neue Server in die vorhandene Puppet-Infrastruktur einbinden kann.

Grundlegende Installation von Cloud-Config Puppet Node

Die Konfiguration voncloud-configfür neue Puppet-Knoten ist ziemlich einfach. Alle puppenspezifischen Konfigurationen befinden sich im Abschnittpuppet:der Datei. Wie bei jedercloud-config-Datei muss die allererste Zeile#cloud-config für sich enthalten:

#cloud-config
puppet:

Darunter gibt es nur zwei Unterabschnitte. Der erste ist der Schlüssel vonca_cert. Mit dem Pipe-Zeichen wird ein YAML-Textblock gestartet, sodass das CA-Zertifikat in seiner Gesamtheit als eingerückter Block angegeben werden kann:

#cloud-config
puppet:
  ca_cert: |
    -----BEGIN CERTIFICATE-----
    MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
    ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
    GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

    . . .

    arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
    rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
    l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
    UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
    -----END CERTIFICATE-----

Stellen Sie sicher, dass Sie das gesamte Zertifikat zusammen mit den Anfangs- und Endmarkierungen einschließen und es entsprechend einrücken.

Der zweite Abschnitt unter dem Dach vonpuppet:ist der Abschnitt vonconf:. Dies wird verwendet, um Schlüssel-Wert-Paare anzugeben, die an eine generischepuppet.conf-Datei angehängt werden. Die Schlüssel-Wert-Paare sollten wie in derpuppet.conf-Datei unter Abschnittsüberschriften platziert werden.

Zum Beispiel muss der neue Server mindestens die Adresse des Puppet-Masterservers kennen. In derpuppet.conf-Datei befindet sich dies im Abschnitt[agent] wie folgt:

. . .

[agent]
server = puppet.example.com

. . .

Um dies in der Syntax voncloud-configanzugeben, fügen Sie dies zu dem hinzu, was wir bisher haben:

#cloud-config
puppet:
  ca_cert: |
    -----BEGIN CERTIFICATE-----
    MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
    ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
    GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

    . . .

    arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
    rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
    l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
    UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
    -----END CERTIFICATE-----
  conf:
    agent:
      server: "puppet.example.com"

Beachten Sie, dass der Abschnittconf: mit dem Abschnittca_cert übereinstimmt und kein untergeordnetes Element ist. Dies ist das Nötigste, um eine Verbindung zum Puppet Master herzustellen. Alle zusätzlichen Konfigurationselemente inpuppet.conf können auf ähnliche Weise hinzugefügt werden, indem zuerst eine Ebene für den Abschnittsnamen erstellt und dann das Schlüssel-Wert-Paar definiert wird.

Danach sollten wir alle zukünftigen Ausgaben in diecloud-init-output.log-Datei umleiten und eineruncmd-Zeile hinzufügen, die mit der für die Chef-Konfiguration hinzugefügten vergleichbar ist. Dies wird warten, bis der Puppet-Agent installiert ist, und ihn dann aktivieren und neu starten. Wir können den Metadaten-Endpunkt auch nach dem ersten Durchlauf auf Null setzen, wie wir es im Abschnitt Chef getan haben. Die Direktiven dieser Zeilencloud-configollten außerhalb aller anderen Modulabschnitte platziert werden:

. . .

  conf:
    agent:
      server: "puppet.example.com"
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
  - while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true

Mit diesen Informationen kann der neue Server eine Verbindung zum Puppet-Master-Server herstellen und anschließend eine Client-Zertifikatsignierungsanforderung zur Übertragung an den Master generieren. Standardmäßig müssen Client-Zertifikate am Puppet-Master manuell signiert werden. Sobald dies geschehen ist, ruft der Knoten beim nächsten Puppet Agent-Aktualisierungsintervall (standardmäßig alle 30 Minuten) seine Konfiguration vom Puppet-Master ab. Wir werden etwas später zeigen, wie ein relativ sicherer Mechanismus zum automatischen Signieren implementiert wird, um diese Verzögerung zu vermeiden.

Definieren des Zertifikatsnamens für den Knoten

Einer der Werte, die in diepuppet.conf-Datei des neuen Servers eingefügt werden können, ist ein Einzelfall. In der Dateicloud-config kann die Optioncertname Werte aus der Umgebung ersetzen, wenn bestimmte Variablen angegeben werden. Folgende Variablen werden erkannt:

  • %i: Die Instanz-ID des Servers. Dies wirdhttp://169.254.169.254/metadata/v1/id entnommen, wenn der Server erstellt wird. Sie entspricht der Tropfen-ID, mit der Tropfen eindeutig identifiziert werden.

  • %f: Der FQDN des Servers.

In diesem Sinne würde eine übliche Einstellung voncertnamefolgendermaßen aussehen:

#cloud-config
puppet:

. . .

  conf:
    agent:
      server: "puppet.example.com"
      certname: "%i.%f"

Dies würde eincertname mit einem ähnlichen Muster erzeugen:

   |-Droplet ID
   |
   |            |-Fully Qualified Domain Name
   |            |
|-----||-------------------|
123456.testnode.example.com

Die Droplet-ID als Teil dercertname zu haben, kann nützlich sein, um die sichere automatische Signatur von Puppets zu konfigurieren, wie wir im nächsten Abschnitt sehen werden.

Implementieren Sie das automatische Signieren des Puppet-Zertifikats

Wenn Sie ein System zur automatischen Signatur von Zertifikaten implementieren möchten, um die Notwendigkeit eines Administratoreingriffs zu vermeiden, stehen einige Optionen zur Verfügung. Sie müssen dies zuerst auf Ihrem Puppet-Master-Server einrichten.

In der Dateipuppet.conf auf dem Puppet-Masterserver können Sie die Optionautosign im Abschnitt[master] der Datei festlegen. Dies kann verschiedene Werte annehmen:

  • true: Dadurch wird der Puppet-Masterserver angewiesen, jede eingehende Zertifikatanforderung zu signieren, ohne dass Überprüfungen durchgeführt werden. Dies ist in einer realen Umgebung äußerst gefährlich, da jeder Host eine CSR-Signatur erhalten und in Ihre Infrastruktur eindringen kann.

  • <whitelist_filename>: Die zweite Option besteht darin, eine Datei anzugeben, die als Whitelist für Hosts oder reguläre Hostausdrücke fungiert. Der Puppet-Master überprüft anhand dieser Liste, ob das Zertifikat signiert werden soll. Dies wird wiederum nicht empfohlen, da die Zertifikatsnamen leicht gefälscht werden können.

  • <policy_executable>: Die dritte Option besteht darin, ein Skript oder eine ausführbare Datei anzugeben, die ausgeführt werden kann, um zu bestimmen, ob die Zertifikatsignierungsanforderung signiert werden soll. Puppet gibt den Zertifikatsnamen als Argument und den gesamten CSR über die Standardeingabe ein. Wenn der Beendigungsstatus 0 zurückgegeben wird, wird das Zertifikat signiert. Wenn ein anderer Status angegeben wird, wird das Zertifikatnot signiert.

Das richtlinienbasierte automatische Signieren ist die sicherste Methode zum Implementieren des automatischen Signierens von Schlüsseln, da Sie damit beliebig komplex zwischen legitimen und nicht legitimen Anforderungen unterscheiden können.

Um die richtlinienbasierte automatische Signatur zu demonstrieren, können Sie die Variablecertname zu Ihrercloud-confighinzufügen, die die Instanz-ID-Variable%ienthält. Wir werden%i.%f verwenden, damit es auch den ausgewählten Hostnamen enthält:

#cloud-config
puppet:
  conf:
    agent:
      server: "puppet.example.com"
      certname: "%i.%f"
  ca_cert: |

   . . .

Ihre vollständigencloud-config könnten jetzt ungefähr so ​​aussehen:

#cloud-config
puppet:
  conf:
    agent:
      server: "puppet.example.com"
      certname: "%i.%f"
  ca_cert: |
    -----BEGIN CERTIFICATE-----
    MIIFXjCCA0agAwIBAgIBATANBgkqhkiG9w0BAQsFADAcMRowGAYDVQQDDBFQdXBw
    ZXQgQ0E6IHB1cHBldDAeFw8xNTAyMTkxOTA0MzVaFw0yMDAyMTkxOTA0MzVaMBwx
    GjAYBgNVBAMMEVB1cHBldCBDQTogcHVwcGV0MIICIjANBgkqhkiG9w0BAQEFAAOC

    . . .

    arsjZT5/CtIhtP33Jl3mCp7U2F6bsk4/GDGRaAsFXjJHvBbL93NzgpkZ7elf0zUP
    rOcSGrDrUuzuJk8lEAtrZr/IfAgfKKXPqbyYF95V1qN3OMY+aTcrK20XTydKVWSe
    l5UfYGY3S9UJFrSn9aBsZzN+10HXPkaFKo7HxpztlYyJNI8UVSatcRF4aYYqt9KR
    UClnR+2WxK5v7ix0CVd4/KpYH/6YivvyTwxrhjF2AksZKg==
    -----END CERTIFICATE-----
output: {all: '| tee -a /var/log/cloud-init-output.log'}
runcmd:
  - while [ ! -e /usr/bin/puppet ]; do sleep 5; done; puppet agent --enable; service puppet restart
disable_ec2_metadata: true

Auf dem Puppet-Masterserver müssen wir ein Validierungsskript einrichten. Da Ruby bereits für Puppet installiert ist, können wir ein einfaches Ruby-Skript erstellen.

Da wir das%i.%f-Format fürcertname verwenden, können wir prüfen, ob der erste Teil voncertname (der Teil vor dem ersten Punkt) einer gültigen Droplet-ID für unser Konto entspricht . Dies ist nur eine einfache Überprüfung, die in der Praxis nicht viel mehr als die Whitelist-Datei bewirkt. Sie können diese Idee jedoch anpassen, um sie viel komplexer zu gestalten, wenn Sie dies wünschen.

Dazu benötigen wir ein persönliches Zugriffstoken aus dem Bereich „Apps & API“ des DigitalOcean-Kontrollfelds. Sie müssen auch eine der DigitalOcean Ruby-Bibliotheken installieren. Im Folgenden zeigen wir Ihnen einige vereinfachte Skripte, die die DigitalOcean Ruby-ClientsBarge undDropletKit verwenden.

Wenn Sie den Barge-Client verwenden möchten, installieren Sie den Edelstein auf Ihrem Puppet Master, indem Sie Folgendes eingeben:

sudo gem install barge

Mit dem folgenden Skript kann überprüft werden, ob der erste Teil dercertname in der Zertifikatsignierungsanforderung einer gültigen Droplet-ID entspricht:

#!/usr/bin/env ruby

require 'barge'

TOKEN = 'YOUR_DIGITALOCEAN_API_TOKEN'

droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i

client = Barge::Client.new(access_token: TOKEN)
droplets = client.droplet.all

droplets.droplets.each do |droplet|
        droplet_ids << droplet.id
end

Kernel.exit(droplet_ids.include?(id_to_check))

Wenn Sie stattdessen DropletKit, den offiziellen DigitalOcean Ruby-Client, verwenden möchten, können Sie den Edelstein installieren, indem Sie Folgendes eingeben:

sudo gem install droplet_kit

Beachten Sie, dass DropletKit gem nur für Ruby 2.0 und höher gültig ist. Daher ist dies möglicherweise nicht möglich, wenn Sie die mit Puppet gelieferte Version von Ruby verwenden.

Das Skript für DropletKit kann folgendermaßen angepasst werden:

#!/usr/bin/env ruby

require 'droplet_kit'

TOKEN = 'YOUR_DIGITALOCEAN_API_TOKEN'

droplet_ids = []
certname = ARGV[0]
id_string = certname.slice(0...(certname.index('.')))
id_to_check = id_string.to_i

client = DropletKit::Client.new(access_token: TOKEN)
droplets = client.droplets.all

droplets.each do |droplet|
        droplet_ids << droplet.id
end

Kernel.exit(droplet_ids.include?(id_to_check))

Sie können das Skript, das dem von Ihnen installierten Juwel entspricht, in eine Datei mit dem Namen/etc/puppet/validate.rb einfügen und es als ausführbar markieren, indem Sie Folgendes eingeben:

sudo chmod +x /etc/puppet/validate.rb

Anschließend können Sie Ihrerpuppet.conf-Datei Folgendes hinzufügen (bei Verwendung von Open Source Puppet unter/etc/puppet/puppet.conf):

. . .

[master]
autosign = /etc/puppet/validate.rb

. . .

Starten Sie den Apache-Dienst neu, um die neue Signaturrichtlinie zu implementieren:

sudo service apache2 restart

Wenn nun Zertifikatsignierungsanfragen bei Ihrem Puppet-Meister eingehen, wird geprüft, ob der erste Teil des Zertifikatsnamens mit einem gültigen Droplet-Namen in Ihrem Konto übereinstimmt. Dies ist ein grobes Beispiel dafür, wie Sie Anforderungen mithilfe einer ausführbaren Datei validieren können.

Fazit

Durch die Nutzung dercloud-config-Skripte können Sie Ihre neuen Server einfach booten und an Ihre vorhandenen Konfigurationsmanagementsysteme übergeben. Auf diese Weise können Sie Ihre Infrastruktur sofort über Ihre vorhandenen Tools steuern, bevor Sie wichtige Änderungen außerhalb des Bereichs Ihrer Verwaltungslösung vornehmen.