突破 K3s CA 证书10 年有效期的限制

前言

K3s 启动时会自动生成 CA 证书,CA 证书的有效期为 10 年。其他证书有效期为 1 年,如果证书已经过期或剩余的时间不足 90 天,则在 K3s 重启时轮换证书。K3s 服务只是一个进程,K3s 服务重启不会影响正在运行的 pod,也不会影响你的业务。

如果你担心 10 年的 CA 有效期太短,你可以自签名一个 CA 证书,然后 K3s 启动时使用你自签的 CA 去启动即可。

下面通过一个示例来介绍如何自签一个 100 年有效期的 CA,并使用这个 CA 来启动 K3s,从而突破K3s CA 证书10 年有效期的限制。

突破K3s CA 证书10 年有效期的限制

创建 100 年有效期的 CA 证书

mkdir -p /var/lib/rancher/k3s/server/tls
cd /var/lib/rancher/k3s/server/tls
openssl genrsa -out client-ca.key 2048
openssl genrsa -out server-ca.key 2048
openssl genrsa -out request-header-ca.key 2048
openssl req -x509 -new -nodes -key client-ca.key -sha256 -days 36500 -out client-ca.crt -addext keyUsage=critical,digitalSignature,keyEncipherment,keyCertSign -subj '/CN=k3s-client-ca'
openssl req -x509 -new -nodes -key server-ca.key -sha256 -days 36500 -out server-ca.crt -addext keyUsage=critical,digitalSignature,keyEncipherment,keyCertSign -subj '/CN=k3s-server-ca'
openssl req -x509 -new -nodes -key request-header-ca.key -sha256 -days 36500 -out request-header-ca.crt -addext keyUsage=critical,digitalSignature,keyEncipherment,keyCertSign -subj '/CN=k3s-request-header-ca'

使用自签名 CA 证书启动 K3s

因为我们已经在 /var/lib/rancher/k3s/server/tls 创建了 CA 证书,所以当启动 K3s 时,将使用已创建的 CA 颁发证书。

你可以像往常一样安装 K3s:

curl -sfL https://get.k3s.io | INSTALL_K3S_CHANNEL=v1.21  sh -

查看证书有效期

root@dev-1:/var/lib/rancher/k3s/server/tls# for i in `ls /var/lib/rancher/k3s/server/tls/*.crt`; do echo $i; openssl x509 -enddate -noout -in $i; done
/var/lib/rancher/k3s/server/tls/client-admin.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-auth-proxy.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/client-controller.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-cloud-controller.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-controller.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-kube-proxy.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/client-scheduler.crt
notAfter=Apr  7 02:50:31 2023 GMT
/var/lib/rancher/k3s/server/tls/request-header-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/server-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt
notAfter=Apr  7 02:50:31 2023 GMT
root@dev-1:/usr/local/bin# kubectl get secret -n kube-system k3s-serving -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep Not
            Not Before: Apr  7 02:49:24 2022 GMT
            Not After : Apr  7 02:50:31 2023 GMT

从以上结果可以看到,CA 证书的有效期已经变成了 100 年,其他的客户端证书的有效期依然是 1 年。

模拟证书过期,轮换证书

将服务器时间调整为 50 年后,比如:20720407

root@dev-1:~# timedatectl set-ntp no
root@dev-1:~# date -s 20720407
Thu Apr  7 00:00:00 CST 2072
root@dev-1:~# date
Thu Apr  7 00:00:00 CST 2072

重启 K3s,触发证书轮换:

root@dev-1:~# service k3s restart

证书轮换后,再次查询证书的有效期:

root@dev-1:~# for i in `ls /var/lib/rancher/k3s/server/tls/*.crt`; do echo $i; openssl x509 -enddate -noout -in $i; done
/var/lib/rancher/k3s/server/tls/client-admin.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-auth-proxy.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/client-controller.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-cloud-controller.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-controller.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-kube-proxy.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/client-scheduler.crt
notAfter=Apr  6 16:00:41 2073 GMT
/var/lib/rancher/k3s/server/tls/request-header-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/server-ca.crt
notAfter=Mar 14 02:49:24 2122 GMT
/var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt
notAfter=Apr  6 16:00:41 2073 GMT
root@dev-1:~# kubectl get secret -n kube-system k3s-serving -o jsonpath='{.data.tls\.crt}' | base64 -d | openssl x509 -noout -text | grep Not
            Not Before: Apr  7 02:49:24 2022 GMT
            Not After : Apr  6 16:01:11 2073 GMT
root@dev-1:~# kubectl get nodes
NAME    STATUS   ROLES                  AGE   VERSION
dev-1   Ready    control-plane,master   50y   v1.21.11+k3s1

