K8S(十六)—— K8S集群apiserver证书有效期修改指南(适配v1.20.11版本)
本文介绍了如何延长Kubernetes集群中apiserver组件证书的有效期。通过分析证书存放位置及有效期,发现apiserver.crt默认仅1年有效期,而CA证书为10年。为解决证书过期导致集群瘫痪的问题,文章详细讲解了修改方案:首先部署Go 1.15.x编译环境,下载匹配的K8S v1.20.11源码;然后修改kubeadm源码中的pki_helpers.go文件,将NewSignedCe
文章目录
前言
在使用kubeadm部署的Kubernetes集群中,核心组件apiserver的证书默认有效期仅为1年。这在生产环境中存在严重隐患——证书过期后会直接导致K8S集群瘫痪,进而中断现网业务。而CA证书默认有效期为10年,无需频繁调整。
本文将以K8S v1.20.11版本为例,详细讲解如何通过修改kubeadm源码的方式,将apiserver及其他核心组件证书的有效期统一延长至10年,彻底解决证书过期问题。
一、查看K8S集群证书现状
在修改证书前,需先确认当前集群的证书存放位置及有效期,明确待解决的问题。
1.1 查看证书存放位置
K8S集群的所有证书默认存储在/etc/kubernetes/pki/目录下,通过ls命令可查看具体证书文件:
# 列出所有证书及密钥文件
ls /etc/kubernetes/pki/
执行后会显示如下文件(不同环境可能略有差异,但核心证书一致):
apiserver.crt apiserver-etcd-client.key apiserver-kubelet-client.crt ca.crt etcd front-proxy-ca.key front-proxy-client.key sa.pub
apiserver-etcd-client.crt apiserver.key apiserver-kubelet-client.key ca.key front-proxy-ca.crt front-proxy-client.crt sa.key
其中apiserver.crt就是我们需要修改有效期的核心证书。
1.2 查看apiserver证书有效期
通过openssl命令解析apiserver.crt,重点关注Validity(有效期)字段:
# 进入证书目录
cd /etc/kubernetes/pki/
# 解析apiserver证书信息,过滤有效期相关内容
openssl x509 -in apiserver.crt -text -noout | grep -A 2 "Validity"
默认输出结果如下(有效期仅1年):
Validity
Not Before: Oct 10 05:06:40 2025 GMT # 证书生效时间
Not After : Oct 10 05:06:41 2026 GMT # 证书过期时间(仅1年)

1.3 查看CA证书有效期
CA证书(ca.crt)是集群所有证书的签发根证书,默认有效期为10年,可通过以下命令验证:
# 解析CA证书信息,过滤有效期
openssl x509 -in ca.crt -text -noout | grep -A 2 "Validity"
输出结果如下(有效期10年,无需修改):
Validity
Not Before: Oct 10 05:06:40 2025 GMT
Not After : Oct 8 05:06:40 2035 GMT # 过期时间(10年)

二、修改apiserver证书有效期至10年
核心思路:通过修改kubeadm源码中证书生成的有效期逻辑,重新编译kubeadm工具,再用新工具生成10年有效期的证书。
2.1 部署Go环境(编译kubeadm依赖)
kubeadm基于Go语言开发,编译前需部署对应版本的Go环境。K8S v1.20.x推荐使用Go 1.15.x。
1、下载Go安装包(访问Go官网或国内镜像studygolang):
# 下载Go 1.15.15(Linux amd64架构)
wget https://studygolang.com/dl/golang/go1.15.15.linux-amd64.tar.gz
2、上传安装包至Master节点的/opt目录,解压至/usr/local:
tar zxvf /opt/go1.15.15.linux-amd64.tar.gz -C /usr/local/
3、配置Go环境变量,确保系统能识别Go命令:
# 将Go二进制目录添加到系统PATH
echo 'export PATH=/usr/local/go/bin:$PATH' >> /etc/profile
# 生效环境变量
source /etc/profile
4、验证Go环境是否部署成功:
go version
成功输出如下(版本需为1.15.x及以上):

