如果证书腐烂并且群集变成南瓜怎么办?

如果响应kubectl get pod命令,您将得到:

 Unable to connect to the server: x509: certificate has expired or is not yet valid 

然后,很可能是一年过去了,您的kubernetes证书已过期,集群组件停止使用它们,它们之间的交互也停止了,并且您的集群变成了南瓜。

图片

怎么办以及如何还原集群?

首先,我们需要了解需要更新的证书的位置。

根据群集的安装方式,证书文件的位置和名称可能会有所不同。 因此,例如,在创建集群时,Kubeadm将根据最佳实践分解证书文件。 因此,所有证书都位于/etc/kuberenetes/pki ,扩展名为.crt文件分别位于.key文件中的私钥中。 在/etc/kubernetes/ .conf文件,这些文件具有来自主节点的用户帐户管理员,经理控制器,sheduler和kubelet的访问配置。 .conf文件中的证书位于base.64编码形式的user.client-certificate-data字段中。

您可以使用此小型shcert脚本查看颁发证书的日期和由谁签名证书的到期日期

shcert
 #!/bin/bash [ -f "$1" ] || exit if [[ $1 =~ \.(crt|pem)$ ]]; then openssl x509 -in "$1" -text -noout fi if [[ $1 =~ \.conf$ ]]; then certfile=$(mktemp) grep 'client-certificate-data:' "$1"| awk '{ print $2}' | base64 -d > "$certfile" openssl x509 -in "$certfile" -text -noout rm -f "$certfile" fi 


在API中,仍然存在在工作节点上使用kubelet进行身份验证的证书。 如果使用kubeadm join将节点添加到集群,则很可能是使用TLS引导过程连接了该节点,在这种情况下,如果kubelet被赋予--rotate-certificates选项,则可以自动更新其证书。 在最新版本的kubernetes中,默认情况下已启用此选项。
使用TLS引导程序检查节点是否已连接非常简单-在这种情况下,通常在/var/lib/kubelet/pki/kubelet-client-current.pem文件中的客户端证书文件中指定/var/lib/kubelet/pki/kubelet-client-current.pem文件。这是当前证书的符号链接。

您还可以使用shcert脚本查看此证书的到期日期shcert

我们回到了续订证书的问题。

如果您使用kubeadm安装了集群,那么我对您来说是个好消息。 从版本1.15开始,kubeadm可以使用一个命令更新几乎所有控制平面证书

 kubeadm alpha certs renew all 

此命令将续订/ etc / kubernetes目录中的所有证书,即使它们已经过期并且一切都已损坏。

仅kubelet证书不会被更新-这是/etc/kubernetes/kubelet.conf文件中的/etc/kubernetes/kubelet.conf
更新:从版本1.17开始的kubeadm,在所有节点上(甚至在完成kubeadm初始化的第一个向导中)都包括自动更新底签证书。 检查非常简单-在/etc/kubernetes/kubelet.conf中,文件/var/lib/kubelet/pki/kubelet-client-current.pem /etc/kubernetes/kubelet.conf路径将显示在客户端证书字段中

要续订此证书,请使用创建用户帐户命令

 kubeadm alpha kubeconfig user --client-name system:node:kube.slurm.io --org system:nodes > /etc/kubernetes/kubelet.conf 

如果系统具有用户帐户,则此命令将更新该帐户的证书。 不要忘记在--client-name选项中指定正确的主机名,您可以在现有证书的“主题”字段中--client-name主机名:

 shcert /etc/kubernetes/kubelet.conf 

当然,更新证书后,您需要重新启动控制平面的所有组件,重新启动整个节点或使用docker docker stop使用etcd,api,controller-manager和Scheduler停止容器,然后重新启动kubelet systemctl restart kubelet

如果您的集群使用的是旧版本:1.13或更低版本,它将无法将kubeadm升级到1.15,因为它附带了kubelet和kubernetes-cni依赖性,这可能会引起问题,因为集群组件的性能在版本中相差一个以上。阶段,不能保证。 解决这种情况的最简单方法是在其他计算机上安装kubeadm,获取二进制文件/usr/bin/kubeadm ,将其复制到已故集群的主节点上,并仅用于续订证书。 在恢复群集活力之后,请使用常规方法逐步更新它,并在每次安装kubeadm时都更新一个版本。

最后,从1.15版开始,kubeadm学习了如何在使用kubeadm upgrade命令更新集群时更新所有证书。 因此,如果您每年至少定期更新一次群集,则证书将始终有效。

但是,如果未使用kubeadm安装集群,则必须选择openssl并单独续订所有证书。

问题在于证书包含扩展字段,并且不同的群集安装工具可以添加自己的字段集。 而且,openssl配置中这些字段的名称与证书内容的输出中的名称相互关联,但关联性很弱。 有必要谷歌和选择。

我将为openssl提供一个示例配置,在单独的部分中描述了每种证书的特定扩展属性。 创建和签名csr时,我们将参考相应的部分。 该配置用于恢复牧场主一年前建立的集群。

openssl.cnf
 [req] distinguished_name = req_distinguished_name req_extensions = v3_req [v3_req] keyUsage = nonRepudiation, digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [client] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth [apiproxyclient] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth [etcd] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [api] keyUsage = critical,digitalSignature, keyEncipherment extendedKeyUsage = clientAuth, serverAuth subjectAltName = @alt_names [alt_names] DNS.1 = ec2-us-east-1-1a-c1-master-2 DNS.2 = ec2-us-east-1-1a-c1-master-3 DNS.3 = ec2-us-east-1-1a-c1-master-1 DNS.4 = localhost DNS.5 = kubernetes DNS.6 = kubernetes.default DNS.7 = kubernetes.default.svc DNS.8 = kubernetes.default.svc.cluster.local IP.1 = 10.0.0.109 IP.2 = 10.0.0.159 IP.3 = 10.0.0.236 IP.4 = 127.0.0.1 IP.5 = 10.43.0.1 


可以使用以下命令查看证书中的实际属性和附加名称

 openssl x509 -in cert.crt -text 

为服务器API续订证书时,出现了一个问题:更新的证书不起作用。 解决方案是颁发过去一年有效的证书。

在openssl中,您不能使用简单的命令来颁发过去有效的证书,该代码严格规定该证书仅在当前时刻有效。 但是您可以使用libfaketime库在本地追溯时间

 yum install libfaketime LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req ... 

我们根据以下算法发行扩展证书:

我们使用现有证书创建CSR,并在配置文件中使用高级属性列表指定所需的部分:

 openssl x509 -x509toreq -in "node.cert" -out "node.csr" -signkey "node.key" -extfile "openssl.cnf" -extensions client 

我们使用相应的根证书对其进行签名,将时间提前一年,并在配置文件中使用高级属性列表指定所需的部分

 LD_PRELOAD=/usr/lib64/faketime/libfaketime.so.1 FAKETIME="-365d" openssl x509 -req -days 36500 -in "node.csr" -CA "kube-ca.pem" -CAkey "kube-ca-key.pem" -CAcreateserial -out "node.new.cert" -extfile "openssl.cnf" -extensions client 

我们检查属性并重新启动控制平面组件。

谢尔盖·邦达列夫,
口语老师
slurm.io

Source: https://habr.com/ru/post/zh-CN465733/


All Articles