k8s集群的CA证书过期处理

文章目录

不改变原CA的公私钥,安全地在线地更新集群CA

制作延期的CA证书

使用go语言开发的证书生成工具cfssl(必须)

获取CA全名

bash 复制代码
cfssl certinfo -cert /etc/kubernetes/pki/ca.crt

准备签发申请配置

把原CA的组织、名称信息写入申请配置,并设置新CA证书的过期时间为10年后

bash 复制代码
tee ca-cfssl-csr.json <<-'EOF'
{
  "CA": {
    "expiry": "87600h",
    "pathlen": 2
  },
  "names":[{
      "C": "",
      "ST": "",
      "L": "",
      "O": "",
      "OU": ""
    }
  ],
  "CN": "kubernetes"
}
EOF

生成新CA

cfssl开启参数initca,传入原CA私钥,保持新生成的CA公钥与之前一致

bash 复制代码
cfssl gencert -initca=true -ca-key ca.key ca-cfssl-csr.json | cfssljson -bare ca-20240406

不能使用openssl来生成CA,因为kubeadm、kube-apiserver是golang开发的,golang的pki工具包核对证书链时,要求CA证书的rawSubject、客户端证书里记录的rawIssuer完全一致;而cfssl、kubeadm都是golang开发的,能够把信息相同的Subject对象(即CA证书的组织、名称)序列化为一致的rawSubject(DER字节数组)

验证并替换CA

确认新CA是否可以用于验证原CA签发的证书

bash 复制代码
openssl verify -CAfile ca-20240406.pem apiserver.crt
# 备份原CA
mv ca.crt ca-20191001.crt
mv ca-20240406.pem ca.crt

更新master组件的CA配置

kube-apiserver

apiserver的client-ca-file 参数,用于验证其他master组件、kubelet的客户端证书的合法性,默认指向/etc/kubernetes/pki/ca.crt;

ca.crt文件更新后,重启apiserver即可。
requestheader-client-ca-file 、etcd-cafile参数指向的其他ca文件,如需延期,也是按照相同步骤来生成延期的新ca文件

kube-controller-manager

controller-manager连接apiserver的配置信息,默认放在/etc/kubernetes/controller-manager.conf文件里;

controller-manager.conf文件里certificate-authority-data字段的值,就是对/etc/kubernetes/pki/ca.crt文件的base64 with padding编码;
root-ca-file 参数控制的是注入到ServiceAccount secret里的CA数据,也是指向/etc/kubernetes/pki/ca.crt;
cluster-signing-cert-file 参数控制的是签发客户端证书的CA,也是指向/etc/kubernetes/pki/ca.crt;

需要替换certificate-authority-data字段后重启controller-manager

kube-scheduler

更新/etc/kubernetes/scheduler.conf里的certificate-authority-data后重启scheduler

kube-admin

更新/etc/kubernetes/admin.conf里的certificate-authority-data;

把admin.conf复制到~/.kube/config里,供kubectl使用

检查证书过期时间

检查apiserver服务端证书、检查配置文件里的客户端证书(client-certificate-data)、检查CA证书:

bash 复制代码
kubeadm certs check-expiration

更新ServiceAccount secret

controller-manager的root-ca-file 更新后,会自动更新所有ServiceAccount secret里的ca.crt字段(用于验证apiserver服务端证书的合法性);

使用了ServiceAccount来查询/管理集群配置的系统组件,如kube-proxy、calico、coredns,需要手动重启,以重新加载由ServiceAccount secret注入的CA文件

bash 复制代码
kubectl rollout restart deployment coredns -n kube-system

ServiceAccount secret里的token部分,就是一个JWT,且不含expire信息,不会过期

更新node组件配置的CA

更新kubelet连接配置

更新/etc/kubernetes/kubelet.conf里的certificate-authority-data后重启kubelet;

kubelet及时恢复与apiserver的通讯,不会影响宿主机已运行的pod

签发kubelet自动申请的客户端证书

kubelet发现自己的证书快过期后,会自动申请续期自己的客户端证书;如果申请的证书可用时间超过了ca本身的有效期,则不允许申请;集群ca更新后,就可以看到待签发的证书申请记录

bash 复制代码
kubectl get csr
# 批量通过申请
kubectl get csr | grep 'Pending'| cut -d ' ' -f 1 |xargs -I{} kubectl certificate approve {}

批准签发证书后,到宿主机查看新的kubelet证书

