Self-hosted service
yuyicai/update-kube-cert avatar
yuyicai/update-kube-cert

update-kube-cert and the certificate expiry date on kubeadm clusters

K8s 集群证书过期处理,更新 kubeadm 生成的证书有效期为 10 年; 为新集群生成 100 年证书支持全部版本。A tool to update and extend Kubernetes certificate expiration dates to 10 years. Generate 100 years certificates for new Kubernetes cluster

680 stars332 forksShellMIT

At a glance

What is it?
update-kube-cert is a shell script that rewrites the certificates kubeadm generated so they expire in ten years instead of one, and it can issue hundred year CA certificates for a cluster that does not exist yet. It is a targeted repair tool for control plane nodes, not a general certificate manager.
Who is it for?
Adopt update-kube-cert when you run kubeadm clusters whose one year certificates are about to expire and you have decided that a long internal lifetime is acceptable. Do not use it for public facing endpoints, for clusters where a shorter certificate lifetime is a policy requirement, or as a substitute for planned rotation, since it rewrites every control plane file and restarts etcd and the control plane pods.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Shell, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

One shell script aimed at a specific expiry problem

The repository contains a single script, update-kubeadm-cert.sh, plus a README, a Chinese README variant named other-zh_CN.md and another document called other.md. The project description states the problem plainly: it is a tool to update and extend Kubernetes certificate expiration dates in kubeadm initiated clusters.

Two distinct jobs sit inside that. The first is extending certificate validity to ten years for clusters that already exist, including clusters that already have expiry problems and clusters that are still healthy. The second is generating long-lived CA certificates valid for a hundred years before a new cluster is initialized. The second job matters because the CA is the root of trust for a cluster; if you intend to run a cluster for a long time, issuing the CA with a long life from the start avoids the awkward situation of having to reissue everything later.

The script is written in Shell and is MIT licensed. It is not a Kubernetes controller, not a CNI and not a general purpose certificate authority tool. It expects a cluster that kubeadm created and it acts on the files kubeadm laid down.

The script backs up /etc/kubernetes before it changes anything

The first thing the script does is check that the certificate files exist, then it makes a copy of the whole certificate directory. The terminal output in the README shows the sequence: an existence check, a backup line, then a table of every certificate with its current expiry date.

bash
[2025-04-01T00:09:48.47+0800] [INFO] checking if all certificate files are existed...
[2025-04-01T00:09:48.47+0800] [INFO] backup /etc/kubernetes to /etc/kubernetes.old-2025-04-01_00-09-48
[2025-04-01T00:09:48.48+0800] [INFO] checking certificate expiration before update...

That table is the diagnostic value of the tool. It enumerates the CA, the apiserver certificate, the kubelet client certificate, the front proxy pair, the three kubeconfig files and the etcd certificates, and it prints the expiry date for each. In the example, the CA and the front proxy CA are dated 2035 while the apiserver, kubelet client and the kubeconfig entries are dated March 2026, which is the picture of a cluster whose leaf certificates are about to lapse while its root is still valid.

Because the run is a single script executed per control plane node, the output is also the audit trail. Every step is timestamped, so a run across master0, master1 and master2 leaves a readable record of which files were rewritten and in which order the services were restarted.

Ten year validity means rewriting the leaf certificates too

The update phase is where the design choice becomes visible. The script reports that it is updating certificates with 3650 days expiration, and it rewrites the leaf files individually: the etcd server, peer, healthcheck client and apiserver etcd client certificates, then the apiserver and kubelet client certificates, then the kubeconfig files for controller manager, scheduler, admin and super-admin, and finally the front proxy client certificate.

bash
[2025-04-01T00:09:48.52+0800] [INFO] updating certificates with 3650 days expiration...
[2025-04-01T00:09:48.53+0800] [INFO] updated /etc/kubernetes/pki/etcd/server.crt
[2025-04-01T00:09:48.69+0800] [INFO] updated /etc/kubernetes/pki/front-proxy-client.crt
[2025-04-01T00:09:48.83+0800] [INFO] checking certificate expiration after update...

The CA certificates are not touched. In the after table, ca.crt, front-proxy-ca.crt and etcd/ca.crt still show the original 2035 date, while every rewritten file shows the same new date of Mar 29 2035. The leaf certificates are reissued against the existing CA, so the chain of trust survives the operation. That is what makes this a repair rather than a rebuild, and it is also why the hundred year variant only applies when the cluster is being created in the first place.

Each rewrite is followed by a restart of the affected component: etcd is restarted, then the apiserver, controller manager and scheduler control plane pods are restarted, and finally kubelet is restarted. The script is therefore not a zero downtime operation, and the README's own sample output shows the pod restarts that result.

Running it means a container runtime flag and a manual kubeconfig copy

Installation is a clone. The README's usage section gives the clone and the directory change, and nothing else, because there is no package to install and no dependency to resolve.

bash
git clone https://github.com/yuyicai/update-kube-cert.git
cd update-kube-cert

For an existing cluster the script is run on every control plane node, and it takes a runtime argument:

bash
bash update-kubeadm-cert.sh --cri containerd

The --cri flag tells the script which container runtime the node uses, because the restart steps and the inspection of running containers depend on it. The README sample shows the matching client command with the containerd socket:

