이전 편에서 Rootless 모드의 보안 원리와 필요성을 살펴봤습니다. 이번 편에서는 Ubuntu 22.04 / 24.04 환경에서 Rootless Docker를 실제로 설치하는 과정을 단계별로 진행합니다. 사전 준비부터 설치 검증, 기존 Root 모드와의 공존 방법까지 빠짐없이 다룹니다.


1. 설치 전 사전 요구사항 확인

1.1 지원 OS 및 커널 버전 확인

Rootless Docker는 다음 환경을 권장합니다.

항목 최소 요구사항 권장 사항
Linux 커널 4.18 이상 5.11 이상
Ubuntu 20.04 LTS 22.04 LTS 이상
cgroup v1 또는 v2 v2 강력 권장
아키텍처 x86_64, aarch64 -
# 커널 버전 확인
uname -r
# 6.8.0-51-generic  (Ubuntu 24.04 예시)

# Ubuntu 버전 확인
lsb_release -a
# Distributor ID: Ubuntu
# Release: 24.04

1.2 cgroup v2 활성화 여부 확인

cgroup v2는 Rootless 모드에서 리소스 제한(메모리, CPU) 기능을 사용하기 위한 핵심 요구사항입니다.

# cgroup v2 활성화 확인
cat /sys/fs/cgroup/cgroup.controllers
# cpuset cpu io memory hugetlb pids rdma misc
# 위와 같은 출력이 나오면 cgroup v2 활성화 상태

# 또는
stat -fc %T /sys/fs/cgroup/
# cgroup2fs  ← cgroup v2
# tmpfs      ← cgroup v1 (업그레이드 필요)

cgroup v2가 비활성화된 경우 활성화 방법:

# 방법 1: grubby 사용 (RHEL 계열)
sudo grubby --update-kernel=ALL --args="systemd.unified_cgroup_hierarchy=1"

# 방법 2: GRUB 설정 수정 (Ubuntu/Debian)
sudo sed -i 's/GRUB_CMDLINE_LINUX=""/GRUB_CMDLINE_LINUX="systemd.unified_cgroup_hierarchy=1"/' /etc/default/grub
sudo update-grub
sudo reboot

1.3 필수 패키지: uidmap

uidmap 패키지는 newuidmap, newgidmap 바이너리를 제공합니다. 이 도구들은 User Namespace에서 uid/gid 매핑을 안전하게 설정하는 데 필수적입니다.

# uidmap 설치
sudo apt-get update && sudo apt-get install -y uidmap

# 설치 확인
which newuidmap newgidmap
# /usr/bin/newuidmap
# /usr/bin/newgidmap

# SUID 비트 확인 (s 비트가 있어야 함)
ls -la $(which newuidmap)
# -rwsr-xr-x 1 root root 40464 ... /usr/bin/newuidmap
#   ↑ 's' 비트 필수

Pro-tip: SUID 비트가 없으면 dockerd-rootless-setuptool.sh가 오류를 반환합니다. 패키지 재설치로 해결되지 않는다면 sudo chmod u+s $(which newuidmap newgidmap)으로 수동 설정하세요.


2. 사전 환경 구성

2.1 /etc/subuid, /etc/subgid 설정

Rootless 모드에서 사용할 uid/gid 범위를 /etc/subuid/etc/subgid에 등록해야 합니다.

# 현재 설정 확인
grep $USER /etc/subuid /etc/subgid 2>/dev/null

# 설정이 없는 경우 추가
sudo usermod --add-subuids 100000-165535 $USER
sudo usermod --add-subgids 100000-165535 $USER

# 설정 확인
grep $USER /etc/subuid /etc/subgid
# /etc/subuid:huni:100000:65536
# /etc/subgid:huni:100000:65536

다중 사용자 환경에서의 범위 충돌 방지:

여러 사용자가 동일 서버를 사용하는 경우, 각 사용자의 uid 범위가 겹치지 않도록 설정해야 합니다.

# 사용자별 비겹침 범위 예시
# /etc/subuid
# huni:100000:65536      # uid 100000-165535
# alice:200000:65536     # uid 200000-265535
# bob:300000:65536       # uid 300000-365535

2.2 네트워크 백엔드 설치

Rootless Docker는 컨테이너 네트워킹을 위해 userspace 네트워크 백엔드가 필요합니다. slirp4netns 또는 더 성능이 좋은 pasta 중 하나를 선택합니다.

# 방법 1: slirp4netns (Ubuntu 20.04/22.04 기본 지원)
sudo apt-get install -y slirp4netns
slirp4netns --version
# slirp4netns version 1.x.x

# 방법 2: pasta (Ubuntu 23.04+, 더 나은 성능 — 권장)
sudo apt-get install -y passt
pasta --version
# pasta 2024.x.x ...

slirp4netns vs pasta 비교:

