Skip to content

修改证书有效期

概述

  Kubernetes 要求组件之间需要双向加密通信,因此在搭建集群时,KubeAdm 会自动生成相关证书,但是该证书的有效期只有一年。Kubernetes 的本意是想让用户每年升级一次(每个版本的维护期为 1 年左右),但是生产环境的话我们无法控制升级周期,为了避免因为证书过期而导致集群出现问题,我们需要延长 Kubernetes 生成的证书有效期。

  延长 KubeAdm 证书有两种方案:

  1. 修改 KubeAdm 源代码,延长生成的证书有效期
  2. 证书轮换

修改 KubeAdm 源代码

思路

  本方法的主要思路是通过修改 KubeAdm 的源代码,修改生成证书相关的代码,延长生成的证书的有效期。将修改后的源代码编译后,生成新的 kubeadm 客户端,使用新的客户端去初始化集群即可。

下载源代码

  通过以下命令下载 Kubernetes 源代码。

bash
# 克隆指定版本的 Kubernetes 源代码
$ git clone -b v1.27.4 --depth=1 https://github.com/kubernetes/kubernetes.git

修改源代码

  使用 VSCode 打开该项目。

go
// 找到 cmd > kubeadm > app > util > pkiutil > pki_helpers.go 文件的 NewSignedCert 方法
// 分析该方法如何生成证书
func NewSignedCert(cfg *CertConfig, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer, isCA bool) (*x509.Certificate, error) {
    ...
    // 确定证书过期时间,该时间由 kubeadmconstants.CertificateValidity 常量控制
	notAfter := time.Now().Add(kubeadmconstants.CertificateValidity).UTC()
	if cfg.NotAfter != nil {
		notAfter = *cfg.NotAfter
	}

	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,
		NotAfter:              notAfter,
		KeyUsage:              keyUsage,
		ExtKeyUsage:           cfg.Usages,
		BasicConstraintsValid: true,
		IsCA:                  isCA,
	}
    ...
}

// 找到 cmd > kubeadm > app > constants > constants.go 文件
// 找到 CertificateValidity 常量,发现该常量的值等于 1 年
const (
    ...
	// CertificateValidity defines the validity for all the signed certificates generated by kubeadm
    // 这里我们修改为 10 年
	CertificateValidity = time.Hour * 24 * 365 * 10
    ...
)

编译源代码

  平时不太开发 Go 语言,因此不想在我的电脑上搭建 Go 的开发环境。这里我们用 Docker 镜像来编译。使用 Docker 镜像来编译还有个好处,就是可以做交叉编译,从生成生多架构的应用文件。

bash
# 运行一次性 docker 镜像
# 将 kubernetes 的源代码以卷的形式挂载到容器里进行编译
$ docker run -it --rm -v /Volumes/AYData/NotBackup/docker/git/kubernetes:/kubernetes golang:1.20.6 bash

# 在容器的 shell 里面进入 kubernetes 源代码文件夹
$ root@04bc89f885cf:/go# cd /kubernetes/

# 编译源代码
$ root@04bc89f885cf:/kubernetes# make WHAT=cmd/kubeadm GOFLAGS=-v

# 退出容器
$ exit

  回到 kubernetes 的源代码目录,发现多了 _output 目录。在 _output/local/go/bin 目录下,可以找到编译好的 kubeadm 程序文件,将该文件替换掉 /usr/local/kubeadm 文件即可使用。

编译指定架构程序

  如果需要编译非本机架构的程序,可以通过以下命令完成。

bash
# 运行一次性 docker 镜像
# 指定 docker 镜像的架构
$ docker run -it --rm --platform linux/arm64 -v /Volumes/AYData/NotBackup/docker/git/kubernetes:/kubernetes golang:1.20.6 bash

# 查看系统架构,可以发现当前架构是 aarch64,也就是 arm64
$ root@34b7dcf7d4e0:/go# uname -m
aarch64

# 后续的步骤与上一节相同,将 go 编译即可

证书轮换

  待补充[链接]


Released under the MIT license.