archived-old-homelab
(Project) HomeLab Cluster - K8s Setting & Trouble Shooting (5)
Index
- Introduction
- Installation
- Trouble Shooting
- Conclusion
Introduction
안녕하세요 Yureutae입니다.
Kubernetes 세팅한 지는 거진 3달이 이미 넘었고 공유할만한 내용도 사실 많은데, 요새 DevOps, SRE 포지션이 많이 열리고 있어서 이력서 업데이트하랴, 포트폴리오 업데이트하랴 정신이 없었습니다. 진짜 시간날 때마다 열심히 쓰도록 노력하겠습니다.

Kubernetes 세팅 관련해서 공유할 것인데요, 사실 요새는 kubespray나 kubeadm 등 K8s 설치 도구가 그렇게 오류가 많지는 않은 편이기 때문에 제가 생각하기에 중요한 점? 조심해야할 점? 트러블슈팅 정도로 간추려서 공유하려합니다.
(이미 구축 경험이 충분하신 분은 아래 Trouble Shooting 부분만 봐도 충분할 것 같습니다 :) )트러블슈팅을 먼저 말하자면, 저는 클러스터 각 노드에 VPN Meshnet을 걸어두었는데 이게 Kubeadm과 Calico CNI에서 문제아닌 문제?를 발생시켜서 이걸 해결하는 과정을 소개합니다.
Installation
Prerequisite
세팅 전에 환경적인 부분에서 문제가 없는지 확인해야합니다.
네트워크나 포트, CRI, cgroup 등에 대해서 아래 링크를 참고하여 구성/세팅합니다.
CRI
면접 단골질문인 CRI 관련입니다. 1.24 이후부터는 dockershim이 아닌 CRI를 만족하는 컨테이너 런타임을 사용해야합니다. 저는 containerd를 사용했습니다.
세팅이 끝나면 systemctl status로 대충 확인 가능합니다.

컨테이너에서는 커널 자원 할당/관리를 위해서 cgroup을 사용합니다.
Kubernetes는 공식문서에서도 Systemd를 cgroup으로 사용하길 권장하기 때문에
/etc/containerd/config.toml 에서 설정해줍시다.(하는 김에 밑에처럼 container를 구동해주는
runc도 설정해줌됩니다.)
containerd의 경우 docker와 별개이기 때문에, CLI 상 편하게 세팅하기 위해서
crictl도 세팅해줍시다. (저는 crictl이 제일 편한 것 같습니다. docker command랑 큰 차이 없는 거 같아요)
SWAP 해제
Kubernetes는 정확한 리소스 할당/관리를 위해 swap을 비활성화합니다.
sudo swapoff -a 하면 일시적으로 비활성화되니, 재부팅 후에도 비활성화하기 위해서 /etc/fstab 에서 해당 라인을 주석처리해주면 끝
Kubeadm
Kubernetes 클러스터 구성 자체는 요즈음 그렇게 어렵지 않은 것 같습니다. Kubeadm, Kubespray, MicroK8s뿐만 아니라 직관적인 UI를 제공하는 Rancer 등 자동화 구성도구가 너무 많아졌기 때문입니다.
사실 클러스터 초기 구성 때만 중요한 부분이라고 생각해서, 전 Kubernetes Docs에서 공식적으로 명시하고 있고 레퍼런스가 많은 Kubeadm을 사용했습니다.
공식문서에 따라 Kubeadm과 명령을 내리기 위한 kubectl을 설치해줌 됩니다.

Kubeadm init
여기서부터 마스터 노드와 워커 노드 세팅이 갈립니다.
우선 컨트롤 플레인 설정을 위해 마스터 노드에서 아래와 같이 kubeadm init을 해줍시다.
저는 router를 통해 내부 고정 ip를 만들어놨기 때문에 해당 ip를 사용했습니다.

정상적으로 Control Plane이 구동되면 아래처럼 다음 Step을 표시해줍니다.
대충, 아래와 같습니다. CNI는 따로 구성할 거라 우선 버립시다.
- root의 kube 디렉토리를 유저로 이관하고 권한 부여
- kubeconfig 세팅
- CNI 세팅
- 워커노드 확장

Kubeadm join
위 control plane 세팅 때 나온 결과를 워커노드에 복붙합시다

CNI (Container Network Interface)
컨테이너화된 애플리케이션이 네트워크에 연결될 수 있도록 해주는 표준 인터페이스입니다. CNI를 통해 컨테이너가 네트워크에 연결될 때 필요한 네트워크 설정, IP 주소 할당, 네트워크 정책 적용 등을 자동화할 수 있습니다.
즉, 컨테이너가 생성되거나 삭제될 때 네트워크 플러그인이 호출되어 네트워크 설정을 추가하거나 제거하는 것 정도를 생각하면 될 것 같습니다.
CNI 종류는 Flannel, Calico, Weave, Cilium 등이 있고, 구축 목적에 따라 사용이 갈리는 것 같습니다. 대개는 Overlay Network (추상화 네트워크)를 올리는데, 이것도 뭐 CNI마다 안올리는 애들도 있어서… 저는 Flannel 기반으로 구축한 경험은 있어서, 추후 세밀한 네트워크 제어를 위해 Calico를 올려보았습니다.
모드는 default인 Ip in Ip로 되어있는데 추후 옵션을 분석해서 적합하게 변경해보겠읍니다.

