개요
Kubernetes 클러스터를 운영하다 보면 어느 날 갑자기 kubectl 명령이 동작하지 않고 kubectl certificate has expired or is not yet valid 오류가 발생하는 경우가 있습니다. 이는 kubeadm으로 구성된 클러스터의 API 서버 인증서가 기본 1년 유효기간을 초과했을 때 발생합니다. 이 글에서는 오류 원인을 확인하고 kubeadm certs renew all로 인증서를 갱신하는 전체 절차를 정리합니다.
증상
kubectl 명령 실행 시 아래와 같이 x509 인증서 만료 오류가 반복 출력되며 클러스터에 접근하지 못합니다.
E1218 05:21:48.113070 1685746 memcache.go:265] couldn't get current server API group list: Get "https://x.x.x.x:6443/api?timeout=32s": tls: failed to verify certificate: x509: certificate has expired or is not yet valid: current time 2024-12-18T05:21:48+09:00 is after 2024-12-05T15:09:04Z Unable to connect to the server: tls: failed to verify certificate: x509: certificate has expired or is not yet valid
원인 확인 — 인증서 만료 현황 조회
kubeadm certs check-expiration으로 전체 인증서 만료 상태를 확인합니다. API 서버, etcd, controller-manager, scheduler 등 kubeadm이 관리하는 모든 컴포넌트 인증서의 만료일이 동시에 도래하는 경우가 많습니다.
@ :~$ sudo kubeadm certs check-expiration [check-expiration] Reading configuration from the cluster... [check-expiration] Error reading configuration from the Cluster. Falling back to default configuration CERTIFICATE EXPIRES RESIDUAL TIME CERTIFICATE AUTHORITY EXTERNALLY MANAGED admin.conf Dec 05, 2024 15:09 UTC <invalid> ca no apiserver Dec 05, 2024 15:09 UTC <invalid> ca no apiserver-etcd-client Dec 05, 2024 15:09 UTC <invalid> etcd-ca no apiserver-kubelet-client Dec 05, 2024 15:09 UTC <invalid> ca no controller-manager.conf Dec 05, 2024 15:09 UTC <invalid> ca no etcd-healthcheck-client Dec 05, 2024 15:09 UTC <invalid> etcd-ca no etcd-peer Dec 05, 2024 15:09 UTC <invalid> etcd-ca no etcd-server Dec 05, 2024 15:09 UTC <invalid> etcd-ca no front-proxy-client Dec 05, 2024 15:09 UTC <invalid> front-proxy-ca no scheduler.conf Dec 05, 2024 15:09 UTC <invalid> ca no CERTIFICATE AUTHORITY EXPIRES RESIDUAL TIME EXTERNALLY MANAGED ca Dec 03, 2033 15:09 UTC 8y no etcd-ca Dec 03, 2033 15:09 UTC 8y no front-proxy-ca Dec 03, 2033 15:09 UTC 8y no
해결 방법 — 인증서 갱신
갱신 전 기존 설정 파일을 백업합니다. 이후 kubeadm certs renew all로 모든 인증서를 일괄 갱신합니다.
# 기존 인증서 백업 sudo cp -pr /etc/kubernetes/ /etc/kubernetes_backup # 인증서 전체 갱신@ :~$ sudo kubeadm certs renew all [renew] Reading configuration from the cluster... [renew] Error reading configuration from the Cluster. Falling back to default configuration 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
kubeconfig 갱신 및 컴포넌트 재시작
인증서 갱신 후 kubectl을 사용하는 계정의 홈 디렉토리 ~/.kube/config에도 새 인증서를 덮어써야 합니다. 이후 kube-apiserver, kube-controller-manager, kube-scheduler 프로세스에 SIGHUP을 전달해 재로드하고, kubelet을 재시작합니다.
# admin.conf을 kubectl 사용 계정의 kubeconfig로 복사 sudo cp /etc/kubernetes/admin.conf /home//.kube/config sudo chown : /home/ /.kube/config # 컨트롤 플레인 컴포넌트 SIGHUP (재시작 없이 인증서 재로드) sudo kill -s SIGHUP $(pidof kube-apiserver) sudo kill -s SIGHUP $(pidof kube-controller-manager) sudo kill -s SIGHUP $(pidof kube-scheduler) # kubelet 재시작 sudo systemctl restart kubelet sudo systemctl daemon-reload
HA 멀티 마스터 클러스터에서의 인증서 갱신
3개 이상의 control-plane 노드로 구성된 HA 클러스터에서는 각 master 노드에서 개별적으로 인증서 갱신 절차를 진행해야 합니다. 하나의 마스터에서 kubeadm certs renew all을 실행해도 다른 마스터 노드의 인증서는 갱신되지 않습니다. 따라서 모든 control-plane 노드에 SSH 접속하여 같은 절차를 반복합니다.
갱신 완료 후 각 노드의 ~/.kube/config도 업데이트해야 합니다. HA 환경에서는 HAProxy 또는 keepalived가 마스터 VIP를 관리하므로, kubeconfig의 server: 주소가 VIP 주소인지 확인합니다. 만약 단일 마스터 주소가 고정되어 있다면 HA LB 주소로 교체합니다.
결과 확인
kubectl 명령이 정상 동작하면 갱신이 완료된 것입니다. 모든 Pod가 Running 상태인지 확인합니다.
kubectl get pods -A
예방을 위해 인증서 갱신을 자동화하거나, 클러스터 업그레이드 시 kubeadm이 자동으로 인증서를 갱신하는 특성을 활용해 정기 업그레이드 주기를 유지하는 것을 권장합니다. 인증서 유효기간 만료 30일 전에 알림을 보내는 스크립트를 cron으로 등록하면 예고 없는 인증서 만료를 방지할 수 있습니다.
참고
관련 포스트: