Mac에서 Docker Desktop 권한 요구 사항 이해하기

Mac에서 Docker Desktop 권한 요구 사항 이해하기

이 페이지는 Mac에서 Docker Desktop을 실행하고 설치하기 위한 권한 요구 사항에 대한 정보를 담고 있어요. 또한 컨테이너를 root로 실행하는 것과 호스트에서 root 접근 권한을 갖는 것의 차이를 명확히 설명해요. Mac의 Docker Desktop은 보안을 염두에 두고 설계됐으며, 관리자 권한은 정말 필요할 때만 요구돼요.

출처: Understand permission requirements for Docker Desktop on Mac

본문

권한 요구 사항

Mac용 Docker Desktop은 권한 없는 사용자(unprivileged user)로 실행돼요. 하지만 다음과 같은 제한된 privileged 구성을 수행하기 위해 특정 기능이 필요해요.

  • /usr/local/bin에 심볼릭 링크 설치.
  • /etc/hostslocalhostkubernetes.docker.internal이 정의되도록 보장. 일부 오래된 macOS 설치에는 /etc/hostslocalhost가 없어서 Docker가 실패해요. kubernetes.docker.internal DNS 이름을 정의하면 Docker가 컨테이너와 Kubernetes 컨텍스트를 공유할 수 있어요.
  • 1024 미만의 privileged 포트 바인딩. 운영체제가 권한 없는 프로세스의 바인딩을 막아서 docker run -p 127.0.0.1:80:80 docker/getting-started 같은 명령이 깨져요. (4.88 및 이전 버전에 적용)
  • 개발자에게 읽기 전용인 Registry Access Management 정책의 안전한 캐싱. (4.88 및 이전 버전에 적용)

필요할 때 privileged 접근은 SettingsAdvanced 페이지를 통해 부여돼요. 4.88 및 이전 버전에서는 설치 중에 부여돼요. Advanced 페이지에서 다음을 활성화할 수 있어요.

  • Docker CLI 도구의 위치(시스템 또는 사용자 디렉터리)
  • 기본 Docker 소켓

로컬 관리 접근이 금지된 환경처럼 보안 요구 사항이 높은 환경에서 일한다면, privileged 접근 부여를 피하기 위해 이 설정을 기본값으로 두면 돼요. 구성한 advanced 설정에 따라 비밀번호를 입력해 확인해야 해요.

심볼릭 링크 설치

Docker 바이너리는 기본적으로 /Applications/Docker.app/Contents/Resources/bin에 설치돼요. Docker Desktop은 $HOME/.docker/bin에 바이너리용 심볼릭 링크를 만들고, 이 디렉터리는 터미널의 PATH에 자동으로 추가돼요. Settings의 Advanced 페이지에서 심볼릭 링크 위치를 /usr/local/bin으로 바꿀 수 있어요. /usr/local/bin이 unprivileged 사용자에게 쓰기 가능하지 않다면, Docker Desktop은 심볼릭 링크를 만들기 전에 이 선택을 확인받기 위한 권한 부여를 요구해요.

Advanced 페이지에서 /var/run/docker.sock 심볼릭 링크 설치를 활성화할 수도 있어요. 이 심볼릭 링크를 만들면 기본 Docker 소켓 경로를 사용하는 다양한 Docker 클라이언트가 추가 변경 없이 동작해요. /var/run은 tmpfs로 마운트돼서 재시작 시 내용이 삭제돼요(Docker 소켓 심볼릭 링크 포함). 재시작 후에도 Docker 소켓이 존재하도록 Docker Desktop은 ln -s -f /Users/<user>/.docker/run/docker.sock /var/run/docker.sock을 실행해 심볼릭 링크를 만드는 launchd 시작 작업을 설정해요. 이 옵션을 활성화하지 않으면 심볼릭 링크와 시작 작업이 만들어지지 않고, 사용 중인 클라이언트에서 DOCKER_HOST 환경 변수를 /Users/<user>/.docker/run/docker.sock으로 명시적으로 설정해야 할 수 있어요. Docker CLI는 소켓 경로를 가져오기 위해 현재 컨텍스트에 의존하고, Docker Desktop 시작 시 현재 컨텍스트는 desktop-linux로 설정돼요.

localhost와 kubernetes.docker.internal이 정의되도록 보장하기