K3s 服务重启后,会自动轮换 K3s 证书。从以上结果可以看到 K3s 的证书已经更新到了 2073 年,已经突破了 K3s 默认生成 CA 的 10 年有效期,证明我们自签名的 CA 已经生效,客户端证书是由自签名 CA 颁发。

后记

本指南只是通过使用自签名 CA 的形式来延长了 CA 证书的有效期,其他客户端证书有效期依然为 1 年。我们还是需要在证书已经过期或剩余的时间不足 90 天时重启 K3s 来触发客户端证书的轮换。

也许有同学希望延长客户端证书的有效期,比如:将 kube-apiserver.crt 的有效期延长至 5 年,这样就不需要每年都重启 K3s。但目前没有原生方法可以做到这一点(改源码除外),你可以通过定时重启 K3s 服务来保证证书不会过期,重启 K3s 服务不会影响正在运行的 pod,所以你不必担心重启 K3s会对你的业务集群造成影响。

K3s 已经计划加入手动轮换证书的功能,这样就可以更新现有证书的过期时间来延长证书有效期。

1 个赞

将 kube-apiserver.crt 的有效期延长至 5 年,这样就不需要每年都重启 K3s
如修改kube-apiserver.crt有效期,可参考如下脚本
修改已经颁发证书的有效期: GitHub - yuyicai/update-kube-cert: K8s集群证书过期处理,更新kubeadm生成的证书有效期为10年。针对旧版集群(小于v1.15),当然大于等于v1.15也是可以用这个脚本更新,新版可直接kubeadm alpha certs renew <cert_name>更新 (deal with K8s cluster certificate expired)
需要一定的openssl基础才能修改成功

大师,单节点Docker Rancher2.4.X , 能不能配置 K3s CA 证书超过10 ?

你自签一个 10 年的配置上不就行了

感谢大师,
1,用 ./create_self-signed-cert.sh 生成的100年证书
2,docker run -d 加证书 rancher/rancher:v2.4.15 跑的Rancher Server
3,这里的k3s 是Rancher Server自带的, 可以改它证书吗? 上面文章提到的k3s是单独安装的版本。

这个没试过,但不推荐这样搞,基本只有生产环境才会考虑证书过期的问题,如果是正产,推荐用高可用方式安装

您好, 我发现在修改完系统时间后, 客户端证书在未重启k3s的情况下就完成了证书轮换

[root@VM-1-11-centos nginx]# for i in `ls /var/lib/rancher/k3s/server/tls/*.crt`; do echo $i; openssl x509 -enddate -noout -in $i; done
/var/lib/rancher/k3s/server/tls/client-admin.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-auth-proxy.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-ca.crt
notAfter=Jul  9 06:18:48 2032 GMT
/var/lib/rancher/k3s/server/tls/client-controller.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-cloud-controller.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-controller.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-kube-proxy.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/client-scheduler.crt
notAfter=Jul 11 16:09:09 2073 GMT
/var/lib/rancher/k3s/server/tls/request-header-ca.crt
notAfter=Jul  9 06:18:48 2032 GMT
/var/lib/rancher/k3s/server/tls/server-ca.crt
notAfter=Jul  9 06:18:48 2032 GMT
/var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt
notAfter=Jul 11 16:09:09 2073 GMT

这是不是意味着我不需要重启就可以达到完备的证书轮换策略
k3s版本: v1.21.7+k3s1

你好, 官网提到v2.2.2之后会自动检查证书有效期,如果发现证书即将过期,将会自动生成新的证书
为啥你还有手动配置个10年的ca

2.2.2 之后?你指的是 rancher 吧,这个是k3s

必须得重启,否则不会轮换,你的环境应该也是在你不知情的情况下重启了,要不你可以找找日志

嗯嗯 好的谢谢
v222那条评论我是回复用户dd的

假如集群内部有上百台机器, 我是需要所有节点的k3s都重启么

还有就是, 请问ca证书有没有可以实现自动轮换的策略(因为存在历史问题的集群, 是使用了默认的证书)

是的,都得重启

CA 证书有效期10 年呢

好的,
还有个问题大佬
如果希望从外界访问k3s api接口,它需要双向认证么
因为我现在希望将k3s server节点放在腾讯云的loadbalence后面, 然后agent节点使用lb地址去访问server
但是loadbalence需要配置证书,我随便签了个自建证书, 似乎是不行

你可以用 4 层啊,这样就不用证书了

自建证书那个是我的问题, 感谢

我使用k3s安装高可用rancher,像上面说的设置了时间为2035,证书过期后k3s/rancher无法访问。之后我使用systemctl restart k3s,发现并没有自动轮换 K3s 证书,证书过期日期还是之前的。
kubectl连不上k3s集群,报下面错误。