2.2 下载K8S源码(对应v1.20.11版本)
需下载与当前K8S版本匹配的源码,避免源码与集群版本不兼容。
1、创建源码存储目录,生成SSH密钥对(用于GitHub仓库克隆):
# 创建目录
mkdir -p /data/k8s-source && cd /data/k8s-source
# 生成SSH密钥(一路回车,无需设置密码)
ssh-keygen -t rsa
2、将公钥添加至GitHub(需提前注册GitHub账号):
- 查看公钥内容:
cat /root/.ssh/id_rsa.pub - 登录GitHub,进入
Settings > SSH and GPG keys > New SSH key,粘贴公钥并保存。

3、克隆Kubernetes源码仓库,切换至对应版本分支:
# 查看当前kubeadm版本,确认集群版本为v1.20.11
kubeadm version

# 克隆源码(SSH方式,避免HTTPS证书问题)
git clone git@github.com:kubernetes/kubernetes.git
# 进入源码目录
cd kubernetes/
# 切换分支至release-1.20(K8S分支命名规则:release-<major>.<minor>)
git checkout -b release-1.20 remotes/origin/release-1.20
切换分支后,可通过git branch确认当前分支为release-1.20。
如果切换分支报错执行:
git checkout -- .丢弃所有未提交的修改
2.3 修改kubeadm源码(核心:调整证书有效期逻辑)
找到证书生成的核心代码文件,修改证书过期时间的计算逻辑。
1、编辑源码文件cmd/kubeadm/app/util/pkiutil/pki_helpers.go:
vim cmd/kubeadm/app/util/pkiutil/pki_helpers.go
2、定位到NewSignedCert函数(证书生成的核心函数)
// NewSignedCert creates a signed certificate using the given CA certificate and key
func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
// 新增:定义10年有效期常量(365天*10年*24小时*3600秒)
const duration10years = time.Hour * 24 * 365 * 10
serial, err := cryptorand.Int(cryptorand.Reader, new(big.Int).SetInt64(math.MaxInt64))
if err != nil {
return nil, err
}
if len(cfg.CommonName) == 0 {
return nil, errors.New("must specify a CommonName")
}
if len(cfg.Usages) == 0 {
return nil, errors.New("must specify at least one ExtKeyUsage")
}
certTmpl := x509.Certificate{
Subject: pkix.Name{
CommonName: cfg.CommonName,
Organization: cfg.Organization,
},
DNSNames: cfg.AltNames.DNSNames,
IPAddresses: cfg.AltNames.IPs,
SerialNumber: serial,
NotBefore: caCert.NotBefore,
// 修改:将证书过期时间从默认1年改为10年(基于上面定义的duration10years)
NotAfter: time.Now().Add(duration10years).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: cfg.Usages,
}
// 后续代码省略(保持原有逻辑不变)
}
3、保存文件并退出(vim中输入:wq)。
2.4 编译kubeadm工具
基于修改后的源码编译kubeadm,生成支持10年证书的新工具。
1、编译前安装依赖(避免因缺少依赖导致编译失败):
yum install -y gcc make
2、编译kubeadm(指定编译目标为cmd/kubeadm):
# 在K8S源码根目录(/data/k8s-source/kubernetes)执行
make WHAT=cmd/kubeadm GOFLAGS=-v
WHAT=cmd/kubeadm:仅编译kubeadm,减少编译时间;GOFLAGS=-v:显示编译详情,便于排查报错。
3、编译完成后,新生成的kubeadm位于_output/bin/目录,复制到/root目录备份:
cp _output/bin/kubeadm /root/kubeadm-new-v1.20.11

2.5 更新系统中的kubeadm工具
替换系统默认的kubeadm,使用新编译的版本生成证书。
1、备份原kubeadm(避免替换失败后无法恢复):
cp /usr/bin/kubeadm /usr/bin/kubeadm.old-v1.20.11

