k3s 3개 노드로 구성하고 나서 가만히 보니 뭔가 부족해 보였다.
실제 샘플 pod 를 띄우고 강제로 node 를 하나씩 죽여다가 살려봤는데 살아나지 않는 경우도 있고..
뭔가 이상해서 찾아봤다
결론적으로 master node 의 HA 구성이 안된것이다.
보통 3개를 설치하면 3개 노드 모두 master 를 설치하여 그들간의 고가용성을 유지한다고 하는데 빠져 있었다.
이미 설치가 완료된 k3s 클러스터를 한번 바꿔보려고 한다.
root@k3s-node1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-node1 Ready control-plane,master 45h v1.33.5+k3s1
k3s-node2 Ready <none> 45h v1.33.5+k3s1
k3s-node3 Ready <none> 45h v1.33.5+k3s1
root@k3s-node1:~#
워커노드 제거
# 1. k3s-node2의 파드를 다른 노드로 옮김 (현재는 k3s-node1로 이동)
sudo kubectl drain k3s-node2 --ignore-daemonsets --delete-emptydir-data
# 2. 클러스터 메타데이터에서 k3s-node2 삭제
sudo kubectl delete node k3s-node2
# 3. k3s-node3에 대해서도 반복
sudo kubectl drain k3s-node3 --ignore-daemonsets --delete-emptydir-data
sudo kubectl delete node k3s-node3
위와 같이 하면
root@k3s-node1:~# kubectl drain k3s-node2 --ignore-daemonsets --delete-emptydir-data
node/k3s-node2 cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/svclb-traefik-fd17bbb8-wqm8p, metallb-system/speaker-4hm7x
evicting pod metallb-system/controller-654858564f-46kh4
evicting pod default/ggmoney-web-deployment-6b84976564-qkqmm
evicting pod default/nginx-deployment-96b9d695-lpv4f
evicting pod default/nginx-deployment-96b9d695-wg87m
evicting pod kube-system/helm-install-traefik-g4x56
pod/helm-install-traefik-g4x56 evicted
pod/controller-654858564f-46kh4 evicted
pod/ggmoney-web-deployment-6b84976564-qkqmm evicted
pod/nginx-deployment-96b9d695-lpv4f evicted
pod/nginx-deployment-96b9d695-wg87m evicted
node/k3s-node2 drained
root@k3s-node1:~# sudo kubectl delete node k3s-node2
node "k3s-node2" deleted
root@k3s-node1:~# sudo kubectl drain k3s-node3 --ignore-daemonsets --delete-emptydir-data
node/k3s-node3 cordoned
Warning: ignoring DaemonSet-managed Pods: kube-system/svclb-traefik-fd17bbb8-7h8tw, metallb-system/speaker-w5k89
evicting pod metallb-system/controller-654858564f-zchbk
evicting pod default/ggmoney-web-deployment-6b84976564-2qczp
evicting pod default/nginx-deployment-96b9d695-d6jdq
evicting pod default/nginx-deployment-96b9d695-q9zz7
evicting pod kube-system/traefik-77dc7b444-s6vdb
pod/controller-654858564f-zchbk evicted
pod/ggmoney-web-deployment-6b84976564-2qczp evicted
pod/nginx-deployment-96b9d695-q9zz7 evicted
pod/nginx-deployment-96b9d695-d6jdq evicted
pod/traefik-77dc7b444-s6vdb evicted
node/k3s-node3 drained
root@k3s-node1:~# sudo kubectl delete node k3s-node3
node "k3s-node3" deleted
root@k3s-node1:~#
이런식으로 삭제 된다.
워커 노드에서 k3s Agent 서비스 중지 및 삭제
각 워커 노드(k3s-node2, k3s-node3)에 SSH로 접속하여 k3s Agent 서비스를 완전히 중지하고 설치된 파일을 제거
sudo /usr/local/bin/k3s-agent-uninstall.sh
HA 서버로 재설치 (k3s-node2, k3s-node3)
root@k3s-node1:~# sudo cat /var/lib/rancher/k3s/server/node-token
K102e2edeaeb6ed7a830352628232ddd585f04e2f9e8cb748672eeeb9c9d75f80cb::server:7c1fea101a572cae30a0bf0a5b94c87d
토큰 가져오고
2, 3번 노드에서 설치
# k3s-node2 또는 k3s-node3에서 실행
curl -sfL https://get.k3s.io | sh -s - server \
--server https://10.34.1.151:6443 \
--token K102e2edeaeb6ed7a830352628232ddd585f04e2f9e8cb748672eeeb9c9d75f80cb::server:7c1fea101a572cae30a0bf0a5b94c87d
root@k3s-node2:~# curl -sfL https://get.k3s.io | sh -s - server \
--server https://10.34.1.151:6443 \
--token K102e2edeaeb6ed7a830352628232ddd585f04e2f9e8cb748672eeeb9c9d75f80cb::server:7c1fea101a572cae30a0bf0a5b94c87d
[INFO] Finding release for channel stable
[INFO] Using v1.33.5+k3s1 as release
[INFO] Downloading hash https://github.com/k3s-io/k3s/releases/download/v1.33.5+k3s1/sha256sum-amd64.txt
[INFO] Skipping binary downloaded, installed k3s matches hash
[INFO] Skipping installation of SELinux RPM
[INFO] Skipping /usr/local/bin/kubectl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/crictl symlink to k3s, already exists
[INFO] Skipping /usr/local/bin/ctr symlink to k3s, already exists
[INFO] Creating killall script /usr/local/bin/k3s-killall.sh
[INFO] Creating uninstall script /usr/local/bin/k3s-uninstall.sh
[INFO] env: Creating environment file /etc/systemd/system/k3s.service.env
[INFO] systemd: Creating service file /etc/systemd/system/k3s.service
[INFO] systemd: Enabling k3s unit
Created symlink /etc/systemd/system/multi-user.target.wants/k3s.service → /etc/systemd/system/k3s.service.
[INFO] No change detected so skipping service start
root@k3s-node2:~#
이미 한번 설치를 했어서 그런지...
already 라는 문구들이 나온다.
일단 잘되었는지 확인해보자.
root@k3s-node1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-node1 Ready control-plane,master 45h v1.33.5+k3s1
root@k3s-node1:~#
잘 안돼었다.
검색을 해보니..
node 1번부터 잘되었다고 나온다.
왜냐하면 single server 로 설치를 했다고 한다.
그래서 모두 지우고 다시 하라고 하네...ㅠ.ㅠ...
다시 해보자. 일단 설정 파일들 git 푸시좀 하고 다시 해봐야겠다.
이것저것 몇번을 하다보니 한가지 etcd 를 위한 방화벽 포트가 열리지 않은것 을 확인했다.
sudo ufw allow from 10.34.1.0/24 to any port 2379:2380 proto tcp
sudo ufw allow from 10.34.1.0/24 to any port 6443 proto tcp
sudo ufw allow from 10.34.1.0/24 to any port 10250 proto tcp
sudo ufw reload
sudo ufw status
그리고 재설치 하는데 한번에 되지 않는다..ㅠ.ㅠ
여러번 오류 로그를 봐가면서 지웠다 설치했다를 반복했다.
중간에 etcd 가 등록되었는데 node 등록은 안되서 etcd 삭제하고... 여러 과정을 다시 했다.
root@k3s-node1:~# ETCDCTL_API=3 etcdctl --endpoints=https://127.0.0.1:2379 --cacert=/var/lib/rancher/k3s/server/tls/etcd/server-ca.crt --cert=/var/lib/rancher/k3s/server/tls/etcd/server-client.crt --key=/var/lib/rancher/k3s/server/tls/etcd/server-client.key member list -w table
+------------------+---------+--------------------+--------------------------+--------------------------+------------+
| ID | STATUS | NAME | PEER ADDRS | CLIENT ADDRS | IS LEARNER |
+------------------+---------+--------------------+--------------------------+--------------------------+------------+
| 16b718b0e73909f | started | k3s-node2-745c8aec | https://10.34.1.152:2380 | https://10.34.1.152:2379 | false |
| b27b351149a56d3 | started | k3s-node3-ff81adc7 | https://10.34.1.153:2380 | https://10.34.1.153:2379 | true |
| b43c7edca9206551 | started | k3s-node1-bc986d48 | https://10.34.1.151:2380 | https://10.34.1.151:2379 | false |
+------------------+---------+--------------------+--------------------------+--------------------------+------------+
root@k3s-node1:~#
실제 이렇게 되면 잘된것 같다.
중간과정에서 node3 가 비정상 동작해서 강제로 저걸 지우고 다시 3번 노드에서 설치하고... 이런과정을 여러번 거쳤다.
root@k3s-node1:~# kubectl get nodes
NAME STATUS ROLES AGE VERSION
k3s-node1 Ready control-plane,etcd,master 31m v1.33.5+k3s1
k3s-node2 Ready control-plane,etcd,master 30m v1.33.5+k3s1
k3s-node3 Ready control-plane,etcd,master 82s v1.33.5+k3s1
root@k3s-node1:~#
결과적으로 이렇게 모두 master 모드로 설치했다.
이제 마스터이면서 worker 로 동작하겠지?
k3s 클러스터 트래픽 흐름 구조
지금까지 내가 구현한 트래픽의 흐름을 이해하기 위해서 gpt 로 요약정리 해봤다.
| 구성 요소 | 위치/타입 | 주요 역할 | 사용자님의 설정 | 고가용성(HA) 기여 |
| pfSense | 외부 방화벽/라우터 | 외부 공인 IP 트래픽을 내부 사설망으로 포워딩하는 진입점 | 공인 IP → **10.34.1.150**으로 포트 포워딩 | 외부 트래픽의 단일 진입점 제공 |
| MetalLB | K8s 애드온 (Speaker/Controller) | K8s LoadBalancer 서비스에 클러스터 외부 IP(VIP) 할당 및 광고 | **10.34.1.150**을 VIP로 할당 | IP 주소가 항상 살아있는 노드 중 하나로 연결되도록 보장 (노드 장애 대비) |
| Traefik | K8s Deployment (Ingress Controller) | 1. 프록시 역할 (트래픽 수신) 2. 레이어 7 라우팅 (Host 기반) 3. TLS 종료 (인증서 처리) | 1. 10.34.1.150으로 트래픽 수신 2. money-dev.gglab.app 등 Host 기반 판단 3. ACME(le)를 이용한 자동 인증서 발급/갱신 | 클러스터 진입 후, 트래픽을 처리하는 Pod가 장애 나면 자동으로 다른 Pod로 전달 |
| K8s Service | ClusterIP 또는 NodePort (Traefik의 Target) | Traefik으로부터 트래픽을 받아 해당 Pod 세트로 분산 | ggmoney-web-service 등으로 트래픽 분산 | Pod 레벨의 로드 밸런싱 (Pod 장애 대비) |
| 최종 트래픽 흐름 | - | 외부 요청을 Pod까지 안전하고 고가용성으로 전달 | 공인 IP → pfSense → 10.34.1.150 (VIP) → Traefik → Service → Pod | 전 구간에 걸쳐 HA가 확보됨 |
중간에 ssl 인증서를 lets encrypt 에서 받아오는 구조가 다소 복잡했다.
최초에 할때는 잘 되었는데 클러스터에 노드 설치시 master 노드를 하나만 설정하면서 본 포스트처럼 재설정 하는 바람에 뭔가 찌꺼지 같은게 남았는지 기존 정보들을 지우고 재시작하는 과정을 거쳐서야 인증서가 잘 생성되었다.
큰 흐름은 위와 같은 것 같다.
아마 깨끗한 서버에서 한번더 하면 어렵지 않게 가능할것 같다.
'인프라 > Kubernetes' 카테고리의 다른 글
| (연습) k3s VIP 설정 (MetalLB) (0) | 2025.11.20 |
|---|---|
| (연습) k3s 설치하기 (마스터1, 워커2 설치) (0) | 2025.11.17 |