kubeadm证书

kubeadm 部署的 kubernetes 集群,默认的证书有效时间是1年,需要每年手工更新。

重新编译kubeadm

1.1 准备

1
2
3
4
5
6
7
8
9
10
# 下载对应的kubernetes源代码,这里采用 "v1.14.1" 版本

wget https://codeload.github.com/kubernetes/kubernetes/tar.gz/v1.14.1

# untar
tar -zxvf kubernetes-1.14.1.tar.gz
cd kubernetes-1.14.1

# 进入源代码目录
cd kubernetes-1.14.1

1.2 修改源代码-cert.go

文件:staging/src/k8s.io/client-go/util/cert/cert.go
NewSelfSignedCACert 方法,签发以下证书,且默认为10年有效期:
front-proxy-ca.crt
front-proxy-client.crt
ca.crt
etcd/ca.crt
etcd/peer.crt

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
35
36
37
38
39
40
41
42
43
44
45
# 1.14.0版本开始,此文件默认10年
vim staging/src/k8s.io/client-go/util/cert/cert.go

const duration365d = time.Hour * 24 * 365

// Config contains the basic fields required for creating a certificate
type Config struct {
CommonName string
Organization []string
AltNames AltNames
Usages []x509.ExtKeyUsage
}

// AltNames contains the domain names and IP addresses that will be added
// to the API Server's x509 certificate SubAltNames field. The values will
// be passed directly to the x509.Certificate object.
type AltNames struct {
DNSNames []string
IPs []net.IP
}

// 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(),
# 默认已调整有效期为10年;
# 但只影响部分证书:
NotAfter: now.Add(duration365d * 10).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)
}

1.3 修改源代码-pki_helpers.go
,以下证书由 NewSignedCert 方法签发,但签发的证书默认只有一年有效期:

1
2
3
4
5
6
7
8
9
apiserver.crt
apiserver-etcd-client.crt
etcd/server.crt
etcd/healthcheck-client.crt
apiserver-kubelet-client.crt

# `NewSignedCert` 方法:
# 部分证书是通过NewSignedCert这个方法签发,而这个方法签发的证书默认只有一年有效期,查看代码逻辑
vim cmd/kubeadm/app/util/pkiutil/pki_helpers.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
26
27
28
29
30
31
32
33
34
// NewSignedCert creates a signed certificate using the given CA certificate and key
func NewSignedCert(cfg *certutil.Config, key crypto.Signer, caCert *x509.Certificate, caKey crypto.Signer) (*x509.Certificate, error) {
serial, err := rand.Int(rand.Reader, new(big.Int).SetInt64(math.MaxInt64))
if err != nil {
return nil, err
}
if len(cfg.CommonName) == 0 {
return nil, errors.New("must specify a CommonName")
}
if len(cfg.Usages) == 0 {
return nil, errors.New("must specify at least one ExtKeyUsage")
}

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,
# 修改签发相关证书的默认有效期为10年
// NotAfter: time.Now().Add(duration365d).UTC(),
NotAfter: time.Now().Add(duration365d * 10).UTC(),
KeyUsage: x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
ExtKeyUsage: cfg.Usages,
}
certDERBytes, err := x509.CreateCertificate(cryptorand.Reader, &certTmpl, caCert, key.Public(), caKey)
if err != nil {
return nil, err
}
return x509.ParseCertificate(certDERBytes)
}

1.4 编译

1
2
3
4
5
6
7
8
9
10
# kubeadm
make WHAT=cmd/kubeadm GOFLAGS=-v

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

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

# 编译生成的二进制文件在 _output/bin/ 目录下

1.5 更新kubeadm

1
2
3
# 将kubeadm 文件拷贝替换系统中原有kubeadm
cp /usr/bin/kubeadm /usr/bin/kubeadm.origin
cp _output/bin/kubeadm /usr/bin/kubeadm

更新证书

2.1 更新 kube-master (任一)节点证书

1.13.x 版本(含)之后的处理方式;

不更新 kubeadm 的情况下,也可手动更新证书,但更新的证书有效期默认仍是一年。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
# 备份
cp -r /etc/kubernetes/pki /etc/kubernetes/pki.origin

# 更新证书;
# "--config" 指定 "kubeadm" 的配置文件,建议使用部署集群时使用的配置文件;
# 其他参数可参考官方文档
cd /etc/kubernetes/pki
kubeadm alpha certs renew all --config=/root/kubeadm/kubeadm-config.yaml

# 验证
openssl x509 -in apiserver.crt -text -noout | grep Not

# 关于kubeconfig:$HOME/.kube/config
# service account的密钥是以rsa密钥对形式生成,没有过期时间

2.2 (optional) HA集群其余mater节点证书更新
在已更新证书的master节点运行脚本,将更新的证书同步到其余master节点

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 如果可以,请提前在被同步master节点做备份
cat certificate.sh
#!/bin/bash
# 2019-05-27 v0.1
# scp certificate files from the first control plane node to the rest.

USER=root # customizable
CONTROL_PLANE_IPS="100.64.198.137 100.64.198.138"
for host in ${CONTROL_PLANE_IPS}; do
scp /etc/kubernetes/pki/ca.crt "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/ca.key "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.key "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/sa.pub "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.crt "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/front-proxy-ca.key "${USER}"@$host:/etc/kubernetes/pki/
scp /etc/kubernetes/pki/etcd/ca.crt "${USER}"@$host:/etc/kubernetes/pki/etcd/ca.crt
scp /etc/kubernetes/pki/etcd/ca.key "${USER}"@$host:/etc/kubernetes/pki/etcd/ca.key
scp /etc/kubernetes/admin.conf "${USER}"@$host:/etc/kubernetes/
done

转载:https://www.cnblogs.com/netonline/p/11207765.html
参考:
https://v1-14.docs.kubernetes.io/docs/reference/setup-tools/kubeadm/kubeadm-alpha/#cmd-certs-renew

http://team.jiunile.com/blog/2019/05/k8s-kubeadm14-ca-upgrade.html