Kubernetes 证书体系与 OpenSSL 命令学习

Kubernetes 证书体系与 OpenSSL 命令全解析

📁 一、Kubernetes 证书目录结构

1.1 核心证书目录(Master节点)

复制代码
/etc/kubernetes/pki/
├── apiserver.crt              # API Server 服务端证书
├── apiserver.key              # API Server 私钥
├── apiserver-kubelet-client.crt  # API Server 访问 kubelet 的客户端证书
├── apiserver-kubelet-client.key
├── ca.crt                     # 集群根证书(CA证书)
├── ca.key                     # CA私钥(最敏感)
├── etcd/                      # etcd 相关证书
│   ├── ca.crt
│   ├── ca.key
│   ├── healthcheck-client.crt
│   ├── healthcheck-client.key
│   ├── peer.crt
│   ├── peer.key
│   ├── server.crt
│   └── server.key
├── front-proxy-ca.crt         # 前端代理CA
├── front-proxy-ca.key
├── front-proxy-client.crt     # 前端代理客户端证书
├── front-proxy-client.key
├── sa.key                     # Service Account 私钥
└── sa.pub                     # Service Account 公钥

1.2 组件证书位置

组件 证书位置 用途
kube-apiserver /etc/kubernetes/pki/ 服务端认证
kube-controller-manager /etc/kubernetes/pki/ 客户端证书
kube-scheduler /etc/kubernetes/pki/ 客户端证书
kubelet /var/lib/kubelet/pki/ 节点证书
etcd /etc/kubernetes/pki/etcd/ etcd集群通信
kube-proxy /var/lib/kube-proxy/ 客户端证书

1.3 证书内嵌(Embedded Certs)机制

Kubernetes 支持将证书内容直接嵌入到 kubeconfig 文件中,避免文件路径依赖:

bash 复制代码
# 生成内嵌证书的 kubeconfig
kubectl config set-credentials user \
  --client-certificate=user.crt \
  --client-key=user.key \
  --embed-certs=true  # 关键参数:内嵌证书内容

内嵌 vs 文件路径

  • 内嵌优点:配置文件自包含,便于分发和迁移
  • 内嵌缺点:配置文件变大,证书更新需要重新生成
  • 文件路径优点:证书更新时无需修改 kubeconfig
  • 文件路径缺点:路径依赖,部署环境需保持一致

1.4 证书轮换目录机制

Kubernetes 支持自动证书轮换,相关目录:

复制代码
/var/lib/kubelet/pki/
├── kubelet-client-current.pem -> kubelet-client-2025-01-21-12-34-56.pem  # 符号链接
├── kubelet-client-2025-01-21-12-34-56.pem  # 实际证书文件
├── kubelet.crt
└── kubelet.key

轮换过程

  1. kubelet 定期检查证书过期时间
  2. 自动向 API Server 申请新证书
  3. 创建新证书文件,更新符号链接
  4. 重启相关服务(部分组件支持热重载)

📄 二、证书格式与内容解析

2.1 证书文件格式

Kubernetes 主要使用两种格式:

格式 扩展名 说明 查看命令
PEM .crt, .pem Base64编码的文本格式 cat cert.crt
DER .der 二进制格式 openssl x509 -in cert.der -inform der -text

2.2 证书内容结构

一个标准的 X.509 证书包含:

bash 复制代码
# 查看证书详细信息
openssl x509 -in cert.crt -text -noout

# 输出示例:
Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number: 1234567890 (0x499602d2)
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: CN = kubernetes-ca  # 颁发者
        Validity
            Not Before: Jan 21 00:00:00 2026 GMT
            Not After : Jan 20 23:59:59 2027 GMT  # 有效期
        Subject: CN = system:node:node1  # 主题(标识身份)
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
            RSA Public-Key: (2048 bit)
        X509v3 extensions:
            X509v3 Key Usage: critical
                Digital Signature, Key Encipherment
            X509v3 Extended Key Usage: 
                TLS Web Server Authentication, TLS Web Client Authentication
            X509v3 Subject Alternative Name:  # SAN扩展
                DNS:kubernetes, DNS:kubernetes.default, DNS:kubernetes.default.svc...

2.3 关键字段说明

字段 说明 Kubernetes 中的典型值
Issuer 证书颁发者 CN=kubernetes-ca
Subject 证书持有者 CN=system:node:node1(节点) CN=system:kube-controller-manager(组件) CN=readonly-user(用户)
SAN 主题备用名称 包含 API Server 的 DNS 名称和 IP
Key Usage 密钥用途 Digital Signature, Key Encipherment
Extended Key Usage 扩展密钥用途 TLS Web Server Authentication(服务端) TLS Web Client Authentication(客户端)

