루트리스 모드로 Docker 데몬을 안전하게 실행하기

루트리스 모드로 Docker 데몬을 안전하게 실행하기

루트리스(Rootless) 모드는 Docker 데몬과 컨테이너를 루트 권한이 없는 일반 사용자로 실행할 수 있게 해주는 기능이에요. 이렇게 하면 데몬이나 컨테이너 런타임에 보안 취약점이 있더라도 공격자가 루트 권한을 얻는 위험을 줄일 수 있답니다. 그리고 사전 준비 사항만 충족하면 Docker 데몬을 설치할 때조차 루트 권한이 필요 없어요. 지금부터 루트리스 모드가 어떻게 동작하는지, 어떤 준비물이 필요한지, 그리고 어떻게 설치하는지 차근차근 설명해 드릴게요.

출처: 공식문서

본문

어떻게 동작하나요?

루트리스 모드는 Docker 데몬과 컨테이너를 사용자 네임스페이스(user namespace) 안에서 실행해요. 이 점이 기존의 userns-remap 모드와 비슷한데, 중요한 차이가 있어요. userns-remap 모드에서는 데몬 자체는 여전히 루트 권한으로 실행되지만, 루트리스 모드에서는 데몬과 컨테이너 모두 루트 권한 없이 실행된답니다.

두 모드는 컨테이너의 UID/GID를 호스트에 매핑하는 방식도 달라요. 자세한 내용은 UID/GID 매핑 문서를 참고해 주세요.

루트리스 모드는 SETUID 비트가 설정된 바이너리나 파일 캐퍼빌리티(file capabilities)를 사용하지 않아요. 단, 예외적으로 newuidmapnewgidmap은 사용하는데, 이 명령어들은 사용자 네임스페이스 안에서 여러 UID/GID를 사용할 수 있게 해주는 역할을 한답니다.

사전 준비 사항

루트리스 모드를 사용하려면 먼저 호스트에 몇 가지 준비가 필요해요.

  • 호스트에 newuidmapnewgidmap을 설치해야 해요. 이 명령어들은 대부분의 배포판에서 uidmap 패키지로 제공된답니다.

  • /etc/subuid/etc/subgid 파일에 현재 사용자에 대한 하위 UID/GID가 최소 65,536개 이상 포함되어 있어야 해요. 아래 예시를 볼게요. testuser라는 사용자에게 65,536개의 하위 UID/GID(231072~296607)가 할당되어 있네요.

$ id -u
1001
$ whoami
testuser
$ grep ^$(whoami): /etc/subuid
testuser:231072:65536
$ grep ^$(whoami): /etc/subgid
testuser:231072:65536

만약 사전 준비 사항이 충족되지 않았다면, 아래에서 소개할 dockerd-rootless-setuptool.sh install 스크립트가 자동으로 도움말을 보여준답니다.

설치하기

참고

시스템 전체에 설치된 Docker 데몬이 이미 실행 중이라면, 먼저 비활성화하는 것을 고려해 보세요.

$ sudo systemctl disable --now docker.service docker.socket
$ sudo rm /var/run/docker.sock

docker 서비스와 소켓을 끄지 않기로 했다면, 다음 섹션에서 --force 파라미터를 사용해야 해요. 알려진 문제는 없지만, 서비스를 끄고 비활성화하기 전까지는 여전히 루트 권한으로 Docker를 실행하고 있는 상태라는 점을 기억해 두세요.

패키지(RPM/DEB)로 설치한 경우

Docker 20.10 이상을 RPM/DEB 패키지로 설치했다면, /usr/bindockerd-rootless-setuptool.sh 스크립트가 이미 있을 거예요. 이제 루트가 아닌 일반 사용자로 다음 명령어를 실행해서 데몬을 설정하면 됩니다.

$ dockerd-rootless-setuptool.sh install
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/usr/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000/docker.sock

만약 dockerd-rootless-setuptool.sh가 없다면, docker-ce-rootless-extras 패키지를 직접 설치해야 해요. 예를 들어 다음과 같이 설치할 수 있답니다.

$ sudo apt-get install -y docker-ce-rootless-extras

패키지 없이 설치하는 경우

apt-get이나 dnf 같은 패키지 매니저를 사용할 권한이 없다면, https://get.docker.com/rootless에서 제공하는 설치 스크립트를 사용해 보세요. 단, s390x 아키텍처는 정적 패키지가 제공되지 않아서 지원되지 않는다는 점 참고해 주세요.

$ curl -fsSL https://get.docker.com/rootless | sh
...
[INFO] Creating /home/testuser/.config/systemd/user/docker.service
...
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|restart) docker.service`
[INFO] To run docker.service on system startup, run: `sudo loginctl enable-linger testuser`

[INFO] Creating CLI context "rootless"
Successfully created context "rootless"
[INFO] Using CLI context "rootless"
Current context is now "rootless"

[INFO] Make sure the following environment variable(s) are set (or add them to ~/.bashrc):
export PATH=/home/testuser/bin:$PATH

[INFO] Some applications may require the following environment variable too:
export DOCKER_HOST=unix:///run/user/1000/docker.sock

이 경우 바이너리는 ~/bin 디렉터리에 설치된답니다.

설치가 끝났다면 docker info 명령어로 docker 클라이언트가 루트리스 데몬에 제대로 연결되어 있는지 확인해 보세요.

$ docker info
Client: Docker Engine - Community
 Version: 28.3.3
 Context: rootless
...
Server:
...
 Security Options:
 seccomp
 Profile: builtin
 rootless
 cgroupns
...

혹시 오류가 발생한다면 트러블슈팅 문서를 확인해 보세요.

더 알아보기 (Learn more)