구성 개요와 결과
WSL2 Ubuntu 26.04에 systemd 기반 single-node k3s cluster를 구성하고 RTX 4090을 Kubernetes resource로 연결했다. k3s는 control-plane과 embedded containerd를 하나의 service로 실행하며, 기본 ingress와 service load balancer는 제외했다.
WSL2 Ubuntu 26.04
→ systemd k3s server
→ embedded containerd
→ RuntimeClass/nvidia
→ NVIDIA Device Plugin
→ allocatable nvidia.com/gpu: 1
→ GPU workload2026-07-15에 Docker Desktop 9p mount 문제를 복구한 뒤, NVIDIA Container Toolkit 1.19.1, k3s embedded containerd의 nvidia runtime, RuntimeClass/nvidia, NVIDIA Device Plugin rollout, Node allocatable GPU 1을 실제로 확인했다.
2026-07-20 재부팅 후 같은 mount 형식 오류가 재발했지만 문제 mount를 제거한 뒤 k3s service, control-plane Node, vLLM과 monitoring Pod가 다시 정상 실행되는 것을 확인했다. CUDA sample의 Test PASSED 원문은 보관되지 않았지만, 같은 날 사용자가 Step 2 완료를 최종 확인했다.
Active: active (running)
momindesktop Ready control-plane v1.36.2+k3s1
containerd://2.3.2-k3s2
nvidia-container-toolkit 1.19.1
RuntimeClass/nvidia
allocatable nvidia.com/gpu: 11. k3s single-node cluster 구성
k3s stable channel의 single-node server를 다음 설정으로 설치했다.
sudo env \
INSTALL_K3S_CHANNEL=stable \
INSTALL_K3S_EXEC="server --disable traefik --disable servicelb --write-kubeconfig-mode 0644" \
sh /tmp/install-k3s.sh| 설정 | 값 | 목적 |
|---|---|---|
| channel | stable | stable k3s release 설치 |
| role | server | single-node control-plane 구성 |
| Traefik | disabled | 이번 GPU serving 범위에서 ingress 제외 |
| ServiceLB | disabled | local single-node 환경에서 불필요한 load balancer 제외 |
| kubeconfig mode | 0644 | cluster 조회용 kubeconfig 읽기 허용 |
| container runtime | k3s embedded containerd | Docker가 아닌 k3s 내부 runtime 사용 |
설치 결과 k3s v1.36.2+k3s1, containerd 2.3.2-k3s2, momindesktop control-plane Node Ready를 확인했다.
2. k3s 기동 트러블슈팅
증상
k3s 설치 직후 systemd service가 restart를 반복했다.
Process: ... ExecStart=/usr/local/bin/k3s server \
--disable traefik --disable servicelb --write-kubeconfig-mode 0644
(code=exited, status=1/FAILURE)systemctl status의 status code만으로는 원인을 알 수 없었다. k3s journal의 마지막 오류가 핵심이었다.
Failed to start ContainerManager
err="system validation failed - wrong number of fields (expected 6, got 7)"원인 확인
Kubelet은 /proc/mounts의 행을 6개 필드로 해석한다. WSL에 연결된 Docker Desktop이 아래 9p mount를 추가했고, Windows 설치 경로의 공백 때문에 7개 필드로 인식됐다.
C:\134Program\040Files\134Docker\134Docker\134resources /Docker/host 9p \
rw,noatime,aname=drvfs;path=C:\Program Files\Docker\Docker\resources;...이 명령으로 비정상 행을 찾았다.
awk 'NF != 6 {print NR ": fields=" NF ":"; print}' /proc/mounts출력에서 /Docker/host가 fields=7로 나타났다. NVIDIA GPU 또는 k3s containerd 설정이 원인이 아니었다.
복구
Docker Desktop이 만든 문제 mount만 해제한 뒤 k3s를 재시작했다.
sudo umount /Docker/host
sudo systemctl restart k3s
sudo systemctl status k3s --no-pager
sudo k3s kubectl get nodes -o wide복구 후 service가 active (running)이 되었고, momindesktop control-plane Node가 Ready가 됐다.
재발 조건
Docker Desktop을 재시작하거나 WSL integration 상태가 바뀌면
/Docker/hostmount가 다시 생성될 수 있다. k3s가 같은 오류로 실패하면 먼저/proc/mounts검사를 반복한다. Docker Desktop의 전역 runtime 설정 변경이나 WSL Linux display driver 설치는 이 문제의 해결책으로 사용하지 않았다.
journalctl로 k3s 로그 읽기
journalctl은 systemd가 관리하는 서비스의 journal log를 조회하는 명령이다. k3s는 systemd service이므로 다음처럼 service 단위로 확인한다.
# 현재 boot 이후 k3s 로그 마지막 160줄
journalctl -u k3s -b --no-pager -n 160
# 현재 boot의 끝부분부터 전체 로그 확인
sudo journalctl -u k3s -b -e --no-pager
# 실시간 로그 추적. Ctrl+C로 종료
sudo journalctl -u k3s -f| option | 의미 |
|---|---|
-u k3s | k3s.service log만 선택 |
-b | 현재 부팅 이후 기록만 선택 |
-n 160 | 최근 160줄 출력 |
-e | 로그 마지막으로 이동 |
-f | 새 로그를 계속 출력 |
3. NVIDIA Container Toolkit 구성
내부 Runbook의 설치 후 검증 명령을 실행했다.
command -v nvidia-container-runtime
command -v nvidia-ctk
nvidia-ctk --versionNVIDIA Container Toolkit 실행 파일과 버전
/usr/bin/nvidia-container-runtime /usr/bin/nvidia-ctk NVIDIA Container Toolkit CLI version 1.19.1 commit: 09ceee5dde66ba9ce25c7cc69b1ebd5e6e3266fa
| key | 값 | 해석 |
|---|---|---|
nvidia-container-runtime | /usr/bin/nvidia-container-runtime | NVIDIA OCI runtime 실행 파일 확인 |
nvidia-ctk | /usr/bin/nvidia-ctk | Toolkit 설정 CLI 확인 |
| Toolkit version | 1.19.1 | Runbook에서 고정한 version과 일치 |
| commit | 09ceee5dde66ba9ce25c7cc69b1ebd5e6e3266fa | 실행한 Toolkit build 식별자 |
4. k3s NVIDIA runtime과 RuntimeClass 구성
sudo grep -n nvidia /var/lib/rancher/k3s/agent/etc/containerd/config.toml
sudo k3s kubectl get runtimeclass nvidiacontainerd NVIDIA runtime과 RuntimeClass 조회 결과
44:[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.'nvidia'] 47:[plugins.'io.containerd.cri.v1.runtime'.containerd.runtimes.'nvidia'.options] 48: BinaryName = "/usr/bin/nvidia-container-runtime" NAME HANDLER AGE nvidia nvidia 5d
| key | 값 | 해석 |
|---|---|---|
| containerd runtime | nvidia | k3s embedded containerd가 NVIDIA runtime을 탐지함 |
| runtime binary | /usr/bin/nvidia-container-runtime | 실제 runtime 실행 파일 연결 확인 |
| RuntimeClass name | nvidia | Pod의 runtimeClassName에 사용할 이름 |
| handler | nvidia | RuntimeClass가 containerd의 NVIDIA handler를 선택 |
5. NVIDIA Device Plugin과 Node GPU 구성
sudo k3s kubectl -n kube-system rollout status \
daemonset/nvidia-device-plugin-daemonset \
--timeout=5mNVIDIA Device Plugin rollout 결과
daemon set "nvidia-device-plugin-daemonset" successfully rolled out
sudo k3s kubectl get nodes \
-o jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.status.allocatable.nvidia\.com/gpu}{"\n"}{end}'Node allocatable NVIDIA GPU 조회 결과
momindesktop 1
| key | 값 | 해석 |
|---|---|---|
| Device Plugin rollout | successfully rolled out | DaemonSet 배포 완료 |
| Node | momindesktop | single-node control plane |
nvidia.com/gpu | 1 | Scheduler가 할당할 수 있는 GPU 1개 노출 |
이 결과로 Toolkit 설치만 된 상태가 아니라 NVIDIA runtime → RuntimeClass → Device Plugin → Node allocatable resource 연결이 실제 cluster에 반영됐음을 확인했다.
6. 재부팅 후 cluster 상태 확인
2026-07-20에 k3s service와 cluster resource를 다시 조회했다.
sudo systemctl status k3s --no-pager
k3s --version
sudo k3s kubectl get nodes -o wide
sudo k3s kubectl get pods -A재부팅 후 k3s·Node·전체 Pod 상태
● k3s.service - Lightweight Kubernetes Loaded: loaded (/etc/systemd/system/k3s.service; enabled; preset: enabled) Active: active (running) since Mon 2026-07-20 00:13:23 KST; 37min ago Invocation: 2cd168e2f9e1453782cfb0a46c6fccc0 Docs: https://k3s.io Process: 390205 ExecStartPre=/sbin/modprobe br_netfilter (code=exited, status=0/SUCCESS) Process: 390207 ExecStartPre=/sbin/modprobe overlay (code=exited, status=0/SUCCESS) Main PID: 390209 (k3s-server) Tasks: 278 Memory: 932M (peak: 950.5M) CPU: 3min 14.022s CGroup: /system.slice/k3s.service ├─390209 "/usr/local/bin/k3s server" ├─390237 "containerd " ├─390648 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391761 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391793 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391824 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391869 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391907 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391939 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─391959 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─392010 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─392054 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… ├─392115 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… └─393564 /var/lib/rancher/k3s/data/25bd5c205b3a990305155ad3b8e899582026d2d802b257105310b41a262941c1/bin/contai… 7월 20 00:38:22 momindesktop k3s[390209]: time="2026-07-20T00:38:22+09:00" level=info msg="COMPACT compactRev=119…=120337" 7월 20 00:38:22 momindesktop k3s[390209]: time="2026-07-20T00:38:22+09:00" level=info msg="COMPACT deleted 43 row…/120337" 7월 20 00:38:22 momindesktop k3s[390209]: time="2026-07-20T00:38:22+09:00" level=info msg="COMPACT compacted from…ver 2ms" 7월 20 00:43:22 momindesktop k3s[390209]: I0720 00:43:22.099239 390209 cidrallocator.go:278] updated ClusterIP a…3.0.0/16 7월 20 00:43:22 momindesktop k3s[390209]: time="2026-07-20T00:43:22+09:00" level=info msg="COMPACT compactRev=119…=120458" 7월 20 00:43:22 momindesktop k3s[390209]: time="2026-07-20T00:43:22+09:00" level=info msg="COMPACT deleted 49 row…/120458" 7월 20 00:43:22 momindesktop k3s[390209]: time="2026-07-20T00:43:22+09:00" level=info msg="COMPACT compacted from…ver 2ms" 7월 20 00:48:22 momindesktop k3s[390209]: time="2026-07-20T00:48:22+09:00" level=info msg="COMPACT compactRev=119…=120578" 7월 20 00:48:22 momindesktop k3s[390209]: time="2026-07-20T00:48:22+09:00" level=info msg="COMPACT deleted 72 row…/120578" 7월 20 00:48:22 momindesktop k3s[390209]: time="2026-07-20T00:48:22+09:00" level=info msg="COMPACT compacted from…er 20ms" Hint: Some lines were ellipsized, use -l to show in full. k3s version v1.36.2+k3s1 (01b6f04a) go version go1.26.4 NAME STATUS ROLES AGE VERSION INTERNAL-IP EXTERNAL-IP OS-IMAGE KERNEL-VERSION CONTAINER-RUNTIME momindesktop Ready control-plane 5d v1.36.2+k3s1 172.17.42.15 <none> Ubuntu 26.04 LTS 6.18.33.2-microsoft-standard-WSL2 (amd64) containerd://2.3.2-k3s2 NAMESPACE NAME READY STATUS RESTARTS AGE gemmaforge gemma4-12b-6c5cc87ffd-smb9m 1/1 Running 0 37m kube-system coredns-5f5694d56b-dcg4q 1/1 Running 16 (5h36m ago) 5d kube-system local-path-provisioner-58d557dc48-jsxxg 1/1 Running 15 (5h36m ago) 5d kube-system metrics-server-7c86f97b8d-2zgt8 1/1 Running 16 (5h36m ago) 5d kube-system nvidia-device-plugin-daemonset-zgrhg 1/1 Running 15 (5h36m ago) 5d monitoring alertmanager-kube-prometheus-stack-alertmanager-0 2/2 Running 24 (5h36m ago) 4d10h monitoring dcgm-exporter-f6wzn 1/1 Running 4 (5h36m ago) 3d13h monitoring kube-prometheus-stack-grafana-5b5d5f4b44-bqskw 3/3 Running 12 (5h36m ago) 3d14h monitoring kube-prometheus-stack-kube-state-metrics-dcd9c7c48-jb9fh 1/1 Running 12 (5h36m ago) 4d10h monitoring kube-prometheus-stack-operator-6fffb6746d-q966z 1/1 Running 12 (5h36m ago) 4d10h monitoring kube-prometheus-stack-prometheus-node-exporter-d94gl 1/1 Running 4 (5h36m ago) 3d14h monitoring prometheus-kube-prometheus-stack-prometheus-0 2/2 Running 24 (5h36m ago) 4d10h
| key | 값 | 해석 |
|---|---|---|
| k3s service | active (running) | mount 오류 복구 후 service 정상 유지 |
| k3s version | v1.36.2+k3s1 | 실제 실행 version |
| container runtime | containerd://2.3.2-k3s2 | k3s embedded containerd |
| Node | momindesktop, Ready | control-plane Node 정상 |
| vLLM Pod | 1/1 Running, restart 0 | 재기동 후 Gemma 4 workload 정상 |
| Device Plugin Pod | 1/1 Running | NVIDIA resource 광고 component 정상 |
| monitoring Pods | 모두 Running | Prometheus, Grafana, DCGM 구성 복구 |
일부 system Pod와 monitoring Pod의 restart 횟수는 재부팅 과정의 과거 재시작 기록이며, 현재 상태는 모두 Running이다.