IL-0183 ckck803 · 2026-02-22kubernetes
kubeadm 으로 구성한 클러스터는 내부 통신에 쓰는 TLS 인증서를 자동으로 만든다. 이 인증서의 기본 유효기간은 1년이고, CA 인증서는 10년이다. 그래서 해마다 하위 인증서만 갱신해야 하는데, 이 시점을 놓치면 클러스터에 갑자기 접속할 수 없게 된다. 작성자의 클러스터에서는 하위 인증서가 2026-02-20 16:16 UTC 에 모두 만료됐다. kube-apiserver 는 만료된 인증서로 etcd 와 TLS 연결을 맺지 못해 시작하자마자 죽기를 반복했다. API 서버가 없으니 kubelet 은 노드 등록과 lease 갱신에 실패했고, Calico 도 API 서버에 닿지 못했다.
sudo kubeadm certs check-expiration 으로 보니 admin.conf, apiserver, apiserver-etcd-client, apiserver-kubelet-client, controller-manager.conf, etcd-healthcheck-client, etcd-peer, etcd-server, front-proxy-client, scheduler.conf, super-admin.conf 의 RESIDUAL TIME 이 모두 <invalid> 였다. CA 인증서인 ca, etcd-ca, front-proxy-ca 는 2035-02-18 까지 유효했다. 작성자는 sudo kubeadm certs renew all 로 인증서를 한 번에 갱신했다. 클러스터가 완전히 멈춰 있어서 Error reading configuration from the Cluster 가 나왔지만, Falling back to default configuration 으로 기본 설정을 써서 갱신이 진행됐다. 새 인증서를 쓰려면 kube-apiserver, kube-controller-manager, kube-scheduler, etcd 를 재시작해야 한다. 이들은 Static Pod 로 돌기 때문에 containerd 와 kubelet 을 재시작해 다시 띄웠다. 마지막으로 홈 디렉터리의 kubeconfig 를 새 admin.conf 로 바꾸고 kubectl get nodes 같은 명령이 동작하는지 확인했다.
외부에서 쿠버네티스 클러스터에 접속할 수 없었다. 작성자는 컨트롤 플레인 노드로 들어가 sudo systemctl status kubelet 으로 kubelet 로그를 확인했다.
kubelet 로그에는 http: TLS handshake error from 101.198.0.183:19517: tls: client requested unsupported application protocols 같은 TLS 핸드셰이크 오류가 찍혀 있었다. 이어서 "Unable to register node with API server" 오류로 노드 등록이 계속 실패했고, "Failed to ensure lease exists, will retry" 오류로 kube-node-lease 갱신도 실패했다. kube-node-lease 는 kubelet 이 주기적으로 하트비트를 보내 노드가 살아 있음을 알리는 리소스다.
containerd 로그를 보면 Calico 도 API 서버에 닿지 못하고 있었다. StopPodSandbox 가 plugin type="calico" failed (delete): error getting ClusterInformation: Get "https://10.96.0.1:443/apis/crd.projectcalico.org/v1/clusterinformations/default": dial tcp 10.96.0.1:443: connect: no route to host 로 실패했다. 10.96.0.1 은 kubernetes 서비스의 ClusterIP 다. API 서버가 동작하지 않아 네트워크 플러그인까지 줄줄이 실패하고 있었다.
sudo crictl ps -a | grep kube-apiserver 로 보니 kube-apiserver 컨테이너는 Exited 상태였고 ATTEMPT 숫자가 계속 늘고 있었다. 시작하자마자 죽고 있었다. 처음 본 컨테이너 로그에는 oidc-issuer-url and oidc-client-id must be specified together when any oidc-* flags are set 만 있어서 인증서 문제인지 바로 알기 어려웠다. 더 최근 컨테이너의 로그에서 etcd 127.0.0.1:2379 에 접속할 때 tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2026-02-22T06:12:12Z is after 2026-02-20T16:16:45Z 오류가 나왔다.
원인 ? 인증서·자격 증명 만료
외부에서 클러스터에 접속이 안 되는 것으로 알아챘다. 컨트롤 플레인 노드에서 kubelet 로그, containerd 로그, kube-apiserver 컨테이너 로그를 차례로 보다가 kube-apiserver 로그의 x509 만료 오류에서 원인을 확인했다.
–
sudo kubeadm certs check-expiration 으로 만료일을 주기적으로 확인하고, 만료 30일 전부터 갱신하는 것이 좋다. kubeadm upgrade apply 를 실행하면 인증서도 함께 갱신되므로, 1년에 한 번 이상 쿠버네티스 버전을 올리는 클러스터는 이 문제를 자연스럽게 피한다. 버전을 올리지 않고 오래 운영하는 클러스터라면 kubeadm certs renew all 과 kubelet 재시작을 cron 으로 매년 걸어 둘 수 있다. 작성자가 든 예시에서는 매년 1월 1일 새벽 3시에 실행한다.
같은 원인 · 공통 kubelet, 쿠버네티스 API 서버
같은 원인 · 공통 쿠버네티스 API 서버