Azure Kubernetes Service (AKS)で証明書を管理およびローテーションする

この記事では、コンポーネント間のセキュリティで保護された通信を維持し、コンプライアンスを確保するために、Azure Kubernetes Service (AKS) クラスターで証明書を管理およびローテーションする方法について説明します。

前提条件

  • Azure CLI バージョン 2.0.77 以降。 az --version コマンドを使用して、バージョンを確認します。 インストールまたはアップグレードするには、「Install Azure CLIを参照してください。

クラスター証明機関 (CA) 証明書の有効期限を確認する

kubectl config view コマンドを使用して、クラスター CA 証明書の有効期限を確認します。

kubectl config view --raw -o jsonpath="{.clusters[?(@.name == '')].cluster.certificate-authority-data}" | base64 -d | openssl x509 -text | grep -A2 Validity

API サーバー証明書の有効期限を確認する

次の curl コマンドを使用して、API サーバー証明書の有効期限を確認します。

curl https://{apiserver-fqdn} -k -v 2>&1 | grep expire

VMSS エージェント ノード証明書の有効期限を確認する

az vmss run-command invoke コマンドを使用して仮想マシン スケール セット エージェント ノード証明書の有効期限を確認します。

az vmss run-command invoke \
    --resource-group <node-resource-group> \
    --name <vmss-name> \
    --command-id RunShellScript \
    --instance-id 1 \
    --scripts "openssl x509 -in  /var/lib/kubelet/pki/kubelet-client-current.pem -noout -enddate" \
    --query "value[0].message"

スタンドアロン VM 証明書の有効期限を確認する

az vm run-command invoke コマンドを使用して、スタンドアロン VM の有効期限を確認します。

az vm run-command invoke \
    --resource-group <resource-group> \
    --name <vm-name> \
    --command-id RunShellScript \
    --scripts "openssl x509 -in /var/lib/kubelet/pki/kubelet-client-current.pem -noout -enddate" \
    --query "value[0].message"

クラスター CA 証明書を手動でローテーションする

クラスター CA 証明書をローテーションすると、次の子証明書も更新されます。

  • サービス アカウント (SA) トークン
  • API サーバー証明書
  • Kubelet クライアント証明書
  • Kubelet サーバー証明書 (クラスターで kubelet サービス証明書のローテーションが有効になっている場合)

Warnung

az aks rotate-certsを使用して証明書をローテーションすると、すべてのノード、仮想マシン スケール セット、ディスクが再作成されます。 このプロセスにより、AKS クラスター に最大 30 分のダウンタイム が発生する可能性があります。 完了する前にコマンドが失敗した場合は、 az aks show コマンドを使用して、クラスターの状態に証明書の ローテーションが表示されていることを確認します。 クラスターがエラー状態になっている場合は、az aks rotate-certs を再実行して、証明書をもう一度ローテーションします。

  1. az aks get-credentials コマンドを使用してクラスターに接続します。

    az aks get-credentials --resource-group <resource-group> --name <cluster-name>
    
  2. az aks rotate-certs を使用して、クラスターのすべての証明書、CA、SA をローテーションします。

    az aks rotate-certs --resource-group <resource-group> --name <cluster-name>
    
  3. kubectl などの任意の kubectl get nodes コマンドを使用して、古い証明書が無効になっていることを確認します。

    kubectl get nodes
    

    kubectlによって使用される証明書を更新しなかった場合は、次の出力例のようなエラーが表示されます。

    Unable to connect to the server: x509: certificate signed by unknown authority (possibly because of "crypto/rsa: verification error" while trying to verify candidate authority certificate "ca")
    

クライアント証明書 kubectl 更新する

  1. kubectl フラグを指定して az aks get-credentials コマンドを使用して、--overwrite-existing クライアント証明書を更新します。

    az aks get-credentials --resource-group <resource-group> --name <cluster-name> --overwrite-existing
    
  2. kubectl get コマンドを使用して証明書が更新されていることを確認します。

    kubectl get nodes
    

    Note

    AKS 上で実行されるサービスがある場合は、それらの証明書の更新が必要になることがあります。

kubelet サービス証明書のローテーションが有効になっていることを確認する

機能が有効になっている各ノードには、ラベル kubernetes.azure.com/kubelet-serving-ca=clusterが自動的に与えられます。 kubectl get nodes -L kubernetes.azure.com/kubelet-serving-ca コマンドを使用して、ラベルが設定されていることを確認します。

kubectl get nodes -L kubernetes.azure.com/kubelet-serving-ca

kubelet が TLS ブートストラップ プロセスを通過するかどうかを確認する

この機能を有効にすると、ノードを実行している各 kubelet は、サービス 提供 TLS ブートストラップ プロセスを通過します。

kubectl get コマンドを使用してブートストラップ プロセスが実行されていることを確認し、クラスター内の現在の CSR オブジェクトを取得します。

kubectl get csr --field-selector=spec.signerName=kubernetes.io/kubelet-serving

すべての現在有効な CSR は Approved,Issued 状態にあり、これは CSR が承認され、署名済み証明書が発行されたことを示します。 サービング CSP の署名者名は kubernetes.io/kubelet-serving です。 例えば次が挙げられます。

NAME        AGE    SIGNERNAME                                    REQUESTOR                    REQUESTEDDURATION   CONDITION
csr-1ab2c   113s   kubernetes.io/kube-apiserver-client-kubelet   system:bootstrap:abcd1e      none              Approved,Issued
csr-defgh   111s   kubernetes.io/kubelet-serving                 system:node:akswinp1000000   none              Approved,Issued
csr-ij3kl   46m    kubernetes.io/kubelet-serving                 system:node:akswinp2000000   none              Approved,Issued
csr-mn4op   46m    kubernetes.io/kube-apiserver-client-kubelet   system:bootstrap:ab1cde      none              Approved,Issued

kubelet がサーバー TLS ブートストラップから取得した証明書を使用されていることを確認する

ノードの kubelet が、[kubectl debug][kubectl-debug] コマンドを使用してクラスター CA によって署名されたサービス証明書を使用して、kubelet の PKI ディレクトリの内容を調べるかどうかを確認します。

kubectl debug node/<node> -ti --image=mcr.microsoft.com/azurelinux/base/core:3.0 -- ls -l /host/var/lib/kubelet/kubelet-server-current.pem

kubelet-server-current.pemシンボリック リンクが存在する場合、kubelet は、TLS ブートストラップ プロセスを通じて独自のサービス証明書をブートストラップしてローテーションし、クラスター CA によって署名されます。

証明書のローテーションを提供する kubelet を無効にする

  1. az aks nodepool update コマンドを使用してノード プールを更新し、タグのaks-disable-kubelet-serving-certificate-rotation=trueを指定して、kubelet サービス証明書のローテーションを無効にします。

    az aks nodepool update \
        --cluster-name <cluster-name> \
        --resource-group <resource-group> \
        --name <node-pool-name> \
        --tags aks-disable-kubelet-serving-certificate-rotation=true
    
  2. ノード イメージのアップグレードを使用するか、プールを0個のインスタンスにスケーリングしてから目的の値まで再度スケーリングして、ノードを再イメージ化します。

AKS のセキュリティの詳細については、次の記事を参照してください。