2.4 私钥格式

私钥同样有 PEM 和 DER 格式,通常使用 RSA 或 ECDSA 算法:

bash 复制代码
# 查看私钥信息
openssl rsa -in private.key -text -noout

# 输出示例:
Private-Key: (2048 bit)
modulus:
    00:aa:bb:cc:...
publicExponent: 65537 (0x10001)
privateExponent:
    00:dd:ee:ff:...

🔧 三、OpenSSL 常用命令大全

3.1 证书生成流程(完整示例)

步骤1:生成私钥
bash 复制代码
# 生成 2048 位 RSA 私钥
openssl genrsa -out user.key 2048

# 生成 ECDSA 私钥(更安全,更小)
openssl ecparam -genkey -name prime256v1 -out user.key
步骤2:创建证书签名请求(CSR)
bash 复制代码
# 创建 CSR,CN 字段标识用户身份
openssl req -new -key user.key -out user.csr \
  -subj "/CN=readonly-user"

# 带 SAN 扩展的 CSR(用于服务端证书)
cat > csr.conf <<EOF
[ req ]
default_bits = 2048
prompt = no
default_md = sha256
distinguished_name = dn

[ dn ]
CN = kubernetes

[ req_ext ]
subjectAltName = @alt_names

[ alt_names ]
DNS.1 = kubernetes
DNS.2 = kubernetes.default
DNS.3 = kubernetes.default.svc
DNS.4 = kubernetes.default.svc.cluster.local
IP.1 = 192.168.124.134
EOF

openssl req -new -key server.key -out server.csr -config csr.conf
步骤3:使用 CA 签署证书
bash 复制代码
# 使用集群 CA 签署证书(有效期365天)
openssl x509 -req -in user.csr \
  -CA /etc/kubernetes/pki/ca.crt \
  -CAkey /etc/kubernetes/pki/ca.key \
  -CAcreateserial \
  -out user.crt \
  -days 365

# 带扩展的签署
openssl x509 -req -in server.csr \
  -CA ca.crt -CAkey ca.key -CAcreateserial \
  -out server.crt -days 365 \
  -extfile csr.conf -extensions req_ext

3.2 证书查看与验证命令

查看证书信息
bash 复制代码
# 查看证书内容(文本格式)
openssl x509 -in cert.crt -text -noout

# 查看证书有效期
openssl x509 -in cert.crt -dates -noout

# 查看证书序列号
openssl x509 -in cert.crt -serial -noout

# 查看证书指纹
openssl x509 -in cert.crt -fingerprint -noout

# 查看证书主题和颁发者
openssl x509 -in cert.crt -subject -issuer -noout
验证证书链
bash 复制代码
# 验证证书是否由指定 CA 签发
openssl verify -CAfile ca.crt user.crt

# 验证证书链(多级CA)
openssl verify -CAfile root-ca.crt -untrusted intermediate-ca.crt user.crt
检查私钥
bash 复制代码
# 查看私钥信息
openssl rsa -in private.key -text -noout

# 检查私钥是否匹配证书
openssl x509 -in cert.crt -pubkey -noout > cert.pub
openssl rsa -in private.key -pubout > key.pub
diff cert.pub key.pub  # 应该相同

3.3 证书转换命令

bash 复制代码
# PEM 转 DER
openssl x509 -in cert.pem -outform der -out cert.der

# DER 转 PEM
openssl x509 -in cert.der -inform der -out cert.pem

# 从证书提取公钥
openssl x509 -in cert.crt -pubkey -noout > public.key

# 从私钥提取公钥
openssl rsa -in private.key -pubout -out public.key

3.4 证书格式检查

bash 复制代码
# 检查文件是否为有效的 PEM 证书
openssl x509 -in file.crt -text -noout >/dev/null 2>&1 && echo "Valid" || echo "Invalid"

# 检查文件是否为有效的私钥
openssl rsa -in file.key -check -noout >/dev/null 2>&1 && echo "Valid" || echo "Invalid"

# 检查证书和私钥是否匹配
openssl x509 -noout -modulus -in cert.crt | openssl md5
openssl rsa -noout -modulus -in private.key | openssl md5
# 两个 MD5 值应该相同

🔄 四、证书轮换与更新

4.1 手动证书轮换流程

