关于kubernetes1.9证书过期(certificate has expired or is not yet valid)

喜欢ヅ旅行 2023-07-24 02:21 83阅读 0赞
胆战心惊的一天

今天突然收到告警,k8s的节点NotReady,我靠!吓了一身冷汗,遂远程登录上去查看,果然都是notready!这一吓真是不轻啊,要知道所有node节点挂掉,等于整个集群挂掉了,线上的服务都不能访问。当时要是采访我当时在想什么,我只能高冷的回答你:“啥都没想”,当时真是脑袋一片空白。
不过呢,辛好留了一手,使用k8s之前,也用虚拟机把k8s上的服务也部署了一遍,就是防止这种现象出现,当时也考虑到k8s集群会有坑,没想到这么深,直接导致整个集群不可用。部署的时候在想最好不要用到,果不其然,天不遂人愿,竟然真的用到了。所以说多做些应急准备工作,就显得非常有必要了。
既然对客户访问和使用不会造成影响,心里如释重负,压力不是很大了。开始着手排查问题。

一、问题现象

Kubernetes 集群日志中出现

  1. Apr 08 17:22:36 beta-k8s-master-1 kube-apiserver[1020]: E0408 17:22:36.857055 1020 authentication.go:64] Unable to authenticate the request due to an error: [x509: certificate has expired or is not yet valid, x509: certificate has expired or is not yet valid]

还有以下日志信息

  1. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.194226 3969 kubelet_node_status.go:383] Error updating node status, will retry: error getting node "node02": Unauthorized
  2. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.195088 3969 kubelet_node_status.go:383] Error updating node status, will retry: error getting node "node02": Unauthorized
  3. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.195961 3969 kubelet_node_status.go:383] Error updating node status, will retry: error getting node "node02": Unauthorized
  4. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.196918 3969 kubelet_node_status.go:383] Error updating node status, will retry: error getting node "node02": Unauthorized
  5. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.197846 3969 kubelet_node_status.go:383] Error updating node status, will retry: error getting node "node02": Unauthorized
  6. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.197870 3969 kubelet_node_status.go:375] Unable to update node status: update node status exceeds retry count
  7. Apr 08 15:34:25 node02 kubelet[3969]: E0408 15:34:25.220090 3969 reflector.go:205] k8s.io/kubernetes/pkg/kubelet/config/apiserver.go:47: Failed to list *v1.Pod: Unauthorized

以上信息显示证书过期了

二、排查思路

1.服务器时间不对,导致证书过期:登上k8s节点查看日志,发现时间都是北京时间,分秒不差。。。
2.确实证书过期了:
我的集群是自己手动搭建的,并没有通过kubeadm安装,证书也是手动一个个作的。

  1. $ openssl x509 -in /root/cfssl/kubernetes/kubernetes-root-ca.pem -noout -text |grep ' Not '
  2. Not Before: Apr 3 09:17:00 2018 GMT
  3. Not After : Apr 2 09:17:00 2023 GMT
  4. $ openssl x509 -in /root/cfssl/kubernetes/kubernetes-client-proxy.pem -noout -text |grep ' Not '
  5. Not Before: Apr 4 07:52:00 2018 GMT
  6. Not After : Apr 3 07:52:00 2023 GMT
  7. $ openssl x509 -in /root/cfssl/kubernetes/kubernetes-client-kubectl.pem -noout -text |grep ' Not '
  8. Not Before: Apr 3 09:29:00 2018 GMT
  9. Not After : Apr 2 09:29:00 2023 GMT

发现证书有效期是5年,还差好几年呢,日志怎么会报证书过期呢?
集群分为两种证书:
1.用于集群 Master、Etcd等通信的证书。
2.用于集群 Kubelet 组件证书。

