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的证书体系。如果您对某个具体的交互流程或签发细节有更多疑问,我很乐意继续探讨。

相关推荐
lichenyang4532 天前
Docker 学习笔记(四):Dockerfile,把项目打成自己的镜像
docker·容器
lichenyang4532 天前
Docker 学习笔记(三):Docker 网络、bridge、子网和容器互通
docker·容器
lichenyang4532 天前
Docker 学习笔记(二):docker run 的参数到底在控制什么?
docker·容器
运维开发故事5 天前
基于 Arthas 的多集群在线诊断系统设计与实现
kubernetes
Patrick_Wilson7 天前
从「改个端口」到 502:Next.js on k8s 的容器端口、Service 映射与 env 覆盖
docker·kubernetes·next.js
探索云原生7 天前
K8s 1.36 这个 GA 特性,把 initContainer 拉模型的 hack 干掉了
ai·云原生·kubernetes
云恒要逆袭7 天前
运行你的第一个Docker容器
后端·docker·容器
Java之美8 天前
一次k8s升级引发的DevicePlugin注册失败
云原生·kubernetes
程序员老赵9 天前
10 分钟部署 OpenCode:Docker 一键安装,浏览器打开就能用 AI 写代码(附完整命令与排错)
docker·容器·ai编程