实用网络站
白蓝主题五 · 清爽阅读
首页  > 服务器维护

Kubernetes部署时证书配置踩坑实录:手把手配通apiserver和kubelet

上周帮客户上线一套K8s集群,三台节点跑得好好的,突然kubectl连不上了,报错:x509: certificate signed by unknown authority。翻日志发现是apiserver证书里没包含新加的负载均衡VIP,kubelet也因为证书CN不匹配拒绝注册——这种问题在真实运维现场太常见了。

证书到底要配哪几处?

Kubernetes不是只靠一个ca.crt就完事的。核心组件间通信依赖三类证书:

  • CA根证书(ca.crt/ca.key)——所有其他证书的签发者
  • apiserver服务端证书(apiserver.crt/apiserver.key)——必须包含所有可访问地址:127.0.0.1、节点内网IP、VIP、域名
  • kubelet客户端证书(kubelet.crt/kubelet.key)——CN字段得是节点名,且需被apiserver的client-ca-file信任

生成apiserver证书的关键一步

很多人用cfssl或openssl生成时漏掉SAN(Subject Alternative Name)。比如你用VIP 192.168.10.100做入口,但证书里只写了localhost和127.0.0.1,kubectl从外网连肯定失败。

用cfssl生成时,config.json里必须明确列出所有IP和域名:

{
  "hosts": [
    "127.0.0.1",
    "192.168.10.10",
    "192.168.10.11",
    "192.168.10.12",
    "192.168.10.100",
    "k8s.example.com",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster.local"
  ],
  "CN": "kubernetes",
  "key": {"algo": "rsa", "size": 2048}
}

kubelet证书不能只靠kubeadm自动生成

如果你用kubeadm init初始化集群,它会自动为每个节点生成kubelet证书,但默认CN是system:node:node1,而RBAC规则要求CN匹配system:node:<hostname>。结果就是节点状态卡在NotReady,日志里反复出现Unable to authenticate the request due to an error: x509: certificate is valid for system:node:node1, not system:node:node01

解决方法:手动签发时确保CN与实际hostname一致,或者修改kubeadm配置中的nodeRegistration.name字段。

检查证书是否生效的土办法

别光看文件存不存在,直接用openssl验:

# 查看apiserver证书支持哪些IP和域名
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -text -noout | grep -A1 "Subject Alternative Names"

# 测试kube-apiserver是否接受该证书连接
curl --cert /etc/kubernetes/pki/apiserver.crt --key /etc/kubernetes/pki/apiserver.key \
     --cacert /etc/kubernetes/pki/ca.crt https://192.168.10.100:6443/version

证书过期了怎么办?

kubeadm生成的证书默认一年有效期。到期前30天,kubectl get nodes可能开始报错,但集群还能跑;等真正过期,kubelet就无法上报心跳,节点变NotReady

快速续期命令(适用于kubeadm集群):

kubeadm certs renew all
systemctl restart kubelet

注意:如果用了外部etcd,还得单独更新etcd证书;若apiserver证书是自己签的,记得同步替换/etc/kubernetes/manifests/kube-apiserver.yaml里挂载的证书路径。