---
# System prepended metadata

title: kubeadm 更新 k8s 內部憑證
tags: [K8S]

---

# kubeadm 更新 k8s 內部憑證

## 在每一個 control-plane 節點檢查 k8s 內部憑證過期時間
```
$ sudo kubeadm certs check-expiration
[check-expiration] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[check-expiration] Use 'kubeadm init phase upload-config --config your-config-file' to re-upload it.

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jun 26, 2026 01:32 UTC   364d            ca                      no
apiserver                  Jun 26, 2026 01:32 UTC   364d            ca                      no
apiserver-etcd-client      Jun 26, 2026 01:32 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jun 26, 2026 01:32 UTC   364d            ca                      no
controller-manager.conf    Jun 26, 2026 01:32 UTC   364d            ca                      no
etcd-healthcheck-client    Jun 26, 2026 01:32 UTC   364d            etcd-ca                 no
etcd-peer                  Jun 26, 2026 01:32 UTC   364d            etcd-ca                 no
etcd-server                Jun 26, 2026 01:32 UTC   364d            etcd-ca                 no
front-proxy-client         Jun 26, 2026 01:32 UTC   364d            front-proxy-ca          no
scheduler.conf             Jun 26, 2026 01:32 UTC   364d            ca                      no
super-admin.conf           Jun 26, 2026 01:32 UTC   364d            ca                      no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Jun 24, 2035 01:32 UTC   9y              no
etcd-ca                 Jun 24, 2035 01:32 UTC   9y              no
front-proxy-ca          Jun 24, 2035 01:32 UTC   9y              no
```

## 手動更新憑證，在每一個 control-plane 節點輪流執行以下指令


```
$ sudo kubeadm certs renew all
[renew] Reading configuration from the cluster...
[renew] FYI: You can look at this config file with 'kubectl -n kube-system get cm kubeadm-config -o yaml'

certificate embedded in the kubeconfig file for the admin to use and for kubeadm itself renewed
certificate for serving the Kubernetes API renewed
certificate the apiserver uses to access etcd renewed
certificate for the API server to connect to kubelet renewed
certificate embedded in the kubeconfig file for the controller manager to use renewed
certificate for liveness probes to healthcheck etcd renewed
certificate for etcd nodes to communicate with each other renewed
certificate for serving etcd renewed
certificate for the front proxy client renewed
certificate embedded in the kubeconfig file for the scheduler manager to use renewed
certificate embedded in the kubeconfig file for the super-admin renewed

Done renewing certificates. You must restart the kube-apiserver, kube-controller-manager, kube-scheduler and etcd, so that they can use the new certificates.
```

* 更新後需要重啟 `kube-apiserver, kube-controller-manager, kube-scheduler and etcd` 才可以使用到新憑證，然後再重啟 `kubelet`
```
$ sudo systemctl daemon-reload

$ sudo crictl ps -a --name 'kube-apiserver|kube-controller-manager|kube-scheduler|etcd' -q | xargs -r -n1 sudo crictl rm -f && sudo systemctl restart kubelet
```



## 在每一個 control-plane 節點驗證憑證都已更新

```
$ sudo kubeadm certs check-expiration
[check-expiration] Reading configuration from the "kubeadm-config" ConfigMap in namespace "kube-system"...
[check-expiration] Use 'kubeadm init phase upload-config --config your-config-file' to re-upload it.

CERTIFICATE                EXPIRES                  RESIDUAL TIME   CERTIFICATE AUTHORITY   EXTERNALLY MANAGED
admin.conf                 Jun 26, 2026 08:52 UTC   364d            ca                      no
apiserver                  Jun 26, 2026 08:52 UTC   364d            ca                      no
apiserver-etcd-client      Jun 26, 2026 08:52 UTC   364d            etcd-ca                 no
apiserver-kubelet-client   Jun 26, 2026 08:52 UTC   364d            ca                      no
controller-manager.conf    Jun 26, 2026 08:52 UTC   364d            ca                      no
etcd-healthcheck-client    Jun 26, 2026 08:52 UTC   364d            etcd-ca                 no
etcd-peer                  Jun 26, 2026 08:52 UTC   364d            etcd-ca                 no
etcd-server                Jun 26, 2026 08:52 UTC   364d            etcd-ca                 no
front-proxy-client         Jun 26, 2026 08:52 UTC   364d            front-proxy-ca          no
scheduler.conf             Jun 26, 2026 08:52 UTC   364d            ca                      no
super-admin.conf           Jun 26, 2026 08:52 UTC   364d            ca                      no

CERTIFICATE AUTHORITY   EXPIRES                  RESIDUAL TIME   EXTERNALLY MANAGED
ca                      Jun 24, 2035 01:32 UTC   9y              no
etcd-ca                 Jun 24, 2035 01:32 UTC   9y              no
front-proxy-ca          Jun 24, 2035 01:32 UTC   9y              no
```
* 更新 kubeconfig
```
$ sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config; sudo chown $(id -u):$(id -g) $HOME/.kube/config
```


* 檢查 pod 都正常
```
$ kubectl -n kube-system get pod
```
## kubelet 憑證更新

* 在每個 worker node 重啟 CRI 和 kubelet 服務
```
$ sudo systemctl restart containerd.service

$ sudo systemctl restart kubelet
```

* kubelet 預設啟用了 `"rotateCertificates": true` 這個功能，它會自動向 `control-plane` 送出 CSR（憑證簽章請求），而在允許後 `control-plane` 會發放一張新的憑證給 kubelet。
* kubelet 將使用 Kubernetes API 自動發出新的憑證簽署要求。這可能發生在證書剩餘有效期的 30% 到 10% 之間的任何時間點。
```
$ kubectl get --raw "/api/v1/nodes/w1/proxy/configz" | jq .
{
  "kubeletconfig": {
    "enableServer": true,
    "staticPodPath": "/etc/kubernetes/manifests",
    "podLogsDir": "/var/log/pods",
    "syncFrequency": "1m0s",
    "fileCheckFrequency": "20s",
    "httpCheckFrequency": "20s",
    "address": "0.0.0.0",
    "port": 10250,
    "tlsCertFile": "/var/lib/kubelet/pki/kubelet.crt",
    "tlsPrivateKeyFile": "/var/lib/kubelet/pki/kubelet.key",
    "rotateCertificates": true
```



* 前述步驟完成後，在 m1 主機上，執行 `kubectl get csr` 看有沒有憑證需要 approve ，如果有，可以執行(預設都會自動核准)
```
$ kubectl get csr
```
* 批次同意
```
$ kubectl certificate approve <csr id>
```
* 一次全部同意
```
$ for csr in $(kubectl get csr --no-headers | awk '{print $1}') ; do kubectl certificate approve $csr; done
```
* 檢查 kubelet 更新後的時間
```
$ sudo openssl x509 -enddate -noout -in /var/lib/kubelet/pki/kubelet-client-current.pem | cut -d= -f 2-
Jul  7 03:12:06 2026 GMT
```



## 參考


https://kubernetes.io/docs/tasks/administer-cluster/kubeadm/kubeadm-certs/#manual-certificate-renewal


https://kubernetes.io/docs/tasks/tls/certificate-rotation/


https://kubernetes.io/docs/reference/config-api/kubelet-config.v1beta1/

https://stackoverflow.com/questions/67643559/what-is-the-best-practice-to-rotate-kubernetes-certificates