나의 잡다한 노트 및 메모

root 계정으로 시작된 dockerd가 ulimit으로 컨테이너에 미치는 영향 본문

DevOps/docker

root 계정으로 시작된 dockerd가 ulimit으로 컨테이너에 미치는 영향

peanutwalnut 2025. 8. 8. 13:54

docker container로 postgres를 올렸을 때 docker proxy나 그런건 root 계정으로 프로세스가 시작되잖아. 그러면 container 자체에서 ulimit을 올린다 해도 결국 커널을 거치니까 root 계정의 ulimit에 영향을 받을 거 같은데 어떻게 생각해?

 

일반적인 리눅스 서버에서 Docker 데몬(dockerd)은 systemd 서비스로 실행되고, 그 서비스의 실행 계정이 root입니다.
즉, ps로 보면 이렇게 보일 거예요.

ps -ef | grep dockerd root 1234 1 0 Aug08 ? 00:01:23 /usr/bin/dockerd ...

여기서 몇 가지 중요한 포인트가 있습니다.

 

1. systemd가 root로 실행시키는 이유

  • Docker 데몬은 네임스페이스, cgroups, iptables, network namespace 생성, 마운트 등 커널 수준 권한이 필요한 작업을 합니다.
  • 이 기능들은 CAP_SYS_ADMIN 같은 강력한 capability가 필요하므로, 보통 root 계정으로 데몬이 실행됩니다.
  • rootless Docker 모드도 있지만, 이건 별도 설정을 한 경우고 기본은 root.

 

2. root 계정이지만 “root 쉘의 ulimit”은 상속 안 함

  • dockerd는 root 로그인 세션에서 직접 실행되는 게 아니라, **PID 1(systemd)**이 실행합니다.
  • systemd는 각 서비스에 독립적인 RLIMIT 값을 적용할 수 있습니다.
    → 따라서 root 쉘에서 ulimit -n을 1024 → 65535로 바꿔도, dockerd에는 전혀 영향이 없습니다.
  • 실제 적용치는 다음 명령으로 확인 가능:
     
    systemctl show docker.service -p LimitNOFILE
    cat /proc/$(pgrep dockerd)/limits | grep "Max open files"

 

3. docker-proxy나 컨테이너에도 영향 주는 건 systemd 설정

  • docker-proxy는 dockerd의 자식 프로세스라서, dockerd의 RLIMIT을 상속합니다.
  • 컨테이너 프로세스(PostgreSQL 등)는 dockerd → containerd → runc로 내려가며, Docker 설정(--ulimit 옵션 또는 daemon.json)에서 지정한 값으로 바뀔 수 있지만, 여전히 상위의 하드 상한을 넘을 수 없습니다.

 

docker-proxy가 root UID로 실행되더라도, 호스트의 “root 로그인 쉘” ulimit과는 무관해요. docker-proxy의 한도는 부모 프로세스가 넘겨준 RLIMIT(대부분 systemd의 docker.service에서 정한 LimitNOFILE 등)과 **커널 상한(fs.nr_open)**에 의해 결정됩니다.

예외는 하나뿐입니다: root 쉘에서 직접 docker-proxy를 실행했다면 그 쉘의 ulimit을 상속받습니다. 하지만 일반 운영에서는 dockerd → docker-proxy 경로이므로 root 계정의 로그인 ulimit은 영향이 없습니다.