2、 替换为新编译的kubeadm,并添加执行权限:
cp -f /root/kubeadm-new-v1.20.11 /usr/bin/kubeadm
chmod +x /usr/bin/kubeadm
3、验证kubeadm是否替换成功(版本仍为v1.20.11,仅内部逻辑修改):
kubeadm version
输出如下(版本号需与原集群一致):
kubeadm version: &version.Info{Major:"1", Minor:"20", GitVersion:"v1.20.11", GitCommit:"27522a29febbcc4badac257763044d0d90c11abd", GitTreeState:"clean", BuildDate:"2021-09-15T19:20:34Z", GoVersion:"go1.15.15", Compiler:"gc", Platform:"linux/amd64"}
2.6 生成10年有效期的Master节点证书
使用新kubeadm重新生成证书,覆盖原有1年有效期的证书。
1、备份原有证书目录(关键:避免证书损坏导致集群不可用):
cp -r /etc/kubernetes/pki /etc/kubernetes/pki.old-$(date +%Y%m%d)

2、 生成新证书(覆盖原有证书):
kubeadm alpha certs renew all --config=/opt/kubeadm-config.yaml --v=5
alpha certs renew all:批量更新所有证书;--config:指定集群配置文件,确保证书与集群配置匹配。kubeadm-config.yaml:使用安装K8s集群时的初始化配置文件
3、 验证新apiserver证书有效期(确认已改为10年):
cd /etc/kubernetes/pki
openssl x509 -in apiserver.crt -text -noout | grep -A 2 "Validity"
成功输出如下(Not After为10年后):

2.7 HA集群其他Master节点证书同步
若为HA(高可用)集群(多Master节点),需将新生成的证书同步到其他Master节点,并重启相关组件。
1、编写证书同步脚本(替换masterNode为实际其他Master节点IP):
vim /root/sync-master-certs.sh
脚本内容:
#!/bin/bash
# 其他Master节点IP列表(根据实际集群修改)
masterNode="192.168.80.15 192.168.80.16"
for host in ${masterNode}
do
echo "正在同步证书到节点:$host"
# 同步CA证书及核心密钥
scp /etc/kubernetes/pki/{ca.crt,ca.key,sa.key,sa.pub,front-proxy-ca.crt,front-proxy-ca.key} root@$host:/etc/kubernetes/pki/
# 同步etcd集群证书
scp /etc/kubernetes/pki/etcd/{ca.crt,ca.key} root@$host:/etc/kubernetes/pki/etcd/
# 同步管理员配置文件
scp /etc/kubernetes/admin.conf root@$host:/etc/kubernetes/
done
echo "证书同步完成!"
2、执行脚本同步证书:
chmod +x /root/sync-master-certs.sh
/root/sync-master-certs.sh
3、登录其他Master节点,重启K8S核心组件(使新证书生效):
# 重启kubelet服务
systemctl restart kubelet
# 重启apiserver、controller-manager、scheduler容器(若使用docker)
docker restart $(docker ps -q --filter name=k8s_kube-apiserver*)
docker restart $(docker ps -q --filter name=k8s_kube-controller-manager*)
docker restart $(docker ps -q --filter name=k8s_kube-scheduler*)
三、总结
本文通过“查看证书现状→部署Go环境→下载源码→修改证书逻辑→编译工具→更新证书→同步HA节点”的流程,成功将K8S v1.20.11集群的apiserver证书有效期从1年延长至10年,彻底解决生产环境证书过期的隐患。
关键注意事项:
- 源码分支需与K8S版本匹配(如v1.20.11对应
release-1.20); - Go版本需符合K8S官方推荐(v1.20.x对应Go 1.15.x);
- 所有操作前必须备份证书和工具(如
pki目录、kubeadm),避免集群故障; - HA集群需同步证书并重启组件,确保所有Master节点使用新证书。
更多推荐

所有评论(0)