Kubernetes v1.23 編譯 kubeadmin 修改證書有效期到 100年


請訪問原文鏈接:https://sysin.cn/blog/kubernetes-kubeadmin-cert-100y/,查看最新版。原創作品,轉載請保留出處。

作者:gc(at)sysin.org,主頁:www.sysin.cn

kubernetes-flower

隨着 Kubernetes 1.23 的發布(December 07, 2021),沒寫完的文章又要測試一下新版本才能完成。

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. 獲取源碼

訪問:https://github.com/kubernetes/kubernetes/releases,下載特定版本源碼

wget https://github.com/kubernetes/kubernetes/archive/v1.23.0.tar.gz
tar -zxvf kubernetes-1.23.0.tar.gz
mv kubernetes-1.23.0 kubernetes
cd kubernetes

或者使用 git 獲取

# yum install git
git clone https://github.com/kubernetes/kubernetes.git
cd kubernetes
git checkout -b remotes/origin/release-1.23 v1.23.0

2. 修改證書有效期

查看網上的資料主要有兩個地方需要修改

2.1 修改 CA 有效期為 100 年(默認為 10 年)

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

// 這個方法里面 NotAfter:              now.Add(duration365d * 10).UTC()
// 默認有效期就是 10 年,改成 100 年
// 輸入 /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

// 就是這個常量定義 CertificateValidity,改成 * 100 年
// 輸入 /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"

git 驗證(可選),修改的內容如下:

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 鏡像編譯

注意:該方法僅適用早期版本,現在已經不可用。

使用該方法可以獲得與官方一致的編譯環境。

  • 查看 kube-cross 的 TAG 版本號
cat ./build/build-image/cross/VERSION

v1.23.0-go1.17.3-bullseye.0

這里我們可以使用官方容器對代碼進行編譯:k8s.gcr.io/kube-cross:v1.17.3-1

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

無法FQ可以用下面的替代鏡像:比較遺憾都沒有更新!

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

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

  • 編譯
# 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.17.3-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 是使用了軟連接
#真實路徑是_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 8.5 x86_64 中編譯完成。

3.2.1 軟件包准備

CentOS:

yum install gcc make -y
yum install rsync jq -y

Ubuntu:

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 版本號

# cat ./build/build-image/cross/VERSION
v1.23.0-go1.17.3-bullseye.0
#注意:之前的版本顯示這種數字格式 v1.17.3-1
  • 安裝 Go 環境:
wget https://dl.google.com/go/go1.17.3.linux-amd64.tar.gz
## 或者
# wget https://golang.google.cn/dl/go1.17.3.linux-amd64.tar.gz
tar zxvf go1.17.3.linux-amd64.tar.gz  -C /usr/local

# 編輯 / etc/profile 文件添加如下:
#go setting
#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
  • 驗證:
go version
# 輸出如下
go version go1.17.3 linux/amd64
  • 編譯:
# 編譯 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 是使用了軟連接
#真實路徑是_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
# 輸出如下
kubeadm version: &version.Info{Major:"1", Minor:"23", GitVersion:"v1.23.0", GitCommit:"ab69524f795c42094a6630298ff53f3c3ebab7f4", GitTreeState:"archive", BuildDate:"2021-12-11T06:51:50Z", GoVersion:"go1.17.3", Compiler:"gc", Platform:"linux/amd64"}

保存備用

# 壓縮保存到用戶主目錄下
tar zcvf ~/kubeadm-1.23.0.tgz -C/usr/bin/ kubeadm

# 在其他節點上替換原有版本
mv /usr/bin/kubeadm /usr/bin/kubeadm_bak
tar zxvf ./kubeadm-1.23.0.tgz -C /usr/bin/

4. 執行命令更新證書

如果是使用原版 kubeadm 安裝之后,可以手動執行命令更新證書有效期到 100 年。

可以先備份證書,證書在 /etc/kubernetes/pki

  • 檢查證書到期時間
kubeadm certs check-expiration
# 早期版本 (1.19 及之前版本) 命令如下
#kubeadm alpha certs check-expiration

kubeadm alpha certs 命令 1.20 開始廢棄。

kubeadm alpha 命令 1.21 開始徹底廢棄。

參看 kubeadm alpha(替換 URL 中的版本號查看狀態)。

輸出如下:

[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
  • 續訂證書,查看可以使用的參數
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.
  • 續訂全部證書
kubeadm certs renew all
  • 再次查看證書有效期,全部都 100 年了
kubeadm certs check-expiration

5. 下載

已經修改好的 kubeadm 下載(1.17.0、1.18.0、1.19.0,持續更新中):

百度網盤鏈接:https://sysin.cn/blog/kubernetes-kubeadmin-cert-100y/

參考文章:

https://blog.csdn.net/fuck487/article/details/102759523

https://www.cnblogs.com/skymyyang/p/11093686.html


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM