중소기업 쿠버네티스 구축 – 03. K3s 부트스트랩: 마스터와 워커 조인 (traefik·servicelb 비활성화·노드 라벨링)

2026.07.14

·

guniq 인사이트 썸네일 — 중소기업 쿠버네티스 구축 – 03. K3s 부트스트랩: 마스터와 워커 조인 (traefik·servicelb 비활성화·노드 라벨링)

시리즈 안내
이 글은 “중소기업 쿠버네티스 구축” 시리즈의 3편입니다. 2편에서 OS 토대를 다졌으니, 이번 편에서는 드디어 K3s를 설치합니다. 마스터를 부트스트랩하고, 워커 3대를 조인시키고, 노드에 역할 라벨을 붙여 클러스터의 뼈대를 완성합니다.


들어가며

여기까지 오느라 고생하셨습니다. 설계(1편)와 OS 준비(2편)를 거쳐, 이제 진짜 쿠버네티스가 올라갑니다.

K3s의 가장 큰 매력이 이번 편에서 드러납니다. vanilla 쿠버네티스라면 etcd, API server, scheduler, controller-manager를 각각 설치·구성해야 하지만, K3s는 명령어 한 줄로 컨트롤 플레인 전체가 뜹니다. 그 한 줄에 우리가 원하는 옵션만 얹으면 끝입니다.

이번 편의 흐름은 이렇습니다.

  1. 마스터 설치 (옵션을 곁들여)
  2. 워커 3대 조인
  3. kubectl을 편하게 쓰도록 설정
  4. 노드에 역할 라벨 붙이기 + 마스터 보호

1. 마스터 설치: 무엇을 끄고 무엇을 켤 것인가

K3s 마스터는 다음 명령으로 설치합니다. 그냥 기본 설치가 아니라, 우리 설계에 맞는 옵션을 함께 줍니다.

curl -sfL https://get.k3s.io | sh -s - server 
  --disable=traefik 
  --disable=servicelb 
  --cluster-cidr=10.44.0.0/16 
  --service-cidr=10.45.0.0/16 
  --tls-san=10.0.12.101

각 옵션이 왜 들어갔는지 하나씩 봅시다.

--disable=traefik — 기본 인그레스를 끈다

K3s는 기본 인그레스 컨트롤러로 Traefik을 내장합니다. 그런데 우리는 더 널리 쓰이고 자료가 많은 Ingress-NGINX를 쓸 계획입니다(05편). 그래서 기본 Traefik을 꺼둡니다. 켜둔 채로 NGINX를 또 설치하면 둘이 충돌하니, 처음부터 끄는 게 깔끔합니다.

--disable=servicelb — 기본 로드밸런서를 끈다

K3s는 기본 로드밸런서로 servicelb(klipper-lb)를 내장합니다. 하지만 우리는 MetalLB를 쓸 겁니다(04편). MetalLB는 L2 모드로 우리 네트워크 대역(10.0.12.200~220)에서 실제 IP를 발급해주는데, 이게 우리 구성에 더 맞습니다. 역시 충돌을 피하려 기본 servicelb를 끕니다.

K3s의 철학이 여기 있습니다. “필요한 건 기본 제공하되, 마음에 안 들면 끄고 원하는 걸 써라.” 이 유연함이 K3s를 단순한 장난감이 아니라 실전 도구로 만듭니다.

--cluster-cidr / --service-cidr — 내부 네트워크 대역 지정

1편에서 정한 prd 전용 CIDR입니다. dev(10.42/10.43)와 겹치지 않게 10.44/10.45로 지정합니다. 나중에 두 클러스터를 연결하거나 마이그레이션할 때 IP 충돌을 막아줍니다.

--tls-san — 인증서에 마스터 IP 추가

K3s API 서버는 TLS 인증서로 보호되는데, 이 인증서가 어떤 주소로 접근할 때 유효한지를 명시해야 합니다. 마스터 IP(10.0.12.101)를 SAN(Subject Alternative Name)에 넣어두면, 로컬 PC 등 외부에서 이 IP로 접근할 때 인증서 오류가 안 납니다.

설치 확인

설치가 끝나면 노드 상태를 확인합니다.

sudo k3s kubectl get nodes

