Featured image of post kubeadm 编译修改证书有效期

kubeadm 编译修改证书有效期

修改kubeadm的证书有效期

kubeadm 默认 ca 证书10年,k8s 证书是 1 年,虽然续期方便,但是为了一劳永逸尝试编译修改 kubeadm 默认证书有效期,并更新现有集群。

环境配置

编译 1.22.9 版本的 kubeadm,首先查看原版的信息

1
2
# kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.9", GitCommit:"6df4433e288edc9c40c2e344eb336f63fad45cd2", GitTreeState:"clean", BuildDate:"2022-04-13T19:56:28Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}

配置 go 环境

为了保持一致,首先配置 go1.16.15

1
2
3
4
5
6
7
8
9
安装 gvm 
# curl -sSL https://github.com/moovweb/gvm/raw/master/binscripts/gvm-installer | bash
安装go1.16.15
# source /root/.gvm/scripts/gvm
# gvm install go1.16.15 -B #只下载二进制
# gvm use go1.16.15
查看go版本
# go version
go version go1.16.15 linux/amd64

下载源码

1
2
# wget https://github.com/kubernetes/kubernetes/archive/refs/tags/v1.22.9.tar.gz
# tar zxvf v1.22.9.tar.gz && cd kubernetes-1.22.9/

修改并编译

修改 CA 证书有效期

 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
# vim staging/src/k8s.io/client-go/util/cert/cert.go

// 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,
                },
                DNSNames:              []string{cfg.CommonName},
                NotBefore:             now.UTC(),
                NotAfter:              now.Add(duration365d * 100).UTC(),     ##### 这里改成 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)
}

修改证书有效期

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
# vim cmd/kubeadm/app/constants/constants.go

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 * 99    ## 修改为 99 

        // 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
 8
 9
10
11
12
13
14
15
16
17
18
# vim cmd/kubeadm/kubeadm.go

package main

import (
        "fmt"
        "k8s.io/kubernetes/cmd/kubeadm/app"
        kubeadmutil "k8s.io/kubernetes/cmd/kubeadm/app/util"
)

func main() {
        kubeadmutil.CheckErr(app.Run())
        fmt.Println("*************************************************************************")
        fmt.Println("****** Change the validity period of all certificates to 100 years ******")
        fmt.Println("******                     Change by xxxxx                         ******")
        fmt.Println("******                     Company: xxxxxxxxxxx                    ******")
        fmt.Println("*************************************************************************")
}

修改版本信息

 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
# vim staging/src/k8s.io/client-go/pkg/version/base.go

var (
        // TODO: Deprecate gitMajor and gitMinor, use only gitVersion
        // instead. First step in deprecation, keep the fields but make
        // them irrelevant. (Next we'll take it out, which may muck with
        // scripts consuming the
 kubectl version output - but most of
        // these should be looking at gitVersion already anyways.)
        gitMajor string = "" // major version, always numeric
        gitMinor string = "" // minor version, numeric possibly followed by "+"

        // semantic version, derived by build scripts (see
        // https://git.k8s.io/community/contributors/design-proposals/release/versioning.md
        // for a detailed discussion of this field)
        //
        // TODO: This field is still called "gitVersion" for legacy
        // reasons. For prerelease versions, the build metadata on the
        // semantic version is a git hash, but the version itself is no
        // longer the direct output of "git describe", but a slight
        // translation to be semver compliant.

        // NOTE: The $Format strings are replaced during 'git archive' thanks to the
        // companion .gitattributes file containing 'export-subst' in this same
        // directory.  See also https://git-scm.com/docs/gitattributes
        gitVersion   string = "v1.22.9"       // 修改版本号
        gitCommit    string = "6df4433e288edc9c40c2e344eb336f63fad45cd2" // sha1 from git, output of $(git rev-parse HEAD)
        gitTreeState string = ""            // state of git tree, either "clean" or "dirty"

        buildDate string = "2022-06-15T10:43:00Z" // 修改编译时间
)

开始编译

1
2
3
4
5
重新编译 kubeadm
# make all WHAT=cmd/kubeadm GOFLAGS=-v
编译后的文件位于 _output/bin/kubeadm
# # ls -l _output/bin/kubeadm
-rwxr-xr-x 1 root root 45838336 Jun 15 10:56 _output/bin/kubeadm

验证

生成新的证书

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ./kubeadm init phase certs all
I0615 11:03:24.174252  293233 version.go:255] remote version is much newer: v1.24.1; falling back to: stable-1.22
[certs] Using certificateDir folder "/etc/kubernetes/pki"
[certs] Generating "ca" certificate and key
[certs] Generating "apiserver" certificate and key
[certs] apiserver serving cert is signed for DNS names [hwcloud kubernetes kubernetes.default kubernetes.default.svc kubernetes.default.svc.cluster.local] and IPs [10.96.0.1 192.168.0.160]
[certs] Generating "apiserver-kubelet-client" certificate and key
[certs] Generating "front-proxy-ca" certificate and key
[certs] Generating "front-proxy-client" certificate and key
[certs] Generating "etcd/ca" certificate and key
[certs] Generating "etcd/server" certificate and key
[certs] etcd/server serving cert is signed for DNS names [hwcloud localhost] and IPs [192.168.0.160 127.0.0.1 ::1]
[certs] Generating "etcd/peer" certificate and key
[certs] etcd/peer serving cert is signed for DNS names [hwcloud localhost] and IPs [192.168.0.160 127.0.0.1 ::1]
[certs] Generating "etcd/healthcheck-client" certificate and key
[certs] Generating "apiserver-etcd-client" certificate and key
[certs] Generating "sa" key and public key

