Skip to main content

Kubernetes 인증서 갱신

대상 환경​

항목값
클러스터 구성HA 3-node 컨트롤 플레인
노드 호스트명dev-a1-ms01, dev-a1-ms02, dev-a1-ms03
Kubernetes 버전v1.25.15
OSRHEL 8.9
컨테이너 런타임cri-o

인증서 갱신​

kubeadm으로 관리되는 클러스터이므로, 각 컨트롤 플레인 노드에서 아래 명령으로 인증서를 갱신합니다.

kubeadm certs renew all

실제 작업에서는 3개 노드 모두에서 총 10개 인증서가 갱신되었고, 갱신 후 만료일은 2027년 3월 3일로 확인되었습니다.

갱신 여부는 아래 명령으로 확인합니다.

kubeadm certs check-expiration

⚠️ 컨트롤 플레인 재시작 — 중요한 정정 사항​

인증서를 갱신한 뒤에는 kube-apiserver, kube-controller-manager, kube-scheduler, etcd가 새 인증서를 읽도록 재시작해야 합니다. 흔히 알려진 아래 두 방법은 이 환경에서는 동작하지 않는 것으로 확인되었습니다.

동작하지 않는 방법​

# 방법 1 — 동작 안 함
touch /etc/kubernetes/manifests/*.yaml

# 방법 2 — 동작 안 함
kill -s SIGHUP <pid>

원인:

  • touch는 파일의 mtime만 변경할 뿐입니다. kubelet은 static pod manifest를 감지할 때 파일의 mtime이 아니라 Pod spec의 실제 내용 변경 여부를 기준으로 판단하기 때문에, 내용이 그대로면 touch만으로는 재시작이 트리거되지 않습니다.
  • kube-apiserver는 SIGHUP을 인증서 재로드 시그널로 처리하지 않습니다. 일부 데몬(nginx 등)과 달리 kube-apiserver에는 이런 핫 리로드 메커니즘이 구현되어 있지 않습니다.

실제로 동작하는 방법​

# 1. 대상 컴포넌트의 컨테이너 ID 확인
crictl ps | grep kube-apiserver

# 2. 확인된 컨테이너 ID로 정지 — kubelet이 자동으로 재생성
crictl stop -t 20 <container-id>

crictl stop -t는 -t(timeout)로 지정한 시간 동안 SIGTERM으로 정상 종료를 먼저 시도하고, 시간 내에 종료되지 않으면 강제 종료(SIGKILL)합니다. 즉 무조건적인 강제 킬이 아니라 그레이스풀 셧다운입니다.

컴포넌트별 권장 timeout​

컴포넌트권장 -t 값비고
etcd30초데이터 정합성 때문에 넉넉하게
kube-apiserver10~20초—
kube-controller-manager10~20초—
kube-scheduler10~20초—

정지된 컨테이너는 kubelet이 static pod manifest를 기준으로 자동 재생성하며, 이때 새로 갱신된 인증서를 읽어들입니다.

재시작 후 확인​

# 모든 컨트롤 플레인 컴포넌트가 정상 기동했는지 확인
kubectl get pods -n kube-system

# 인증서 만료일 재확인
kubeadm certs check-expiration

참고: 대안 (fallback)​

crictl stop 방식이 어떤 이유로든 여의치 않을 경우, manifest 파일을 임시로 다른 경로로 옮겼다가 되돌리는 방법도 사용할 수 있습니다 (kubelet이 manifest 디렉토리에서 파일이 사라졌다가 다시 나타나는 것을 감지하여 재생성).

mv /etc/kubernetes/manifests/kube-apiserver.yaml /tmp/
sleep 5
mv /tmp/kube-apiserver.yaml /etc/kubernetes/manifests/

다만 이 방법보다는 crictl stop -t가 더 예측 가능하고 로그로 확인하기 쉬워 주 방법으로 권장합니다.