Kubeadm 证书过期时间调整

下载源码

手动下载源码编译,这里我使用v1.15.6来做示范。我们使用容器编译,这里我使用4c8gcentos7.6+docker-ce-18.09。想办法把源码拉下来

1
2
3
git clone https://github.com/kubernetes/kubernetes -b v1.15.6
cd kubernetes
git checkout -b v1.15.6

编译前准备

因为我们拉取后修改了源码,编译出的version信息会是下面带-dirty

1
2
$ kube-controller-manager --version
Kubernetes v1.15.5-dirty

可以执行下面命令去掉-dirty,或者自己git add后commit也行

1
sed -ri 's#KUBE_GIT_TREE_STATE="dirty"#KUBE_GIT_TREE_STATE="clean"#g' hack/lib/version.sh

另外如果有需求也编译docker镜像的话可以先提前准备本地镜像,修改build/lib/release.sh,命令sed -ri 's#(build)\s+--pull#\1#' build/lib/release.sh

1
2
3
"${DOCKER[@]}" build --pull -q -t "${docker_image_tag}" "${docker_build_path}" >/dev/null
修改为下面
"${DOCKER[@]}" build -q -t "${docker_image_tag}" "${docker_build_path}" >/dev/null

因为我们使用docker镜像编译,需要提前准备镜像,可以先到下面的make quick-release先看报错无法拉取的镜像名,获取到了后再下面拉取镜像

1
2
[root@k8s-m1 kubernetes]# grep FROM  _output/images/kube-build\:build-7db96ab759-5-v1.12.12-1/Dockerfile 
FROM k8s.gcr.io/kube-cross:v1.12.12-1

清理编译文件

1
make clean

拉取该镜像

1
curl -s https://zhangguanzhang.github.io/bash/pull.sh | bash -s k8s.gcr.io/kube-cross:v1.12.12-1

拉下来之后挂载到容器去编译,环境都弄好了(挂载上之后先暂时不管,先修改代码)

1
docker run -it --rm -v /root/kubernetes:/go/src/k8s.io/kubernetes k8s.gcr.io/kube-cross:v1.12.12-1  /bin/sh

修改关键部分代码的证书生产有效期(自签CA的有效期)

1
[root@k8s-m1 kubernetes]# 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
// NewSelfSignedCACert creates a CA certificate
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字段,默认为10年改为100年
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)
}

修改kubeadm生成的有效期

1
[root@k8s-m1 kubernetes]# 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
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 * 100 # 修改CertificateValidity字段

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

进入容器内开始编译

1
2
3
4
5
6
7
[root@k8s-m1 kubernetes]# docker run -it --rm -v /root/kubernetes:/go/src/k8s.io/kubernetes k8s.gcr.io/kube-cross:v1.12.12-1  /bin/sh
# cd /go/src/k8s.io/kubernetes

# pwd
/go/src/k8s.io/kubernetes

# make WHAT=cmd/kubeadm GOFLAGS=-v

编译成功后二进制文件在./_output/local/bin/linux/amd64/ 目录下,直接覆盖掉 /usr/bin/ 下的 kubeadm 就行了,这个只在 master 节点替换掉就行了(如果有多台master,则将第一台生成的相关证书拷贝到其余master即可。)

1
cp _output/local/bin/linux/amd64/kubeadm  /usr/bin/

获取kubeadm版本信息

1
2
[root@k8s-m1 kubernetes]# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"15", GitVersion:"v1.15.6", GitCommit:"7015f71e75f670eb9e7ebd4b5749639d42e20079", GitTreeState:"clean", BuildDate:"2019-12-05T05:59:03Z", GoVersion:"go1.12.12", Compiler:"gc", Platform:"linux/amd64"}

更新所有证书

由 kubeadm 生成的客户端证书在 1 年后到期。 下面将介绍如何使用 kubeadm 管理证书续订。

检查证书是否过期

check-expiration 能被用来检查证书是否过期

1
kubeadm alpha certs check-expiration

输出类似于以下内容:

1
2
3
4
5
6
7
8
9
10
11
CERTIFICATE                EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
admin.conf May 15, 2020 13:03 UTC 364d false
apiserver May 15, 2020 13:00 UTC 364d false
apiserver-etcd-client May 15, 2020 13:00 UTC 364d false
apiserver-kubelet-client May 15, 2020 13:00 UTC 364d false
controller-manager.conf May 15, 2020 13:03 UTC 364d false
etcd-healthcheck-client May 15, 2020 13:00 UTC 364d false
etcd-peer May 15, 2020 13:00 UTC 364d false
etcd-server May 15, 2020 13:00 UTC 364d false
front-proxy-client May 15, 2020 13:00 UTC 364d false
scheduler.conf May 15, 2020 13:03 UTC 364d false

该命令显示 /etc/kubernetes/pki 文件夹中的客户端证书以及 kubeadm 使用的 KUBECONFIG 文件中嵌入的客户端证书的到期时间/剩余时间。
另外, kubeadm 会通知用户证书是否由外部管理; 在这种情况下,用户应该小心的手动/使用其他工具来管理证书更新。

警告: kubeadm 不能管理由外部 CA 签名的证书

注意: 上面的列表中没有包含 kubelet.conf 因为 kubeadm 将 kubelet 配置为自动更新证书。

手动更新证书

您能随时通过 kubeadm alpha certs renew 命令手动更新您的证书。

1
kubeadm  alpha certs renew all 

完成后重启kube-apiserver,kube-controller,kube-scheduler这三个容器

这个命令用 CA (或者 front-proxy-CA )证书和存储在 /etc/kubernetes/pki 中的密钥执行更新。

警告: 如果您运行了一个 HA 集群,这个命令需要在所有控制面板节点上执行。

注意:alpha certs renew 使用现有的证书作为属性 (Common Name、Organization、SAN 等) 的权威来源,而不是 kubeadm-config ConfigMap 。强烈建议使它们保持同步。

启用 Kubelet Server 证书

kubelet证书分为serverclient两种, k8s 1.9默认启用了client证书的自动轮换,但server证书出于安全原因需要用户手动签发

增加 kubelet 参数

1
2
# 在/etc/systemd/system/kubelet.service.d/10-kubeadm.conf 增加如下参数
Environment="KUBELET_EXTRA_ARGS=--rotate-server-certificates"

增加 controller-manager 参数

1
2
3
4
5
# 在/etc/kubernetes/manifests/kube-controller-manager.yaml 添加如下参数
- command:
- kube-controller-manager
- --experimental-cluster-signing-duration=87600h0m0s
- ....

Kubeadm 证书过期时间调整
https://system51.github.io/2019/12/05/Kubeadm-certificate-modified/
作者
Mr.Ye
发布于
2019年12月5日
许可协议