Kubernetes v1.25 编译 kubeadm 修改证书有效期到 100 年

Posted by sysin on 2022-10-09
Estimated Reading Time 12 Minutes
Words 2.3k In Total
更新日期:Sun Oct 09 2022 12:10:00 GMT+0800,阅读量:

请访问原文链接:Kubernetes v1.25 编译 kubeadm 修改证书有效期到 100 年,查看最新版。原创作品,转载请保留出处。

作者主页:sysin.org


无耻抄袭者 Yu Tao,请立遁!!!

kubernetes-flower

随着 Kubernetes 1.25 的发布(August 23, 2022),没写完的文章又要测试一下新版本才能完成。

kubeadm 默认证书为一年,一年过期后,会导致 api service 不可用,使用过程中会出现:x509: certificate has expired or is not yet valid.

Google 建议通过不停更新版本来自动更新证书,太坑 ^_^

可以在初始化群集之前重新编译 kubeadm,证书有效期自动为 100 年。

兼容性:

已经测试适用于以下版本

  • 1.17.0
  • 1.18.0
  • 1.19.0
  • 1.20.0
  • 1.21.0
  • 1.22.0
  • 1.23.0
  • 1.24.0
  • 1.25.0

1. 获取源码

访问:https://github.com/kubernetes/kubernetes/releases,下载特定版本源码

1
2
3
4
wget https://github.com/kubernetes/kubernetes/archive/v1.25.0.tar.gz
tar -zxvf kubernetes-1.25.0.tar.gz
mv kubernetes-1.25.0 kubernetes
cd kubernetes

或者使用 git 获取

1
2
3
4
5
# yum install git
# sudo apt install git
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
git checkout -b remotes/origin/release-1.25 v1.25.0

2. 修改证书有效期

查看网上的资料主要有两个地方需要修改

2.1 修改 CA 有效期为 100 年(默认为 10 年)

vim ./staging/src/k8s.io/client-go/util/cert/cert.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
// 这个方法里面 NotAfter:              now.Add(duration365d * 10).UTC()
// 默认有效期就是 10 年,改成 100 年 (sysin)
// 输入 /NotAfter 查找,回车定位
func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, error) {
now := time.Now()
tmpl := x509.Certificate{
SerialNumber: new(big.Int).SetInt64(0),
Subject: pkix.Name{
CommonName: cfg.CommonName,
Organization: cfg.Organization,
},
NotBefore: now.UTC(),
// NotAfter: now.Add(duration365d * 10).UTC(),
NotAfter: now.Add(duration365d * 100).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,
}

certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &tmpl, &tmpl, key.Public(), key)
if err != nil {
return nil, err
}
return x509.ParseCertificate(certDERBytes)
}

2.2 修改证书有效期为 100 年(默认为 1 年)