查看证书有效期

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
# ./kubeadm certs check-expiration
CERTIFICATE                         EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
!MISSING! admin.conf
apiserver                           May 22, 2121 03:03 UTC   98y             ca                      no
apiserver-etcd-client               May 22, 2121 03:03 UTC   98y             etcd-ca                 no
apiserver-kubelet-client            May 22, 2121 03:03 UTC   98y             ca                      no
!MISSING! controller-manager.conf
etcd-healthcheck-client             May 22, 2121 03:03 UTC   98y             etcd-ca                 no
etcd-peer                           May 22, 2121 03:03 UTC   98y             etcd-ca                 no
etcd-server                         May 22, 2121 03:03 UTC   98y             etcd-ca                 no
front-proxy-client                  May 22, 2121 03:03 UTC   98y             front-proxy-ca          no
!MISSING! scheduler.conf

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      May 22, 2122 03:03 UTC   99y             no
etcd-ca                 May 22, 2122 03:03 UTC   99y             no
front-proxy-ca          May 22, 2122 03:03 UTC   99y             no

查看版本

1
2
# ./kubeadm version
kubeadm version: &version.Info{Major:"1", Minor:"22", GitVersion:"v1.22.9", GitCommit:"6df4433e288edc9c40c2e344eb336f63fad45cd2", GitTreeState:"archive", BuildDate:"2022-06-15T02:56:47Z", GoVersion:"go1.16.15", Compiler:"gc", Platform:"linux/amd64"}

更新集群证书

替换新编译的 kubeadm 文件到 k8s 任意 master 节点的

查看证书有效期

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
# kubeadm certs check-expiration
[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 -o yaml'
W0615 11:30:27.657289   11850 utils.go:69] The recommended value for "clusterDNS" in "KubeletConfiguration" is: [11.254.0.10]; the provided value is: [169.254.25.10]

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 May 26, 2023 08:03 UTC   345d            ca                      no
apiserver                  May 26, 2023 08:03 UTC   345d            ca                      no
apiserver-etcd-client      May 26, 2023 08:03 UTC   345d            etcd-ca                 no
apiserver-kubelet-client   May 26, 2023 08:03 UTC   345d            ca                      no
controller-manager.conf    May 26, 2023 08:03 UTC   345d            ca                      no
etcd-healthcheck-client    May 26, 2023 08:03 UTC   345d            etcd-ca                 no
etcd-peer                  May 26, 2023 08:03 UTC   345d            etcd-ca                 no
etcd-server                May 26, 2023 08:03 UTC   345d            etcd-ca                 no
front-proxy-client         May 26, 2023 08:03 UTC   345d            front-proxy-ca          no
scheduler.conf             May 26, 2023 08:03 UTC   345d            ca                      no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      May 23, 2032 08:03 UTC   9y              no
etcd-ca                 May 23, 2032 08:03 UTC   9y              no
front-proxy-ca          May 23, 2032 08:03 UTC   9y              no

更新证书

所有 master 节点上面执行

1
# kubeadm certs renew all

再次查看有效期

注: 已经运行的集群 ca 证书不会更新

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
# kubeadm certs check-expiration

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 May 22, 2121 04:10 UTC   98y             ca                      no
apiserver                  May 22, 2121 04:10 UTC   98y             ca                      no
apiserver-etcd-client      May 22, 2121 04:10 UTC   98y             etcd-ca                 no
apiserver-kubelet-client   May 22, 2121 04:10 UTC   98y             ca                      no
controller-manager.conf    May 22, 2121 04:10 UTC   98y             ca                      no
etcd-healthcheck-client    May 22, 2121 04:10 UTC   98y             etcd-ca                 no
etcd-peer                  May 22, 2121 04:10 UTC   98y             etcd-ca                 no
etcd-server                May 22, 2121 04:10 UTC   98y             etcd-ca                 no
front-proxy-client         May 22, 2121 04:10 UTC   98y             front-proxy-ca          no
scheduler.conf             May 22, 2121 04:10 UTC   98y             ca                      no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      May 23, 2032 08:03 UTC   9y              no
etcd-ca                 May 23, 2032 08:03 UTC   9y              no
front-proxy-ca          May 23, 2032 08:03 UTC   9y              no

更新配置文件

所有master节点执行

1
2
3
# kubectl -n kube-system get configmap kubeadm-config -o jsonpath='{.data.ClusterConfiguration}' > kubeadm.yaml
# kubeadm init phase kubeconfig all --config kubeadm.yaml
# mv /root/.kube/config /root/.kube/config.bak && cp /etc/kubernetes/admin.conf /root/.kube/config

重启服务

重启容器让apiserver、controller、scheduler、etcd配置生效

1
# docker ps |grep -E 'k8s_kube-apiserver|k8s_kube-controller-manager|k8s_kube-scheduler|k8s_etcd_etcd' | awk -F ' ' '{print $1}' |xargs docker restart

再次验证

1
2
# echo | openssl s_client -showcerts -connect 127.0.0.1:6443 -servername api 2>/dev/null | openssl x509 -noout -enddate
notAfter=May 22 04:13:09 2121 GMT

参考文章:

更新一个10年有效期的 Kubernetes 证书

kubeadm修改证书有效期100年

一个默默无闻的工程师的日常
Built with Hugo
主题 StackJimmy 设计