Arcane Weekly에 오신 것을 환영합니다. 오늘은 평소에는 잘 마주치지 않겠지만, 한 번 겪으면 빠른 해결책이 절실해지는 문제를 다뤄보겠습니다. 준비물은 LXD 컨테이너와 Docker입니다. 목표는 이 둘을 동시에 구동하는 것, 즉 LXD 컨테이너를 생성한 뒤 그 안에서 Docker 컨테이너를 실행하는 것입니다. 왜냐고요? 왜 안 되겠습니까.
그런데 여기서 문제가 발생합니다. Docker 실행이 다음과 같은 오류와 함께 실패합니다.
docker: Error response from daemon: OCI runtime create failed:
container_linux.go:367: starting container process caused:
process_linux.go:495: container init caused:
rootfs_linux.go:60: mounting "proc" to rootfs at "/proc"
caused: permission denied: unknown.
꽤 긴 메시지죠. 그럼 지금부터 하나씩 디버깅해 보겠습니다.
문제의 상세 분석
일반적으로 Docker 컨테이너를 실행할 때는 /proc 접근에 아무런 문제가 없습니다. 그러나 위 오류는 이 접근이 차단되었다고 알려줍니다. 정보가 워낙 많다 보니 오히려 잘못된 방향으로 유도하는, 다소 혼란스러운 메시지이기도 합니다. 물론 이 문제의 원인은 매우 다양할 수 있습니다.
제 경우에는 설정이 완전히 새것이었고, 별도의 커스터마이징도 전혀 없었습니다. 다른 오류 메시지도 없었으며, 실질적으로 Docker는 올바르게 설치·구성되어 있었습니다.
그래서 LXD가 내부적으로 어떻게 동작하는지 살펴보기로 했습니다. 이것이 문제를 이해하는 열쇠가 될 수 있었거든요. 실제로 곧 LXD에 관한 오래된 참고 자료를 찾았고, 원인이 명확해졌습니다. 보안상의 이유로 컨테이너는 /proc과 /sys에 안전하지 않은 방식으로 접근하는 것이 기본적으로 허용되지 않습니다. 이에 대한 우회 방법(물론 보안 측면의 영향은 감수해야 함)은 해당 접근을 허용하도록 설정을 변경하는 것입니다.
해결 방법: nesting 허용하기
해결책은 간단합니다. 해당 컨테이너에 대해 중첩(nesting)을 허용하면 됩니다.
새 컨테이너를 생성하면서 바로 적용하려면 다음 명령을 사용하세요.
lxc launch "image" "container name" -c security.nesting=true
이미 컨테이너가 존재한다면, 시작하기 전에 아래처럼 설정을 추가합니다.
lxc config set "container name" security.nesting true
그리고 컨테이너를 시작합니다.
lxc start "container name"
컨테이너가 이미 실행 중이라면 먼저 중지하고, 정책을 설정한 뒤 다시 시작하면 됩니다. 이 작업은 비파괴적이므로, 컨테이너를 이미 만든 후에 문제를 발견했더라도 내부의 작업이나 데이터는 전혀 잃지 않습니다. 설정 역시 언제든 되돌릴 수 있습니다. 이걸로 끝!
맺음말
약 5년 가까이 존재해 온 문제를 이제야 겪었다는 점이 흥미롭습니다. 아니면 이 문제를 겪는 사람이 많은데도 관련 정보가 드물고 여기저기 흩어져 있다는 점이 더 의외일지도 모르겠네요. 어쨌든 결론은 명확합니다. 중첩 컨테이너를 사용하려면 LXD에서 해당 컨테이너의 보안 정책(security.nesting)을 수정해야 합니다.
물론 더 깊은 주제도 있습니다. 권한 있는(privileged) 컨테이너와 권한 없는(unprivileged) 컨테이너의 개념, 그 밖의 보안 고려사항들이 있죠. 하지만 여러분의 작업이 보안과 직접 관련이 없다면, 이 변경으로 인한 실질적인 단점은 없습니다.
더 나은 공식 문서가 있다면 좋겠고, 오류 메시지도 좀 더 친절했으면 하는 바람입니다. 그동안은 자신의 환경에서 하려던 작업에 왜 권한 오류가 발생할 수 있는지 먼저 생각해 보세요. 그러면 올바른 해결 방향을 찾을 수 있습니다. 문제를 제대로 정의하는 순간, 이미 80%는 해결한 것과 다름없으니까요.
이제 컨테이너 속의 컨테이너가 가능합니다. "Yo Dawg, 난 니가 컨테이너 좋아한다 들었어. 그래서 니 컨테이너 안에 컨테이너를 넣어뒀지"... 인셉션이죠. 보너스 과제로, 우주가 붕괴하기 전까지 몇 단계까지 중첩이 가능한지 직접 확인해 보는 것도 재미있을 겁니다.
그럼, 즐거운 개발 되세요!