bash 复制代码
# 默认的kubelet证书存放位置
ls -al /var/lib/kubelet/pki/

更新master组件的服务端/客户端证书(可选)

如果不想每年手动生成新的证书,可以自己制作长期证书

kube-apiserver

使用原证书的信息,使用原证书的私钥,制作csr文件;

csr文件包含了证书subject(所属组织、证书名称)、公钥原文这两个关键信息,并使用私钥进行了自签名

bash 复制代码
/usr/bin/openssl x509 -x509toreq -in apiserver.crt -signkey apiserver.key -out apiserver.csr
# 查看csr内容
/usr/bin/openssl req -text -noout -in apiserver.csr

根据csr文件,使用CA私钥签发证书

bash 复制代码
# 指定证书的密钥用法(TLS密钥协商)、扩展用途(服务端证书)、可选名称(域名和IP)
tee apiserver_ext.cnf <<-'EOF'
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = @alt_names
[alt_names]
DNS.1= kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
DNS.5 = <服务器名字/域名>
IP.1 = 10.96.0.1
IP.2 = <服务器IP/反向代理IP>
EOF
# 制作10年有效期的证书
/usr/bin/openssl x509 -req -days 3650 -in apiserver.csr -extfile apiserver_ext.cnf -CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver-new20240305.crt
# 验证新证书
/usr/bin/openssl verify -CAfile ca.crt -verbose apiserver-new20240305.crt

覆盖原先的apiserver.crt文件,重启apiserver即可

kube-admin

从/etc/kubernetes/admin.conf里获取admin的客户端证书和私钥;

client-certificate-data,进行base64 decode后得到的文本保存为kube-admin.crt文件;

client-key-data,进行base64 decode后得到的文本保存为kube-admin.key文件

bash 复制代码
/usr/bin/openssl x509 -x509toreq -in kube-admin.crt -signkey kube-admin.key -out kube-admin.csr

使用CA私钥签发证书

bash 复制代码
tee kube-admin_ext.cnf <<-'EOF'
basicConstraints = CA:FALSE
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid,issuer
keyUsage = critical, digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth
EOF
# 制作10年有效期的证书
/usr/bin/openssl x509 -req -days 3650 -in kube-admin.csr -extfile kube-admin_ext.cnf -CA ca.crt -CAkey ca.key -CAcreateserial -out kube-admin-new20240305.crt
# 验证新证书
/usr/bin/openssl verify -CAfile ca.crt -verbose kube-admin-new20240305.crt

更新admin.conf文件,把kube-admin-new20240305.crt文件进行base64 with padding编码,填回client-certificate-data字段;

把admin.conf复制到~/.kube/config里,供kubectl使用

相关推荐
Z21-X7 分钟前
云原生运维实战笔记:华为云存储类服务全景解析——EVS、OBS、SFS与CBR深度实践
运维·笔记·学习·云原生·华为云
分布式存储与RustFS1 小时前
K8s 集群备份落到自建对象存储:Velero 接 RustFS 配置指南
运维·云原生·开源·对象存储·分布式存储·s3·性能基准
无言听风雨丶10 小时前
Kubernetes 控制平面深度剖析:从 kubectl apply 到 etcd 写入的全链路
平面·kubernetes·etcd
openFuyao11 小时前
openFuyao x 复旦大学软件工程实验室 Panel 回顾:Agentic时代,集群调度技术体系将如何演进?
kubernetes·openfuyao
螺蛳粉 螺蛳粉11 小时前
第 05 篇:etcd 深入:Raft 共识、watch 机制与快照备份恢复实战(底座认知 05)
docker·云原生·容器·kubernetes·etcd·分布式存储·kube-apiserver
知已难寻12 小时前
03 · OpenStack的计算管理 Nova
运维·服务器·开发语言·云原生·云计算·openstack·开源软件
相思难忘成疾14 小时前
从零搭建 Kubernetes 1.30 集群:kubeadm 部署一主多从实战(RHEL 9.3 + Docker + flannel)
linux·运维·kubernetes
n1121215 小时前
Ollama 接 Open WebUI 中文界面:我踩的 4 个坑
云原生·eureka·ollama·本地大模型·open webui·私有部署·中文界面
阿里云云原生15 小时前
用户说 App“下不了单”:用 Session Replay 看清流程卡在哪一步
云原生
weirong15 小时前
给 K8s 加一个自动值班员:分级故障自愈引擎
kubernetes