PKI基础设施构建:手动创建Kubernetes TLS证书体系
引言:Kubernetes安全通信的基石
你是否曾因Kubernetes集群证书过期导致服务中断?是否在排查组件间TLS握手失败时无从下手?本文将带你深入理解PKI(Public Key Infrastructure,公钥基础设施)在Kubernetes中的核心作用,通过12个实战步骤从零构建完整的证书体系,掌握证书生命周期管理的关键技术。
读完本文后,你将能够:
- 设计符合生产标准的Kubernetes PKI架构
- 使用OpenSSL手动创建根CA及各类组件证书
- 理解证书扩展字段对Kubernetes认证的影响
- 正确配置kubeconfig文件实现安全访问
- 建立证书轮换与应急恢复机制
一、Kubernetes PKI体系深度解析
1.1 为什么Kubernetes需要PKI?
Kubernetes集群由多个组件构成,这些组件间的通信必须通过TLS加密以确保安全性。PKI通过以下机制保障集群安全:
- 身份认证:验证组件身份,如kube-apiserver确认kubelet身份
- 数据加密:确保传输数据机密性,防止中间人攻击
- 完整性校验:保证配置和镜像不被篡改
1.2 Kubernetes证书类型与用途
Kubernetes需要多种证书来支持不同组件和功能,主要分为以下几类:
| 证书类型 | 用途 | 示例组件 | 安全级别 |
|---|---|---|---|
| 根CA证书 | 签发其他所有证书 | ca.crt/ca.key | 最高,需离线存储 |
| API服务器证书 | 提供API服务端认证 | kube-apiserver.crt | 高,包含所有API地址 |
| 客户端证书 | 组件身份认证 | kubelet.crt, admin.crt | 中,按角色区分权限 |
| 服务账户证书 | 为Pod提供身份 | service-accounts.crt | 中,自动轮换 |
| etcd证书 | etcd集群通信加密 | etcd-server.crt | 高,存储集群状态 |
1.3 证书层次结构设计
生产环境中推荐采用多层CA架构,而非单一根CA:
生产实践:单一根CA虽简单但风险高,一旦泄露需重建整个集群。多层CA架构可降低根CA暴露风险,符合NIST SP 800-155安全标准。
二、环境准备与工具链配置
2.1 必要工具安装
在jumpbox节点安装以下工具:
# Ubuntu/Debian
sudo apt update && sudo apt install -y openssl kubectl
# 验证安装
openssl version # 需1.1.1及以上版本
kubectl version --client
2.2 工作目录结构规划
创建标准化目录结构,便于证书管理:
mkdir -p ~/k8s-pki/{ca,etcd,kubernetes,pki}
cd ~/k8s-pki
tree .
推荐目录结构:
k8s-pki/
├── ca/ # 根CA相关文件
├── etcd/ # etcd专用CA
├── kubernetes/ # Kubernetes组件证书
└── pki/ # 所有证书最终存放位置
三、构建根证书颁发机构(CA)
3.1 根CA配置文件深度解析
创建ca.conf配置文件,定义根CA属性:
[req]
distinguished_name = req_distinguished_name
prompt = no
x509_extensions = ca_x509_extensions
[ca_x509_extensions]
basicConstraints = CA:TRUE
keyUsage = cRLSign, keyCertSign
subjectKeyIdentifier = hash
authorityKeyIdentifier = keyid:always,issuer:always
[req_distinguished_name]
C = CN # 国家代码
ST = Beijing # 省份
L = Beijing # 城市
O = MyCompany # 组织名称
OU = Kubernetes # 部门
CN = MyCompany Kubernetes CA # 通用名称
关键扩展字段说明:
basicConstraints = CA:TRUE:标记为CA证书keyUsage = cRLSign, keyCertSign:允许签发证书和CRLauthorityKeyIdentifier:确保证书链可验证
3.2 生成根CA证书与私钥
使用OpenSSL生成根CA私钥和自签名证书:
# 生成4096位RSA私钥,使用AES-256加密
openssl genrsa -aes256 -out ca/ca.key 4096
# 生成自签名根证书,有效期10年(3653天)
openssl req -x509 -new -nodes -sha512 -days 3653 \
-key ca/ca.key \
-config ca.conf \
-out ca/ca.crt
# 验证证书信息
openssl x509 -in ca/ca.crt -noout -text
安全最佳实践:
- 私钥必须设置密码保护
- 私钥应存储在安全环境,生产环境建议使用HSM
- 证书使用SHA-512哈希算法增强安全性
3.3 建立CA证书签发目录结构
创建CA所需的标准目录和文件:
mkdir -p ca/{newcerts,crl}
touch ca/index.txt
echo 1000 > ca/serial # 证书序列号起始值
echo 1000 > ca/crlnumber # CRL序列号起始值
CA目录结构说明:
newcerts/:存储已签发证书副本index.txt:证书数据库serial:下一个证书序列号crl/:证书吊销列表
四、Kubernetes组件证书创建全流程
4.1 证书创建通用流程
所有Kubernetes组件证书创建遵循以下步骤:
4.2 API服务器证书深度配置
API服务器证书是最复杂的证书,需要包含所有可能的访问地址:
- 创建API服务器配置文件
kubernetes/apiserver.conf:
[req]
distinguished_name = req_distinguished_name
prompt = no
req_extensions = v3_extensions
[v3_extensions]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = serverAuth, clientAuth
subjectAltName = @alt_names
subjectKeyIdentifier = hash
[alt_names]
IP.0 = 127.0.0.1 # 本地回环地址
IP.1 = 192.168.1.100 # API服务器IP
DNS.0 = kubernetes # 集群内部域名
DNS.1 = kubernetes.default # 默认服务域名
DNS.2 = kubernetes.default.svc # 完整服务域名
DNS.3 = kubernetes.default.svc.cluster.local # 集群域名
DNS.4 = api.k8s.mycompany.com # 外部访问域名
[req_distinguished_name]
C = CN
ST = Beijing
L = Beijing
O = MyCompany
OU = Kubernetes
CN = kube-apiserver
- 生成API服务器证书和私钥:
# 生成API服务器私钥
openssl genrsa -out kubernetes/apiserver.key 2048
# 生成CSR
openssl req -new -sha512 \
-key kubernetes/apiserver.key \
-config kubernetes/apiserver.conf \
-out kubernetes/apiserver.csr
# 使用根CA签发证书,有效期3年
openssl x509 -req -sha512 -days 1095 \
-in kubernetes/apiserver.csr \
-CA ca/ca.crt \
-CAkey ca/ca.key \
-CAcreateserial \
-extfile kubernetes/apiserver.conf \
-extensions v3_extensions \
-out kubernetes/apiserver.crt
- 验证证书内容:
# 查看证书基本信息
openssl x509 -in kubernetes/apiserver.crt -noout -text
# 验证主题备用名称(SAN)
openssl x509 -in kubernetes/apiserver.crt -noout -ext subjectAltName
常见问题排查:
- API服务器启动失败:检查SAN是否包含所有必要的IP和域名
- 客户端访问提示证书错误:验证CN和SAN是否匹配访问地址
4.3 kubelet证书自动化配置
kubelet证书需要与节点名称匹配,使用循环批量生成:
# 定义节点列表
NODES=("node-0" "node-1" "node-2")
# 批量生成节点证书
for NODE in "${NODES[@]}"; do
# 创建节点配置文件
cat > kubernetes/${NODE}.conf << EOF
[req]
distinguished_name = req_distinguished_name
prompt = no
req_extensions = v3_extensions
[v3_extensions]
basicConstraints = CA:FALSE
keyUsage = digitalSignature, keyEncipherment
extendedKeyUsage = clientAuth, serverAuth
subjectAltName = DNS:${NODE},IP:192.168.1.10${i}
subjectKeyIdentifier = hash
[req_distinguished_name]
C = CN
ST = Beijing
L = Beijing
O = system:nodes
CN = system:node:${NODE}
EOF
# 生成私钥和CSR
openssl genrsa -out kubernetes/${NODE}.key 2048
openssl req -new -sha512 \
-key kubernetes/${NODE}.key \
-config kubernetes/${NODE}.conf \
-out kubernetes/${NODE}.csr
# 签发证书
openssl x509 -req -sha512 -days 1095 \
-in kubernetes/${NODE}.csr \
-CA ca/ca.crt \
-CAkey ca/ca.key \
-CAcreateserial \
-extfile kubernetes/${NODE}.conf \
-extensions v3_extensions \
-out kubernetes/${NODE}.crt
done
kubelet证书特殊要求:
O = system:nodes:必须属于system:nodes组CN = system:node:<node-name>:必须符合节点用户命名规范- 包含
clientAuth和serverAuth扩展用途
4.4 其他核心组件证书创建
为kube-controller-manager、kube-scheduler和kube-proxy创建证书:
# 创建kube-controller-manager证书
openssl genrsa -out kubernetes/kube-controller-manager.key 2048
openssl req -new -sha512 \
-key kubernetes/kube-controller-manager.key \
-subj "/C=CN/ST=Beijing/L=Beijing/O=system:kube-controller-manager/CN=system:kube-controller-manager" \
-out kubernetes/kube-controller-manager.csr
openssl x509 -req -sha512 -days 1095 \
-in kubernetes/kube-controller-manager.csr \
-CA ca/ca.crt \
-CAkey ca/ca.key \
-CAcreateserial \
-out kubernetes/kube-controller-manager.crt
# 类似方式创建kube-scheduler和kube-proxy证书...
各组件证书规范:
| 组件 | CN | O(组织) | 扩展用途 |
|---|---|---|---|
| kube-controller-manager | system:kube-controller-manager | system:kube-controller-manager | clientAuth |
| kube-scheduler | system:kube-scheduler | system:kube-scheduler | clientAuth |
| kube-proxy | system:kube-proxy | system:node-proxier | clientAuth |
| admin | admin | system:masters | clientAuth |
五、kubeconfig文件配置详解
5.1 kubeconfig文件结构解析
kubeconfig文件包含集群、用户和上下文信息,典型结构如下:
apiVersion: v1
clusters:
- cluster:
certificate-authority-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t...
server: https://api.k8s.mycompany.com:6443
name: kubernetes
contexts:
- context:
cluster: kubernetes
user: kubelet
name: default
current-context: default
kind: Config
preferences: {}
users:
- name: kubelet
user:
client-certificate-data: LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0t...
client-key-data: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVkt...
5.2 为节点生成kubeconfig文件
为node-0生成kubeconfig:
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca/ca.crt \
--embed-certs=true \
--server=https://api.k8s.mycompany.com:6443 \
--kubeconfig=kubernetes/node-0.kubeconfig
kubectl config set-credentials system:node:node-0 \
--client-certificate=kubernetes/node-0.crt \
--client-key=kubernetes/node-0.key \
--embed-certs=true \
--kubeconfig=kubernetes/node-0.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=system:node:node-0 \
--kubeconfig=kubernetes/node-0.kubeconfig
kubectl config use-context default \
--kubeconfig=kubernetes/node-0.kubeconfig
关键参数说明:
--embed-certs=true:将证书内容嵌入kubeconfig,无需单独分发证书文件--certificate-authority:CA证书路径--server:API服务器地址
5.3 管理员kubeconfig配置
创建具有管理员权限的kubeconfig:
kubectl config set-cluster kubernetes-the-hard-way \
--certificate-authority=ca/ca.crt \
--embed-certs=true \
--server=https://api.k8s.mycompany.com:6443 \
--kubeconfig=kubernetes/admin.kubeconfig
kubectl config set-credentials admin \
--client-certificate=kubernetes/admin.crt \
--client-key=kubernetes/admin.key \
--embed-certs=true \
--kubeconfig=kubernetes/admin.kubeconfig
kubectl config set-context default \
--cluster=kubernetes-the-hard-way \
--user=admin \
--kubeconfig=kubernetes/admin.kubeconfig
# 测试配置
export KUBECONFIG=kubernetes/admin.kubeconfig
kubectl get nodes
六、证书分发与权限设置
6.1 证书分发策略
根据组件类型,证书分发方式不同:
| 组件类型 | 分发方式 | 存储路径 | 文件权限 |
|---|---|---|---|
| 控制平面组件 | scp传输 | /etc/kubernetes/pki/ | 600 |
| kubelet | scp传输 | /var/lib/kubelet/pki/ | 600 |
| kube-proxy | ConfigMap | /var/lib/kube-proxy/ | 600 |
| 管理员 | 本地存储 | ~/.kube/config | 600 |
示例:分发node-0证书和kubeconfig:
# 创建远程目录
ssh root@node-0 "mkdir -p /var/lib/kubelet/pki /etc/kubernetes/pki"
# 复制证书
scp ca/ca.crt root@node-0:/etc/kubernetes/pki/
scp kubernetes/node-0.crt root@node-0:/var/lib/kubelet/pki/kubelet.crt
scp kubernetes/node-0.key root@node-0:/var/lib/kubelet/pki/kubelet.key
scp kubernetes/node-0.kubeconfig root@node-0:/var/lib/kubelet/kubeconfig
# 设置权限
ssh root@node-0 "chmod -R 600 /var/lib/kubelet/pki /var/lib/kubelet/kubeconfig"
6.2 证书权限加固
证书和私钥权限设置原则:
- 私钥文件权限必须为600,仅所有者可读写
- 证书文件权限可设为644,允许读取但禁止修改
- 证书目录权限应为700,防止未授权访问
# 控制平面节点权限设置
chmod 600 /etc/kubernetes/pki/*.key
chmod 644 /etc/kubernetes/pki/*.crt
chmod 700 /etc/kubernetes/pki
# kubelet权限设置
chmod 600 /var/lib/kubelet/pki/*.key
chmod 600 /var/lib/kubelet/kubeconfig
七、证书生命周期管理与监控
7.1 证书轮换策略
制定合理的证书轮换计划:
自动轮换方案对比:
| 方案 | 优点 | 缺点 | 适用场景 |
|---|---|---|---|
| cert-manager | 自动化程度高,支持ACME | 额外组件,学习曲线 | 云环境,生产集群 |
| kubelet TLS Bootstrap | 原生支持,无需第三方 | 仅支持kubelet证书 | 简单集群,测试环境 |
| 自定义脚本 | 高度可控,按需定制 | 需维护脚本,易出错 | 特殊需求场景 |
7.2 证书监控与告警
部署证书监控工具:
# 安装kube-cert-manager
kubectl apply -f https://raw.githubusercontent.com/enix/kube-cert-manager/master/deploy/cert-manager.yaml
# 配置Prometheus监控
cat > cert-monitor.yaml << EOF
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
name: cert-manager
namespace: cert-manager
spec:
selector:
matchLabels:
app: cert-manager
endpoints:
- port: http
path: /metrics
interval: 30s
EOF
kubectl apply -f cert-monitor.yaml
关键监控指标:
certmanager_certificate_expiration_timestamp_seconds:证书过期时间certmanager_certificate_ready_status:证书就绪状态certmanager_certificate_revision:证书修订版本
八、故障排查与应急处理
8.1 常见证书问题诊断
证书相关故障排查流程:
常见问题解决示例:
# 检查证书有效期
openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates
# 验证证书链
openssl verify -CAfile /etc/kubernetes/pki/ca.crt /etc/kubernetes/pki/apiserver.crt
# 查看kube-apiserver证书配置
ps aux | grep kube-apiserver | grep -i cert
8.2 证书应急恢复
当证书过期或泄露时的应急处理步骤:
- 紧急恢复访问:
# 生成临时管理员证书
openssl req -x509 -newkey rsa:2048 -nodes -days 1 \
-keyout temp-admin.key -out temp-admin.crt \
-subj "/CN=temp-admin/O=system:masters"
# 配置kubeconfig使用临时证书
kubectl config set-credentials temp-admin \
--client-certificate=temp-admin.crt \
--client-key=temp-admin.key
kubectl config set-context temp-context --cluster=kubernetes --user=temp-admin
kubectl config use-context temp-context
- 全面证书轮换:
# 使用脚本批量轮换证书
git clone https://gitcode.com/GitHub_Trending/ku/kubernetes-the-hard-way.git
cd kubernetes-the-hard-way
./scripts/rotate-certificates.sh
九、总结与最佳实践
9.1 PKI管理最佳实践清单
- 安全存储:CA私钥必须离线存储,使用硬件安全模块(HSM)或加密保险库
- 最小权限:证书仅包含必要的扩展和权限
- 定期轮换:根CA(10年)、中间CA(5年)、组件证书(1年)
- 严格审计:记录所有证书操作,建立审计日志
- 自动化管理:生产环境必须实现证书管理自动化
- 备份策略:定期备份CA和所有证书,测试恢复流程
- 监控告警:设置证书过期告警,提前90天开始轮换
9.2 进阶学习路径
要深入掌握Kubernetes PKI,建议学习以下内容:
- 椭圆曲线加密(ECC)在Kubernetes中的应用
- 证书透明(Certificate Transparency)技术
- SPIFFE/SPIRE身份标识标准
- 自动化PKI管理工具(如cert-manager, step-ca)
- 云原生环境中的PKI即服务(PKIaaS)
十、附录:实用工具与资源
10.1 OpenSSL常用命令速查表
| 功能 | 命令 |
|---|---|
| 查看证书信息 | openssl x509 -in cert.crt -noout -text |
| 检查证书有效期 | openssl x509 -in cert.crt -noout -dates |
| 验证证书链 | openssl verify -CAfile ca.crt cert.crt |
| 生成CSR | openssl req -new -key key.key -out cert.csr -config config.conf |
| 签发证书 | openssl x509 -req -in cert.csr -CA ca.crt -CAkey ca.key -out cert.crt |
| 转换PEM到DER | openssl x509 -in cert.pem -outform der -out cert.der |
10.2 参考文档
- Kubernetes官方文档:PKI证书和要求
- OpenSSL文档:OpenSSL Certificate Authority
- NIST PKI指南:SP 800-155
如果觉得本文有价值,请点赞、收藏并关注,下期将带来《Kubernetes证书自动化管理:从cert-manager到Vault》。
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考



