导读:本期聚焦于本地能跑创作的《Kubernetes手动生成证书怎么做?从零搭建CA到签发组件证书的完整指南》,敬请观看详情。用kubeadm搭建集群虽然省心,可一旦遇到证书过期、自定义SAN或需要复用CA的场景,手动生成证书就成了绕不开的技能。本文围绕Kubernetes手动生成证书这一主题,先讲清楚集群里各个组件到底需要哪些证书、谁来验证谁,再用cfssl从零创建CA、签发apiserver、etcd、kubelet等证书,并给出常用的openssl命令作为备选方案。文中还整理了SAN字段写不全、证书过期、权限错误等高频坑点及规避方法,帮助你彻底掌握证书生成流程,收藏起来以备不时之需。

Kubernetes集群的安全体系完全建立在PKI证书之上,apiserver、etcd、kubelet、controller-manager等组件之间的双向认证都依赖证书完成。平时用kubeadm部署时证书会自动生成,一年一换,看似省心,但当你需要延长证书有效期、修改 apiserver 的SAN列表、多集群复用同一CA,或者排障时发现证书对不上,就必须理解证书的生成原理并掌握手动签发方法。本文用cfssl工具完整演示从零创建CA到签发各组件证书的全过程,并附上openssl备选方案和踩坑经验。

Kubernetes手动生成证书怎么做?从零搭建CA到签发组件证书的完整指南

一、先弄清楚Kubernetes到底需要哪些证书

Kubernetes的证书体系比很多人想象的复杂,一个生产级集群至少需要十来张证书,分别服务于不同的组件和通信路径。动手之前必须先梳理清楚谁持有证书、谁验证证书,否则签出来的证书放错位置,排错会非常痛苦。

首先是集群的根证书,也就是CA证书及其私钥。CA是整个信任链的起点,所有组件证书都由它签发,apiserver、kubelet、etcd各角色默认会复用同一个CA,也可以为etcd单独建一个CA实现隔离。CA私钥是集群中最高机密,泄露意味着任何人都能签发合法证书,务必妥善保管。

其次是apiserver的服务端证书。这张证书最关键,它的SAN字段必须包含apiserver对外提供服务的所有可能被访问到的地址,包括服务IP(默认10.96.0.1)、Kubernetes短域名、完整域名、Master节点IP、Master主机名、负载均衡地址等。任何一个访问地址没写进SAN,客户端校验就会报证书主体不匹配的错误。除了服务端证书,apiserver还需要一张客户端证书用于访问etcd,一张用于访问kubelet的客户端证书。etcd如果是独立部署,还需要自己的服务端证书和对等证书。kubelet侧则包含apiserver访问kubelet用的客户端证书,以及kubelet自己的服务端证书。

另外controller-manager和scheduler各需要一张客户端证书连接apiserver,集群管理员用的kubectl以及ServiceAccount自动挂载的证书也都属于这套体系。理清这些关系后你会发现,手动生成证书本质上就是围绕一个CA,按角色签发对应用途的证书。

二、用cfssl创建CA并签发组件证书

cfssl是CloudFlare开源的证书工具,相比openssl命令行,它的JSON配置更易维护、可重复执行,是社区里手动管理Kubernetes证书的主流选择。先下载安装cfssl、cfssljson两个工具,然后将它们移动到PATH目录下即可。

第一步创建CA。编写ca-config.json定义签名策略,编写ca-csr.json定义CA自身信息:

cat > ca-config.json <<EOF
{
  "signing": {
    "default": {
      "expiry": "87600h"
    },
    "profiles": {
      "server": {
        "expiry": "87600h",
        "usages": ["signing", "key encipherment", "server auth"]
      },
      "client": {
        "expiry": "87600h",
        "usages": ["signing", "key encipherment", "client auth"]
      },
      "peer": {
        "expiry": "87600h",
        "usages": ["signing", "key encipherment", "server auth", "client auth"]
      }
    }
  }
}
EOF

cat > ca-csr.json <<EOF
{
  "CN": "kubernetes",
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "k8s",
      "OU": "system"
    }
  ]
}
EOF

cfssl gencert -initca ca-csr.json | cfssljson -bare ca

执行后得到ca.pem和ca-key.pem,分别对应CA证书和私钥。这里的87600h是十年有效期,CA有效期建议设置得比组件证书长很多,避免CA先过期导致整个信任链失效。

第二步签发apiserver证书,这是最容易出错的一步,核心在于hosts字段要写全。编写kubernetes-csr.json:

