k3s 서비스, 라즈베리파이 부트로더의 미로를 뚫고 마침내 정상 작동!
오늘날 k3s 서비스가 라즈베리파이에서 제대로 동작하지 않는 문제에 직면했습니다. 수많은 시행착오 끝에 문제의 근원이 `cgroup_disable=memory` 커널 파라미터에 있다는 것을 알게 되었고, 마치 미로를 헤매듯 복잡한 라즈베리파이의 부트로더 구조를 파헤치며 결국 해결에 성공했습니다. 이 경험을 통해 단순히 k3s 문제를 넘어, 임베디드 시...
k3s 서비스, 라즈베리파이 부트로더의 미로를 뚫고 마침내 정상 작동!
오늘날 k3s 서비스가 라즈베리파이에서 제대로 동작하지 않는 문제에 직면했습니다. 수많은 시행착오 끝에 문제의 근원이 cgroup_disable=memory 커널 파라미터에 있다는 것을 알게 되었고, 마치 미로를 헤매듯 복잡한 라즈베리파이의 부트로더 구조를 파헤치며 결국 해결에 성공했습니다. 이 경험을 통해 단순히 k3s 문제를 넘어, 임베디드 시스템의 깊숙한 곳까지 이해하는 귀중한 시간을 가졌습니다.
학습 주제
- 학습 주제: k3s 서비스의
cgroup_disable=memory문제 해결 - 대화 제목: k3s 서비스 문제 해결
- 학습 날짜: 2026년 1월 30일
질문과 탐구
처음에는 k3s 서비스가 정상적으로 시작되지 않는 현상에 당황했습니다. journalctl 로그를 확인했을 때 failed to find memory cgroup 또는 cgroup memory not supported와 같은 에러 메시지를 보며, 문제의 원인이 메모리 cgroup과 관련되어 있음을 직감했습니다.
특히 라즈베리파이 환경에서 Ubuntu를 사용할 때 cgroup_disable=memory 옵션이 문제의 핵심이라는 AI의 첫 번째 답변은 명확한 단서를 제공했습니다. 하지만 이후 cmdline.txt 파일을 수정해도 문제가 해결되지 않으면서, 라즈베리파이의 부트로더와 커널 파라미터가 어떻게 작동하는지에 대한 근본적인 궁금증이 생겼습니다.
주요 탐구 과정은 다음과 같습니다.
cgroup_disable=memory옵션의 의미와 k3s 동작에 미치는 영향 이해- 라즈베리파이에서 커널 파라미터가 실제로 어떻게 로드되는지 파악
- 여러 부트로더(GRUB, systemd-boot 등) 가능성 탐색 및 배제
- 최종적으로
/boot/firmware/config.txt및/boot/firmware/current/cmdline.txt파일의 중요성 발견
핵심 학습 내용
AI와의 대화를 통해 k3s 서비스의 정상 동작에 메모리 cgroup의 활성화가 필수적임을 배웠습니다. 특히 라즈베리파이 환경에서 Ubuntu를 사용할 때, 기본적으로 cgroup_disable=memory 옵션이 활성화되어 있어 k3s와 같은 컨테이너 오케스트레이션 도구들이 정상적으로 작동하지 않는다는 것을 알게 되었습니다.
핵심 원인은 다음과 같습니다.
- k3s, containerd, kubelet 등 컨테이너 관련 도구들은 메모리 cgroup에 의존합니다.
- Ubuntu on RPi 이미지 중 일부는
cgroup_disable=memory옵션을 기본으로 포함하고 있어 메모리 cgroup 기능이 비활성화됩니다. - 이로 인해 k3s 실행 시 "메모리 cgroup을 찾을 수 없다"는 오류가 발생하며 서비스가 시작되지 않습니다.
AI는 이 문제를 해결하기 위해 여러 단계를 제시했습니다. 처음에는 /boot/firmware/cmdline.txt 파일을 수정하는 방법을 안내했지만, 실제 부팅 소스가 다른 파일에 있음을 파악하는 과정이 복잡했습니다. 결국, 라즈베리파이의 펌웨어 레벨에서 config.txt를 통해, 그리고 Ubuntu의 기본 로직에 의해 cmdline.txt 파일의 옵션이 결정되고 최종적으로 커널에 전달된다는 복잡한 인과관계를 이해하게 되었습니다.
최종적으로 cgroup_enable=memory cgroup_memory=1 옵션을 cmdline.txt에 명시적으로 추가함으로써, 뒤따라오는 옵션이 우선권을 가져 cgroup_disable=memory를 효과적으로 덮어쓰는 방식으로 문제를 해결했습니다.
# 문제 해결을 위한 최종 cmdline.txt 내용 (일부)
... cgroup_enable=memory cgroup_memory=1
이해한 내용
가장 큰 수확은 라즈베리파이의 복잡한 부트로더 구조에 대한 이해입니다. 처음에는 단순히 cmdline.txt 파일만 수정하면 될 것이라고 생각했지만, 실제로는 /boot/firmware/config.txt의 cmdline=cmdline.txt 설정과 Ubuntu의 기본 로직이 cmdline.txt 파일을 생성하는 데 영향을 미친다는 것을 알게 되었습니다.
ls -l /proc/device-tree/chosen/bootargs 명령어를 통해 커널에 실제로 전달되는 부트 인자를 확인하고, bootctl status로 systemd-boot 사용 여부를 파악하는 등, 단서를 찾아가는 과정이 마치 탐정처럼 흥미로웠습니다. 특히 grep 명령어로 파일 시스템 내에서 옵션을 찾지 못했을 때, /proc/device-tree/chosen/bootargs나 펌웨어 자체에서 생성되는 정보라는 것을 인지하는 것이 중요했습니다.
결론적으로, 리눅스 시스템에서 부트 옵션의 최종 결정권은 어떤 파일을 수정했느냐가 아니라, 어떤 프로세스가 커널에게 최종적으로 옵션을 전달하느냐에 달려 있다는 것을 명확히 이해하게 되었습니다.
실전 적용
이번 경험은 라즈베리파이나 기타 ARM 기반 임베디드 시스템에서 k8s(k3s) 또는 Docker와 같은 컨테이너 환경을 구축할 때 매우 유용하게 적용될 것입니다.
실습 계획:
- 새로운 라즈베리파이에 Ubuntu Server를 설치하고 k3s를 설치하여 동일한 문제가 발생하는지 재현해봅니다.
- 오늘 학습한 부트로더 구조를 바탕으로
config.txt및current/cmdline.txt파일을 수정하여 문제를 해결하는 과정을 반복 실습합니다. - 다른 ARM 보드(예: Orange Pi, Jetson Nano)에서 유사한 문제가 발생했을 때, 오늘 배운 디버깅 방법을 적용해봅니다.
응용 아이디어:
- 라즈베리파이 클러스터를 구축하여 홈랩 환경을 구성하고, ArgoCD, Prometheus, Grafana 등 다양한 Kubernetes 네이티브 애플리케이션을 배포하고 관리합니다.
- Edge 컴퓨팅 환경에서 k3s를 활용하여 IoT 장치 관리 및 데이터 처리를 위한 솔루션을 개발합니다.
추가 학습 계획
이번 경험을 통해 부트로더와 커널 파라미터에 대한 깊은 이해의 중요성을 느꼈습니다. 앞으로 다음과 같은 부분을 더 깊이 공부하고 싶습니다.
더 깊이 공부하고 싶은 부분:
- 다양한 리눅스 배포판(Debian, Fedora 등)에서의 부트로더(GRUB, systemd-boot, U-Boot) 작동 방식 비교
- 커널 모듈 로딩 및 파라미터 설정 메커니즘 심층 학습
- 임베디드 시스템에서의
dtb(Device Tree Blob)파일의 역할과 활용법
관련 자료 찾기:
- 각 리눅스 배포판의 공식 문서
- 커널 관련 서적 및 온라인 강의
- 임베디드 개발 관련 커뮤니티 및 포럼
다음 학습 주제:
- ARM 아키텍처에서의 커널 컴파일 및 커스터마이징
- 네트워크 부팅(PXE boot)의 원리와 설정 방법
참고 자료
AI와의 대화에서 직접적으로 언급되지는 않았지만, 대화 내용을 통해 얻은 중요한 정보와 관련된 자료는 다음과 같습니다.
- 라즈베리파이 공식 문서:
config.txt및cmdline.txt파일에 대한 상세 정보 - Ubuntu 공식 문서: 커널 파라미터 및 부트로더 관련 정보
- k3s 공식 문서: 서비스 설치 및 문제 해결 가이드