어느 날 갑자기 K8s의 모든 pod들이 이런 에러 메시지를 출력하기 시작했다.
kubectl logs xxx-yyyy-0
Defaulted container "xxx-yyyy" out of: xxx-yyyy, init-chmod-data (init)
Error from server: Get "https://192.168.0.10:10250/containerLogs/mynamespace/xxx-yyyy-0/xxx-yyyy": tls: failed to verify certificate: x509: certificate is valid for 192.168.0.26, not 192.168.0.10
ingress controller pod도 비슷한 에러 메시지를 출력하기 시작했다.
kubectl logs nginx-ingress-microk8s-controller-pz4m9
Error from server: Get "https://192.168.0.10:10250/containerLogs/ingress/nginx-ingress-microk8s-controller-pz4m9/nginx-ingress-microk8s": tls: failed to verify certificate: x509: certificate is valid for 192.168.0.26, not 192.168.0.10
K8s가 설치되어 있는 노드(호스트)의 IP가 변경되어 발생한 문제이다. kubelet이 pod와 통신하기 위해 10250 포트를 이용해서 TLS 통신을 하는데, TLS 인증서에 IP 정보가 하드코드되기 때문에 발생하는 것이다.
K8s 설치 도구에 따라 인증서 파일이 위치하는 경로가 조금씩 다른데, 이건 직접 찾아보도록 하자.
- /etc/kubernetes/
- /var/snap/microk8s/current
- ~/.minikube
- /etc/rancher
이 경로의 하위에 crt, key 파일들이 있는데, 이 디렉토리에서 인증서를 재생성하면 된다.
우선 kubelet.csr과 front-proxy-client.csr 파일이 있는 디렉토리를 찾아서 거기서 작업을 한다.
주의사항
- 아래 명령의 마지막 아규먼트에 IP가 적혀 있는데 자신이 사용하는 노드의 IP를 적어주면 된다.
- key 파일과 csr 파일이 현재 디렉토리에 존재한다고 가정한다. 혹시 다른 디렉토리에 위치해 있다면 전체 경로로 적어줘야 한다.
- crt 파일도 현재 디렉토리에 생성된다. 대부분은 같은 디렉토리에 존재하면 되겠지만, 혹시 다른 디렉토리에 설치해야 할 수도 있다.
openssl x509 -req -in kubelet.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet.crt -days 365 -extfile <(printf "subjectAltName=IP:192.168.0.10")
openssl x509 -req -in front-proxy-client.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out front-proxy-client.crt -days 365 -extfile <(printf "subjectAltName=IP:192.168.0.10")
혹시 여러 노드를 사용하는 경우에는 IP를 멀티로 적어줘야 한다.
openssl x509 -req -in kubelet.csr -CA ca.crt -CAkey ca.key -CAcreateserial -out kubelet.crt -days 365 -ext "subjectAltName = IP:192.168.0.10, IP:192.168.0.11, IP:192.168.0.12"
K8s 클러스터에 적용
K8s 설치 도구를 이용해서 K8s 클러스터를 재시작해줘야 한다. 설치 도구마다 방법이 다르다.
- microk8s stop && microk8s start
- minikube stop && minikube start
- systemctl restart kubelet
root 권한이 필요하면 sudo를 이용하자.