逐个节点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配置存在于两个地方。
| 位置 | 作用 |
| kube-system/kubelet-config (ConfigMap) | 集群范围标准配置 (单一事实来源) |
| /var/lib/kubelet/config.yaml (各节点) | 节点上kubelet实际读取的配置文件 |
这两个文件不会自动同步。修改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。

💻 实践 / 示例代码
步骤 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
步骤 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 -
步骤 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
# 备份现有配置
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
步骤 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
步骤 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
步骤 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充当单一事实来源。将来添加新节点时,只需执行kubeadm join即可自动部署相同的设置。这种结构大大降低了管理复杂性。

发表回复