Kubernetes
Jan 17
好久没有更新了,遇到个问题,简单记录一下吧。

创建 k3s 时,默认 CA 证书有效期 10 年,Client 证书 1 年。在 Client 证书到期前,可以通过重启 k3s 服务来自动延期(不影响运行中 Pod)。但如果是 CA 证书到期,那就麻烦多了,官方的轮换证书的方式相当的复杂。

所以,网上才有了通过自定义 100 年时效的 CA 证书,以及修改系统时间,生成更长 Client 证书的方式。

参考:
K3s生成100年CA证书
K3s生成100年非CA证书

这方式不用修改 k3s 源码,可以通过脚本来处理,但调整系统时间可能会引发其他的问题,而且步骤也比较多。

既然证书是 k3s 生成的,那么应该从 k3s 代码中会有这部分的处理逻辑。经过分析,其实 k3s 是引用 dynamiclistener 这个库来生成证书的。

查看 dynamiclistener 的说明,其原来就有提供一个 CATTLE_NEW_SIGNED_CERT_EXPIRATION_DAYS 来控制生成 Client 证书的有效期时间。但 k3s 的 install.sh 脚本中没有引用(首次启动 k3s 服务时)。

沿用类似的方法,对 dynamiclistener 做了简单的修改,增加一个环境变量 CATTLE_NEW_SIGNED_CA_EXPIRATION_YEARS ,可以定义 CA 证书的有效期,单位是年,默认 100 年。
具体 commit 见这里,tag 对应 v0.3.6-ske.3 。

然后,可以修改 k3s 项目的 go.mod ,替换为修改过的 dynamiclistener。

replace github.com/rancher/dynamiclistener => github.com/qkboy/dynamiclistener v0.3.6-ske.3
require github.com/rancher/dynamiclistener v0.0.0-00010101000000-000000000000


保存后,手动运行一下 go mod tidy 生成新的 go.sum ,重新编译 k3s 即可。
# SKIP_VALIDATE=true make


从源码编译 k3s 也没什么复杂的,只要当前环境装了 docker ,可以科学上网,直接运行就能搞掂。

最后一步,改改 instal.sh ,让在首次启动 k3s 时可以读到新增的两个环境变量:
# --- capture current env and create file containing k3s_ variables ---
create_env_file() {
    info "env: Creating environment file ${FILE_K3S_ENV}"
    $SUDO touch ${FILE_K3S_ENV}
    $SUDO chmod 0600 ${FILE_K3S_ENV}
    sh -c export | while read x v; do echo $v; done | grep -E '^(K3S|CONTAINERD)_' | $SUDO tee ${FILE_K3S_ENV} >/dev/null
    sh -c export | while read x v; do echo $v; done | grep -Ei '^(NO|HTTP|HTTPS)_PROXY' | $SUDO tee -a ${FILE_K3S_ENV} >/dev/null
    sh -c export | while read x v; do echo $v; done | grep -E '^(CATTLE_NEW_SIGNED_CA_EXPIRATION_YEARS|CATTLE_NEW_SIGNED_CERT_EXPIRATION_DAYS)' | $SUDO tee -a ${FILE_K3S_ENV} >/dev/null
}


用修改后的 install.sh 运行安装 k3s:
# INSTALL_K3S_SKIP_DOWNLOAD=true CATTLE_NEW_SIGNED_CERT_EXPIRATION_DAYS=3650 CATTLE_NEW_SIGNED_CA_EXPIRATION_YEARS=50 ./install.sh


结果:
root@env2-node01:~# 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=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-auth-proxy.crt
notAfter=Jan 13 07:46:06 2034 GMT <-- 客户端 10年
/var/lib/rancher/k3s/server/tls/client-ca.crt
notAfter=Jan  3 07:46:06 2074 GMT <-- 根 CA 50 年
/var/lib/rancher/k3s/server/tls/client-ca.nochain.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/client-controller.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-cloud-controller.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-k3s-controller.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-kube-apiserver.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-kube-proxy.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-scheduler.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/client-supervisor.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/request-header-ca.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/server-ca.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/server-ca.nochain.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/serving-kube-apiserver.crt
notAfter=Jan 13 07:46:06 2034 GMT
root@env2-node01:~# for i in `ls /var/lib/rancher/k3s/server/tls/etcd/*.crt`; do echo $i; openssl x509 -enddate -noout -in $i; done
/var/lib/rancher/k3s/server/tls/etcd/client.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/etcd/peer-ca.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/etcd/peer-server-client.crt
notAfter=Jan 13 07:46:06 2034 GMT
/var/lib/rancher/k3s/server/tls/etcd/server-ca.crt
notAfter=Jan  3 07:46:06 2074 GMT
/var/lib/rancher/k3s/server/tls/etcd/server-client.crt
notAfter=Jan 13 07:46:06 2034 GMT


结束语,如果你觉得上面修改比较复杂。可以使用我修改过的两个 k3s 版本:
v1.24.17+k3s1
v1.29.0+k3s1

下载对应的分支后,直接编译即可。
相关的修改已经提了 PR(#90),等待回复。
有空我再把编译好的二进制文件放上来吧。
Tags: ,
Mar 30
    生产环境发现不定时 Java 应用出现 coredump 故障,测试环境不定时出现写入 /cgroup/memory 报  no space left on device 的故障,导致整个 kubernetes node 节点无法使用。设置会随着堆积的 cgroup 越来越多,docker ps 执行异常,直到把内存吃光,机器挂死。
    典型报错:
引用
kubelet.ns-k8s-node001.root.log.ERROR.20180214-113740.15702:1593018:E0320 04:59:09.572336 15702 remote_runtime.go:92] RunPodSandbox from runtime service failed: rpc error: code = Unknown desc = failed to start sa
ndbox container for pod "osp-xxx-com-ljqm19-54bf7678b8-bvz9s": Error response from daemon: oci runtime error: container_linux.go:247: starting container process caused "process_linux.go:258: applying cgroup configuration
for process caused \"mkdir /sys/fs/cgroup/memory/kubepods/burstable/podf1bd9e87-1ef2-11e8-afd3-fa163ecf2dce/8710c146b3c8b52f5da62e222273703b1e3d54a6a6270a0ea7ce1b194f1b5053: no space left on device\""

或者
引用
Mar 26 18:36:59 ns-k8s-node-s0054 kernel: SLUB: Unable to allocate memory on node -1 (gfp=0x8020)
Mar 26 18:36:59 ns-k8s-noah-node001 kernel: cache: ip6_dst_cache(1995:6b6bc0c9f30123084a409d89a300b017d26ee5e2c3ac8a02c295c378f3dbfa5f), object size: 448, buffer size: 448, default order: 2, min order: 0

    该问题发生前后,进行过 kubernetes 1.6 到 1.9 的升级工作。怀疑问题与 kubernetes 、内核有关。
分页: 1/1 第一页 1 最后页 [ 显示模式: 摘要 | 列表 ]