vim ./cmd/kubeadm/app/constants/constants.go

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
// 就是这个常量定义 CertificateValidity,改成 * 100 年 (sysin)
// 输入 /CertificateValidity 查找,回车定位
const (
// KubernetesDir is the directory Kubernetes owns for storing various configuration files
KubernetesDir = "/etc/kubernetes"
// ManifestsSubDirName defines directory name to store manifests
ManifestsSubDirName = "manifests"
// TempDirForKubeadm defines temporary directory for kubeadm
// should be joined with KubernetesDir.
TempDirForKubeadm = "tmp"

// CertificateValidity defines the validity for all the signed certificates generated by kubeadm
// CertificateValidity = time.Hour * 24 * 365
CertificateValidity = time.Hour * 24 * 365 * 100

// CACertAndKeyBaseName defines certificate authority base name
CACertAndKeyBaseName = "ca"
// CACertName defines certificate name
CACertName = "ca.crt"
// CAKeyName defines certificate name
CAKeyName = "ca.key"

验证一下已经正确修改:

1
2
cat ./staging/src/k8s.io/client-go/util/cert/cert.go | grep NotAfter
cat ./cmd/kubeadm/app/constants/constants.go | grep CertificateValidity

git 验证(可选,适用于 git 获取的源码),修改的内容如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
git diff

diff --git a/cmd/kubeadm/app/constants/constants.go b/cmd/kubeadm/app/constants/constants.go
index 75adf43..54f25fa 100644
--- a/cmd/kubeadm/app/constants/constants.go
+++ b/cmd/kubeadm/app/constants/constants.go
@@ -44,7 +44,7 @@ const (
TempDirForKubeadm = "tmp"

// CertificateValidity defines the validity for all the signed certificates generated by kubeadm
- CertificateValidity = time.Hour * 24 * 365
+ CertificateValidity = time.Hour * 24 * 365 * 100

// CACertAndKeyBaseName defines certificate authority base name
CACertAndKeyBaseName = "ca"
diff --git a/staging/src/k8s.io/client-go/util/cert/cert.go b/staging/src/k8s.io/client-go/util/cert/cert.go
index 9fd097a..865d6bb 100644
--- a/staging/src/k8s.io/client-go/util/cert/cert.go
+++ b/staging/src/k8s.io/client-go/util/cert/cert.go
@@ -63,7 +63,7 @@ func NewSelfSignedCACert(cfg Config, key crypto.Signer) (*x509.Certificate, erro
Organization: cfg.Organization,
},
NotBefore: now.UTC(),
- NotAfter: now.Add(duration365d * 10).UTC(),
+ NotAfter: now.Add(duration365d * 100).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature | x509.KeyUsageCertSign,
BasicConstraintsValid: true,
IsCA: true,

源代码改好了,接下来就是编译 kubeadm 了。

3. 编译

3.1 Docker 镜像编译

注意:该方法仅适用早期版本,现在已经不可用。

使用该方法可以获得与官方一致的编译环境。

目前 gcr 上的最新版本仍然是 v1.13.6-1(665.3 MB),构建于 2020年1月16日。

  • 查看 kube-cross 的 TAG 版本号
1
2
3
cat ./build/build-image/cross/VERSION

v1.25.0-go1.19-bullseye.0

这里我们可以使用官方容器对代码进行编译:k8s.gcr.io/kube-cross:v1.19-1

  • 拉取镜像
1
docker pull k8s.gcr.io/kube-cross:v1.19-1

无法翻墙可以用下面的替代镜像:比较遗憾都没有更新!

1
docker pull gcrcontainer/kube-cross:v1.19-1

或者:docker pull registry.aliyuncs.com/google_containers/kube-cross:v1.19-1

  • 编译
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# docker run --rm -v <你修改后的代码目录>:/go/src/k8s.io/kubernetes -it gcrcontainer/kube-cross bash
docker run --rm -v /root/kubernetes:/go/src/k8s.io/kubernetes -it k8s.gcr.io/kube-cross:v1.19-1 bash

cd /go/src/k8s.io/kubernetes

# 编译 kubeadm, 这里主要编译 kubeadm 即可
make all WHAT=cmd/kubeadm GOFLAGS=-v

# 编译 kubelet
# make all WHAT=cmd/kubelet GOFLAGS=-v

# 编译 kubectl
# make all WHAT=cmd/kubectl GOFLAGS=-v

# 退出容器
exit

#编译完产物在 _output/bin/kubeadm 目录下,
#其中 bin 是使用了软连接 (sysin)
#真实路径是_output/local/bin/linux/amd64/kubeadm
mv /usr/bin/kubeadm /usr/bin/kubeadm_backup
cp _output/local/bin/linux/amd64/kubeadm /usr/bin/kubeadm
#chmod +x /usr/bin/kubeadm

# 验证版本
kubeadm version

3.2 本机编译

环境需求参看 官方文档

本例在 AlmaLinux 9 x86_64 中编译完成。

3.2.1 软件包准备

CentOS:

1
2
yum groupinstall "Development Tools" -y #gcc, make etc.
yum install rsync jq -y

Ubuntu:

1
2
sudo apt install build-essential #(Following command will install essential commands like gcc, make etc.)
sudo apt install rsync jq -y

3.2.2 GoLang 环境

  • 查看 kube-cross 的 TAG 版本号
1
2
3
# cat ./build/build-image/cross/VERSION
v1.25.0-go1.19-bullseye.0
#注意:之前的版本显示这种数字格式 v1.19-1
  • 安装 Go 环境:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
wget https://dl.google.com/go/go1.19.linux-amd64.tar.gz
## 或者
# wget https://golang.google.cn/dl/go1.19.linux-amd64.tar.gz
tar zxvf go1.19.linux-amd64.tar.gz -C /usr/local

# 编辑 / etc/profile 文件添加如下:
#go setting (sysin)
#export GOROOT=/usr/local/go
#export GOPATH=/usr/local/gopath
#export PATH=$PATH:$GOROOT/bin
#生效
#source /etc/profile

# 这里一次性编译,直接执行如下命令即可
export PATH=$PATH:/usr/local/go/bin
  • 验证:
1
2
3
go version
# 输出如下
go version go1.19 linux/amd64
  • 编译:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
# 编译 kubeadm, 这里主要编译 kubeadm 即可
make all WHAT=cmd/kubeadm GOFLAGS=-v

# 编译 kubelet
# make all WHAT=cmd/kubelet GOFLAGS=-v

# 编译 kubectl
# make all WHAT=cmd/kubectl GOFLAGS=-v

#编译完产物在 _output/bin/kubeadm 目录下,
#其中 bin 是使用了软连接 (sysin)
#真实路径是_output/local/bin/linux/amd64/kubeadm
mv /usr/bin/kubeadm /usr/bin/kubeadm_backup
cp _output/local/bin/linux/amd64/kubeadm /usr/bin/kubeadm
chmod +x /usr/bin/kubeadm
  • 查看编译后的版本信息
1
2
3
kubeadm version
# 输出如下
kubeadm version: &version.Info{Major:"1", Minor:"25", GitVersion:"v1.25.0", GitCommit:"a866cbe2e5bbaa01cfd5e969aa3e033f3282a8a2", GitTreeState:"archive", BuildDate:"2022-10-09T05:25:21Z", GoVersion:"go1.19", Compiler:"gc", Platform:"linux/amd64"}
  • 保存备用
1
2
3
4
5
6
# 压缩保存到用户主目录下
tar zcvf ~/kubeadm-1.25.0.tgz -C/usr/bin/ kubeadm

# 在其他节点上替换原有版本
mv /usr/bin/kubeadm /usr/bin/kubeadm_bak
tar zxvf ./kubeadm-1.25.0.tgz -C /usr/bin/

4. 执行命令更新证书

如果是使用原版 kubeadm 安装之后,可以手动执行命令更新证书有效期到 100 年。

可以先备份证书,证书在 /etc/kubernetes/pki

  • 检查证书到期时间
1
2
3
kubeadm certs check-expiration
# 早期版本 (1.19 及之前版本) 命令如下
#kubeadm alpha certs check-expiration

kubeadm alpha certs 命令 1.20 开始废弃。

kubeadm alpha 命令 1.21 开始彻底废弃。

参看 kubeadm alpha(替换 URL 中的版本号查看状态)。

输出如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
[check-expiration] Reading configuration from the cluster...
[check-expiration] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -oyaml'

CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED
admin.conf Dec 08, 2121 05:35 UTC 99y no
apiserver Dec 08, 2121 05:35 UTC 99y ca no
apiserver-etcd-client Dec 08, 2121 05:35 UTC 99y etcd-ca no
apiserver-kubelet-client Dec 08, 2121 05:35 UTC 99y ca no
controller-manager.conf Dec 08, 2121 05:35 UTC 99y no
etcd-healthcheck-client Dec 08, 2121 05:35 UTC 99y etcd-ca no
etcd-peer Dec 08, 2121 05:35 UTC 99y etcd-ca no
etcd-server Dec 08, 2121 05:35 UTC 99y etcd-ca no
front-proxy-client Dec 08, 2121 05:35 UTC 99y front-proxy-ca no
scheduler.conf Dec 08, 2121 05:35 UTC 99y no

CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED
ca Dec 08, 2121 05:35 UTC 99y no
etcd-ca Dec 08, 2121 05:35 UTC 99y no
front-proxy-ca Dec 08, 2121 05:35 UTC 99y no
  • 续订证书(查看可以使用的参数)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
kubeadm certs renew --help
This command is not meant to be run on its own. See list of available subcommands.

Usage:
kubeadm certs renew [flags]
kubeadm certs renew [command]

Available Commands:
admin.conf Renew the certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself
all Renew all available certificates
apiserver Renew the certificate for serving the Kubernetes API
apiserver-etcd-client Renew the certificate the apiserver uses to access etcd
apiserver-kubelet-client Renew the certificate for the API server to connect to kubelet
controller-manager.conf Renew the certificate embedded in the kubeconfig file for the controller manager to use
etcd-healthcheck-client Renew the certificate for liveness probes to healthcheck etcd
etcd-peer Renew the certificate for etcd nodes to communicate with each other
etcd-server Renew the certificate for serving etcd
front-proxy-client Renew the certificate for the front proxy client
scheduler.conf Renew the certificate embedded in the kubeconfig file for the scheduler manager to use

Flags:
-h, --help help for renew

Global Flags:
--add-dir-header If true, adds the file directory to the header of the log messages
--log-file string If non-empty, use this log file
--log-file-max-size uint Defines the maximum size a log file can grow to. Unit is megabytes. If the value is 0, the maximum file size is unlimited. (default 1800)
--one-output If true, only write logs to their native severity level (vs also writing to each lower severity level)
--rootfs string [EXPERIMENTAL] The path to the 'real' host root filesystem.
--skip-headers If true, avoid header prefixes in the log messages
--skip-log-headers If true, avoid headers when opening log files
-v, --v Level number for the log level verbosity

Use "kubeadm certs renew [command] --help" for more information about a command.
  • 续订全部证书
1
kubeadm certs renew all
  • 再次查看证书有效期,全部都 100 年了
1
kubeadm certs check-expiration

5. 下载

已经修改好的 kubeadm 下载(1.17.0、1.18.0、1.19.0,1.20.0 - 1.25.0 持续更新中):

百度网盘链接:https://pan.baidu.com/s/17_fJhoBBIO-B-M596UX_bA?pwd=f588


捐助本站 ❤️ Donate

点击访问官方网站


文章用于推荐和分享优秀的软件产品及其相关技术,所有软件默认提供官方原版(免费版或试用版),免费分享。对于部分产品笔者加入了自己的理解和分析,方便学习和测试使用。任何内容若侵犯了您的版权,请联系作者删除。如果您喜欢这篇文章或者觉得它对您有所帮助,或者发现有不当之处,欢迎您发表评论,也欢迎您分享这个网站,或者赞赏一下作者,谢谢!

支付宝赞赏 微信赞赏

赞赏一下


☑️ 评论恢复,欢迎留言❗️
敬请注册!点击 “登录” - “用户注册”(已知不支持 21.cn/189.cn 邮箱)。请勿使用联合登录(已关闭)