Rootless 모드를 시도한 Docker

8028 단어 Docker
Docker 19.03으로 시작하는 새로운 기능 Docker의 Rootless 모드를 시도했습니다.

Rootless 모드


이전에는 루트 권한을 사용하여 docker 수호 프로세스를 실행했기 때문에 취약성 전달과 docker 플러그인 등을 잘못 설정하면 호스트의 루트 권한을 박탈할 수 있습니다.
Rootless 모드에서는 모든 사용자가 docker 수호 프로세스를 실행하기 때문에 취약성 등이 있어도 해당 사용자의 권한 내에만 영향을 미칠 수 있습니다. (또는 각 사용자에서 권한으로 승격되면 별개의 문제입니다.)

Rootless 모드를 설치한 Docker


Rootless 모드의 Docker를 실제로 설치해 봅니다.
시험해 본 환경은 다음과 같다.
OS: Ubuntu 18.04(Hyper-V)
Memory : 2GB
CPU : Intel Core i9
docker-compose가 설치되어 있음

  • 설치 명령 실행
    $ curl -fsSL https://get.docker.com/rootless | sh
    

  • bashrc에 추가
    설치된 Rootles 모드 Docker 바이너리 및 소켓 경로입니다.bashrc에 기술합니다.설치 후 콘솔에 기재된 내용을 복제하면 OK.
    export PATH=$HOME/bin:$PATH
    export DOCKER_HOST=unix:///run/user/1000/docker.sock
    

  • 자동 시작 설정
    마지막으로 Rootless 모드에서 Docker의 시작 설정을 수행합니다.이것은 시스템ctl로 진행됩니다.
    $ systemctl --user enable docker
    $ systemctl --user start docker
    
  • 실제 실행 명령


    단일 컨테이너 실행


    우선 Hello-world의 컨테이너를 순서대로 집행합시다.
    $ docker run -it --rm hello-world
    Unable to find image 'hello-world:latest' locally
    latest: Pulling from library/hello-world
    0e03bdcc26d7: Pull complete
    Digest: sha256:8e3114318a995a1ee497790535e7b88365222a21771ae7e53687ad76563e8e76
    Status: Downloaded newer image for hello-world:latest
    
    Hello from Docker!
    This message shows that your installation appears to be working correctly.
    
    To generate this message, Docker took the following steps:
     1. The Docker client contacted the Docker daemon.
     2. The Docker daemon pulled the "hello-world" image from the Docker Hub.
        (amd64)
     3. The Docker daemon created a new container from that image which runs the
        executable that produces the output you are currently reading.
     4. The Docker daemon streamed that output to the Docker client, which sent it
        to your terminal.
    
    To try something more ambitious, you can run an Ubuntu container with:
     $ docker run -it ubuntu bash
    
    Share images, automate workflows, and more with a free Docker ID:
     https://hub.docker.com/
    
    For more examples and ideas, visit:
     https://docs.docker.com/get-started/
    
    읊다, 읊조리다

    단일 컨테이너로 포트 공개


    그럼 WEB 서버로서 포트를 외부에 공개하는 컨테이너를 만들어 보세요.
    예전에 Docker의 포트에서 IPtables forward를 공개적으로 사용한다고 들었기 때문에 여기서는 안 된다고 생각합니다.
    $ docker run -d --rm -p 80:80 nginx:1.17-alpine
    Unable to find image 'nginx:1.17-alpine' locally
    1.17-alpine: Pulling from library/nginx
    cbdbe7a5bc2a: Pull complete
    c554c602ff32: Pull complete
    Digest: sha256:763e7f0188e378fef0c761854552c70bbd817555dc4de029681a2e972e25e30e
    Status: Downloaded newer image for nginx:1.17-alpine
    45bc78be4cc1d2f35321ae80ea3d9fe82cfc3b545a17f16b2eb1c3ea81e5a535
    docker: Error response from daemon: driver failed programming external connectivity on endpoint youthful_einstein (9fddff03eda43e5fc3d29328cc20040d5a1a57168bd2fcd7d08473f2a2af6e9d): Error starting userland proxy:.
    
    역시 안 돼...
    오류 정보로 볼 때 포트 공개를 설정하려고 했는데 오류가 발생한 것 같습니다.

    docker-compose로 볼게요.


    그럼 docker-compose로 여러 개의 컨테이너를 가동하세요.
    다음 내용은 docker-compose입니다.yml 썼어요.이번에는 당분간 gitea부터 움직였으면 좋겠어요.
    docker-compose.yml
    version: "3.7"
    services:
      server:
        image: gitea/gitea:latest
        environment:
          - USER_UID=1000
          - USER_GID=1000
          - DB_TYPE=postgres
          - DB_HOST=db:5432
          - DB_NAME=gitea
          - DB_USER=gitea
          - DB_PASSWORD=gitea
          - DISABLE_SSH=false
        restart: always
        networks:
          - gitea
        volumes:
          - ./gitea:/data
          - /etc/timezone:/etc/timezone:ro
          - /etc/localtime:/etc/localtime:ro
        ports:
          - 3000:3000
        depends_on:
          - db
      db:
        image: postgres:11-alpine
        restart: always
        environment:
          - POSTGRES_USER=gitea
          - POSTGRES_PASSWORD=gitea
          - POSTGRES_DB=gitea
        networks:
          - gitea
        volumes:
          - ./postgres:/var/lib/postgresql/data
    networks:
      gitea:
        external: false
    
    아까의 예로 볼 때 포트 공개는 실패할 수 있지만 먼저 실행해 보세요...
    $ docker-compose up -d
    Creating network "foo_gitea" with the default driver
    Creating foo_db_1 ... done
    Creating foo_server_1 ... done
    $ docker-compose ps
          Name                     Command               State               Ports
    -------------------------------------------------------------------------------------------
    foo_db_1       docker-entrypoint.sh postgres    Up      5432/tcp
    foo_server_1   /usr/bin/entrypoint /bin/s ...   Up      22/tcp, 0.0.0.0:3000->3000/tcp
    
    고마워, 잘 돌아가고 있대.
    그럼 브라우저에서 봅시다.

    나왔네.

    총결산


    Rootless 모드의 Docker는 단일 실행(배치 등)에 적합합니다.
    docker-compose의 포트 공개와 docker 명령의 포트 공개 행위는 상당히 신경을 쓰지만, docker-compose 웹 응용 프로그램을 사용하는 개발 환경에서도 사용할 수 있다.
    그럼에도 불구하고 docker-compose의 포트 공개는 어떻게 이루어졌을까?불가사의하다.혹시 아시는 분?

    좋은 웹페이지 즐겨찾기