ノードごとにSSH接続して設定を修正する時代は終わった。
ConfigMap一つでクラスタ全体を制御せよ。
>
>
ConfigMap一つでクラスタ全体のワーカーノードの証明書更新サイクルを一括制御する物語 — 数十個の時計(ノード)を同時に同期させる時計職人の精密さ。
🎯 この記事で扱うこと
- kube-systemネームスペースのkubelet-config ConfigMapの構造と役割
- ConfigMapを修正してrotateCertificates: trueを適用する全体手順
- 変更をワーカーノードの/var/lib/kubelet/config.yamlに反映する方法
- 自動更新が実際に動作するか検証する方法
- アップグレード時に設定が上書きされる問題と対処方法
📌 導入 / 背景
kubeletクライアント証明書は、基本的に1年の有効期間を持ちます。クラスタ規模が大きくなるにつれて、ワーカーノードごとにSSHで接続して/var/lib/kubelet/config.yamlを修正する方法は現実的に不可能です。
kubeadmで構成されたクラスタは、これを解決するための構造をすでに備えています。kubeadmはBootstrap Tokenを活用したTLSブートストラップ過程でkubelet-config ConfigMapをダウンロードし、/var/lib/kubelet/config.yamlに書き込みます。つまり、kube-systemのConfigMapを修正し、各ノードでこれをダウンロードして適用する流れが公式にサポートされています。
rotateCertificates: trueに設定すると、kubeletは証明書全体の寿命の約70〜90%の時点でCSRを自動的に提出し、kube-controller-managerがこれを監視してクラスタCAキーで署名・承認することで、クライアント証明書が自動更新されます。
🔍 概念説明
ConfigMapとローカルconfig.yamlの関係
kubeadmクラスタでは、kubeletの設定は2箇所に存在します。
| 場所 | 役割 |
| kube-system/kubelet-config (ConfigMap) | クラスタ全体基準設定 (Single Source of Truth) |
| /var/lib/kubelet/config.yaml (各ノード) | ノードで実際にkubeletが読み込む設定ファイル |
これら2つのファイルは自動的に同期されません。ConfigMapを修正した後、各ワーカーノードで直接ダウンロードして反映する過程が必要です。この点が重要です。
ConfigMapに保存された設定と/var/lib/kubelet/config.yamlの内容は自動的に同期されません。ノードローカル設定を永続的に維持するには、/var/lib/kubelet/config.yamlを直接手動で更新するか、/var/lib/kubelet/kubeadm-flags.envにフラグを追加し、kubeletを再起動する必要があります。
rotateCertificatesの動作原理
kubeletが–bootstrap-kubeconfigフラグでブートストラップされるように設定されている場合、初期証明書でKubernetes APIに接続してCSRを提出します。CSRが一定基準を満たすとcontroller-managerが自動承認し、–cluster-signing-durationパラメータで指定された期間の証明書を署名してkubeletに渡します。有効期限が近づくと、kubeletは残りの時間の30%〜10%の間のいずれかの時点で自動的に新しいCSRを提出します。

