k8s内的主节点与工作节点组件通信依赖ssl证书进行加密通信,而证书是会过期的
1、手动续签证书:https://egonlin.com/?p=11593
2、自动续签证书:需针对不同组件采用不同策略
主节点(控制平面)证书自动更新:推荐使用 Cert-Manager + 自签名 CA
工作节点(kubelet)证书自动更新:工作节点证书通过 Kubernetes 原生 TLS Bootstrapping 机制实现全自动轮换(已默认开启),无需外部工具。
kubeadm部署会自动创建自签名CA,默认 默认有效期 10 年,需手动更新(高风险操作)
针对用户的环境(Kubernetes 1.22.2),我自动化方案:
一、控制平面证书自动化续期(使用cert-manager)
步骤:
1. 安装cert-manager(使用Helm或YAML)
2. 创建自签名CA(或使用现有CA)并存储为Secret
3. 创建ClusterIssuer引用该CA
4. 为每个控制平面组件(apiserver, etcd, controller-manager, scheduler等)创建Certificate资源
5. 修改控制平面组件的静态Pod定义,使其使用cert-manager管理的证书(从Secret挂载),并启用证书热加载(如果组件支持)
6. 重启控制平面组件(一次性的,之后由cert-manager自动续期)
二、工作节点证书自动化续期
工作节点的kubelet证书通过TLS Bootstrapping自动轮换,但需要确保:
1. kubelet配置了`--rotate-certificates=true`(默认开启)详解工作节点的/var/lib/kubelet/config.yaml中的配置项rotateCertificates为true
2. controller-manager配置了自动批准CSR(默认开启)
3. 确保RBAC授权正确(默认已设置)
三、CA根证书的考虑
控制平面组件的根证书(ca.crt)默认10年,但若需要更新,则需要手动操作(风险高)。建议在初始化集群时使用长期有效的CA,或者定期(比如每8年)更新CA并重新签所有证书,不过有几个人能在一家公司干满10年呢,或者说同一个项目谁能维护10年呢哈哈哈。
四、监控与告警
部署监控,对证书过期时间进行告警(如使用Prometheus监控cert-manager的指标,或定期检查证书过期时间)。
具体操作步骤(针对控制平面):
1. 安装cert-manager
由于是离线环境?这里假设有网络(如果没有,需要先下载镜像)
使用Helm安装:
```
helm repo add jetstack https://charts.jetstack.io
helm repo update
helm install cert-manager jetstack/cert-manager --namespace cert-manager --create-namespace --version v1.13.1 --set installCRDs=true
```
2. 创建自签名CA(如果集群现有的CA可以继续使用,则跳过创建,直接创建Secret)
生成CA(在master节点上):
```
openssl genrsa -out ca.key 2048
openssl req -x509 -new -nodes -key ca.key -subj "/CN=Kubernetes" -days 3650 -out ca.crt
查看
openssl x509 -in /etc/kubernets/pki/ca.crt -noout -text |grep Not
```
创建Secret(在kube-system命名空间):
```
kubectl create secret tls k8s-root-ca --cert=ca.crt --key=ca.key -n kube-system
```
3. 创建ClusterIssuer
```yaml
apiVersion: cert-manager.io/v1
kind: ClusterIssuer
metadata:
name: k8s-root-issuer
namespace: kube-system
spec:
ca:
secretName: k8s-root-ca
```
4. 为每个组件创建Certificate资源(以apiserver为例)
```yaml
apiVersion: cert-manager.io/v1
kind: Certificate
metadata:
name: kube-apiserver
namespace: kube-system
spec:
secretName: kube-apiserver-tls # 这个Secret名称需要与apiserver启动参数中指定的证书一致
duration: 8760h # 1年
renewBefore: 720h # 提前30天续期
issuerRef:
name: k8s-root-issuer
kind: ClusterIssuer
commonName: kube-apiserver
usages:
- server auth
- client auth
dnsNames:
- kubernetes
- kubernetes.default
- kubernetes.default.svc
- kubernetes.default.svc.cluster.local
- localhost
# 添加其他DNS名称(如master节点的主机名、负载均衡器的域名等)
ipAddresses:
- 127.0.0.1
- 10.96.0.1 # ClusterIP of kubernetes service
# 添加master节点的IP地址
- 192.168.110.128
```
注意:需要为etcd、controller-manager、scheduler等创建类似的Certificate资源。
5. 修改控制平面组件的静态Pod定义(以apiserver为例)
文件位置:/etc/kubernetes/manifests/kube-apiserver.yaml
修改内容:
- 将`--tls-cert-file`和`--tls-private-key-file`指向新证书(从Secret挂载的路径)
- 添加volume挂载(将Secret挂载到容器内)
示例:
```yaml
spec:
containers:
- command:
- kube-apiserver
- --tls-cert-file=/etc/kubernetes/secrets/kube-apiserver-tls/tls.crt
- --tls-private-key-file=/etc/kubernetes/secrets/kube-apiserver-tls/tls.key
# ... 其他参数保持不变
volumeMounts:
- name: apiserver-tls
mountPath: /etc/kubernetes/secrets/kube-apiserver-tls
readOnly: true
volumes:
- name: apiserver-tls
secret:
secretName: kube-apiserver-tls
```
注意:修改后,kubelet会自动重启apiserver的Pod。
6. 重启控制平面组件(如果不确定是否支持热加载,可以重启)
实际上,修改静态Pod定义后,kubelet会自动重启对应的Pod。
7. 注意:其他组件(etcd, controller-manager, scheduler)也需要做类似的修改。
8. 对于kubelet.conf等kubeconfig文件,不需要再手动更新,因为控制平面组件已经使用了新证书,且kubeconfig中的证书是由同一个CA签发的,所以信任链一致。
五、工作节点:
无需额外操作,只要确保kubelet的配置正确(自动轮换开启),并且controller-manager能够自动批准CSR。
六、监控:
使用cert-manager自带的Prometheus指标进行监控,并设置告警规则,例如:
```
# 证书在30天内过期
certmanager_certificate_expiration_timestamp_seconds - time() < 86400 * 30
```
七、注意事项:
- 在迁移过程中,需要确保集群处于可维护状态(可能短暂不可用)。
- 备份原有的证书和配置文件。
- 由于用户集群版本为1.22.2,注意cert-manager的版本兼容性(cert-manager v1.13.1支持Kubernetes 1.22+)。
八、关于CA根证书的长期管理:
- 如果使用自签名CA,建议设置较长的有效期(例如10年),并定期检查CA的过期时间。
- 更新CA根证书是一个复杂且危险的操作,需要谨慎。
总结:通过上述步骤,控制平面证书将由cert-manager自动续期,工作节点证书由Kubernetes原生机制自动续期,从而实现全集群证书的自动化管理。
以下是完整的自动化解决方案,可避免未来证书过期导致的服务中断:
自动化证书管理方案(基于 Kubernetes 1.22.2)
一、控制平面证书自动化(Master 节点)
核心工具:cert-manager + 自签名 CA
# 1. 安装 cert-manager(v1.13.1 兼容 Kubernetes 1.22) helm repo add jetstack https://charts.jetstack.io helm install cert-manager jetstack/cert-manager \ --namespace cert-manager \ --create-namespace \ --version v1.13.1 \ --set installCRDs=true # 2. 创建长期有效的根 CA(10年有效期) openssl genrsa -out ca.key 4096 openssl req -x509 -new -nodes -key ca.key \ -subj "/CN=Kubernetes Internal CA" \ -days 3650 -out ca.crt # 3. 创建 CA Secret kubectl create secret tls k8s-root-ca \ --namespace=kube-system \ --cert=ca.crt \ --key=ca.key # 4. 创建 ClusterIssuer cat <<EOF | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: ClusterIssuer metadata: name: k8s-root-issuer namespace: kube-system spec: ca: secretName: k8s-root-ca EOF
二、为控制平面组件配置自动续期
# 5. API Server 证书配置(示例) cat <<EOF | kubectl apply -f - apiVersion: cert-manager.io/v1 kind: Certificate metadata: name: kube-apiserver namespace: kube-system spec: secretName: kube-apiserver-tls duration: 8760h # 1年 renewBefore: 720h # 提前30天续期 issuerRef: name: k8s-root-issuer kind: ClusterIssuer commonName: kube-apiserver dnsNames: - kubernetes - kubernetes.default - kubernetes.default.svc - kubernetes.default.svc.cluster.local - localhost ipAddresses: - 127.0.0.1 - 10.96.0.1 - 192.168.110.128 # Master IP organization: - system:masters usages: - server auth - client auth EOF
三、修改控制平面组件配置
# 6. 修改 API Server 配置 sudo vi /etc/kubernetes/manifests/kube-apiserver.yaml
添加以下配置:
spec: containers: - command: - kube-apiserver - --tls-cert-file=/etc/kubernetes/secrets/kube-apiserver-tls/tls.crt - --tls-private-key-file=/etc/kubernetes/secrets/kube-apiserver-tls/tls.key - --feature-gates=APIServerIdentity=true - --tls-cert-file-watch=true # 启用证书监控 volumeMounts: - name: apiserver-tls mountPath: /etc/kubernetes/secrets/kube-apiserver-tls volumes: - name: apiserver-tls secret: secretName: kube-apiserver-tls
四、工作节点自动化(Worker 节点)
核心机制:原生 TLS Bootstrapping
# 1. 确保所有节点 kubelet 配置 sudo vi /etc/systemd/system/kubelet.service.d/10-kubeadm.conf
添加参数:
Environment="KUBELET_EXTRA_ARGS=--rotate-certificates=true --cert-dir=/var/lib/kubelet/pki"
# 2. 配置 Controller Manager 自动审批 sudo vi /etc/kubernetes/manifests/kube-controller-manager.yaml
添加参数:
spec: containers: - command: - kube-controller-manager - --cluster-signing-duration=87600h # 10年有效期 - --controllers=*,csrapprover - --feature-gates=RotateKubeletServerCertificate=true
五、监控与告警系统
# 1. 创建证书过期告警(Prometheus) cat <<EOF | kubectl apply -f - apiVersion: monitoring.coreos.com/v1 kind: PrometheusRule metadata: name: cert-expiry-alert namespace: kube-system spec: groups: - name: cert-expiry rules: - alert: CertificateExpiringSoon expr: (certmanager_certificate_expiration_timestamp_seconds - time()) / 86400 < 30 for: 5m labels: severity: critical annotations: summary: "证书即将过期 ({{ $labels.name }})" description: "证书 {{ $labels.name }} 将在 {{ printf \"%.0f\" ( (certmanager_certificate_expiration_timestamp_seconds - time()) / 86400 ) }} 天后过期" EOF # 2. 定期检查脚本 sudo tee /usr/local/bin/check-certs.sh <<'EOF' #!/bin/bash kubeadm certs check-expiration find /etc/kubernetes/pki -type f -name "*.crt" -print0 | xargs -0 openssl x509 -noout -dates | awk -F= '/notAfter/{print "证书过期时间:", $2}' EOF sudo chmod +x /usr/local/bin/check-certs.sh # 3. 添加到 cronjob(每月检查) (crontab -l ; echo "0 0 1 * * /usr/local/bin/check-certs.sh | mail -s 'K8s证书检查' admin@example.com") | crontab -
六、灾备与恢复方案
# 1. 自动备份证书 sudo tee /usr/local/bin/backup-certs.sh <<'EOF' #!/bin/bash BACKUP_DIR="/backup/certs/$(date +%Y%m%d)" mkdir -p $BACKUP_DIR cp -a /etc/kubernetes $BACKUP_DIR cp -a /var/lib/kubelet/pki $BACKUP_DIR/kubelet-certs tar -czf $BACKUP_DIR.tar.gz $BACKUP_DIR find /backup -type f -mtime +30 -delete EOF sudo chmod +x /usr/local/bin/backup-certs.sh # 2. 添加到 cronjob(每周备份) (crontab -l ; echo "0 3 * * 0 /usr/local/bin/backup-certs.sh") | crontab - # 3. Velero 备份关键 Secrets velero backup create certs-backup --include-resources secrets --selector cert-manager.io/certificate-name
方案验证流程
# 1. 强制触发续期测试 kubectl patch certificate kube-apiserver -n kube-system \ --type='json' -p='[{"op": "replace", "path": "/spec/renewBefore", "value": "5m"}]' # 2. 观察续期过程 kubectl get certificates -n kube-system -w kubectl logs -f -n cert-manager deploy/cert-manager # 3. 验证新证书加载 openssl s_client -connect 127.0.0.1:6443 -showcerts 2>/dev/null | openssl x509 -noout -dates
关键注意事项
-
版本兼容性
-
cert-manager v1.13.x 完美兼容 Kubernetes 1.22
-
确保所有节点时间同步(NTP 服务)
-
-
多主节点部署
# 在所有 Master 节点执行相同配置 for node in k8scludes1 k8scludes2 k8scludes3; do scp /etc/kubernetes/manifests/*.yaml ${node}:/etc/kubernetes/manifests/ ssh ${node} "systemctl restart kubelet" done
-
证书迁移策略
-
首次配置在维护窗口进行
-
使用
kubeadm certs renew all生成新证书 -
逐步替换为 cert-manager 管理
-
-
安全加固
# 限制 CA Secret 访问 kubectl create rolebinding cert-manager-ca \ --role=cert-manager-ca-role \ --serviceaccount=kube-system:cert-manager \ --namespace=kube-system
方案优势:
控制平面证书全自动续期(cert-manager)
工作节点证书自动轮换(原生 TLS Bootstrapping)
过期前主动告警(Prometheus)
灾难恢复保障(自动备份 + Velero)
零手动干预,彻底避免证书过期导致的集群故障