docs: record why Docker must not be installed on the lab host
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5
parent
6c90468c5a
commit
deae8966b8
@@ -1895,6 +1895,123 @@ EOF
|
||||
**왜 여기 나오나** — JGroups 7800 포트만 골라서 막는 실험을 nftables가
|
||||
아니라 NetworkPolicy로 하면, **운영에서 쓸 방식 그대로** 검증하게 된다.
|
||||
|
||||
### 무엇을 어디에 설치하는가
|
||||
|
||||
| 도구 | lab host | 게스트 | 워크스테이션 |
|
||||
|---|---|---|---|
|
||||
| libvirt / QEMU | 필요 | — | — |
|
||||
| nginx | 필요 (L7 진입점) | — | — |
|
||||
| certbot | 필요 | — | — |
|
||||
| kubectl / helm / k9s | 필요 | 불필요 | — |
|
||||
| **k3s** | — | **필요** | — |
|
||||
| **docker** | **설치 금지** | **설치 금지** | 필요 (이미지 빌드) |
|
||||
| java / maven | 불필요 | 불필요 | 불필요 |
|
||||
|
||||
**kubectl을 게스트에 안 깔아도 되는 이유** — k3s 바이너리가 kubectl을
|
||||
내장한다. 게스트에서는 `sudo k3s kubectl ...`로 쓰고, 평소 조작은 lab host의
|
||||
kubectl로 한다.
|
||||
|
||||
**java/maven이 아무 데도 필요 없는 이유** — Keycloak도 애플리케이션도
|
||||
컨테이너로 돈다. 이미지 안에 JRE가 들어 있고, 빌드는 Dockerfile의 Maven
|
||||
스테이지가 컨테이너 안에서 수행한다.
|
||||
|
||||
### Docker를 lab host에 설치하면 안 되는 이유
|
||||
|
||||
**결론부터: 이미지 저장소가 둘로 갈려서 `docker build`한 이미지를 k3s가
|
||||
보지 못하게 된다.**
|
||||
|
||||
**컨테이너 런타임의 층 구조**
|
||||
|
||||
```
|
||||
dockerd 사용자 편의 계층 — 빌드, 볼륨, 네트워크, CLI
|
||||
│
|
||||
containerd 컨테이너 수명주기 데몬 — 이미지를 자기 저장소에 보관
|
||||
│
|
||||
runc 프로세스를 실제로 격리해 실행하는 저수준 도구
|
||||
```
|
||||
|
||||
**k3s는 자체 containerd를 번들한다.** Docker와 무관하게 이미 완결된 스택이다.
|
||||
|
||||
| | k3s | Docker |
|
||||
|---|---|---|
|
||||
| 소켓 | `/run/k3s/containerd/containerd.sock` | `/run/containerd/containerd.sock` |
|
||||
| 이미지 저장 | `/var/lib/rancher/k3s/agent/containerd/` | `/var/lib/docker/` |
|
||||
|
||||
Docker를 설치하면 **containerd 인스턴스가 두 개**가 된다. 그리고 둘은 서로의
|
||||
이미지를 알지 못한다.
|
||||
|
||||
```
|
||||
docker build ─▶ dockerd ─▶ /var/lib/docker/ ← k3s 는 여기를 안 본다
|
||||
파드 생성 ─▶ k3s containerd ─▶ /var/lib/rancher/... ← 이미지 없음
|
||||
```
|
||||
|
||||
증상은 **`docker images`에는 보이는데 파드는 `ErrImageNeverPull`** 이다.
|
||||
쿠버네티스 입문에서 가장 흔한 혼란이며, 원인이 눈에 보이지 않아 오래 헤맨다.
|
||||
|
||||
**저장소 분리 말고도 충돌 지점이 있다**
|
||||
|
||||
| 자원 | 충돌 내용 |
|
||||
|---|---|
|
||||
| cgroup 드라이버 | dockerd 기본은 `cgroupfs`, k3s는 `systemd`. 한 노드에서 두 관리자가 cgroup 트리를 다툰다 |
|
||||
| iptables/nftables | Docker가 `DOCKER`, `DOCKER-USER` 체인과 MASQUERADE 규칙을 심는다. flannel 규칙과 순서가 엉키면 파드 트래픽이 Docker 규칙에 걸린다 |
|
||||
| 브리지 대역 | `docker0`가 `172.17.0.0/16`을 점유한다. 클러스터 서비스 대역이나 사내망과 겹치면 라우팅이 깨진다 |
|
||||
| 디스크 | 같은 이미지가 두 벌 저장된다 |
|
||||
|
||||
**이 실험대에는 이유가 하나 더 있다.** lab host에는 libvirt가
|
||||
`virbr0` NAT와 자체 방화벽 규칙을 운영 중이다. Docker의 iptables 규칙이
|
||||
여기에 얹히면 게스트 네트워크가 예측 불가능해진다. **네트워크 장애를
|
||||
의도적으로 주입하는 실험대에서 원인 불명의 네트워크 변수를 늘리는 것은
|
||||
치명적이다** — 실험 결과인지 환경 문제인지 구분할 수 없게 된다.
|
||||
|
||||
> `k3s server --docker`로 Docker를 런타임으로 지정하는 방법이 과거에
|
||||
> 있었지만, 쿠버네티스 1.24의 dockershim 제거 이후 별도 `cri-dockerd`를
|
||||
> 요구하며 권장되지 않는다. 얻는 것이 없다.
|
||||
|
||||
### 그러면 이미지는 어떻게 넣는가
|
||||
|
||||
| 방법 | 적합한 경우 |
|
||||
|---|---|
|
||||
| 공개 레지스트리에서 pull | **Keycloak·PostgreSQL·Redis 등 공식 이미지** — 아무 준비도 필요 없다 |
|
||||
| **`ctr images import`** | **자체 빌드 이미지가 소수일 때** ← 이 실험대 |
|
||||
| 클러스터 내 레지스트리 | 빌드·배포 반복이 잦아질 때 |
|
||||
|
||||
자체 이미지는 애플리케이션(BFF, token-mediator, echo)뿐이므로 두 번째로 충분하다.
|
||||
|
||||
```
|
||||
워크스테이션 (docker 보유) lab host (경유만) 게스트 (k3s containerd)
|
||||
docker build
|
||||
docker save ──── ssh ────▶ ──── ssh ────▶ sudo k3s ctr images import -
|
||||
```
|
||||
|
||||
```bash
|
||||
docker build -t keycloak-pattern-api:lab backend
|
||||
docker save keycloak-pattern-api:lab \
|
||||
| ssh test-server "ssh kc-lab-1 'sudo k3s ctr images import -'"
|
||||
docker save keycloak-pattern-api:lab \
|
||||
| ssh test-server "ssh kc-lab-2 'sudo k3s ctr images import -'"
|
||||
```
|
||||
|
||||
**주의 세 가지**
|
||||
|
||||
1. **노드마다 따로 반입한다.** 스케줄러가 어느 노드에 배치할지 모른다.
|
||||
한쪽에만 있으면 반대편에 배치될 때 실패한다.
|
||||
2. **매니페스트에 `imagePullPolicy: Never`를 준다.** 없으면 로컬에 이미지가
|
||||
있어도 레지스트리에서 당기려 시도하다 실패한다.
|
||||
3. **`ctr`이 아니라 `k3s ctr`을 쓴다.** `k3s ctr`은 k3s의 containerd 소켓을
|
||||
가리키는 래퍼다. 시스템에 별도 `ctr`이 있으면 다른 소켓을 보게 되어
|
||||
"성공했는데 파드는 이미지를 못 찾는" 상태가 된다.
|
||||
|
||||
**ssh가 두 번 중첩되는 이유** — 게스트가 lab host의 libvirt NAT 뒤에 있어서
|
||||
워크스테이션에서 직접 접속할 수 없다. lab host의 `~/.ssh/config`에 있는
|
||||
`kc-lab-*` 별칭을 거쳐야 한다.
|
||||
|
||||
**확인**
|
||||
|
||||
```bash
|
||||
ssh test-server "ssh kc-lab-1 'sudo k3s ctr images ls -q | grep keycloak-pattern'"
|
||||
kubectl -n header-lab get pods -o wide # ErrImageNeverPull 이면 반입 실패
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## 6층. Arch 특이사항
|
||||
|
||||
Reference in New Issue
Block a user