bash 复制代码
# 1. 生成新证书(使用相同 CN)
openssl req -new -key user.key -out user-new.csr -subj "/CN=readonly-user"
openssl x509 -req -in user-new.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out user-new.crt -days 365

# 2. 验证新证书
openssl verify -CAfile ca.crt user-new.crt

# 3. 替换证书文件(注意权限)
cp user-new.crt user.crt
chmod 600 user.crt

# 4. 重启相关服务(部分组件支持热重载)
systemctl restart kube-apiserver  # 或相关组件

4.2 自动证书轮换(kubelet)

kubelet 支持自动证书轮换,配置参数:

yaml 复制代码
# /var/lib/kubelet/config.yaml
rotateCertificates: true
certificateRotationDuration: 8760h  # 1年

4.3 检查证书过期时间

bash 复制代码
# 检查单个证书过期时间
openssl x509 -in cert.crt -enddate -noout

# 批量检查目录下所有证书
find /etc/kubernetes/pki -name "*.crt" -exec sh -c 'echo "=== $1 ==="; openssl x509 -enddate -noout -in "$1"' sh {} \;

# 使用 kubeadm 检查集群证书
kubeadm certs check-expiration

🛡️ 五、安全最佳实践

5.1 文件权限设置

bash 复制代码
# CA 私钥(最敏感)
chmod 600 /etc/kubernetes/pki/ca.key

