kubeadm拉起的k8s集群证书过期的做法集群已奔溃也可以解决

kubeadm拉起的k8s集群证书过期的做法

这个是很久之前遇到的了,今天有空(心血来潮)就都回忆回忆写在这里为爱发光,部分内容来自arch先生(死党)的帮助。

有时候有很多部门提了建k8s的需求,有些是临时的,有些没有说具体用多久,但是某天,他们和你说集群坏了,这时候你上去一看证书过期了,这里又有两种情况我们分别说明:

集群还活着

集群已归西(麻烦事儿)

集群还活着

bash 复制代码
#查看证书过期时间
kubeadm certs check-expiration

#如果过期就更新
kubeadm certs renew all

#更新完证书再次查看
kubeadm certs check-expiration

#更新完证书后还需要重启api-server,controller-manager,scheduler,etcd

#看看有没有这个文件
ll /etc/crictl.yaml

#没有就主动生成
echo "runtime-endpoint: unix:///run/containerd/containerd.sock" \
    |  tee /etc/crictl.yaml

containerd执行脚本更新相关服务
pods="crictl pods --namespace kube-system --state READY"
for component in  kube-apiserver kube-controller-manager kube-scheduler etcd; do
    echo "> `date +%DT%T` Restart $component"
    $pods | grep "$component" | awk '{print "crictl stopp "$1 | "sh"}'
    sleep 5
    echo "---------------------------------------"
done

使用kubectl获取集群资源看是否正常。

集群已归西

此时集群无法连接、无法管理,甚至无法启动

1、备份数据
bash 复制代码
mkdir ~/recovery

sudo rsync -av /etc/kubernetes/ ~/recovery/etc-kubernetes/

sudo rsync -av /var/lib/etcd/ ~/recovery/var-lib-etcd/

sudo rsync -av /var/lib/kubelet/ ~/recovery/var-lib-kubelet/
2、报错内容及分析
bash 复制代码
journalctl -u kubelet.service
kubelet[2447]: E0923 bootstrap.go:265]  part of the existing bootstrap client certificate in /etc/kubernetes/kubelet.conf is expired: xxxxxxxxx

显而易见,kubelet 使用的证书过期了

查看 /etc/kubernetes/kubelet.conf 内容,看它使用的证书文件路径

yaml 复制代码
users:
- name: system:node:xxxx
  user:
    client-certificate: /var/lib/kubelet/pki/kubelet-client-current.pem
    client-key: /var/lib/kubelet/pki/kubelet-client-current.pem

接着进入 /var/lib/kubelet/pki kubelet 的证书、私钥都在这里,而且还有一个 kubelet.conf 引用的 pem 文件

.crt + .key = .pem

接着解析 kubelet.crt 内容

bash 复制代码
openssl x509 -in kubelet/pki/kubelet.crt -noout -text

Certificate:
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN=kubernetes
        Validity
            Not Before: Jan  6 15:53:54 2022 GMT
            Not After : Jan  6 15:53:54 2023 GMT
        Subject: O=system:nodes, CN=system:node:vm-m1
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
        X509v3 extensions:
            X509v3 Subject Alternative Name:
                DNS:vm-m1

主机名是 vm-m1,被 CN 和 DNS 用到

Subject 格式 O=system:nodes, CN=system:node:${主机名}
DNS 格式 ${主机名}
3、生成证书

由于过期的是 kubelet 使用的证书,而 ca 没过期,因此基于已有 ca 生成证书

node_name=vm-m1

bash 复制代码
#生成 EC 私钥 (P-256 椭圆曲线)
openssl ecparam -genkey -name prime256v1 -noout -out kubelet.key

#创建证书签署请求 (CSR)
openssl req -new -key kubelet.key -out kubelet.csr -subj "/O=system:nodes/CN=system:node:${node_name}"

#引用已有 ca,生成 crt 证书
openssl x509 -req -in kubelet.csr \
    -CA /etc/kubernetes/pki/ca.crt \
    -CAkey /etc/kubernetes/pki/ca.key \
    -CAcreateserial \
    -out kubelet.crt \
    -days 365 \
    -extensions v3_req \
    -extfile <(cat <<EOF
[ v3_req ]
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = ${node_name}
EOF
)
4、证书内容合并

date_time= ( d a t e + c a t k u b e l e t . c r t > k u b e l e t − c l i e n t − (date +%F-%H-%M-%S) cat kubelet.crt > kubelet-client- (date+catkubelet.crt>kubelet−client−{date_time}.pem

cat kubelet.key >> kubelet-client-${date_time}.pem

5、证书替换
bash 复制代码
systemctl stop kubelet.service

cp -vf kubelet.crt kubelet.key /var/lib/kubelet/pki/

cd /var/lib/kubelet/pki/

ln -sf /var/lib/kubelet/pki/kubelet-client-${date_time}.pem kubelet-client-current.pem 

systemctl start kubelet.service
6、证书生效

当然这个场景下也得同步更新其他组件的证书

bash 复制代码
kubeadm certs renew all

接着刷新各个组件使用的证书,更建议直接 reboot 刷新

相关推荐
@郭小茶2 小时前
windows部署docker
windows·docker·容器
云上艺旅3 小时前
K8S学习之基础七十二:Ingress基于Https代理pod
学习·云原生·容器·https·kubernetes
XAL13 小时前
Docker的备份与恢复
运维·docker·容器
liux35283 小时前
k8s之Ingress讲解
云原生·容器·kubernetes
阿里云云原生3 小时前
函数计算支持热门 MCP Server 一键部署
云原生
阿里云云原生4 小时前
AI 网关代理 LLMs 最佳实践
云原生
欧先生^_^5 小时前
docker的文件系统Overlay2
运维·docker·容器
小刘爱喇石( ˝ᗢ̈˝ )7 小时前
玛卡巴卡的k8s知识点问答题(六)
云原生·容器·kubernetes
rider1897 小时前
【1】搭建k8s集群系列(二进制部署)之系统初始化
云原生·容器·kubernetes
阳小江7 小时前
Docker知识点
运维·docker·容器