마스터 한 대가 Ready 상태로 보이면 성공입니다.


2. 조인 토큰 확보

워커를 마스터에 합류시키려면 조인 토큰이 필요합니다. 마스터에서 토큰을 꺼냅니다.

sudo cat /var/lib/rancher/k3s/server/node-token

긴 문자열이 출력됩니다. 이걸 복사해두세요. 다음 단계에서 워커마다 사용합니다.


3. 워커 3대 조인

이제 각 워커 노드(.111, .112, .116)에서 다음 명령을 실행합니다. K3S_URL은 마스터 주소, K3S_TOKEN은 방금 복사한 토큰입니다.

curl -sfL https://get.k3s.io | K3S_URL=https://10.0.12.101:6443 
  K3S_TOKEN=<위에서_복사한_토큰> sh -

세 워커 모두에서 실행하면 됩니다. 각 워커는 마스터에 연결되어 클러스터에 합류합니다.

조인 확인

다시 마스터에서 노드 목록을 봅니다.

sudo k3s kubectl get nodes

이제 4대가 모두 Ready로 보여야 합니다.

NAME            STATUS   ROLES                  AGE   VERSION
dzpik8smsys     Ready    control-plane,master   10m   v1.xx.x+k3s1
dzpik8swapp1    Ready    <none>                 2m    v1.xx.x+k3s1
dzpik8swapp2    Ready    <none>                 2m    v1.xx.x+k3s1
dzpik8sosys     Ready    <none>                 1m    v1.xx.x+k3s1

워커들의 ROLES가 <none>인 건 정상입니다. 다음 단계에서 역할 라벨을 붙여줄 겁니다.


4. kubectl을 편하게: sudo 없이 쓰기

지금은 명령마다 sudo k3s kubectl을 쳐야 합니다. 번거로우니 일반 kubectl로 쓸 수 있게 설정합니다. 마스터에서 진행합니다.

mkdir -p ~/.kube
sudo cp /etc/rancher/k3s/k3s.yaml ~/.kube/config
sudo chown $USER:$USER ~/.kube/config
chmod 600 ~/.kube/config

# 영구 적용
echo 'export KUBECONFIG=~/.kube/config' >> ~/.bashrc
source ~/.bashrc

# 확인
kubectl get nodes

이제 sudo 없이 kubectl get nodes가 동작합니다.

로컬 PC에서 접근하고 싶다면, 위 k3s.yaml 내용을 로컬로 복사한 뒤 server: 줄의 https://127.0.0.1:6443https://10.0.12.101:6443(마스터 IP)으로 바꾸면 됩니다. 1번에서 --tls-san에 이 IP를 넣어둔 덕분에 인증서 오류 없이 접근됩니다.


5. 노드 역할 라벨링

1편 설계대로 노드에 역할을 부여합니다. 앱 워커 2대는 role=app, 플랫폼 워커는 role=platform입니다. 마스터에서 실행합니다.

# 앱 워커 → 앱 워크로드용
kubectl label node dzpik8swapp1 role=app
kubectl label node dzpik8swapp2 role=app

# 플랫폼 워커 → ArgoCD·MinIO·모니터링용
kubectl label node dzpik8sosys role=platform

이 라벨이 나중에 “이 워크로드는 app 노드에만, 저 워크로드는 platform 노드에만 배치하라”고 지시할 때 기준이 됩니다. 예를 들어 ArgoCD는 nodeSelector: role=platform으로 플랫폼 노드에만 뜨게 만들 수 있습니다.


6. 마스터 보호: 워크로드가 뜨지 않게

K3s는 기본적으로 마스터에도 워크로드가 뜰 수 있습니다. 하지만 1편에서 정했듯, 마스터는 컨트롤 플레인 전용으로 두는 게 안정적입니다. 컨트롤 플레인이 앱과 자원을 두고 경쟁하면 클러스터 전체가 불안정해질 수 있으니까요.

taint로 마스터에 워크로드가 스케줄링되지 않게 막습니다.

kubectl taint node dzpik8smsys node-role.kubernetes.io/control-plane=:NoSchedule

NoSchedule은 “이 노드에는 (특별히 허용된 것 외에는) 새 Pod를 배치하지 마라”는 표식입니다. 이제 마스터는 순수하게 두뇌 역할만 합니다.


