资讯动态

Kubernetes 集群 TLS 证书与密钥创建实战:基于 CFSSL 的 CA 与组件证书生成全指南

发布时间:2026/9/23 16:26:30 来源:尧图企业网站定制
Kubernetes 集群 TLS 证书与密钥创建实战基于 CFSSL 的 CA 与组件证书生成全指南【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook本指南完整讲解如何在 Kubernetes 集群安装的第一步——使用 CloudFlare 的 PKI 工具集 CFSSL 生成 Certificate Authority (CA) 及各组件etcd、kube-apiserver、kubelet、kube-proxy、kubectl、kube-controller-manager所需的 TLS 证书与私钥。读者将掌握 CA 配置ca-config.json、证书签名请求CSR编写、cfssl gencert签名流程、openssl/cfssl-certinfo校验方法以及证书与RBAC认证授权模型的对应关系为后续在 CentOS 上手工部署 Kubernetes 集群详见 install-kubernetes-on-centos打下坚实基础。在动手执行之前建议先通读以下三篇前置文档理解 TLS 在整个集群安全体系中的位置管理集群中的 TLS讲解集群根 CA 的信任模型、certificates.k8s.io证书签名请求 API 与签发流程以及集群管理员建议--cluster-signing-cert-file/--cluster-signing-key-filekubelet 的认证授权说明如何通过 X509 客户端证书认证访问 kubelet 的 HTTPS 端点TLS bootstrap介绍 kubelet 如何利用 bootstrap token 与csrapproving控制器自动申请客户端证书。注意事项务必先读这一步是安装配置 Kubernetes 的所有步骤中最容易出错、也最难排查问题的一步而它恰恰又是第一步。万事开头难不要因为这点困难就望而却步。如果您足够有信心能够在完全不了解自己在做什么的情况下成功地完成这一步的配置那么可以跳过上面的几篇文章直接进行下面的操作。Kubernetes 系统的各组件需要使用 TLS 证书对通信进行加密本文档使用 CloudFlare 的 PKI 工具集 cfssl 来生成 Certificate Authority (CA) 和各类证书。待生成的证书清单与组件使用对照生成的 CA 证书和私钥文件如下ca-key.pemca.pemkubernetes-key.pemkubernetes.pemkube-proxy.pemkube-proxy-key.pemadmin.pemadmin-key.pem使用证书的组件如下组件使用的证书文件etcdca.pem、kubernetes-key.pem、kubernetes.pemkube-apiserverca.pem、kubernetes-key.pem、kubernetes.pemkubeletca.pemkube-proxyca.pem、kube-proxy-key.pem、kube-proxy.pemkubectlca.pem、admin-key.pem、admin.pemkube-controller-managerca-key.pem、ca.pem操作范围说明以下所有操作都在 master 节点即172.20.0.113这台主机上执行。证书只需要创建一次即可以后在向集群中添加新节点时只要将/etc/kubernetes/目录下的证书拷贝到新节点上即可。这些证书在仓库的实际部署配置中均有印证例如 etc/kubernetes/apiserver 中KUBE_API_ARGS显式引用了--tls-cert-file/etc/kubernetes/ssl/kubernetes.pem --tls-private-key-file/etc/kubernetes/ssl/kubernetes-key.pem --client-ca-file/etc/kubernetes/ssl/ca.pem --etcd-cafile/etc/kubernetes/ssl/ca.pem --etcd-certfile/etc/kubernetes/ssl/kubernetes.pem --etcd-keyfile/etc/kubernetes/ssl/kubernetes-key.pem与上表完全对应。安装 CFSSLCFSSL 是 CloudFlare 开源的 PKI/TLS 工具包提供了cfssl签发、cfssljson将 JSON 输出转为 PEM 文件、cfssl-certinfo查看证书详情等子命令。方式一直接使用二进制源码包安装wget https://pkg.cfssl.org/R1.2/cfssl_linux-amd64 chmod x cfssl_linux-amd64 mv cfssl_linux-amd64 /usr/local/bin/cfssl wget https://pkg.cfssl.org/R1.2/cfssljson_linux-amd64 chmod x cfssljson_linux-amd64 mv cfssljson_linux-amd64 /usr/local/bin/cfssljson wget https://pkg.cfssl.org/R1.2/cfssl-certinfo_linux-amd64 chmod x cfssl-certinfo_linux-amd64 mv cfssl-certinfo_linux-amd64 /usr/local/bin/cfssl-certinfo export PATH/usr/local/bin:$PATH方式二使用 go 命令安装如果系统中已安装 Go本文场景为 Go 1.7.5使用以下命令安装更快捷$ go get -u github.com/cloudflare/cfssl/cmd/... $ echo $GOPATH /usr/local $ ls /usr/local/bin/cfssl* cfssl cfssl-bundle cfssl-certinfo cfssljson cfssl-newkey cfssl-scan在$GOPATH/bin目录下会得到以cfssl开头的几个命令。注意后续操作中凡是cat命令写入的文件如果不存在需要手工创建。创建 CACertificate AuthorityCA 是整个集群信任链的根后续所有组件证书都由它签发。因此 CA 的私钥ca-key.pem需要妥善保管——从仓库配置看kube-controller-manager需要它来为 kubelet 的 bootstrap 请求签发证书。创建 CA 配置文件mkdir /root/ssl cd /root/ssl cfssl print-defaults config config.json cfssl print-defaults csr csr.json # 根据config.json文件的格式创建如下的ca-config.json文件 # 过期时间设置成了 87600h cat ca-config.json EOF { signing: { default: { expiry: 87600h }, profiles: { kubernetes: { usages: [ signing, key encipherment, server auth, client auth ], expiry: 87600h } } } } EOF字段说明ca-config.json可以定义多个 profiles配置模板分别指定不同的过期时间、使用场景等参数后续在签名证书时使用某个 profile。本例定义了一个名为kubernetes的 profile后续所有组件证书签名都复用该 profilesigning表示该证书可用于签名其它证书生成的ca.pem证书中CATRUEserver auth表示 client 可以用该 CA 对 server 提供的证书进行验证即验证服务端身份client auth表示 server 可以用该 CA 对 client 提供的证书进行验证即验证客户端身份expiry: 87600h证书有效期87600h即 10 年365 × 24 × 10。生产环境可根据安全策略适当缩短但 CA 根证书的有效期应长于所有由它签发的子证书。创建 CA 证书签名请求创建ca-csr.json文件内容如下{ CN: kubernetes, key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: BeiJing, L: BeiJing, O: k8s, OU: System } ], ca: { expiry: 87600h } }字段说明CNCommon Namekube-apiserver 从证书中提取该字段作为请求的用户名User Name浏览器则使用该字段验证网站是否合法。这里 CA 的 CN 设为kubernetesOOrganizationkube-apiserver 从证书中提取该字段作为请求用户所属的组Groupkey.algo / key.size密钥算法与长度本例为 RSA 2048 位是当前兼容性与安全性平衡的默认选择names证书主体信息包含国家C、省ST、市L、组织O、组织单元OU。关于 CN 与 O 如何映射为 Kubernetes 用户与组可进一步阅读 Kubernetes 中的用户与身份认证授权 中 X509 Client Certs 一节API server 通过--client-ca-fileSOMEFILE启用客户端证书认证客户端证书验证通过后使用 subject 的 CN 作为请求的用户名使用证书的 organization 字段指示用户的组成员身份。生成 CA 证书和私钥$ cfssl gencert -initca ca-csr.json | cfssljson -bare ca $ ls ca* ca-config.json ca.csr ca-csr.json ca-key.pem ca.pem-initca表示以该 CSR 初始化一个自签名的根 CAcfssljson -bare ca将输出写入以ca为前缀的文件得到ca.pem证书与ca-key.pem私钥同时保留ca.csr以便审计。创建 kubernetes 证书kubernetes.pem是本集群中用途最广的一张证书它同时被kube-apiserver与etcd使用既充当 HTTPS 服务端证书又充当访问 etcd 的客户端证书。仓库配置中etc/kubernetes/apiserver 的--tls-cert-file、--etcd-certfile都指向它systemd/kube-apiserver.service 与其一致。创建证书签名请求文件创建kubernetes-csr.json{ CN: kubernetes, hosts: [ 127.0.0.1, 172.20.0.112, 172.20.0.113, 172.20.0.114, 172.20.0.115, 10.254.0.1, kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster, kubernetes.default.svc.cluster.local ], key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: BeiJing, L: BeiJing, O: k8s, OU: System } ] }关键点hosts字段如果hosts字段不为空则需要指定授权使用该证书的IP 或域名列表。由于该证书后续被etcd集群和kubernetes master集群共同使用所以这里分别指定了etcd集群、kubernetes master集群的主机 IP172.20.0.112~172.20.0.115其中172.20.0.113为 master 节点其余为集群其他节点kubernetes服务的服务 IP一般是kube-apiserver指定的service-cluster-ip-range网段的第一个 IP如10.254.0.1仓库 etc/kubernetes/apiserver 中--service-cluster-ip-range10.254.0.0/16与该值对应kubernetes、kubernetes.default、kubernetes.default.svc、kubernetes.default.svc.cluster、kubernetes.default.svc.cluster.local等内置 DNS 名称。这是最小化安装的 Kubernetes 集群包括一个私有镜像仓库、一个三节点的 Kubernetes 集群以上物理节点的 IP 也可以更换为主机名。hosts会写入证书的X509v3 Subject Alternative NameSAN扩展客户端在 TLS 握手时会校验对方的主机名/IP 是否落在 SAN 列表中因此漏写任何将被访问的地址都会导致握手失败——这是最常见也最难排查的问题之一。生成 kubernetes 证书和私钥$ cfssl gencert -caca.pem -ca-keyca-key.pem -configca-config.json -profilekubernetes kubernetes-csr.json | cfssljson -bare kubernetes $ ls kubernetes* kubernetes.csr kubernetes-csr.json kubernetes-key.pem kubernetes.pem或者直接在命令行上指定相关参数hosts 通过-hostname传入echo {CN:kubernetes,hosts:[],key:{algo:rsa,size:2048}} | cfssl gencert -caca.pem -ca-keyca-key.pem -configca-config.json -profilekubernetes -hostname127.0.0.1,172.20.0.112,172.20.0.113,172.20.0.114,172.20.0.115,kubernetes,kubernetes.default - | cfssljson -bare kubernetes签名命令参数拆解-caca.pem -ca-keyca-key.pem指定签发者我们的根 CA及 CA 私钥-configca-config.json指定配置文件-profilekubernetes选用ca-config.json中名为kubernetes的 profile即证书用途为signing key encipherment server auth client auth有效期 87600h-hostname...命令行方式直接指定 SAN 列表适合动态拼接 IP/域名cfssljson -bare kubernetes输出kubernetes.pem与kubernetes-key.pem。创建 admin 证书admin证书用于管理员kubectl身份认证其特殊之处在于 OrganizationO字段为system:masters这与 Kubernetes 预置的 RBAC 绑定直接关联。创建证书签名请求文件创建admin-csr.json{ CN: admin, hosts: [], key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: BeiJing, L: BeiJing, O: system:masters, OU: System } ] }为什么 admin 证书的 O 是system:masters后续kube-apiserver使用RBAC对客户端如kubelet、kube-proxy、Pod请求进行授权kube-apiserver预定义了一些RBAC使用的RoleBindings如cluster-admin将 Groupsystem:masters与 Rolecluster-admin绑定该 Role 授予了调用kube-apiserver的所有 API的权限O 指定该证书的 Group 为system:masters。kubelet使用该证书访问kube-apiserver时由于证书被 CA 签名所以认证通过同时由于证书用户组为经过预授权的system:masters所以被授予访问所有 API 的权限hosts为空数组表示该证书不绑定任何 SAN因为它只用作客户端身份凭证不用于服务端 TLS 握手。注意这个 admin 证书是将来生成管理员用的 kubeconfig 配置文件用的。现在我们一般建议使用 RBAC 来对 Kubernetes 进行角色权限控制。Kubernetes 将证书中的 CN 字段作为 User、O 字段作为 Group具体参考 Kubernetes 中的用户与身份认证授权 中 X509 Client Certs 一段。验证 cluster-admin 绑定搭建完 Kubernetes 集群后可以通过以下命令查看到clusterrolebinding cluster-admin的 subjects 的 kind 是 Group、name 是system:mastersroleRef对象是ClusterRole cluster-admin。意思是凡是system:mastersGroup 的 user 或者 serviceAccount 都拥有cluster-admin的角色。因此我们使用 kubectl 命令时才拥有整个集群的管理权限。$ kubectl get clusterrolebinding cluster-admin -o yaml apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: annotations: rbac.authorization.kubernetes.io/autoupdate: true creationTimestamp: 2017-04-11T11:20:42Z labels: kubernetes.io/bootstrapping: rbac-defaults name: cluster-admin resourceVersion: 52 selfLink: /apis/rbac.authorization.k8s.io/v1/clusterrolebindings/cluster-admin uid: e61b97b2-1ea8-11e7-8cd7-f4e9d49f8ed0 roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: cluster-admin subjects: - apiGroup: rbac.authorization.k8s.io kind: Group name: system:masters生成 admin 证书和私钥$ cfssl gencert -caca.pem -ca-keyca-key.pem -configca-config.json -profilekubernetes admin-csr.json | cfssljson -bare admin $ ls admin* admin.csr admin-csr.json admin-key.pem admin.pem创建 kube-proxy 证书kube-proxy以独立身份访问 kube-apiserver 的 Proxy 相关 API因此其证书 CN 必须设置为 Kubernetes 预定义的system:kube-proxy否则无法匹配预置的 RBAC 绑定。创建证书签名请求文件创建kube-proxy-csr.json{ CN: system:kube-proxy, hosts: [], key: { algo: rsa, size: 2048 }, names: [ { C: CN, ST: BeiJing, L: BeiJing, O: k8s, OU: System } ] }字段说明CN 指定该证书的 User 为system:kube-proxykube-apiserver预定义的 RoleBindingsystem:node-proxier将 Usersystem:kube-proxy与 Rolesystem:node-proxier绑定该 Role 授予了调用kube-apiserverProxy 相关 API 的权限。生成 kube-proxy 客户端证书和私钥$ cfssl gencert -caca.pem -ca-keyca-key.pem -configca-config.json -profilekubernetes kube-proxy-csr.json | cfssljson -bare kube-proxy $ ls kube-proxy* kube-proxy.csr kube-proxy-csr.json kube-proxy-key.pem kube-proxy.pem生成的kube-proxy.pem、kube-proxy-key.pem与仓库 etc/kubernetes/proxy 中KUBE_PROXY_ARGS--kubeconfig/etc/kubernetes/kube-proxy.kubeconfig配合使用由 kubeconfig 文件引用该证书对 apiserver 做客户端认证。校验证书签发完成后务必逐一校验证书内容确认 Issuer、Subject、SAN、Key Usage 等字段与 CSR 及 profile 配置一致。下面以 Kubernetes 证书为例。使用openssl命令$ openssl x509 -noout -text -in kubernetes.pem ... Signature Algorithm: sha256WithRSAEncryption Issuer: CCN, STBeiJing, LBeiJing, Ok8s, OUSystem, CNKubernetes Validity Not Before: Apr 5 05:36:00 2017 GMT Not After : Apr 5 05:36:00 2018 GMT Subject: CCN, STBeiJing, LBeiJing, Ok8s, OUSystem, CNkubernetes ... X509v3 extensions: X509v3 Key Usage: critical Digital Signature, Key Encipherment X509v3 Extended Key Usage: TLS Web Server Authentication, TLS Web Client Authentication X509v3 Basic Constraints: critical CA:FALSE X509v3 Subject Key Identifier: DD:52:04:43:10:13:A9:29:24:17:3A:0E:D7:14:DB:36:F8:6C:E0:E0 X509v3 Authority Key Identifier: keyid:44:04:3B:60:BD:69:78:14:68:AF:A0:41:13:F6:17:07:13:63:58:CD X509v3 Subject Alternative Name: DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc, DNS:kubernetes.default.svc.cluster, DNS:kubernetes.default.svc.cluster.local, IP Address:127.0.0.1, IP Address:172.20.0.112, IP Address:172.20.0.113, IP Address:172.20.0.114, IP Address:172.20.0.115, IP Address:10.254.0.1 ...校验清单确认Issuer字段的内容和ca-csr.json一致即 CA 的 CN 为Kubernetes确认Subject字段的内容和kubernetes-csr.json一致CN 为kubernetes确认X509v3 Subject Alternative Name字段的内容和kubernetes-csr.json一致所有 hosts 都进入了 SAN确认X509v3 Key Usage、Extended Key Usage字段的内容和ca-config.json中kubernetesprofile 一致Digital Signature, Key EnciphermentTLS Web Server Authentication, TLS Web Client AuthenticationX509v3 Basic Constraints: CA:FALSE确认该证书是叶子证书而非 CA。使用cfssl-certinfo命令$ cfssl-certinfo -cert kubernetes.pem ... { subject: { common_name: kubernetes, country: CN, organization: k8s, organizational_unit: System, locality: BeiJing, province: BeiJing, names: [ CN, BeiJing, BeiJing, k8s, System, kubernetes ] }, issuer: { common_name: Kubernetes, country: CN, organization: k8s, organizational_unit: System, locality: BeiJing, province: BeiJing, names: [ CN, BeiJing, BeiJing, k8s, System, Kubernetes ] }, serial_number: 174360492872423263473151971632292895707129022309, sans: [ kubernetes, kubernetes.default, kubernetes.default.svc, kubernetes.default.svc.cluster, kubernetes.default.svc.cluster.local, 127.0.0.1, 10.64.3.7, 10.254.0.1 ], not_before: 2017-04-05T05:36:00Z, not_after: 2018-04-05T05:36:00Z, sigalg: SHA256WithRSA, ...cfssl-certinfo以结构化 JSON 输出同样的信息便于脚本化校验注意实际集群若添加了节点如示例中的10.64.3.7SAN 列表会相应增加。分发证书将生成的证书和私钥文件后缀名为.pem拷贝到所有机器的/etc/kubernetes/ssl目录下备用mkdir -p /etc/kubernetes/ssl cp *.pem /etc/kubernetes/ssl分发完成后各组件通过配置引用这些证书。仓库中的实际部署配置可作为核对依据kube-apiserveretc/kubernetes/apiserver 中KUBE_API_ARGS通过--tls-cert-file/etc/kubernetes/ssl/kubernetes.pem、--tls-private-key-file/etc/kubernetes/ssl/kubernetes-key.pem、--client-ca-file/etc/kubernetes/ssl/ca.pem启用 TLS 与客户端证书认证并通过--etcd-cafile、--etcd-certfile、--etcd-keyfile以kubernetes证书身份访问 etcdkube-controller-manageretc/kubernetes/controller-manager 中通过--cluster-signing-cert-file/etc/kubernetes/ssl/ca.pem与--cluster-signing-key-file/etc/kubernetes/ssl/ca-key.pem为 kubelet 的 TLS bootstrap 请求签发证书并通过--root-ca-file向 API 服务器提供根 CAkubeletetc/kubernetes/kubelet 中--cert-dir/etc/kubernetes/ssl指定证书目录配合--experimental-bootstrap-kubeconfig实现 kubelet 证书引导详见 TLS bootstrapkube-proxyetc/kubernetes/proxy 中通过--kubeconfig/etc/kubernetes/kube-proxy.kubeconfig引用kube-proxy.pem与kube-proxy-key.pemetcdetc/etcd/etcd.conf 中ETCD_LISTEN_CLIENT_URLS/ETCD_LISTEN_PEER_URLS均为https://协议对应[security]段可配置ETCD_CERT_FILE、ETCD_KEY_FILE、ETCD_TRUSTED_CA_FILE、ETCD_CLIENT_CERT_AUTH等与上表etcd 使用 ca.pem、kubernetes-key.pem、kubernetes.pem的约定一致。进阶运行期证书签发与 CSR API除了一次性手工签发Kubernetes 还提供运行期的证书签名请求 APIcertificates.k8s.io供 Pod 内应用按需申请证书详见 管理集群中的 TLS。其流程为cfssl genkey生成私钥与 CSR → 将 base64 编码的 CSR 提交为CertificateSigningRequest对象 → 管理员用kubectl certificate approve批准 → 通过kubectl get csr ... -o jsonpath{.status.certificate} | base64 -d下载签发后的证书。生产环境建议为 Kubernetes 生成专用 CA并妥善管理 CA 私钥的生命周期。参考管理集群中的 TLS集群根 CA 信任模型与 CSR API 使用详解kubelet 的认证授权kubelet HTTPS 端点的认证与授权机制TLS bootstrapkubelet 客户端证书引导的完整配置Kubernetes 中的用户与身份认证授权X509 客户端证书中 CN/O 字段与 User/Group 的映射关系生成自签名证书CoreOS客户端证书与服务器证书Microsoft。【免费下载链接】kubernetes-handbookKubernetes 架构与生态从云原生到 AI 原生基础设施的构建指南项目地址: https://gitcode.com/gh_mirrors/ku/kubernetes-handbook创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

读完文章,也想定制专属网站?

尧图设计师 24 小时内与您沟通定制方案

免费获取报价