Rootless 모드는 데몬과 컨테이너를 일반 사용자 권한으로 돌린다. 데몬이 root 로 돌지 않으므로 컨테이너 탈출이 곧 호스트 root 로 이어지지 않는다. RHEL 8 계열에서 사용자 haedong 으로 구성하는 절차를 기준으로 정리한다. 명령마다 어느 계정으로 실행하는지가 중요하다.
newuidmap · newgidmap — RHEL·Rocky 는 shadow-utils, 데비안 계열은 uidmap 패키지에 들어 있다./etc/subuid · /etc/subgid 에 해당 사용자 항목이 있어야 한다. 보통 사용자 생성 때 자동으로 들어간다.loginctl enable-linger <사용자> 를 해 두지 않으면 로그아웃과 동시에 데몬이 죽는다.# root 로
dnf install -y shadow-utils iptables fuse-overlayfs
grep haedong /etc/subuid /etc/subgid
loginctl enable-linger haedong
/etc/subuid 에 항목이 없으면 usermod --add-subuids 100000-165535 --add-subgids 100000-165535 haedong 으로 넣는다.
RHEL 계열은 docker-ce-rootless-extras 패키지에 dockerd-rootless-setuptool.sh 가 들어 있다. 패키지 저장소를 쓸 수 없으면 설치 스크립트를 쓴다.
# haedong 계정으로
dockerd-rootless-setuptool.sh install
# 저장소를 못 쓸 때
curl -fsSL https://get.docker.com/rootless | sh
스크립트가 ~/bin 에 바이너리를 두고 ~/.config/systemd/user/docker.service 를 만든다. 마지막에 출력되는 환경 변수를 셸 초기화 파일에 넣는다.
echo 'export PATH=$HOME/bin:$PATH' >> ~/.bashrc
echo 'export DOCKER_HOST=unix:///run/user/'"$(id -u)"'/docker.sock' >> ~/.bashrc
source ~/.bashrc
systemctl --user enable --now docker
systemctl --user status docker
docker info | grep -i rootless
docker run --rm hello-world
docker info 의 Security Options 에 rootless 가 보이면 정상이다.
systemctl --user 가 사용자 D-Bus 세션을 찾지 못한 것이다. su - haedong 으로 전환한 세션에는 사용자 systemd 가 붙지 않는 경우가 많으므로 해당 계정으로 직접 SSH 로그인해서 실행한다. 그래도 안 되면 XDG_RUNTIME_DIR 를 확인한다.
echo $XDG_RUNTIME_DIR # /run/user/<uid> 여야 한다
loginctl enable-linger haedong
/run/user/<uid> 를 손으로 만들어서는 안 된다. systemd-logind 가 세션을 열 때 만드는 tmpfs 라 손으로 만든 디렉터리는 다음 로그인에서 뒤엉킨다.
기본적으로 비특권 사용자는 낮은 포트에 바인딩하지 못한다. 상위 포트(8080 등)를 쓰거나, 호스트 전체에 net.ipv4.ip_unprivileged_port_start=80 을 주거나, rootlesskit 바이너리에 CAP_NET_BIND_SERVICE 를 부여한다.
스토리지 드라이버로 fuse-overlayfs 를 쓰는 환경에서는 네이티브 overlay2 보다 느리다. --net=host, cgroup v1 환경에서의 자원 제한, 일부 장치 전달이 제한된다. cgroup v2 + systemd 드라이버 조합에서만 CPU·메모리 제한이 제대로 걸린다.
Red Hat 계열에서 rootless 가 목적이라면 Podman 이 기본 선택지다. 데몬이 없어 구조가 단순하고 배포판 지원을 받는다. Docker CLI 습관을 유지해야 할 때만 rootless Docker 를 쓴다.