localhost127.0.0.1로 해석되도록 하고, Kubernetes를 사용한다면 kubernetes.docker.internal127.0.0.1로 해석되도록 보장하는 것은 사용자의 책임이에요.

privileged 포트 바인딩

설치 중(4.88.0 및 이전 버전) 또는 설치 후 Settings의 Advanced 페이지에서 privileged 포트 매핑을 활성화할 수 있어요. Docker Desktop은 이 선택을 확인하기 위한 권한 부여를 요구해요.

명령줄에서 설치하기

install 명령의 --user 플래그로 설치 중 privileged 구성이 적용돼요. 이 경우 Docker Desktop 첫 실행 때 root 권한 부여를 요구받지 않아요. --user 플래그는:

  • 이전 com.docker.vmnetd가 있으면 제거
  • 심볼릭 링크 설정
  • localhost127.0.0.1로 해석되도록 보장

이 접근 방식의 한계는 Docker Desktop이 머신당 한 사용자 계정으로만 실행될 수 있고, 바로 그 --user 플래그에 지정된 계정만 된다는 점이에요.

Privileged helper (버전 4.88 및 이전)

privileged helper가 필요한 제한된 상황(예: privileged 포트 바인딩, Registry Access Management 정책 캐싱)에서 privileged helper는 launchd에 의해 시작되고, 런타임에 비활성화하지 않는 한 백그라운드에서 실행돼요. Docker Desktop 백엔드는 Unix 도메인 소켓 /var/run/com.docker.vmnetd.sock으로 통신해요. 그것이 수행하는 기능은:

  • 1024 미만의 privileged 포트 바인딩.
  • 개발자에게 읽기 전용인 Registry Access Management 정책의 안전한 캐싱.
  • privileged helper 제거.

privileged helper 프로세스 제거는 launchd 프로세스를 제거하는 것과 같은 방식으로 해요.

$ ps aux | grep vmnetd
root             28739   0.0  0.0 34859128    228   ??  Ss    6:03PM   0:00.06 /Library/PrivilegedHelperTools/com.docker.vmnetd
user             32222   0.0  0.0 34122828    808 s000  R+   12:55PM   0:00.00 grep vmnetd

$ sudo launchctl unload -w /Library/LaunchDaemons/com.docker.vmnetd.plist
Password:

$ ps aux | grep vmnetd
user             32242   0.0  0.0 34122828    716 s000  R+   12:55PM   0:00.00 grep vmnetd

$ rm /Library/LaunchDaemons/com.docker.vmnetd.plist

$ rm /Library/PrivilegedHelperTools/com.docker.vmnetd

백엔드 헬퍼 소켓

Docker Desktop 백엔드 프로세스(com.docker.backend)는 내부 헬퍼 소켓(~/Library/Containers/com.docker.docker/Data/forkexecd.sock)을 사용해 Docker Desktop 실행의 일부로 헬퍼 프로세스를 fork하고 실행해요. 이 소켓은 root로 실행되지 않고 어떤 상승된 권한도 부여하지 않아요. Docker Desktop을 실행하는 같은 macOS 사용자가 소유하고 접근할 수 있으며, Docker Desktop 애플리케이션 컨테이너 안에 포함돼 있어요.

Linux VM 안에서 root로 실행되는 컨테이너

Docker Desktop에서 Docker 데몬과 컨테이너는 Docker가 관리하는 가벼운 Linux VM에서 실행돼요. 즉 컨테이너가 기본적으로 root로 실행되지만 Mac 호스트 머신에 root 접근을 부여하지는 않아요. Linux VM이 보안 경계 역할을 하고 호스트에서 접근할 수 있는 리소스를 제한해요. 호스트에서 Docker 컨테이너로 바인드 마운트된 디렉터리는 원래 권한을 유지해요.

Enhanced Container Isolation

또한 Docker Desktop은 Business 고객만 사용할 수 있는 Enhanced Container Isolation(ECI) 모드를 지원해서, 개발자 워크플로에 영향을 주지 않고 컨테이너를 더욱 보호해요. ECI는 모든 컨테이너를 자동으로 Linux user-namespace 안에서 실행해서, 컨테이너 안의 root가 Docker Desktop VM 안의 unprivileged 사용자로 매핑돼요. ECI는 이 고급 기법을 써서 Docker Desktop Linux VM 안의 컨테이너를 VM 안에서 실행되는 Docker 데몬 및 다른 서비스와 더욱 격리시켜요.

더 알아보기