항목 slirp4netns pasta
성능 보통 (userspace TCP/IP) 우수 (tap 기반)
UDP 성능 낮음 양호
IPv6 제한적 완전 지원
설치 용이성 쉬움 Ubuntu 23.04+
권장 환경 Ubuntu 20.04/22.04 Ubuntu 23.04+

3. Docker Rootless 모드 설치

3.1 방법 A: docker-ce-rootless-extras 패키지 설치 (권장)

기존에 Docker CE가 설치된 환경이라면 docker-ce-rootless-extras 패키지를 추가로 설치하는 방법이 가장 간단합니다.

# 기존 Docker CE 설치 여부 확인
docker --version
# Docker version 27.x.x, build ...

# rootless extras 패키지 설치
sudo apt-get install -y docker-ce-rootless-extras

# 패키지 설치 후 setuptool 위치 확인
which dockerd-rootless-setuptool.sh
# /usr/bin/dockerd-rootless-setuptool.sh

3.2 방법 B: 설치 스크립트로 처음부터 설치

Docker가 설치되어 있지 않은 환경이라면 공식 설치 스크립트를 활용합니다.

# Docker 공식 설치 스크립트 (rootless 포함)
curl -fsSL https://get.docker.com/rootless | sh

# 또는 수동으로 패키지 저장소 추가 후 설치
sudo apt-get install -y ca-certificates curl
sudo install -m 0755 -d /etc/apt/keyrings
sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg \
  -o /etc/apt/keyrings/docker.asc
sudo chmod a+r /etc/apt/keyrings/docker.asc

echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] \
  https://download.docker.com/linux/ubuntu \
  $(. /etc/os-release && echo "$VERSION_CODENAME") stable" | \
  sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io \
  docker-buildx-plugin docker-compose-plugin docker-ce-rootless-extras

3.3 dockerd-rootless-setuptool.sh 실행

패키지 설치 후 dockerd-rootless-setuptool.sh install 명령으로 Rootless 환경을 구성합니다.

# Rootless 환경 설치 (일반 사용자 권한으로 실행)
dockerd-rootless-setuptool.sh install

성공 시 다음과 같은 출력이 나타납니다.

[INFO] Creating /home/huni/.config/systemd/user/docker.service
[INFO] starting systemd service docker.service
Created symlink /home/huni/.config/systemd/user/default.target.wants/docker.service
  → /home/huni/.config/systemd/user/docker.service
[INFO] Installed docker.service successfully.
[INFO] To control docker.service, run: `systemctl --user (start|stop|enable|disable) docker.service`
[INFO] To run docker.service on system startup, enable lingering: `loginctl enable-linger huni`

# =================== INFO ===================
# Some applications may require the following environment variables to be set:
#   export PATH=/usr/bin:$PATH
#   export DOCKER_HOST=unix:///run/user/1000/docker.sock

4. 설치 후 환경 변수 설정

4.1 DOCKER_HOST 환경 변수

Rootless 모드의 Docker 소켓 경로는 Root 모드와 다릅니다. DOCKER_HOST 환경 변수를 설정하지 않으면 기본 소켓(/var/run/docker.sock)을 참조하려다 실패합니다.

# ~/.bashrc 또는 ~/.profile에 추가
echo 'export DOCKER_HOST=unix:///run/user/$(id -u)/docker.sock' >> ~/.bashrc
echo 'export PATH=/usr/bin:$PATH' >> ~/.bashrc
echo 'export DOCKER_BUILDKIT=1' >> ~/.bashrc

# 즉시 적용
source ~/.bashrc

# 설정 확인
echo $DOCKER_HOST
# unix:///run/user/1000/docker.sock

Pro-tip: $(id -u) 방식으로 설정하면 uid가 다른 계정에서도 동일한 .bashrc를 재사용할 수 있습니다.

4.2 시스템 부팅 시 자동 시작 설정

로그아웃 후에도 Docker 데몬이 계속 실행되려면 loginctl enable-linger를 활성화해야 합니다.

# linger 활성화 (로그아웃 후에도 user 서비스 유지)
loginctl enable-linger $USER

# 설정 확인
loginctl show-user $USER | grep Linger
# Linger=yes

# 부팅 시 자동 시작 활성화
systemctl --user enable docker

# 현재 상태 확인
systemctl --user status docker

5. 설치 검증

5.1 rootless 데몬 동작 확인

# 데몬 상태 확인
systemctl --user status docker
# ● docker.service - Docker Application Container Engine (Rootless)
#      Loaded: loaded (/home/huni/.config/systemd/user/docker.service; enabled)
#      Active: active (running) since ...
#    Main PID: 12345 (rootlesskit)

# 소켓 파일 존재 확인
ls -la /run/user/$(id -u)/docker.sock
# srw-rw---- 1 huni huni 0 Apr 4 09:00 /run/user/1000/docker.sock

5.2 docker info로 rootless 확인

docker info 2>/dev/null | grep -E "Server Version|rootless|Context|Storage Driver|Docker Root Dir"