여기까지 다 되어서 아래처럼 조회하면 STATUS READY가 뜨면 됩니다.
(클라우드 아니면 EXTERNAL-IP는 따로 부여되지 않는게 정상입니다.

Trouble Shooting
Internal IP
위에 결과는 사실 다 처리하고 나온 이미지이고 원래는 아래처럼 NordVPN Meshnet IP가 잡혀버렸습니다.

그냥 내버려둬도 되긴한데 계획대로 되지 않고 뭔가 그냥 넘겨버리는 것 같아 다른 방법을 찾아 해결하기로 했습니다.
kubelet status를 조회해보니까 kubeadm.conf 위치가 있더라구요. 초기 세팅 때 자동으로 IP가 잡혔을 것 같아서 여기를 뒤져봤습니다.

참고자료를 찾다보니 ExecStart에
--node-ip flag를 줘서 강제로 ip 지정을 강제할 수 있었습니다.세팅 후 daemon-reload와 kubelet 재시작 해주시면 지정한 ip로 변경이 완료됩니다.

Access to Cluster
세팅이 다 끝나고, 제 로컬 랩탑에서 NordVPN Meshnet ip를 통해 HomeLab Cluster에 접근을 시도해봤는데 정상 접근이 되지 않았습니다.
당연하게 생각해보면, 위에서 node-ip를 internal로 변경했기 때문인데요. 그래서 접근 가능한 경로를 더 줄 수 없는가 찾아보니 아래처럼 SAN을 추가 할당할 수 있다는 것을 찾았습니다.
kubeadm을 사용하여 배포했기 때문에 kube-apiserver 인증서 교체를 kubeadm으로 해주어야합니다.
일반적인 갱신 과정처럼 .crt와 .key를 백업 후 제거하고 새로 생성해주심 됩니다.
kubeadm init phase certs apiserver --apiserver-cert-extra-sans [extra ip]
VPN Meshnet TroubleShooting
클러스터를 구축하고 정상동작에 문제가 없는 지 확인하려했습니다.
간단하게 테스트 케이스로 많이 사용하는 Nginx Pod를 띄우고 NodePort를 통해 접근하려했는데…서비스타입을 NodePort로 했음에도 Meshnet IP로 접근이 되질 않더라구요. Pod가 실제 배포된 Node의 ip로 접근했을 때는 접근이 되지만, 다른 Node로 접근했을 때는 되지 않는 상황이었습니다.

앞 전에 NordVPN Meshnet IP가 자동으로 잡혔기 때문에, Kubernetes 클러스터가 아닌 네트워크 단에서 문제를 분석했습니다.
CNI with Meshnet IP
sudo calicoctl node status 를 사용하면 각 구성 node의 정보를 조회할 수 있습니다. 아니나 다를까 VPN IP가 자동으로 잡혀있더라구요. 위에서 무지성으로 적용한 calico.yaml을 살펴봅시다.
어떤 기준인진 모르겠는데, 대충 autodetect한다는 것을 알 수 있습니다/.

즉 nordlynx 인터페이스가 먼저 잡혀버리는 것 같습니다.

저희가 원하는 것은
enp1s0 이더넷 인터페이스가 calico에 잡히는 것이므로, 아래와 같이 calico.yaml에 옵션을 추가해주고 재배포해줍니다.

이렇게 할 경우, HomeLab Cluster와 같은 네트워크 안에서는 정상적으로 동작합니다.
Meshnet Peer Local Access
윗 방법은 내부에서만 해결했고, 외부에서 클러스터 접근의 경우에 대해서는 해결이 되지 않았습니다.
그러다 NordVPN Meshnet의 Docs를 처음부터 다시보던 중에, 아래를 발견했습니다.

요약하자면, Meshnet Peer(
HomeLab Cluster Node 1이라 가정)를 통해서 Meshnet Peer와 같은 로컬네트워크에 있는 디바이스(HomeLab Cluster Node 2라 가정)에 접근하려면 권한을 따로 허용해줘야한다는 것입니다.저는 Kubernetes Cluster 내부 네트워크는 전부 internal ip를 사용했기 때문에, 접근이 안되고 있었던 것이죠.
그럼 허용을 해봅시다. 먼저 command를 좀 뒤져봤습니다. (GUI에서는 “딸깍”으로 끝나기 때문에 쉽습니다.)

저는 이런 식으로 각 노드에 대해서 모두 허용 작업을 처리해줬습니다.
이러고 나니 정상적으로 접근이 모두 가능해졌습니다.


Conclusion
이렇게 Kubernetes 기초 세팅을 마쳤습니다. NordVPN Meshnet을 켜둔 상태에서 구축해서 트러블슈팅 할 거리가 좀 많았던 것 같습니다. 역시 웹에서 제공하는 오브젝트 리소스 yaml이나 helm은 한번 다운받아서 확인을 해보는게 좋은 것 같습니다.
구직활동 중이라 좀 포스팅에 간격이 있었는데요, 다음 주 중에 거의 끝날 것 같아 이제 포스팅을 여유롭게 작성할 수 있을 것 같습니다.
다음 포스팅은
홈 서버/클러스터에서 실제 불특정 다수에게 서비스 프로덕션 with VPN 에 대해 진행할 예정입니다. 해당 주제에 대해서 정말 공을 많이 들였고 뭔가 해결하고 많이 뿌듯했던 부분이라 기대해도 좋을 것 같습니다.감사합니다.


