메뉴 닫기

Kubespray 환경에서 Kubernetes 워커 노드 가입(Join) 실패 해결

쿠버네티스
쿠버네티스 이미지
 
안녕하세요. MSP 사업부 김병학 입니다.
미숙한 지식으로 쿠버네티스 클러스터를 다루다가 발생했던 문제를 기록하였습니다.
Kubespray로 배포된 Kubernetes 클러스터에 새 워커 노드를 추가하는 과정에서 Kubelet 권한 오류가 반복적으로 발생했을 때, 문제를 진단하고 해결한 과정을 기록하였습니다. 혹여나 비슷한 문제가 있으신분들은 참고하시고, 더 좋은 해결방법이 있으면 공유 부탁드립니다.
 

1. 초기 문제 진단: Kubelet 설정 파일 누락

최초로 워커 노드 (`worker01`)에 Kubelet을 실행했을 때, 다음과 같은 로그와 함께 Kubelet이 시작에 실패했습니다. 이는 부트스트랩 설정 파일이 누락되었기 때문입니다.
E1029 23:26:16.469906 3925358 run.go:74] "command failed" err="failed to run Kubelet: unable to load bootstrap kubeconfig: stat /etc/kubernetes/bootstrap-kubelet.conf: no such file or directory"

워커 노드의 Kubelet이 클러스터에 접속하여 최종 인증서와 설정을 받기 위해 필요한 `/etc/kubernetes/bootstrap-kubelet.conf` 파일이 존재하지 않았습니다. 이는 노드 추가(Join) 과정이 제대로 완료되지 않았음을 의미합니다.

초기 해결 시도 (Kubespray 재실행 결정)

클러스터가 Kubespray로 배포되었으므로, `kubeadm join`과 같은 명령은 사용하지 않고, Kubespray의 `scale.yml` 플레이북을 사용하여 노드 가입을 다시 시도했습니다.
ansible-playbook -i ~/cp-deployment/standalone/inventory/mycluster/hosts.yaml --become --become-user=root scale.yml
 

2. 해결 시도 후 발생한 반복적인 권한 오류

`scale.yml` 플레이북을 실행한 후, Kubelet은 파일 누락 오류는 해결했지만, 이번에는 API 서버와의 통신에서 `Forbidden` (권한 거부) 오류를 반복적으로 발생시켰습니다.
E1030 00:05:45.895332 3937212 kubelet_node_status.go:96] "Unable to register node with API server" err="nodes \"woker01\" is forbidden: node \"erp-paas-master01\" is not allowed to modify node \"woker01\"" node="woker01"

이 오류는 Kubelet이 자신의 노드 인증서가 아닌, 마스터 노드의 권한을 가진 잘못된 kubeconfig 파일을 사용하여 API 서버에 접속하려고 시도하고 있음을 나타냅니다.
Kubernetes의 RBAC 정책상, 노드가 다른 노드의 정보를 수정할 수 없으므로 요청이 거부됩니다.
이는 이전에 `kubeadm` 등을 시도했거나, Kubespray 재배포 과정에서 기존에 캐시된 잘못된 설정이 덮어쓰이지 못하고 Kubelet에 의해 계속 사용되고 있기 때문으로 판단했습니다.
또한, 이 과정에서 `–limit` 옵션 없이 `scale.yml`이 실행되어 다른 워커 노드(`worker02`)의 상태까지 `NotReady`로 바뀌는 부작용이 발생했습니다.


 

3. 최종 해결책: 워커 노드의초기화 및 Kubespray 재배포

문제를 근본적으로 해결하고 클러스터의 일관성을 복구하기 위해, 워커 노드의 Kubelet 관련 설정 파일을 완전히 정리하고 Kubespray를 특정 노드에 대해서만 재실행하는 강제 초기화 방법을 적용했습니다.
 

3.1. 워커 노드 (woker01) 클린업 작업

CRI-O 런타임을 사용하고 있었으므로, 관련 서비스 중지 및 설정 파일 삭제를 수행했습니다.
1. 서비스 중지 및 런타임 정리
# Kubelet 및 CRI-O 런타임 중지
sudo systemctl stop kubelet
sudo systemctl stop crio 
 
2. 설정 및 인증서 파일 삭제
Kubelet이 사용하는 kubeconfig와 부트스트랩 파일을 포함하여 Kubelet의 모든 데이터를 삭제했습니다.
# Kubelet 설정 및 인증서 삭제
sudo rm -f /etc/kubernetes/kubelet.conf
sudo rm -f /var/lib/kubelet/kubeconfig
sudo rm -rf /etc/kubernetes/ssl/kubelet* # Kubelet 데이터 디렉토리 전체 삭제 (파드 데이터 포함)
sudo rm -rf /var/lib/kubelet/*
sudo rm -rf /etc/kubernetes/*
 

3.2. 마스터 노드에서 노드 객체 삭제

클린업된 노드가 API 서버에 남아있는 잔여 객체에 묶이는 것을 방지하기 위해 노드 객체를 삭제했습니다.
kubectl delete node woker01
 

3.3. Kubespray `scale.yml` 재실행 (특정 노드 지정)

모든 정리 작업 후, `–limit` 옵션을 사용하여 `woker01` 노드만 대상으로 지정하여 Kubespray의 노드 추가/복구 플레이북을 실행했습니다.
# --limit을 사용하여 새로운 워커 노드만 대상으로 지정
ansible-playbook -i ~/cp-deployment/standalone/inventory/mycluster/hosts.yaml --become --become-user=root scale.yml --limit=woker01
# 완료 후 worker01 노드에서 실행
sudo systemctl daemon-reload
sudo systemctl restart crio
sudo systemctl restart kubelet
 

4. 결론

Kubespray로 관리되는 클러스터에서 노드 가입(Join) 문제가 발생하고 권한 오류가 반복될 경우, 가장 효과적인 해결책은 문제가 된 노드의 Kubelet 관련 설정 파일을 완전히 정리하고, `–limit` 옵션을 사용하여 Kubespray 플레이북을 재실행하여 클린한 상태에서 Kubelet 부트스트랩을 다시 진행하도록 유도하는 것입니다.
이 과정을 통해 `woker01` 노드는 성공적으로 클러스터에 가입되었으며, 다른 노드들의 상태도 안정화되었습니다.
아래는 제가 해결하면서 찾아봤던 문서 링크입니다. 공유 드립니다.
 
– kubesplay 노드 추가/삭제 : https://kubespray.io/#/docs/add-remove-node
– kubernetes 인증서 관리 : https://kubernetes.io/docs/reference/command-line-tools-reference/kubelet/

답글 남기기

이메일 주소는 공개되지 않습니다.