期限切れのクラスタ証明書を手動で更新する

このドキュメントでは、Google Distributed Cloud の期限切れの証明書を手動で更新する方法について説明します。Transport Layer Security(TLS)証明書は、Google Distributed Cloud のコントロール プレーン コンポーネントで使用されます。これらの証明書の期限が切れると、証明書が更新されるまで、ワークロードとクラスタのライフサイクルを管理する機能が無効になります。期限切れの証明書の影響について詳しくは、証明書の有効期限をご覧ください。

このページは、基盤となる技術インフラストラクチャのライフサイクルを管理し、サービスレベル目標(SLO)が達成されていない場合やアプリケーションで障害が発生した場合にアラートやページに対応する管理者、アーキテクト、オペレーターを対象としています。Google Cloud のコンテンツで参照する一般的なロールとタスク例の詳細については、一般的な GKE Enterprise ユーザーロールとタスクをご覧ください。

デフォルトでは、TLS 証明書の有効期限は 1 年間です。Google Distributed Cloud は、クラスタのアップグレード中と認証局のローテーション時に、これらの証明書を自動的に更新します。クラスタは定期的にアップグレードして、安全でサポートされることを維持し、TLS 証明書の有効期限が切れないようにすることをおすすめします。

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。

証明書の有効期限切れが原因で発生したエラー

クラスタの TLS 証明書が期限切れになると、コア コントローラは Kubernetes API サーバーとの TLS 接続を確立できません。この接続がないと、次のエラーが発生します。

  • サーバーに接続できない: x509

    kubectl を使用してクラスタノードを取得すると、次のような出力例のように、証明書の有効期限が切れたことを示すエラーがレスポンスに含まれます。

    Unable to connect to the server: x509: certificate has expired or is not yet valid
    
  • 接続できませんでした: x509 または拒否された接続

    期限切れの証明書は、ピアが相互に通信できないため、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 "")
    

証明書の有効期限を確認する

証明書の有効期限を確認するには、各コントロール プレーン ノードで次の操作を行います。

  1. コントロール プレーン ノードマシンの一つにサインインし、次のコマンドを実行します。

    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
    
  2. 次のコマンドを実行して、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
    

    すべてのコントロール プレーンノードが同時にブートストラップされた場合、証明書の有効期限は互いに数分以内です。このタイミング関係は、すべてのコントロール プレーンノードにわたって適用されます。各コントロール プレーンノードで上記のコマンドを実行することで、有効期限を確認できます。

  3. 管理ワークステーションで次のコマンドを実行して、クラスタの 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
    
  4. 次のコマンドを実行して、管理クラスタ内のクラスタ 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 証明書を手動で更新するには、以降のセクションの手順を使用してください。

各コントロール プレーンノードの証明書を更新する

影響を受けるクラスタの各コントロール プレーンノードで次の手順を実施します。

  1. /etc/kubernetes フォルダをバックアップします。

  2. 次の 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
    
  3. 次のコマンドを実行して、証明書に新しい有効期限があることを確認します。

    sudo kubeadm certs check-expiration
    
  4. すべてのコントロール プレーン コンポーネントは、動的証明書の再読み込みをサポートしているわけではありません。更新された証明書を取得するには、kube-apiserverkube-schedulerkube-controller-manageretcd の各コンテナで再起動します。

    4 つのコンテナのそれぞれについて、次の手順を繰り返します。

    1. 各コンテナのコンテナ ID を探します。

      sudo crictl ps | grep CONTAINER_NAME
      

      CONTAINER_NAME は、コンテナ名 kube-apiserverkube-schedulerkube-controller-manageretcdetcd-defrag ではない)に置き換えます。

      レスポンスは次の例のようになります。

      c331ade490cb6       28df10594cd92      26 hours ago       Running          kube-apiserver ...
      

      コンテナ ID は最初の列の値です。

    2. 各コンテナを停止します。

      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 ファイルを更新された証明書を含むものに置き換えるには、次の手順を使用します。

  1. 新しい 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 ファイルには、更新された証明書データが含まれています。

  2. 新しい認証情報を使用して任意の kubectl コマンドを実行し、新しい kubeconfig が機能することを確認します。

    kubectl get nodes --kubeconfig new_kubeconfig.conf
    
  3. 管理ワークステーションのクラスタ ディレクトリに保存されている古い kubeconfig ファイルの内容を、新しい kubeconfig ファイル new-kubeconfig.conf の内容に置き換えます。

    デフォルトでは、クラスタ構成ファイルへのパスは bmctl-workspace/CLUSTER_NAME/CLUSTER_NAME-kubeconfig です。

kubelet の証明書を確認して etcd-defrag を再起動する

クラスタ証明書を手動で更新するプロセスを完了するには、各コントロール プレーンノードで次の手順を実施します。

  1. 次のコマンドを実行して、コントロール プレーンノードにサインインし、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
    
  2. 次のコマンドを使用して、etcd-defrag コンテナを再起動します。

    etcd-defrag コンテナは、apiserver-etcd クライアント証明書を使用して etcd と通信し、更新された証明書を取得するために再起動する必要があります。

    kubectl rollout restart daemonset etcd-defrag -n kube-system --kubeconfig KUBECONFIG_PATH
    

クラスタ証明書を更新する手動の手順を完了したら、すべての Pod が正しく実行されていること、コントロール プレーン コンテナの TLS エラーが報告されていないことを確認します。

次のステップ

さらにサポートが必要な場合は、Cloud カスタマーケアにお問い合わせください。