这时坑位出现了:
我们在搭建 Kubernetes 集群时,一般只声明用于集群 Master、Etcd等通信的证书 为 10年 或者 更久,但未声明集群 Kubelet 组件证书 ,Kubelet 组件证书 默认有效期为1年。集群运行1年以后就会导致报 certificate has expired or is not yet valid 错误,导致集群 Node不能于集群 Master正常通信,node显示是NotReady状态。

三、解决问题

分两种解决方案:
1.临时解决证书问题:
重启node节点上kube-proxy 和 kubelet 服务,

  1. systemctl restart kubelet && systemctl restart kube-proxy

删除NotReady节点重新加入k8s集群

  1. $ kubectl delete node beta-k8s-node-1 beta-k8s-node-2 beta-k8s-node-3
  2. $ kubectl get csr
  3. $ kubectl certificate approve node-csr-T4t2IpJvE73djBPsqq-xx3FnMWOLTFyPNK-sQ
  4. $ kubectl certificate approve node-csr-_FaAvAIsXGZ4_vYfbT43xxwX9kMJCKDElfsRwA
  5. $ kubectl certificate approve node-csr-nHBw2mUbjxK9ZZLvxpOx_gxxx9VYBDlUCKybW6Y8D4

最后查看弄的状态都已经是ready了。服务也恢复正常

2.永久性解决证书问题(配置证书自动重载、轮转)

添加参数:
修改 kubelet 组件配置,具体添加下面参数

  1. --feature-gates=RotateKubeletServerCertificate=true
  2. --feature-gates=RotateKubeletClientCertificate=true
  3. # 1.8版本以上包含1.8都支持证书更换自动重载,以下版本只能手动重启服务
  4. --rotate-certificates

修改 controller-manager 组件配置,具体添加下面参数

  1. # 证书有效期为10年
  2. --experimental-cluster-signing-duration=87600h0m0s
  3. --feature-gates=RotateKubeletServerCertificate=true

创建自动批准相关 CSR 请求的 ClusterRole

  1. vim tls-instructs-csr.yaml && kubectl apply -f tls-instructs-csr.yaml
  2. kind: ClusterRole
  3. apiVersion: rbac.authorization.k8s.io/v1
  4. metadata:
  5. name: system:certificates.k8s.io:certificatesigningrequests:selfnodeserver
  6. rules:
  7. - apiGroups: ["certificates.k8s.io"]
  8. resources: ["certificatesigningrequests/selfnodeserver"]
  9. verbs: ["create"]

自动批准 kubelet-bootstrap 用户 TLS bootstrapping 首次申请证书的 CSR 请求

  1. kubectl create clusterrolebinding node-client-auto-approve-csr --clusterrole=system:certificates.k8s.io:certificatesigningrequests:nodeclient --user=kubelet-bootstrap

自动批准 system:nodes 组用户更新 kubelet 自身与 apiserver 通讯证书的 CSR 请求

  1. kubectl create clusterrolebinding node-client-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeclient --group=system:nodes

自动批准 system:nodes 组用户更新 kubelet 10250 api 端口证书的 CSR 请求

  1. kubectl create clusterrolebinding node-server-auto-renew-crt --clusterrole=system:certificates.k8s.io:certificatesigningrequests:selfnodeserver --group=system:nodes

重启kube-controller-manager 和 kubelet 服务

  1. $ systemctl restart kube-controller-manager
  2. # 进入到ssl配置目录,删除 kubelet 证书
  3. $ rm -f kubelet-client-current.pem kubelet-client-2019-05-10-09-57-21.pem kubelet.key kubelet.crt
  4. # 重启启动,启动正常后会颁发有效期10年的ssl证书
  5. $ systemctl restart kubelet
  6. # 进入到ssl配置目录,查看证书有效期
  7. $ openssl x509 -in kubelet-client-current.pem -noout -text | grep "Not"
  8. Not Before: May 13 02:36:00 2019 GMT
  9. Not After : May 10 02:36:00 2029 GMT

发表评论

表情:
评论列表 (有 0 条评论,83人围观)

还没有评论,来说两句吧...

相关阅读