rootless Docker — br_netfilter 로드 실패
컨테이너를 만들고 지우는 매니저 프로세스가 하나 돌고 있는데, 이 프로세스를 root 로 띄울 수 없는 상황이었습니다. 그렇다고 root 로 뜬 Docker 데몬에 붙이면 컨테이너 레이어에 파일을 쓸 때 권한이 어긋나서, 데몬을 아예 매니저와 같은 사용자로 띄우는 rootless 모드로 갔습니다.
그런데 데몬이 시작하다 죽었습니다.
br_netfilter 로드 실패로 데몬 종료
로그 끝에 이렇게 나왔습니다.
Running modprobe bridge br_netfilter failed with message:
modprobe: ERROR: could not insert 'br_netfilter': Operation not permitted
failed to start daemon: Error initializing network controller:
error creating default "bridge" network:
cannot restrict inter-container communication:
ensure that the br_netfilter kernel module is loaded
br_netfilter 는 커널 모듈입니다. 모듈을 올리는 modprobe 는 커널을
건드리는 작업이라 root 가 필요합니다. rootless 데몬은 root 가 아니니
Operation not permitted 가 납니다.
rootless는 bridge 미사용, 기본 설정은 bridge 요구
그런데 여기서 전제가 깨지는데, rootless Docker 는 컨테이너 네트워크로 bridge 가
아니라 slirp4netns 를 써서 애초에 bridge 네트워크를 안 만듭니다.
그런데 데몬이 시작할 때 기본 bridge 네트워크(docker0)를 구성하려 하고, 그
과정에서 br_netfilter 를 요구합니다. 안 쓸 네트워크를 준비하려다 못 올리는
모듈에 막혀서 데몬 전체가 안 뜨는 겁니다.
~/.config/docker/daemon.json 에서 bridge 관련 기능을 끕니다.
{
"iptables": false,
"ip6tables": false,
"bridge": "none"
}
rootless 는 어차피 이 기능들을 안 쓰니 꺼도 잃는 게 없습니다. 데몬이 bridge 구성 단계를 건너뛰고 정상적으로 뜹니다.
사전 준비 사항
rootless 데몬을 세팅하기 전에 걸리는 것들입니다.
storage driver 는 overlay2 여야 합니다. AUFS 는 rootless 데몬을 지원하지 않습니다.
필요한 패키지가 따로 있습니다.
apt-get install -y dbus-user-session docker-ce-rootless-extras uidmap
사용자 세션이 로그인 없이도 유지돼야 합니다. 데몬을 user systemd 서비스로 띄우는데, 그 사용자가 로그인 상태가 아니면 서비스가 안 붙습니다.
loginctl enable-linger <username>
이걸 안 하면 systemctl --user 가 Failed to connect to bus: No such file or directory 로 실패합니다. machinectl shell <username>@ 로 붙어서
작업하면 세션이 잡힙니다.
rootless를 택한 이유
컨테이너 레이어에 파일을 직접 써넣는 구조라면 그 write 권한이 root 에게 있습니다. 컨테이너 레이어를 만드는 게 Docker 데몬이고, 데몬이 root 로 떠 있기 때문입니다.
매니저 프로세스가 docker cp 같은 방식으로 우회하도록 앱 로직을 고치는
방법도 있지만, 사이드 이펙트 검증이 필요하고 공수가 큽니다. 그래서 앱을
안 고치고, 데몬을 매니저 프로세스와 같은 사용자로 띄우는 쪽을 택했습니다.
데몬과 매니저가 같은 사용자면 권한 문제가 사라집니다.
댓글 0