# 其他私钥
chmod 600 /etc/kubernetes/pki/*.key

# 证书文件(只读)
chmod 644 /etc/kubernetes/pki/*.crt

# kubeconfig 文件
chmod 600 ~/.kube/config

5.2 证书有效期管理

  • CA 证书:通常 10 年
  • 组件证书:通常 1 年
  • 用户证书:建议 90 天到 1 年
  • kubelet 自动轮换:建议开启

5.3 证书撤销(CRL/OCSP)

Kubernetes 默认不启用证书撤销列表(CRL),如需撤销:

  1. 删除 RBAC 绑定
  2. 从信任链中移除证书
  3. 重新生成受影响的证书

📋 六、补充要点(您可能遗漏的)

6.1 Service Account 令牌

Service Account 使用 JWT 令牌而非证书:

bash 复制代码
# 查看 Service Account 令牌
kubectl get secret default-token-xxxx -o jsonpath='{.data.token}' | base64 -d

# 令牌格式:eyJhbGciOiJSUzI1NiIsImtpZCI6...

6.2 证书签名请求(CSR)API

Kubernetes 提供了 CSR API 用于证书管理:

bash 复制代码
# 查看所有 CSR
kubectl get csr

# 批准 CSR
kubectl certificate approve csr-name

# 拒绝 CSR
kubectl certificate deny csr-name

6.3 证书续期(kubeadm)

使用 kubeadm 管理集群时:

bash 复制代码
# 检查证书过期时间
kubeadm certs check-expiration

# 续期所有证书
kubeadm certs renew all

# 续期指定证书
kubeadm certs renew apiserver

6.4 证书备份与恢复

bash 复制代码
# 备份证书目录
tar -czf k8s-certs-backup-$(date +%Y%m%d).tar.gz /etc/kubernetes/pki/

# 恢复时注意权限
tar -xzf backup.tar.gz -C /
chmod 600 /etc/kubernetes/pki/*.key

6.5 证书调试技巧

bash 复制代码
# 查看 API Server 日志(证书相关错误)
journalctl -u kube-apiserver -f

# 使用 curl 测试证书
curl --cacert ca.crt --cert user.crt --key user.key https://api-server:6443/api

# 使用 openssl s_client 测试 TLS 连接
openssl s_client -connect api-server:6443 -CAfile ca.crt -cert user.crt -key user.key

🎯 复习要点总结

主题 核心内容 关键命令
证书目录 /etc/kubernetes/pki/ 结构 ls -la /etc/kubernetes/pki/
证书生成 CSR → CA 签名流程 openssl req, openssl x509
证书查看 查看证书信息 openssl x509 -text -noout
证书验证 验证证书链 openssl verify
kubeconfig 内嵌证书机制 --embed-certs=true
权限管理 RBAC + 证书认证 kubectl auth can-i
轮换机制 自动/手动轮换 kubeadm certs renew
安全实践 文件权限、有效期 chmod 600

建议按照目录结构→证书格式→OpenSSL命令→实践操作的顺序复习,重点掌握证书生成流程和权限验证方法。

🔐 核心概念:双向TLS认证

在Kubernetes集群中,组件间的通信普遍采用双向TLS(mTLS)认证 来确保安全。这意味着通信双方(客户端和服务端)都需要验证对方身份的真实性。整个过程依赖于证书颁发机构(CA) 作为信任的基石 。

📜 证书签发流程

证书的签发遵循一个标准流程,下图展示了从生成密钥对到最终签发证书的完整过程:
生成私钥
创建证书签名请求

(CSR)
CA审核并签署

(生成正式证书)
部署证书到组件
组件使用证书建立安全通信

具体到Kubernetes集群的CA签发组件证书,主要过程如下:

  1. 创建CA(证书颁发机构)

    这是信任的起点。您需要生成一个自签名的根证书和私钥,集群中的所有组件都将信任由此CA签发的证书 [citation:2, citation:3]。

    bash 复制代码
    # 生成CA私钥
    openssl genrsa -out ca.key 2048
    # 生成自签名的CA证书
    openssl req -x509 -new -nodes -key ca.key -subj "/CN=kubernetes-ca" -days 3650 -out ca.crt
  2. 为组件签发证书

    为每个需要认证的组件(如kube-apiserver, etcd, kubelet等)生成证书。这个过程遵循上述流程图,关键在于证书签名请求(CSR)中的主题(Subject) ,尤其是 CN 字段,它常被用于标识组件身份 [citation:1, citation:4]。例如,为kube-apiserver签发证书:

    bash 复制代码
    # 生成私钥
    openssl genrsa -out apiserver.key 2048
    # 生成证书签名请求,CN通常设置为组件名
    openssl req -new -key apiserver.key -out apiserver.csr -subj "/CN=kube-apiserver"
    # 使用CA签署,生成正式证书
    openssl x509 -req -in apiserver.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out apiserver.crt -days 365

    对于kube-apiserver这类服务端证书,还需在配置文件中指定subjectAltName,包含服务的域名和IP地址,否则客户端会认为证书无效 。

🔌 组件认证关系详解

下表清晰地展示了集群中核心组件在相互通信时,谁充当客户端,谁充当服务端,以及分别使用哪些证书来证明自己的身份。

客户端 服务端 客户端使用的证书 服务端使用的证书 认证目的
kubectl / kube-controller-manager / kube-scheduler kube-apiserver 各自的客户端证书(如admin.crt, controller-manager.crt apiserver.crt 控制平面组件和管理员通过API Server操作集群
kube-apiserver etcd apiserver-etcd-client.crt etcd/server.crt API Server作为客户端读写etcd中的数据 [citation:6, citation:7]
kubelet kube-apiserver kubelet-client.crt apiserver.crt kubelet上报节点状态,接收Pod部署指令
kube-apiserver kubelet apiserver-kubelet-client.crt kubelet.crt API Server主动访问kubelet(如日志获取、exec功能)
etcd集群成员 etcd集群成员 etcd/peer.crt etcd/peer.crt etcd节点间的 peer-to-peer 通信与数据同步

💡 关键总结与最佳实践

  • 身份标识 :证书中的 CN 字段是身份标识的关键,Kubernetes的RBAC系统常通过CN来识别用户或组件身份 。
  • 服务端认证 :除了身份标识,服务端证书还必须正确配置subjectAltName,包含其服务的所有域名和IP地址,否则客户端会验证失败 。
  • 安全实践 :妥善保管CA私钥,定期轮换证书。生产环境可以考虑使用cfssl等工具来简化证书管理流程 。

希望这份梳理能帮助您更清晰地理解Kubernetes的证书体系。如果您对某个具体的交互流程或签发细节有更多疑问,我很乐意继续探讨。

相关推荐
栗少2 小时前
Three.js快速入门
学习
想进部的张同学2 小时前
RK3588 Docker 中部署 GStreamer + MPP 并固化镜像(完整踩坑实录)
学习
AI_56782 小时前
K8s新手入门:从“Pod创建”到“服务暴露”,3个案例理解容器编排
人工智能·学习·测试工具
炽烈小老头2 小时前
【每天学习一点算法 2026/01/21】倒二进制位
学习·算法
风流倜傥唐伯虎2 小时前
docker常用命令
docker·容器
ShiLiu_mtx2 小时前
k8s - 1
云原生·容器·kubernetes
峰顶听歌的鲸鱼2 小时前
Kubernetes核心概述
运维·笔记·云原生·容器·kubernetes·云计算
在繁华处2 小时前
Markdow文档初学
学习
weixin_481950352 小时前
跟AI学习用python制作下载器-3
开发语言·python·学习