cat > kubernetes-csr.json <<EOF
{
  "CN": "kubernetes",
  "hosts": [
    "127.0.0.1",
    "10.96.0.1",
    "169.169.0.1",
    "kubernetes",
    "kubernetes.default",
    "kubernetes.default.svc",
    "kubernetes.default.svc.cluster",
    "kubernetes.default.svc.cluster.local",
    "192.168.10.10",
    "master01",
    "master01.k8s.local",
    "192.168.10.100"
  ],
  "key": {
    "algo": "rsa",
    "size": 2048
  },
  "names": [
    {
      "C": "CN",
      "ST": "Beijing",
      "L": "Beijing",
      "O": "k8s",
      "OU": "system"
    }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
  -config=ca-config.json -profile=server \
  kubernetes-csr.json | cfssljson -bare kubernetes

hosts列表中10.96.0.1是service网段的第一个IP,apiserver的ClusterIP固定用它;127.0.0.1覆盖本机访问;后面依次是节点IP、主机名和负载均衡VIP。如果后续扩容Master或者更换LB地址,记得重新签发证书补充SAN,否则kubectl会报证书校验失败。

第三步签发客户端和节点证书。admin用户的客户端证书有一个特殊细节:O字段必须写成system:masters,apiserver通过O字段做RBAC用户组识别。kubelet的证书CN要采用system:node:节点名 格式,这样它才能被内建的Node授权器认可:

cat > admin-csr.json <<EOF
{
  "CN": "admin",
  "hosts": [],
  "key": { "algo": "rsa", "size": 2048 },
  "names": [
    { "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "system:masters", "OU": "system" }
  ]
}
EOF

cfssl gencert -ca=ca.pem -ca-key=ca-key.pem \
  -config=ca-config.json -profile=client \
  admin-csr.json | cfssljson -bare admin

cat > kubelet-csr.json <<EOF
{
  "CN": "system:node:node01",
  "hosts": [],
  "key": { "algo": "rsa", "size": 2048 },
  "names": [
    { "C": "CN", "ST": "Beijing", "L": "Beijing", "O": "system:nodes", "OU": "system" }
  ]
}
EOF

etcd集群的证书建议用peer profile签发,因为etcd节点之间既要作为服务端也要作为客户端,双向认证场景下一张证书同时承担两种角色。每张证书签发完成后,可以用openssl x509 -in kubernetes.pem -text -noout查看SAN和有效期,确认无误再分发到各节点。

三、openssl备选方案与关键参数

如果不方便安装cfssl,openssl同样可以完成全部工作,只是命令较长且容易出错。核心命令是生成私钥、构造CSR、用CA签发三步:

# 生成apiserver私钥
openssl genrsa -out apiserver-key.pem 2048

# 生成CSR,重点在extfile中定义SAN
openssl req -new -key apiserver-key.pem \
  -subj "/CN=kubernetes/O=k8s" \
  -out apiserver.csr

cat > apiserver-ext.cnf <<EOF
basicConstraints=CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth
subjectAltName = IP.1=127.0.0.1,IP.2=10.96.0.1,IP.3=192.168.10.10,DNS.1=kubernetes,DNS.2=kubernetes.default,DNS.3=master01
EOF

# 用CA签发
openssl x509 -req -in apiserver.csr \
  -CA ca.pem -CAkey ca-key.pem -CAcreateserial \
  -out apiserver.pem -days 3650 \
  -extfile apiserver-ext.cnf

openssl方案最大的坑是忘写-extfile参数,导致签出来的证书没有SAN字段。现代客户端普遍强制校验SAN而忽略CN,所以用openssl签发Kubernetes证书时,subjectAltName绝对不能省,签发后务必检查一遍。

四、常见坑点与避坑建议

第一类坑是SAN不全。表现为kubectl偶发性报证书错误,直接IP访问没问题但通过LB访问失败,或者Pod内访问ClusterIP失败。原因都是证书没有覆盖对应的访问路径。对策是在签发前把所有可能的地址列全,宁可多写不要漏写,并预留未来扩容的地址。

第二类坑是证书有效期。kubeadm默认一年,到期后集群所有组件同时失联,恢复起来相当狼狈。建议自签证书时把有效期设为三到十年,并建立监控,在到期前三十天告警。检查证书有效期的命令是kubeadm certs check-expiration,或者用openssl逐张查看。

第三类坑是CN和O字段不符合Kubernetes约定。apiserver内置的授权器对证书里的组织信息有硬编码要求,kubelet证书CN必须是system:node:加上节点名且与kubelet配置中的节点名完全一致,admin证书的O必须是system:masters。这些字段写错,证书本身校验能通过,但请求会被授权层拒绝,报权限不足的问题,排查方向容易跑偏。

第四类是文件权限和分发问题。CA私钥只能保存在Master节点,权限建议600;各组件私钥权限也要收紧,放在kubelet可读的目录并防止普通用户读取。证书更新后需要重启对应组件才能加载新证书,apiserver可以借助--tls-cert-file等参数指定路径,kubelet则可以开启轮转机制实现自动续期。最后建议把所有CSR的JSON文件纳入版本管理,下次换证时直接复用,既保证SAN信息不丢,也大幅降低操作失误的概率。

Kubernetes证书手动生成证书cfssl修改时间:2026-09-02 13:32:55

免责声明:已尽一切努力确保本网站所含信息的准确性。网站作品多为原创整理与精心创作,观点力求客观中立。本站旨在免费分享,内容仅供个人学习、研究或参考使用。若引用了第三方作品,版权归原作者所有。如内容涉及您的权益,请联系我们进行处理Email:chomcom@qq.com。
引用或转载本作品时,请注明当前出处:https://www.ipipp.com/html/20260902/48961.html,基于非商业用途的前提下,欢迎转载或二创本作品。
内容垂直聚焦
专注技术核心技术栏目,确保每篇文章深度聚焦于实用技能。从代码技巧到架构设计,为用户提供无干扰的纯技术知识沉淀,精准满足专业提升需求。
知识结构清晰
覆盖从开发到部署的全链路。AI、前端、编程、数据库、服务器、建站、系统层层递进,构建清晰学习路径,帮助用户系统化掌握开发与运维所需的核心技术。
深度技术解析
拒绝泛泛而谈,深入技术细节与实践难点。无论是数据库优化还是服务器配置,均结合真实场景与代码示例进行剖析,致力于提供可直接应用于工作的解决方案。
专业领域覆盖
精准对应开发生命周期。从前端界面到后端编程,从数据库操作到服务器运维,形成完整闭环,一站式满足全栈工程师和运维人员的技术需求。
即学即用高效
内容强调实操性,步骤清晰、代码完整。用户可根据教程直接复现和应用于自身项目,显著缩短从学习到实践的距离,快速解决开发中的具体问题。
持续更新保障
专注既定技术方向进行长期、稳定的内容输出。确保各栏目技术文章持续更新迭代,紧跟主流技术发展趋势,为用户提供经久不衰的学习价值。