225 lines
11 KiB
Markdown
225 lines
11 KiB
Markdown
# 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 mismatch` join 실패를 예방한다
|
|
- 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/*.yaml` drop-in.
|
|
- critical 값 (cluster-cidr / service-cidr / cluster-dns / cluster-domain / disable 세트 / CNI / embedded-registry 활성화)이 서버 간 불일치면 `critical configuration value mismatch` join 실패.
|
|
- packaged Helm component(`traefik` 등) 커스터마이징은 `HelmChartConfig` (apiVersion `helm.cattle.io/v1`).
|
|
- K3s 기본 local storage는 Rancher Local Path Provisioner (`local-path` StorageClass, 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는 “편의 기능”, 직접 수정 절대 금지
|
|
|
|
관리 대상:
|
|
|
|
- `coredns`
|
|
- `traefik`
|
|
- `local-storage`
|
|
- `metrics-server`
|
|
- `servicelb` (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-domain`
|
|
- `disable` 세트
|
|
- `flannel-backend` / `disable-network-policy`
|
|
- `embedded-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.yaml` placeholder)
|
|
- 서버별로 다른 파일을 두고 "알아서 맞겠지"는 금지
|
|
- `.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 유지가 불가피할 때:
|
|
|
|
```yaml
|
|
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-nginx` DaemonSet 또는 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
|
|
- `HelmChartConfig` schema
|
|
- `disable-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-snapshot` CLI 또는 `--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 도입은 별 RFC
|
|
- `embedded registry mirror`: off (현재 airgap 아님), 옵션으로 남김
|
|
- `etcd snapshot`: S3 업로드 활성, 6시간 주기, 72시간 retention
|
|
- `HelmChartConfig`: 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 기본
|