💻 実習 / 例示コード
Step 0. 現在の状態確認
# ConfigMap名を確認 (バージョンによって名前の形式が異なる場合があります)
kubectl get configmap -n kube-system | grep kubelet
# Kubernetes 1.24+の場合: kubelet-config
# 旧バージョン: kubelet-config-1.{minor} (例: kubelet-config-1.27)
# 現在のConfigMapの全内容を確認
kubectl get configmap kubelet-config -n kube-system -o yaml
出力例のdata.kubelet部分を確認します:
data:
kubelet: |
apiVersion: kubelet.config.k8s.io/v1beta1
kind: KubeletConfiguration
authentication:
...
rotateCertificates: false # ← この部分をtrueに変更
Step 1. ConfigMap修正 (コントロールプレーンで)
方法 A — kubectl edit (対話型編集)
kubectl edit configmap kubelet-config -n kube-system
エディタが開いたら、data.kubeletブロック内部でrotateCertificates項目を探して修正します。存在しない場合は直接追加します。
# 修正前
rotateCertificates: false
# 修正後
rotateCertificates: true
保存してエディタを終了すると、ConfigMapが即座に更新されます。
方法 B — kubectl patch (スクリプトベースの自動化に適している)
# 現在のkubelet設定を抽出
kubectl get configmap kubelet-config -n kube-system
-o jsonpath='{.data.kubelet}' > /tmp/kubelet-config-current.yaml
# rotateCertificates項目を確認
grep rotateCertificates /tmp/kubelet-config-current.yaml
# sedで値を変更 (false → true、または存在しない場合は追加)
sed -i 's/rotateCertificates: false/rotateCertificates: true/'
/tmp/kubelet-config-current.yaml
# rotateCertificates項目が全くない場合
grep -q 'rotateCertificates' /tmp/kubelet-config-current.yaml ||
echo "rotateCertificates: true" >> /tmp/kubelet-config-current.yaml
# 修正された内容をConfigMapに反映
kubectl create configmap kubelet-config
-n kube-system
--from-file=kubelet=/tmp/kubelet-config-current.yaml
--dry-run=client -o yaml | kubectl apply -f -
Step 2. ワーカーノードで設定反映
ConfigMapを修正しても、ワーカーノードのkubeletは即座に変更を認識しません。各ワーカーノードで以下の手順を実行する必要があります。
方法 A — kubeadm upgrade node活用 (推奨)
# ワーカーノードで実行 (SSH接続後)
sudo kubeadm upgrade node phase kubelet-config
# kubeletを再起動
sudo systemctl daemon-reload
sudo systemctl restart kubelet
kubeadm upgrade node phase kubelet-configコマンドは、クラスタに保存されたkubelet-config ConfigMapをダウンロードし、該当ノードのkubelet設定をアップグレードします。
方法 B — ConfigMapを直接ダウンロードして置き換え
# ワーカーノードで実行 (kubectlアクセス可能な環境が必要)
# ConfigMapからkubelet設定を抽出
kubectl get configmap kubelet-config -n kube-system
-o jsonpath='{.data.kubelet}' > /tmp/kubelet-config-new.yaml
# 既存のconfigをバックアップ
sudo cp /var/lib/kubelet/config.yaml
/var/lib/kubelet/config.yaml.bak.$(date +%Y%m%d)
# 新しい設定を適用
sudo cp /tmp/kubelet-config-new.yaml /var/lib/kubelet/config.yaml
# 適用を確認
grep rotateCertificates /var/lib/kubelet/config.yaml
# kubeletを再起動
sudo systemctl daemon-reload
sudo systemctl restart kubelet
# 再起動状態を確認
sudo systemctl status kubelet
Step 3. 複数ノードに一括適用 (スクリプト)
ノードが複数台ある場合、以下のスクリプトを活用して一括処理できます。
#!/bin/bash
# apply-kubelet-rotate.sh
# すべてのワーカーノードにrotateCertificates設定を一括適用
WORKER_NODES=$(kubectl get nodes
--selector='!node-role.kubernetes.io/control-plane'
-o jsonpath='{.items[*].metadata.name}')
for NODE in $WORKER_NODES; do
echo "=== 처리 중: $NODE ==="
# 1. ConfigMapの最新設定をダウンロード
ssh $NODE "sudo kubeadm upgrade node phase kubelet-config"
# 2. kubeletを再起動
ssh $NODE "sudo systemctl daemon-reload && sudo systemctl restart kubelet"
# 3. 適用結果を確認
ssh $NODE "grep rotateCertificates /var/lib/kubelet/config.yaml"
echo "=== $NODE 완료 ==="
sleep 3 # ノード間の間隔
done
echo "전체 완료"
chmod +x apply-kubelet-rotate.sh
./apply-kubelet-rotate.sh
Step 4. 自動更新動作検証
# rotateCertificatesが有効になっているか確認 (各ノードで)
sudo grep rotateCertificates /var/lib/kubelet/config.yaml
# 現在の証明書の有効期限を確認
sudo openssl x509
-in /var/lib/kubelet/pki/kubelet-client-current.pem
-noout -enddate
# kubeletログで証明書更新の試行を確認
sudo journalctl -u kubelet --since "1 hour ago" | grep -i rotate
sudo journalctl -u kubelet --since "1 hour ago" | grep -i certificate
# CSRリストで自動提出されたリクエストを確認 (コントロールプレーンで)
kubectl get csr | grep "system:node"
# 出力例 — Approved,Issued状態であれば正常
# NAME SIGNERNAME REQUESTOR CONDITION
# csr-abc12 kubernetes.io/kube-apiserver-client-kubelet system:node:worker-1 Approved,Issued
# 実際に適用されたkubelet設定をリアルタイムで確認 (APIプロキシを活用)
kubectl proxy &
curl -s http://127.0.0.1:8001/api/v1/nodes/<노드명>/proxy/configz |
python3 -m json.tool | grep rotateCertificates
Step 5. RBAC — 自動承認の前提条件確認
rotateCertificates: trueだけでは不十分です。ノードグループがCSRを自動承認できるRBAC権限を持っている必要があります。
# クライアント証明書の自動更新権限を確認
kubectl get clusterrolebinding | grep "auto-approve"
kubectl get clusterrolebinding | grep "node-client"
ない場合は、以下のコマンドで作成します:
# ノードグループにクライアント証明書の自動更新権限を付与
kubectl create clusterrolebinding auto-approve-renewals
--clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient
--group=system:nodes
⚠️ 注意事項 / よくある間違い
1. ConfigMapの修正だけでは終わらない ConfigMapを修正しても、実行中のkubeletは自動的に再ロードしません。必ずkubeadm upgrade node phase kubelet-configまたは直接ファイルを置き換えた後、systemctl restart kubeletを実行する必要があります。
2. kubeadmアップグレード時の上書きに注意 kubeadmアップグレード時、/var/lib/kubelet/config.yamlの内容がクラスタ全体のkubelet-config ConfigMapの内容で上書きされる可能性があります。したがって、設定を永続的に維持するには、ConfigMap自体を修正するか、/var/lib/kubelet/kubeadm-flags.envにフラグを追加する必要があります。
3. serving証明書は自動承認されない rotateCertificatesはクライアント証明書の自動更新を制御します。serving証明書(serverTLSBootstrap: true)は別の設定であり、この場合controller-managerは自動承認しないため、管理者が直接kubectl certificate approveを実行する必要があります。
4. ConfigMapの名前がバージョンごとに異なる kubeadm 1.24未満ではkubelet-config-1.{minor}形式です。以下のコマンドで正確な名前をまず確認してください。
kubectl get configmap -n kube-system | grep kubelet-config
5. YAMLのインデントエラーに注意 ConfigMapのdata.kubeletフィールドは、YAML文字列の中にさらにYAMLが入る構造です。kubectl edit使用時にインデントが間違っているとkubeletが設定をパースできないため、保存前に必ず確認してください。
✅ まとめ / 締めくくり
ConfigMapベースのrotateCertificates設定の流れをまとめると以下のようになります。
- kubectl get configmap kubelet-config -n kube-systemで現在の設定を確認
- kubectl editまたはpatchでrotateCertificates: trueを反映
- 各ワーカーノードでkubeadm upgrade node phase kubelet-configを実行
- systemctl restart kubeletで再起動
- kubectl get csrと証明書の有効期限で正常動作を確認
この方式の主な利点は、ConfigMapがSingle Source of Truthの役割を果たす点です。今後新しいノードが追加された際、kubeadm joinを実行するだけで同じ設定が自動的にデプロイされます。これにより管理の複雑さが大幅に軽減されます。

コメントを残す