7. 최종 확인

라벨과 taint가 잘 적용됐는지 확인합니다.

# 역할 라벨 확인
kubectl get nodes -L role

출력이 이렇게 나오면 완성입니다.

NAME            STATUS   ROLES                  AGE   VERSION        ROLE
dzpik8smsys     Ready    control-plane,master   15m   v1.xx.x+k3s1
dzpik8swapp1    Ready    <none>                 7m    v1.xx.x+k3s1   app
dzpik8swapp2    Ready    <none>                 7m    v1.xx.x+k3s1   app
dzpik8sosys     Ready    <none>                 6m    v1.xx.x+k3s1   platform
  • 4대 모두 Ready
  • 앱 워커 2대 = app, 플랫폼 워커 = platform
  • 마스터는 taint 적용으로 워크로드 안 뜸

부록: 부팅 시 나오는 메시지들

설치·재부팅 과정에서 콘솔에 낯선 메시지가 보일 수 있습니다. 자주 묻는 두 가지를 짚고 갑니다.

cloud-init 메시지

cloud-init ... finished ... Datasource DataSourceNone

cloud-init은 VM 첫 부팅 시 호스트명·네트워크·SSH 키 등을 자동 설정하는 표준 도구입니다. Proxmox에서 cloud-init 설정 없이 부팅하면 DataSourceNone이 뜨는데, 정상이며 무해합니다. 매 부팅마다 잠깐 돌고 끝납니다. 거슬리면 비활성화할 수 있습니다.

sudo touch /etc/cloud/cloud-init.disabled

overlayfs 메시지

overlayfs: idmapped layers are currently not supported

컨테이너 런타임이 최신 기능을 시도했다가 커널이 지원 안 한다고 알리는 단순 정보 메시지입니다. K3s/containerd가 알아서 fallback하므로 동작에 아무 영향 없습니다. 무시해도 됩니다.


마치며

3편에서 클러스터의 뼈대가 섰습니다. 핵심을 정리하면:

  • 마스터 설치: traefik·servicelb를 끄고(나중에 NGINX·MetalLB로 대체), CIDR과 TLS-SAN을 명시했습니다.
  • 워커 3대 조인: 토큰 하나로 합류. 4대가 모두 Ready.
  • kubectl 편의 설정: sudo 없이, 그리고 로컬 PC에서도 접근 가능하게.
  • 역할 분리: 라벨(app/platform)과 마스터 taint로 워크로드 배치 규칙을 세웠습니다.

이제 빈 클러스터가 준비됐습니다. 하지만 아직 외부에서 접근할 수도, 데이터를 영구 저장할 수도 없습니다. 다음 편에서는 그 두 가지 토대를 놓습니다. 04편에서는 스토리지(local-path)와 로드밸런서(MetalLB)를 설치해, 클러스터에 영속 저장소와 외부 진입 IP를 마련하겠습니다.


이전 글: 중소기업 쿠버네티스 구축 – 02. OS 사전 준비: 전 노드 공통 세팅
다음 글: 중소기업 쿠버네티스 구축 – 04. 스토리지와 로드밸런서: 트래픽 진입점 (local-path·MetalLB L2)


MORE POSTS

다른 글 보기

Photo by Unsplash (unsplash.com) — Free to use
뉴스

API를 바꾸는 AI와 ‘의도 이해’ 기반 웹 — SOA 2.0의 부상

2026.07.24
guniq 인사이트 썸네일 — IT 프로젝트 관리 도구 완전 해부 – 20. PSTA의 장단점과 한계 — 그리고 시리즈를 마치며
프로젝트 관리

IT 프로젝트 관리 도구 완전 해부 – 20. PSTA의 장단점과 한계 — 그리고 시리즈를 마치며

2026.07.23
guniq 인사이트 썸네일 — 중소기업 쿠버네티스 구축 – 06. 웹 대시보드: 클러스터 시각화 (Headlamp·ServiceAccount)
테크 랩

중소기업 쿠버네티스 구축 – 06. 웹 대시보드: 클러스터 시각화 (Headlamp·ServiceAccount)

2026.07.22

프로젝트 문의 환영합니다

기획부터 개발, 운영까지 함께 만들어 드립니다.