11 KiB
K3s-specific 기준
목적
이 문서는 일반 Kubernetes 표준과 분리해서, K3s 운영에서만 발생하는 특수성을 고정한다.
목표:
- K3s packaged component (
coredns,traefik,local-storage,metrics-server,servicelb)를 일반 manifest처럼 관리하는 실수를 막는다 /var/lib/rancher/k3s/server/manifests를 source-of-truth로 쓰는 실수를 막는다- 멀티 server HA 환경에서
critical configuration value mismatchjoin 실패를 예방한다 - embedded registry mirror(Spegel)의 네트워크·버전 게이트를 정확히 이해한다
- 1000+ 서비스 prod 스케일에서 K3s의 어떤 기능을 켜고 어떤 기능을 외부로 뺄지 기준을 박는다
공식 의미 (근거 URL 포함)
- K3s packaged component:
coredns,traefik,local-storage,metrics-server(매니페스트 파일 기반) +servicelb(매니페스트 없이--disable만 가능). - AddOn auto-deploy:
/var/lib/rancher/k3s/server/manifests하위 파일은 server 시작 시 + 파일 변경 시 자동 apply. packaged component는 K3s가 재기록하므로 직접 수정 금지. - multi-server 유저 AddOn은 서버 간 자동 동기화되지 않는다.
- K3s 설정:
/etc/rancher/k3s/config.yaml+/etc/rancher/k3s/config.yaml.d/*.yamldrop-in. - critical 값 (cluster-cidr / service-cidr / cluster-dns / cluster-domain / disable 세트 / CNI / embedded-registry 활성화)이 서버 간 불일치면
critical configuration value mismatchjoin 실패. - packaged Helm component(
traefik등) 커스터마이징은HelmChartConfig(apiVersionhelm.cattle.io/v1). - K3s 기본 local storage는 Rancher Local Path Provisioner (
local-pathStorageClass, node-local, not replicated). - embedded registry mirror (Spegel): 기본 비활성. 활성화 시 노드 간 TCP 5001 (p2p gossip) + TCP 6443 (registry + supervisor)이 reachable해야 한다. 출처:
https://docs.k3s.io/installation/registry-mirror— "all nodes must be able to reach each other via their internal IP addresses, on TCP ports 5001 and 6443". - K3s 이미지 import:
/var/lib/rancher/k3s/agent/images/*.tar{,.zst,.gz}. - K3s는 기본적으로 network policy enforcer (kube-router 기반)를 포함한다. 외부 CNI(Cilium 등) 사용 시
--disable-network-policy+--flannel-backend=none조합 필요.
기본 규칙
1. K3s 전용 규칙은 별도 문서로 유지
일반 Kubernetes 표준 문서에 K3s 특수성을 흩뿌리지 않는다. 분리 범주:
- packaged component
- AddOn auto-deploy
- config.yaml / config.yaml.d
- local-path provisioner
- embedded registry mirror
- critical server flags
- Helm component customization
2. packaged component는 “편의 기능”, 직접 수정 절대 금지
관리 대상:
corednstraefiklocal-storagemetrics-serverservicelb(manifest 없음, flag로만 제어)
금지:
/var/lib/rancher/k3s/server/manifests/traefik.yaml직접 edit- packaged manifest를 Git SoT로 관리
- 재시작 후 overwrite되는 파일에 운영 커스터마이징 저장
3. packaged component 유지/비활성은 cluster bootstrap 때 박는다
1000-서비스 prod 스케일에서 현재 기준:
| component | prod 기본 | 이유 |
|---|---|---|
traefik |
disable | ingress-nginx / Envoy Gateway로 교체. Traefik은 dev만. |
servicelb |
disable | MetalLB L2/BGP 또는 외부 LB. klipper는 노드 80/443 점유. |
local-storage |
disable | Longhorn / Ceph RBD / CSI. node-local은 DR 불가. |
metrics-server |
keep | HPA + kubectl top 전제. 대체 pipeline 준비되면 교체 가능. |
coredns |
keep | 교체는 특수 케이스. node-local dns cache는 별도로 추가. |
| network policy | 상황별 | Cilium 도입 시 disable. 기본 kube-router 유지도 가능. |
4. server critical config는 Git에서 단일 파일로 관리
/etc/rancher/k3s/config.yaml이 Git의 inventory repo (Ansible / Fleet / CI)에서 push된다.
서버별 ad-hoc 수정 금지. critical 값 mismatch는 join 실패로 직결된다.
일치해야 하는 값:
cluster-cidr,service-cidr,cluster-dns,cluster-domaindisable세트flannel-backend/disable-network-policyembedded-registry활성화 여부datastore-endpoint(etcd / external DB)
5. CLI argument보다 config file 우선
재현성 / diff / multi-node 동기화를 위해 server/agent 플래그는 모두 config.yaml로.
/etc/rancher/k3s/config.yaml.d/*.yaml drop-in은 역할별 파일 분리(예: 10-networking.yaml, 20-audit.yaml)에 사용.
6. /var/lib/rancher/k3s/server/manifests는 apply sink, SoT 아님
- 운영 SoT = Git (+ Kustomize / ArgoCD / Flux)
- 이 디렉터리는 bootstrap addon에만 한정 (예:
k3s-addons-disabled.yamlplaceholder) - 서버별로 다른 파일을 두고 "알아서 맞겠지"는 금지
.skip파일은 임시 비활성화 용. 장기 disable은--disable플래그로.
7. multi-server user AddOn은 Git push, 로컬 scp 금지
K3s는 user AddOn을 서버 간 동기화하지 않는다. 멀티 server 환경에서 AddOn을 쓰려면:
- GitOps 컨트롤러(ArgoCD/Flux)가 apply
- 또는 Ansible/Fleet이 단일 server 노드에만 drop
- 또는 완전히 포기하고
kubectl apply로만 관리 (권장)
8. packaged Helm component 커스터마이징은 HelmChartConfig
traefik 유지가 불가피할 때:
apiVersion: helm.cattle.io/v1
kind: HelmChartConfig
metadata:
name: traefik
namespace: kube-system
spec:
valuesContent: |-
<override values>
metadata.name/namespace는 대응HelmChart와 반드시 일치- 민감 값은
valuesSecrets로 Secret 참조 (valuesContent에 하드코딩 금지) - HelmChartConfig 자체는 Git 관리
9. local-path provisioner는 dev/test 한정
Rancher Local Path Provisioner = node-local hostPath. 특성:
- ReadWriteOnce only
- 노드 장애 시 데이터 접근 불가
- 백업/DR 불가 (StorageClass 레벨 스냅샷 없음)
- binding mode = WaitForFirstConsumer (Pod가 뜰 때 PV 생성)
기준:
- dev/test StatefulSet의 PVC 기본값으로만 허용
- prod의 DB / Vault / MinIO / Kafka / etcd backup target에 절대 사용 금지
- prod storage는 Longhorn (K3s 권장) / Ceph RBD / 외부 CSI 중 택1
10. metrics-server는 유지 기본값
HPA v2 metrics, kubectl top, VPA, kube-state-metrics 연동 모두가 전제. disable 시 Prometheus Adapter 등 대체 pipeline을 먼저 준비한 뒤에만 꺼야 한다.
11. traefik / servicelb는 포트 점유 + 노드 노출 전략을 같이 본다
servicelb(klipper) = 모든 노드가 80/443 HostPort로 열림. prod에서는 거의 항상 disable + MetalLB 또는 외부 LB.traefik유지 시 IngressClass / Middleware / EntryPoint 세 레이어가 전부 K3s 관리. prod에서는 disable +ingress-nginxDaemonSet 또는 Envoy Gateway Deployment.
12. network policy controller 충돌
- 기본: K3s 내장 kube-router 기반 enforcer
- Cilium / Calico 도입 시:
--flannel-backend=none+--disable-network-policy+--disable=servicelb - 도입 계획은 클러스터 bootstrap 결정 사항 (리빌드 없이 swap 불가에 가까움)
13. embedded registry mirror (Spegel): 명시적 opt-in + 네트워크 요구사항
- 기본 비활성
- 활성화 방법:
/etc/rancher/k3s/config.yaml에embedded-registry: true+registries.yaml에 mirror 설정 - 네트워크 요구사항 (공식): 모든 노드가 서로 **TCP 5001 (p2p gossip) + TCP 6443 (local registry + supervisor)**에 도달 가능해야 한다. firewall / security group에서 해당 포트 오픈 필수.
- 활성화 대상:
- airgap / 반-airgap 환경
- 이미지 pull bottleneck이 심한 대규모 배포
- external registry 의존을 낮춰야 하는 환경
- 클러스터 범위 기능이므로 모든 server/agent에 동일 적용
14. 이미지 import / airgap 전략
- 평상시: registry pull (internal mirror 선호)
- airgap:
/var/lib/rancher/k3s/agent/images/*.tar{,.zst,.gz}사용, import 절차를 runbook에 명시 - 이미지 import는 agent startup 때만 로드됨 → 런타임 교체는 re-push 필요
15. K3s version gating을 항상 확인
다음 기능은 버전에 따라 동작/옵션이 바뀌므로, 업그레이드 전 CHANGELOG 확인 필수:
- embedded registry mirror (Spegel)
- image pre-import
HelmChartConfigschemadisable-helm-controller동작- etcd snapshot / S3 backup 옵션
16. K3s-specific 예외는 component 문서보다 먼저 확정
이 문서에서 박고 내려가야 하는 결정:
- traefik 유지/비활성
- servicelb 유지/비활성
- local-storage 유지 범위 (env별)
- metrics-server 유지
- network policy controller 선택
- embedded registry mirror 사용 여부
그 다음에 keycloak / vault / minio / ingress / storage 문서로 내려간다.
17. kubectl apply --server-side 기본 사용
K3s도 SSA 지원. ArgoCD / Flux / CI 모두 --server-side --field-manager=<id> 기본. last-applied-configuration annotation 2MB 한계 회피 + multi-controller ownership 명시.
18. etcd snapshot은 K3s 고유 메커니즘 사용
- embedded etcd면
k3s etcd-snapshotCLI 또는--etcd-snapshot-*config - S3 업로드 설정은
/etc/rancher/k3s/config.yaml에 선언 - 외부 datastore(PostgreSQL/MySQL) 사용 시 backup은 해당 DB 레이어에서 따로
현재 스택 기본 권장안 (prod)
traefik: disable, ingress-nginx + cert-manager로 교체servicelb: disable, MetalLB (L2 또는 BGP)로 교체local-storage: disable (prod), dev/staging 만 유지. Longhorn으로 교체metrics-server: keep (HPA 전제)network policy: 현 단계 kube-router 유지, Cilium 도입은 별 RFCembedded registry mirror: off (현재 airgap 아님), 옵션으로 남김etcd snapshot: S3 업로드 활성, 6시간 주기, 72시간 retentionHelmChartConfig: traefik 유지 경로를 쓰지 않으므로 현재 미사용- apply 방식:
kubectl apply --server-side --field-manager=argocd
프로젝트 기준 요약
- K3s 전용 규칙은 별도 문서
- packaged component 직접 수정 금지 (HelmChartConfig / disable만)
manifests/는 SoT 아님- critical config는 Git 단일 파일, 서버 간 동일
- local-path는 dev/test만
- embedded registry mirror는 TCP 5001 + 6443 reachability가 전제
- prod에서 traefik/servicelb/local-storage 전부 disable이 기본
- Server-Side Apply가 GitOps 기본