このドキュメントでは、ベアメタル版 GKE の期限切れの証明書を手動で更新する方法について説明します。Transport Layer Security(TLS)証明書は、ベアメタル版 GKE のコントロール プレーン コンポーネントで使用されます。これらの証明書の期限が切れると、証明書が更新されるまで、ワークロードとクラスタのライフサイクルを管理する機能が無効になります。期限切れの証明書の影響について詳しくは、証明書の有効期限をご覧ください。
デフォルトでは、TLS 証明書の有効期限は 1 年間です。ベアメタル版 GKE は、クラスタのアップグレード時と認証局のローテーション時に、これらの証明書を自動的に更新します。クラスタは定期的にアップグレードして、安全でサポートされることを維持し、TLS 証明書の有効期限が切れないようにすることをおすすめします。
証明書の有効期限切れが原因で発生したエラー
クラスタの TLS 証明書が期限切れになると、コア コントローラは Kubernetes API サーバーとの TLS 接続を確立できません。この接続がないと、次のエラーが発生します。
Unable to connect to the server: x509: Unable to connect to the server
kubectl
を使用してクラスタノードを取得すると、証明書の有効期限を参照するエラーがレスポンスに含まれます。kubectl get nodes --kubeconfig KUBECONFIG_PATH
KUBECONFIG_PATH
は、クラスタの kubeconfig ファイルへのパスに置き換えます。証明書が期限切れになると、レスポンスは次のようになります。
Unable to connect to the server: x509: certificate has expired or is not yet valid
could not connect: x509
またはrejected connection
期限切れの証明書は、ピアが相互に通信できないため、etcd クラスタへのアクセスをブロックします。etcd のログに、次のようなエラーエントリが含まれている場合があります。
W | rafthttp: health check for peer 6221a1d241bb2d0a could not connect: x509: certificate has expired or is not yet valid I | embed: rejected connection from "10.200.0.4:46108" (error "remote error: tls: bad certificate", ServerName "")
証明書の有効期限を確認する
このセクションでは、クラスタで使用される証明書の有効期限の時期を確認する手順を説明します。各コントロール プレーンノードで次の手順を実施します。
証明書の有効期限を確認するには:
コントロール プレーン ノードマシンの一つにログインし、次のコマンドを実行します。
sudo kubeadm certs check-expiration
コマンド出力には、コントロール プレーン コンポーネントとその有効期限用に
kubeadm
によって作成された証明書が一覧表示されます。CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED admin.conf Nov 28, 2021 19:09 UTC 53m no apiserver Nov 28, 2021 19:09 UTC 53m ca no apiserver-etcd-client Nov 28, 2021 19:09 UTC 53m etcd-ca no apiserver-kubelet-client Nov 28, 2021 19:09 UTC 53m ca no controller-manager.conf Nov 28, 2021 19:09 UTC 53m no etcd-healthcheck-client Nov 28, 2021 19:09 UTC 53m etcd-ca no etcd-peer Nov 28, 2021 19:09 UTC 53m etcd-ca no etcd-server Nov 28, 2021 19:09 UTC 53m etcd-ca no front-proxy-client Nov 28, 2021 19:09 UTC 53m front-proxy-ca no scheduler.conf Nov 28, 2021 19:09 UTC 53m no CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED ca Nov 26, 2031 18:06 UTC 9y no etcd-ca Nov 26, 2031 18:06 UTC 9y no front-proxy-ca Nov 26, 2031 18:06 UTC 9y no
次のコマンドを実行して、
kubelet
証明書の有効期限の時期を確認します。sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2 sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
各コマンドのレスポンスは、次の出力のようになります。
Validity Not Before: Sep 17 22:27:53 2021 GMT Not After : Sep 17 22:33:16 2022 GMT
すべてのコントロール プレーンノードが同時にブートストラップされた場合、証明書の有効期限は互いに数分以内です。このタイミング関係は、すべてのコントロール プレーンノードにわたって適用されます。各コントロール プレーンノードで上記のコマンドを実行することで、有効期限を確認できます。
管理ワークステーションで次のコマンドを実行して、クラスタの kubeconfig ファイルのクライアント証明書の有効期限の時期を確認します。
grep 'client-certificate-data' KUBECONFIG_PATH | \ awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
レスポンスは次の出力例のようになります。
Validity Not Before: Sep 17 22:27:53 2021 GMT Not After : Sep 17 22:33:16 2022 GMT
次のコマンドを実行して、管理クラスタ内のクラスタ kubeconfig の証明書の有効期限を探します。
kubectl get secret/CLUSTER_NAME-kubeconfig -n CLUSTER_NAMESPACE -o --kubeconfig=ADMIN_KUBECONFIG jsonpath='{.data.value}' | base64 --decode | grep client-certificate-data | awk '{print $2}' | base64 -d | openssl x509 -text | grep Validity -A2
Validity Not Before: Sep 17 22:27:53 2021 GMT Not After : Sep 17 22:33:16 2022 GMT
管理クラスタの kubeconfig 証明書と管理ワークステーションの kubeconfig ファイル内の証明書は同じです。したがって、このコマンドの出力と前の手順のコマンドは一致している必要があります。
証明書を手動で更新する
クラスタの TLS 証明書を手動で更新するには、以降のセクションの手順を使用してください。
各コントロール プレーンノードの証明書を更新する
影響を受けるクラスタの各コントロール プレーンノードで次の手順を実施します。
/etc/kubernetes
フォルダをバックアップします。次の
kubeadm
コマンドを実行して、すべての証明書を更新します。このコマンドは、マシン上の既存の認証局(CA)を使用して証明書を更新します。
sudo kubeadm certs renew all
コマンド出力は次のようになります。
certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed certificate for serving the Kubernetes API renewed certificate the apiserver uses to access etcd renewed certificate for the API server to connect to kubelet renewed certificate embedded in the kubeconfig file for the controller manager to use renewed certificate for liveness probes to healthcheck etcd renewed certificate for etcd nodes to communicate with each other renewed certificate for serving etcd renewed certificate for the front proxy client renewed certificate embedded in the kubeconfig file for the scheduler manager to use renewed
次のコマンドを実行して、証明書に新しい有効期限があることを確認します。
sudo kubeadm certs check-expiration
次のコマンドでコンテナを再起動します。
すべてのコントロール プレーン コンポーネントは動的証明書の再読み込みをサポートしていないため、このステップでコンテナ
kube-apiserver
、kube-scheduler
、kube-controller-manager
、etcd
が再起動され、更新された証明書です。4 つのコンテナのそれぞれについて、次の手順を繰り返します。
各コンテナのコンテナ ID を探します。
sudo crictl ps | grep CONTAINER_NAME
CONTAINER_NAME
は、コンテナ名kube-apiserver
、kube-scheduler
、kube-controller-manager
、etcd
(etcd-defrag
ではない)に置き換えます。レスポンスは次の例のようになります。
c331ade490cb6 28df10594cd92 26 hours ago Running kube-apiserver ...
コンテナ ID は最初の列の値です。
各コンテナを停止します。
sudo crictl stop CONTAINER_ID
CONTAINER_ID を前のステップで確認したコンテナ ID に置き換えます。
停止したコンテナが終了すると、kubelet は新しいコンテナを代わりに作成し、停止したものを削除します。
context deadline exceeded
(エラーコードDeadlineExceeded
)などのエラーが発生した場合は、コマンドを再実行してください。
接続性が復元されたことを確認する
この時点で、kubeadm 証明書はすべてのコントロール プレーンノードで更新されます。期限切れの証明書を更新する場合は、次のステップを実施します。
Kubernetes API サーバーとの接続を確認するには、任意のコントロール プレーンノードで次の
kubectl
コマンドを実行します。kubectl get nodes --kubeconfig=/etc/kubernetes/admin.conf
レスポンスで、クラスタのノードのリストが返されます。証明書が正しく更新されると、TLS または証明書のエラーは返されません。
クラスタの kubeconfig ファイルを置き換える
クラスタの kubeconfig ファイルを更新された証明書を含むものに置き換えるには、次の手順を使用します。
新しい kubeconfig ファイルを作成するには、管理ワークステーションで次の
kubectl
コマンドを実行します。kubectl --kubeconfig="ADMIN_KUBECONFIG" get secret/CLUSTER_NAME-kubeconfig \ -n "CLUSTER_NAMESPACE" -o jsonpath='{.data.value}' | base64 --decode > new_kubeconfig.conf
以下を置き換えます。
ADMIN_KUBECONFIG: 管理クラスタの kubeconfig ファイルのパス。
CLUSTER_NAME: 証明書を更新するクラスタの名前。
CLUSTER_NAMESPACE: 証明書を更新するクラスタの名前空間。
new_kubeconfig.conf
ファイルには、更新された証明書データが含まれています。新しい認証情報を使用して任意の
kubectl
コマンドを実行し、新しい kubeconfig が機能することを確認します。kubectl get nodes --kubeconfig new_kubeconfig.conf
管理ワークステーションのクラスタ ディレクトリに保存されている古い kubeconfig ファイルの内容を、新しい kubeconfig ファイル
new-kubeconfig.conf
の内容に置き換えます。デフォルトでは、クラスタ構成ファイルへのパスは
bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig
です。
kubelet の証明書を確認して etcd-defrag
を再起動する
クラスタ証明書を手動で更新するプロセスを完了するには、各コントロール プレーンノードで次の手順を実施します。
次のコマンドを実行して、コントロール プレーンノードにログインし、kubelet クライアントとサービス提供証明書の有効期限を確認します。
コントロール プレーンにアクセスできる限り、kubelet 証明書は自動的にローテーションされます。kubelet 証明書の自動更新期間は、コントロール プレーン コンポーネント証明書の有効期限よりも短いです。そのため、kubelet 証明書が以前に更新されている可能性があります。
sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -text | grep Validity -A2 sudo openssl x509 -in /var/lib/kubelet/pki/kubelet-server-current.pem -text | grep Validity -A2
それぞれのコマンドの出力は、次の例のようになります。
Validity Not Before: Nov 28 18:04:57 2022 GMT Not After : Nov 28 19:04:57 2023 GMT
次のコマンドを使用して、
etcd-defrag
コンテナを再起動します。etcd-defrag
コンテナは、apiserver-etcd
クライアント証明書を使用して etcd と通信し、更新された証明書を取得するために再起動する必要があります。kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
これで、クラスタ証明書を更新する手動手順を完了しました。すべての Pod が正しく実行されており、コントロール プレーン コンテナの TLS エラーが報告されていないことを確認します。