출력 예시:

 Server Version: 27.5.1
 Storage Driver: overlay2
 Docker Root Dir: /home/huni/.local/share/docker
 ...
 rootless: true

rootless: true 항목이 표시되면 Rootless 모드로 정상 동작하는 것입니다.

5.3 hello-world 컨테이너 실행

# 기본 테스트
docker run --rm hello-world
# Hello from Docker!
# This message shows that your installation appears to be working correctly.

# 컨테이너 내부 uid 확인
docker run --rm alpine id
# uid=0(root) gid=0(root)

# 호스트에서 실제 프로세스 uid 확인
docker run -d --name uid-test alpine sleep 30
ps -o uid,pid,comm | grep containerd
# 100000  5678  containerd-shi
docker rm -f uid-test

호스트에서 uid=100000(subuid 시작값)으로 확인되면 Rootless 모드가 올바르게 작동하는 것입니다.


6. 기존 Root 모드 Docker와 공존 설정

6.1 Docker Context 전환 방법

시스템에 Root 모드 Docker와 Rootless 모드 Docker가 공존하는 경우, Docker Context 기능으로 손쉽게 전환할 수 있습니다.

# 현재 컨텍스트 목록 확인
docker context ls
# NAME        DESCRIPTION                               DOCKER ENDPOINT
# default *   Current DOCKER_HOST based configuration   unix:///var/run/docker.sock
# rootless    Rootless mode                             unix:///run/user/1000/docker.sock

# rootless 컨텍스트로 전환
docker context use rootless
# rootless
# Current context is now "rootless"

# root 모드로 복귀
docker context use default

# 특정 명령에만 컨텍스트 지정
docker --context rootless ps
docker --context default ps

6.2 Context 별 작업 분리 전략

# ~/.bashrc에 별칭 추가 (선택사항)
alias dockerr='docker --context rootless'
alias dockerd-root='docker --context default'

# CI/CD 환경에서 환경변수로 컨텍스트 지정
export DOCKER_CONTEXT=rootless
docker ps

7. 설치 트러블슈팅

문제 1: “newuidmap: write to uid_map failed”

# 증상
dockerd-rootless-setuptool.sh install
# [ERROR] newuidmap: write to uid_map failed: Operation not permitted

# 원인 및 해결
# 1. /etc/subuid 설정 확인
grep $USER /etc/subuid
# 2. newuidmap SUID 비트 확인
ls -la $(which newuidmap) | grep s
# 3. sysctl 설정 확인
sysctl kernel.unprivileged_userns_clone
# 0이면 1로 변경 필요
echo 'kernel.unprivileged_userns_clone=1' | sudo tee /etc/sysctl.d/99-userns.conf
sudo sysctl -p /etc/sysctl.d/99-userns.conf

문제 2: “cgroup v2가 없어 리소스 제한 불가” 경고

# 증상 (설치는 되나 경고 메시지)
# [WARNING] Memory cgroup is disabled in the kernel or cgroup v2 controller
#           'memory' is not delegated to unprivileged users.

# 해결: /etc/systemd/system/user@.service.d/ 오버라이드 생성
sudo mkdir -p /etc/systemd/system/user@.service.d/
sudo bash -c 'cat > /etc/systemd/system/user@.service.d/delegate.conf << EOF
[Service]
Delegate=cpu cpuset io memory pids
EOF'
sudo systemctl daemon-reload

문제 3: slirp4netns 없음 오류

# 증상
# [ERROR] Failed to start rootlesskit: ... slirp4netns not found

# 해결
sudo apt-get install -y slirp4netns
# 또는 pasta
sudo apt-get install -y passt

결론

Ubuntu 환경에서 Rootless Docker 설치는 크게 다섯 단계로 요약됩니다.

  1. 사전 확인: cgroup v2, uidmap 패키지, newuidmap SUID 비트
  2. subuid/subgid 설정: usermod --add-subuids 명령으로 uid 범위 등록
  3. 패키지 설치: docker-ce-rootless-extras 설치 후 dockerd-rootless-setuptool.sh install 실행
  4. 환경 변수 설정: DOCKER_HOSTPATH.bashrc에 추가
  5. linger 활성화: loginctl enable-linger로 로그아웃 후에도 데몬 유지

다음 편에서는 Rootless Docker의 systemd 서비스 관리, daemon.json 설정, 스토리지 드라이버 선택 등 운용에 필요한 세부 설정을 다룹니다.

참고자료


Docker Rootless Mode 시리즈

  • [Part 1] Rootless 모드란? 보안 개념과 필요성
  • [Part 2] Ubuntu에서 Rootless Docker 설치하기 ← 현재 글
  • [Part 3] Rootless Docker 설정 및 운용 가이드](/container/docker-rootless-mode-configuration/)
  • [Part 4] Rootless Docker 실전 활용 및 트러블슈팅](/container/docker-rootless-mode-practical-guide/)

댓글남기기