Wenn Sie als Antwort auf den Befehl
kubectl get pod
erhalten:
Unable to connect to the server: x509: certificate has expired or is not yet valid
Dann ist höchstwahrscheinlich ein Jahr vergangen, Ihre Kubernetes-Zertifikate sind abgelaufen, die Cluster-Komponenten haben sie nicht mehr verwendet, die Interaktion zwischen ihnen wurde gestoppt und Ihr Cluster wurde zu einem Kürbis.

Was ist zu tun und wie wird ein Cluster wiederhergestellt?
Zunächst müssen wir verstehen, wo sich die zu aktualisierenden Zertifikate befinden.
Abhängig von der Art und Weise, wie der Cluster installiert wurde, können Speicherort und Name der Zertifikatdateien variieren. So zerlegt Kubeadm beispielsweise beim Erstellen eines Clusters Zertifikatdateien gemäß
Best Practices . Daher befinden sich alle Zertifikate im
/etc/kuberenetes/pki
in Dateien mit der Erweiterung
.crt
privaten Schlüsseln in den
.key
. Außerdem befinden sich in
/etc/kubernetes/
.conf
Dateien mit Zugriffskonfiguration für Benutzerkontenadministrator, Manager-Controller, Sheduler und Kubelet vom Masterknoten. Zertifikate in
.conf
Dateien liegen im Feld user.client-certificate-data in base64-codierter Form.
Mit diesem kleinen shcert-Skript können Sie das Ablaufdatum anzeigen, an das es ausgestellt wurde und von wem das Zertifikat signiert wurde
Es gibt immer noch Zertifikate, die Kubelet auf Arbeitsknoten zur Authentifizierung in der API verwenden. Wenn Sie kubeadm join verwendet haben, um Knoten zum Cluster hinzuzufügen, wurde der Knoten höchstwahrscheinlich mithilfe des
TLS-Bootstrapping- Verfahrens verbunden. In diesem Fall kann kubelet sein Zertifikat automatisch erneuern, wenn ihm die Option
--rotate-certificates
. In neueren Versionen von Kubernetes ist diese Option bereits standardmäßig aktiviert.
Das Überprüfen, ob der Knoten mit dem TLS-Bootstrap-Verfahren verbunden ist, ist recht einfach. In diesem Fall wird die Datei
/etc/kubernetes/kubelet.conf
normalerweise in der
/var/lib/kubelet/pki/kubelet-client-current.pem
in der Datei
/var/lib/kubelet/pki/kubelet-client-current.pem
Dies ist ein Symlink zum aktuellen Zertifikat.
Sie können die Ablaufdaten dieses Zertifikats auch mithilfe des
shcert
Skripts
shcert
Wir kehren zum Problem der Erneuerung von Zertifikaten zurück.Wenn Sie den Cluster mit kubeadm installiert haben, habe ich gute Nachrichten für Sie. Ab Version 1.15 kann kubeadm fast alle Zertifikate der Steuerebene mit einem Befehl aktualisieren
kubeadm alpha certs renew all
Dieser Befehl aktualisiert alle Zertifikate im Verzeichnis / etc / kubernetes, auch wenn sie bereits abgelaufen sind und alles kaputt gegangen ist.
Nur das Kubelet-Zertifikat wird nicht aktualisiert - dies ist das Zertifikat, das in der Datei
/etc/kubernetes/kubelet.conf
enthalten ist!
Update: kubeadm, beginnend mit Version 1.17, enthält auf allen Knoten (auch auf dem ersten Assistenten, auf dem kubeadm init ausgeführt wurde) die automatische Erneuerung des Culet-Zertifikats. Die Überprüfung ist sehr einfach: In /etc/kubernetes/kubelet.conf
Pfad zur Datei /var/lib/kubelet/pki/kubelet-client-current.pem
im Feld /var/lib/kubelet/pki/kubelet-client-current.pem
angegeben
Verwenden Sie den Befehl create user account, um dieses Zertifikat zu erneuern
kubeadm alpha kubeconfig user --client-name system:node:kube.slurm.io --org system:nodes > /etc/kubernetes/kubelet.conf
Wenn das System über ein Benutzerkonto verfügt, aktualisiert dieser Befehl das Zertifikat für dieses Konto. Vergessen Sie nicht, den richtigen Hostnamen in der Option
--client-name
anzugeben. Sie können
--client-name
Hostnamen im Feld Betreff eines vorhandenen Zertifikats
--client-name
:
shcert /etc/kubernetes/kubelet.conf
Und natürlich müssen Sie nach dem Aktualisieren der Zertifikate alle Komponenten der Steuerebene
systemctl restart kubelet
, den gesamten Knoten neu starten oder die Container mit etcd, api, controller-manager und scheduler mit dem
docker stop
docker
systemctl restart kubelet
docker stop
und dann kubelet
systemctl restart kubelet
restart
systemctl restart kubelet
.
Wenn Ihr Cluster eine alte Version hat: 1.13 oder weniger, funktioniert es einfach nicht, kubeadm auf 1.15 zu aktualisieren, da die Abhängigkeiten kubelet und kubernetes-cni berücksichtigt werden, was zu Problemen führen kann, da sich die Leistung von Clusterkomponenten in Versionen um mehr als eine unterscheidet Bühne, nicht garantiert. Der einfachste Ausweg aus dieser Situation besteht darin, kubeadm auf einem anderen Computer zu installieren, die Binärdatei
/usr/bin/kubeadm
, sie auf die Hauptknoten des verstorbenen Clusters zu kopieren und sie nur zum Erneuern von Zertifikaten zu verwenden. Und nachdem der Cluster revitalisiert wurde, aktualisieren Sie ihn Schritt für Schritt mit regulären Methoden und installieren Sie kubeadm jedes Mal um eine neuere Version.
Ab Version 1.15 lernte kubeadm schließlich, wie alle Zertifikate erneuert werden, wenn ein Cluster mit dem Befehl
kubeadm upgrade
. Wenn Sie Ihren Cluster also mindestens einmal im Jahr regelmäßig aktualisieren, sind Ihre Zertifikate immer gültig.
Wenn der Cluster jedoch nicht mit kubeadm installiert wird, müssen Sie openssl abholen und alle Zertifikate einzeln erneuern.
Das Problem besteht darin, dass die Zertifikate erweiterte Felder enthalten und verschiedene Cluster-Installationstools ihre eigenen Felder hinzufügen können. Darüber hinaus sind die Namen dieser Felder in der openssl-Konfiguration und in der Ausgabe des Zertifikatinhalts korreliert, jedoch schwach. Es ist notwendig zu googeln und auszuwählen.
Ich werde eine Beispielkonfiguration für openssl geben, in separaten Abschnitten, in denen erweiterte Attribute beschrieben werden, die für jeden Zertifikatstyp spezifisch sind. Wir werden beim Erstellen und Signieren von csr auf den entsprechenden Abschnitt verweisen. Diese Konfiguration wurde verwendet, um den vor einem Jahr vom Rancher eingerichteten Cluster wiederzubeleben.
openssl.cnf [req] distinguished_name = req_distinguished_name req_extensions = v3_req [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [client] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [apiproxyclient] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth [etcd] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [api] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = ec2-us-east-1-1a-c1-master-2 DNS.2 = ec2-us-east-1-1a-c1-master-3 DNS.3 = ec2-us-east-1-1a-c1-master-1 DNS.4 = localhost DNS.5 = kubernetes DNS.6 = kubernetes.default DNS.7 = kubernetes.default.svc DNS.8 = kubernetes.default.svc.cluster.local IP.1 = 10.0.0.109 IP.2 = 10.0.0.159 IP.3 = 10.0.0.236 IP.4 = 127.0.0.1 IP.5 = 10.43.0.1
Aktuelle Attribute und zusätzliche Namen im Zertifikat können mit dem Befehl angezeigt werden
openssl x509 -in cert.crt -text
Beim Erneuern des Zertifikats für die Server-API hatte ich ein Problem: Das aktualisierte Zertifikat funktionierte nicht. Die Lösung bestand darin, ein Zertifikat auszustellen, das in der Vergangenheit 1 Jahr gültig war.
In openssl können Sie mit einem einfachen Befehl kein in der Vergangenheit gültiges Zertifikat ausstellen. Der Code gibt streng an, dass das Zertifikat nur ab dem aktuellen Zeitpunkt gültig ist. Mit der libfaketime-Bibliothek können Sie jedoch lokal in die Vergangenheit reisen
yum install libfaketime LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req ...
Wir stellen erweiterte Zertifikate nach folgendem Algorithmus aus:
Wir erstellen eine CSR mit einem vorhandenen Zertifikat und geben den gewünschten Abschnitt mit einer Liste der erweiterten Attribute in der Konfigurationsdatei an:
openssl x509 -x509toreq -in "node.cert" -out "node.csr" -signkey "node.key" -extfile "openssl.cnf" -extensions client
Wir signieren es mit dem entsprechenden Stammzertifikat, verschieben die Zeit um 1 Jahr und geben den gewünschten Abschnitt mit einer Liste der erweiterten Attribute in der Konfigurationsdatei an
LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req -days 36500 -in "node.csr" -CA "kube-ca.pem" -CAkey "kube-ca-key.pem" -CAcreateserial -out "node.new.cert" -extfile "openssl.cnf" -extensions client
Wir überprüfen die Attribute und starten die Steuerebenenkomponenten neu.
Sergey Bondarev,
Slurm Lehrer
slurm.io