1. Kubernetes TLS证书基础认知
在云原生架构中,TLS证书如同集群的"身份证"和"保险柜钥匙"。我管理过的生产级Kubernetes集群中,90%的认证问题都源于证书配置不当。理解证书体系是每个Kubernetes运维人员的必修课。
TLS证书在Kubernetes中主要承担三大职能:
- 身份认证:确保组件间通信双方的真实性,比如kube-apiserver需要验证kubelet的身份
- 通信加密:保护数据传输安全,防止敏感信息(如Pod配置、Secret内容)被窃取
- 访问控制:基于证书中的CN(Common Name)和O(Organization)字段实现RBAC
典型集群需要以下几类证书:
- etcd集群证书:包括CA证书、server证书、peer证书和client证书
- API Server证书:包含serving证书和client证书
- kubelet证书:用于节点身份认证
- front-proxy证书:用于聚合API的中间层认证
关键经验:生产环境证书有效期建议设置为1年(8760h),测试环境可适当延长。过短会增加维护成本,过长则存在安全风险。
2. 方案一:使用CFSSL工具链
2.1 工具安装与配置
CFSSL是Cloudflare开源的PKI/TLS工具链,相比OpenSSL更适用于Kubernetes证书管理。我在多个生产集群中验证过其稳定性,以下是优化后的安装流程:
bash复制# 下载指定版本(建议锁定版本以避免兼容性问题)
CFSSL_VERSION="1.6.5"
wget https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssl_${CFSSL_VERSION}_linux_amd64 -O cfssl
wget https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssljson_${CFSSL_VERSION}_linux_amd64 -O cfssljson
wget https://github.com/cloudflare/cfssl/releases/download/v${CFSSL_VERSION}/cfssl-certinfo_${CFSSL_VERSION}_linux_amd64 -O cfssl-certinfo
# 安装到系统路径并设置权限
chmod +x cfssl cfssljson cfssl-certinfo
sudo mv cfssl cfssljson cfssl-certinfo /usr/local/bin/
# 验证安装
cfssl version
2.2 证书目录结构设计
合理的目录结构能降低维护成本,这是我经过多个集群验证的最佳实践:
bash复制sudo mkdir -p /etc/kubernetes/pki/{etcd,front-proxy,kubernetes}
sudo chmod 700 /etc/kubernetes/pki
sudo chown -R root:root /etc/kubernetes/pki
目录权限设置要点:
700权限确保只有root可访问- 分离etcd与kubernetes证书便于权限管理
- 统一的pki目录方便备份和迁移
2.3 CA配置深度解析
ca-config.json是证书体系的控制中心,这个配置经过生产环境验证:
json复制{
"signing": {
"default": {
"expiry": "8760h" # 1年有效期
},
"profiles": {
"server": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth"
]
},
"client": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"client auth"
]
},
"peer": {
"expiry": "8760h",
"usages": [
"signing",
"key encipherment",
"server auth",
"client auth"
]
}
}
}
}
关键参数说明:
usages必须准确设置,错误的usage会导致认证失败- server auth用于服务端证书,client auth用于客户端证书
- peer证书同时需要server和client auth(如etcd节点间通信)
2.4 etcd证书全流程
2.4.1 CA证书生成
etcd作为Kubernetes的数据存储,其证书需要最高级别的安全配置:
json复制{
"CN": "etcd-ca",
"key": {
"algo": "rsa",
"size": 4096 # 生产环境建议4096位
},
"names": [
{
"C": "CN",
"L": "Beijing",
"ST": "Beijing",
"O": "etcd",
"OU": "Etcd Security"
}
],
"ca": {
"expiry": "87600h" # 10年CA有效期
}
}
生成命令:
bash复制cfssl gencert -initca etcd-ca-csr.json | cfssljson -bare /etc/kubernetes/pki/etcd/ca
2.4.2 Server证书最佳实践
etcd server证书需要包含所有可能的访问端点:
bash复制ETCD_NODES="kube-master-1,kube-master-2,kube-master-3"
ETCD_IPS="172.18.1.101,172.18.1.102,172.18.1.103"
LOCALHOST="localhost,127.0.0.1,::1"
cfssl gencert \
-ca=/etc/kubernetes/pki/etcd/ca.pem \
-ca-key=/etc/kubernetes/pki/etcd/ca-key.pem \
-config=ca-config.json \
-hostname="${ETCD_NODES},${ETCD_IPS},${LOCALHOST}" \
-profile=server \
etcd-server-csr.json | cfssljson -bare /etc/kubernetes/pki/etcd/server
避坑指南:必须包含所有节点IP和主机名,否则会导致跨节点通信失败。曾因漏掉IPv6地址导致集群异常。
2.4.3 Client证书生成
etcd client证书用于健康检查等场景:
bash复制cfssl gencert \
-ca=/etc/kubernetes/pki/etcd/ca.pem \
-ca-key=/etc/kubernetes/pki/etcd/ca-key.pem \
-config=ca-config.json \
-profile=client \
etcd-client-csr.json | cfssljson -bare /etc/kubernetes/pki/etcd/healthcheck-client
3. 方案二:kubeadm证书管理
3.1 kubeadm证书体系
kubeadm内置了完整的证书管理功能,适合快速部署场景。其证书目录结构与手动创建基本一致:
bash复制/etc/kubernetes/pki
├── apiserver.crt
├── apiserver-etcd-client.crt
├── apiserver-etcd-client.key
├── apiserver.key
├── apiserver-kubelet-client.crt
├── apiserver-kubelet-client.key
├── ca.crt
├── ca.key
├── etcd
│ ├── ca.crt
│ ├── ca.key
│ ├── healthcheck-client.crt
│ ├── healthcheck-client.key
│ ├── peer.crt
│ ├── peer.key
│ ├── server.crt
│ └── server.key
├── front-proxy-ca.crt
├── front-proxy-ca.key
├── front-proxy-client.crt
└── front-proxy-client.key
3.2 证书生成与更新
查看证书有效期:
bash复制kubeadm certs check-expiration
手动更新所有证书:
bash复制kubeadm certs renew all
更新特定组件证书(如apiserver):
bash复制kubeadm certs renew apiserver
实测发现:kubeadm 1.19+版本支持自动轮换,但建议在维护窗口手动执行更可靠
4. 证书管理进阶技巧
4.1 证书轮换策略
安全的证书轮换流程:
- 备份现有证书:
tar -zcvf pki-backup-$(date +%Y%m%d).tar.gz /etc/kubernetes/pki - 生成新证书:
kubeadm certs renew all --config=/etc/kubernetes/kubeadm-config.yaml - 重启控制平面组件(按顺序):
bash复制
systemctl restart kube-apiserver systemctl restart kube-controller-manager systemctl restart kube-scheduler - 滚动重启worker节点:
kubectl drain <node> && systemctl restart kubelet && kubectl uncordon <node>
4.2 证书问题排查
常见错误及解决方案:
| 错误现象 | 可能原因 | 排查命令 |
|---|---|---|
| x509: certificate has expired or is not yet valid | 证书过期 | openssl x509 -in /etc/kubernetes/pki/apiserver.crt -noout -dates |
| x509: certificate signed by unknown authority | CA不匹配 | 比较各节点的ca.crt的MD5值 |
| connection refused | 证书包含错误的IP/域名 | openssl x509 -in server.crt -text -noout | grep DNS |
4.3 自定义证书SAN
在kubeadm配置中添加额外SAN:
yaml复制apiVersion: kubeadm.k8s.io/v1beta3
kind: ClusterConfiguration
apiServer:
certSANs:
- "cluster.example.com"
- "10.96.0.1"
- "192.168.1.100"
然后重新生成证书:
bash复制kubeadm init phase certs apiserver --config /etc/kubernetes/kubeadm-config.yaml
5. 证书安全实践
5.1 密钥保护措施
-
设置严格的文件权限:
bash复制chmod 600 /etc/kubernetes/pki/*.key chmod 644 /etc/kubernetes/pki/*.crt -
使用硬件安全模块(HSM)存储CA私钥(企业级方案)
-
定期轮换证书(建议每6-12个月)
5.2 证书吊销处理
虽然Kubernetes不直接支持CRL,但可以通过以下方式实现等效安全:
- 立即轮换受影响证书
- 更新所有节点的证书包
- 使用NetworkPolicy限制访问
- 对于严重泄露,考虑重建CA
我曾遇到私钥泄露事件,通过以下命令在30分钟内完成应急响应:
bash复制# 1. 暂停服务
kubectl cordon <affected-node>
# 2. 生成新证书
kubeadm certs renew all
# 3. 分发新证书到所有节点
ansible-playbook -i hosts deploy-certs.yml
# 4. 重启服务
systemctl restart kubelet
在Kubernetes证书管理这条路上,最大的教训是:永远要有备份证书的方案,并且定期测试恢复流程。我现在的习惯是每次证书变更后立即执行:
bash复制tar -zcvf /opt/backup/k8s-certs-$(date +%s).tar.gz /etc/kubernetes/pki
aws s3 cp /opt/backup/*.tar.gz s3://my-k8s-backup/certs/