bash
root@master0:~/update-kube-cert# crictl --runtime-endpoint unix:///run/containerd/containerd.sock pods

One step is deliberately left to the operator. After the run, the terminal output tells you to copy admin.conf to /root/.kube/config manually, keeping the old file first:

bash
    # back old config
    cp /root/.kube/config /root/.kube/config_backup
    # copy new admin.conf to /root/.kube/config for kubectl manually
    cp -i /opt/kube/tmp/kubernetes/admin.conf /root/.kube/config

Because the kubeconfig contains a client certificate, the old one has to be replaced on the machine that runs kubectl. Leaving that step undone leaves you talking to the cluster with the old credentials, which is the most likely way a successful run still looks like a failure.

The hundred year path exists but the README shows only the repair path

The overview lists both jobs, and the project topics include 100year-certificate. The README section shown here only demonstrates the renewal of an existing cluster though. The hundred year CA generation for a new cluster is covered in the other documents in the repository, other.md and other-zh_CN.md, not in the commands quoted above.

That asymmetry is worth flagging before you rely on it. If your plan is to create a cluster with a hundred year CA, the sequence matters: the CA has to be generated before kubeadm init, otherwise you are back in the repair path with a CA that already has a shorter life. The README does not spell out that ordering in the section quoted above, so read other.md before running kubeadm init.

There is a second consequence to the design that follows from the repair path. Since the CA is left untouched, a cluster repaired this way keeps its original root. Extending the leaves to ten years buys time for the leaf certificates, but the root still carries the lifetime it was issued with. Long lived internal certificates are a deliberate choice with a cost: a compromised root certificate stays trusted for as long as its expiry date allows.

Maintenance state and the cost of running a shell script in production

The repository is not archived, and the last push was on 2026-04-03. The releases are older than that: v1.1.0 on 2024-05-15, v2.0.0 on 2025-04-01 and v2.1.0 on 2025-04-11, with the v1.1.0 note mentioning a fix for super_admin.conf on Kubernetes v1.29. Between that release history and the more recent push there is a gap with no tagged version, so the master branch has moved beyond what the v2.1.0 tag contains.

That matters because the script's blast radius is large. It rewrites every certificate in /etc/kubernetes/pki, rewrites kubeconfig files, restarts etcd, restarts three control plane pods and restarts kubelet on each node where it runs. There is no dry run flag described in the README and no rollback command. The recovery path is the backup directory it creates, restored by hand.

The realistic alternative for long lived certificates is to let the cluster's own certificate machinery handle renewal, which is what kubeadm certs renew and the built in certificate rotation are for, rather than reissuing everything by hand on a schedule the script imposes. The difference in approach is that rotation keeps the expiry date short and renews continuously, while this script rewrites the whole set once and then leaves the cluster alone for years. Teams with a compliance requirement for short lived credentials should prefer rotation; teams with a single planned maintenance window and a clear internal-only trust boundary may find the rewrite simpler. The third option is issuing certificates through your own PKI and loading them yourself, which gives full control over validity but means you own the issuance process instead of a script.

Editorial conclusion

Adopt update-kube-cert when you run kubeadm clusters whose one year certificates are about to expire and you have decided that a long internal lifetime is acceptable. Do not use it for public facing endpoints, for clusters where a shorter certificate lifetime is a policy requirement, or as a substitute for planned rotation, since it rewrites every control plane file and restarts etcd and the control plane pods. Before running it, confirm the container runtime flag matches the node, keep the /etc/kubernetes.old-<timestamp> backup the script creates, and copy the new admin.conf to /root/.kube/config by hand as the script instructs.

Frequently asked questions

What does update-kube-cert do to Kubernetes certificates?

It renews the certificates kubeadm generated in an existing cluster with a validity of 3650 days, or ten years, and it can also generate hundred year CA certificates before a new cluster is initialized. The CA files themselves are not rewritten during the renewal.

How do I run update-kube-cert on an existing cluster?

Run bash update-kubeadm-cert.sh --cri containerd on every control plane node, so master0, master1 and master2 and any others. The --cri flag selects the container runtime used by the node.

Is there a backup before update-kube-cert changes the certificates?

Yes. The script reports that it backs up /etc/kubernetes to a timestamped directory such as /etc/kubernetes.old-2025-04-01_00-09-48 before it starts updating certificates, and the README does not document a rollback command, so restoring that directory is a manual operation.

What has to be done manually after update-kube-cert finishes?

The terminal output asks you to copy the new admin.conf to /root/.kube/config yourself, backing up the old kubeconfig first with cp /root/.kube/config /root/.kube/config_backup and then copying the new file with cp -i /opt/kube/tmp/kubernetes/admin.conf /root/.kube/config.

How do I get a hundred year CA for a new Kubernetes cluster?

The project overview states that long-lived CA certificates valid for 100 years can be generated before initializing a new cluster. The commands quoted in the README cover renewing an existing cluster, so the new cluster procedure is described in the other.md and other-zh_CN.md documents in the repository.

Official sources

  1. Issues
  2. License: MIT
  3. README
  4. Releases
  5. yuyicai/update-kube-cert on GitHub
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/yuyicai-update-kube-cert.svg)](https://hysenlabs.com/projects/yuyicai-update-kube-cert)

Was this useful?