Docker 2. 설정(volume, port, network, compose)

최강일·2022년 12월 11일
2

Docker

목록 보기
4/5

개요

컨테이너 생성에 필요한 설정을 다룬다.
그리고 여러 컨테이너를 한번에 만들 수 있는 compose 설정을 다룬다.

목차

  • Docker 설정(volume, port, network, compose)
    • volume,mount 설정
    • port 설정
    • network 설정
    • docker compose

Volume

볼륨이란 도커에 의해 관리되는 가상 하드 디스크다.
이미지로 컨테이너를 만들면 해당 컨테이너마다 독립적인 볼륨(하나의 파일시스템을 갖춘 접근 가능한 저장 공간)이 할당되고, 컨테이너가 삭제되면 해당 볼륨 또한 삭제된다. 문제는 컨테이너 내부에 저장된 데이터는 컨테이너가 삭제되었을 경우 같이 삭제된다.

그래서 도커에서 데이터의 영속성을 보장하기 위하여 볼륨과 바인드 마운트를 이용한다. 볼륨과 바인드 마운트는 영속성을 보장하며 파일 시스템과 컨테이너를 분리하여 관리한다.
즉, 컨테이너를 지웠다가 다시 실행해도 도커 볼륨과 연결한다면 데이터는 그대로 유지된다.

Mount

물리적인 장치를 특정한 디렉토리 위치에 연결시켜 주는 과정
리눅스에서는 하드디스크의 파티션,cd/dvd,usb메모리 등을 사용하려면 특정한 위치에 연결을 해 줘야 한다.

  1. 디스크를 디렉토리에 마운팅한다.
  2. 데이터를 마운트 디렉토리에 저장한다.
  3. 실제 물리적으로 디스크에 저장한다.

ex) test.txt라는 데이터를 /data 아래에 저장하면 실제로 해당 데이터는 /dev/sda1 디스크에 저장이 된다.

명령어

  • 생성 : docker volume create [test-vol]
  • 조회 : docker volume ls
  • 상세조회 : docker volume inspect [test-vol]
  • 볼륨을 컨테이너에 마운트하기
    • docker run -v [마운트할 볼룸명]:[컨테이너 내의 경로] ...
    • 설정확인 : inspect명령어 사용
  • 삭제 : docker volume rm [test-vol]

종류(volume vs bind mount vs tmpfs mount)

volume

도커 공식 문서에서 권장하는 방식으로 도커 엔진이 관리하는 도커 스토리지 디렉토리에 새 디렉토리를 생성하여 컨테이너 내부의 볼륨 데이터를 저장하는 방식이다.
생성된 볼륨은 자동으로 호스트의 도커 스토리지 디렉토리인 /var/lib/docker/volumes/ 에 저장된다. 볼륨을 컨테이너에 탑재하면 이 디렉토리가 컨테이너에 탑재되며, 도커에 의해 관리되고 호스트 시스템의 핵심 기능과 분리된다. 바인드 마운트가 호스트 머신의 디렉토리 구조나 os에 의존적인 반면, 볼륨은 도커에 의해 완전히 관리된다.

  • 볼륨 연결 : docker run -d -p 8080:80 -v myVolume:/user/share/nginx/test

bind mount

도커 볼륨 방식과 유사하지만, 호스트 특정 파일 시스템의 디렉토리에 마운트한다.

도커가 관리하는 디렉토리가 아닌, 호스트 시스템의 파일이나 디렉터리가 컨테이너에 마운트되며 호스트 시스템의 절대 경로가 참조되는 방식이다. 단점은 도커의 관리없이 호스트 디렉터리와 마운트를 하다 보니 컨테이너에서 호스트의 파일 시스템에 접근하여 컨테이너에 지정된 파일이 아닌 다른 파일을 삭제하거나 수정할 수 있게된다. 호스트 시스템의 비 docker 프로세스에 영향을 줄 수 있고 보안에도 영향을 미칠 수 있다.

  • 어떤 경우에 bind mount를 사용할까?
    • 로컬에서 개발할 때, git clone하고 작업을 진행함으로, 바인드 마운트를 이용해서 해당 디렉터리를 컨테이너의 특정 경로에 마운트해주면 코드를 변경할 때마다 변경 사항을 실시간으로 컨테이너를 통해 확인할 수 있다. 컨테이너를 통해 변경된 부분도 현재 작업 디렉터리에도 반영이 되기 때문에 편리하다는 장점이 있다.

tmpfs mount

리눅스 환경에서만 가능하며 볼륨을 메모리에 저장한다.

컨테이너 내부에 저장된 볼륨을 호스트의 파일 시스템이 아닌, 메모리에 저장하는 방식으로 리눅스에서 도커를 실행하는 경우에만 사용할 수 있는 기능이다. 호스트 시스템이나 컨테이너 내에서 데이터를 유지하지 않으려는 경우에 적합하다. 많은 양의 비 영구 상태 데이터를 작성해야 할 때 컨테이너의 성능을 보호하기 위한 것일 수 있다.

참고 : https://bentist.tistory.com/79

상세 설정들은 docker compose에서 다룬다.

Port 설정

port forwarding

Host와 Conainer는 독립된 포트를 가져서 바인딩을 해줘야한다.

  • docker run -p <호스트 포트>:<컨테이너 포트>/<protocol> [이미지]
    • 호스트 포트 : 호스트 시스템에서 사용되는 포트 번호
    • 컨테이너 포트 : 컨테이너 내에서 사용되는 포트 번호
    • 프로토콜 : 프로토콜 유형. udp,tcp,stcp 등등
    • (예제)docker run --name engine -p 80:8080 httpd
    • 호스트 80포트랑 도커 컨테이너 8080이랑 연결해주는 것. 외부에서 80포트를 사용하여 요청을 날리면된다.

상세 설정들은 docker compose에서 다룬다.

Network 1(docker)

Docker 컨테이너는 격리된 환경에서 돌아가기 때문에 다른 컨테이너와 통신이 불가능
하지만 여러 개의 컨테이너를 하나의 도커 네트워크에 연결시키면 서로 통신이 가능

  • 종류
    • bridge(많이 사용) : 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 소통할 수 있도록 해줌
    • host : 컨터이너를 호스트 컴퓨터와 동일한 네트워크에서 컨테이너를 돌리기 위해서 사용
    • overlay : 여러 호스트에 분산되어 돌아가는 컨테이너들 간에 네트워킹을 위해서 사용

상세 설정들은 docker compose에서 다룬다.

Network 2(docker compose)

아래 docker compose먼저 보기

기본적으로 docker compose는 하나의 디폴트 네트워크에 모든 컨테이너를 연결한다. 디폴트 네트워크의 이름은 docker-compose.yml가 위치한 디렉터리 이름 뒤에 _default가 붙는다.
ex) common/docker-compose.yml에서 docker-compose up을 실행하였다면, 디폴트 네트워크의 이름은 common_default 이다.
docker compose로 실행된 컨테이너는 디폴트같은 네트워크에 위치한다고 보면 된다. 만약에 docker compose를 사용하지 않고 단일 컨테이너들을 같은 네트워크로 묶고싶다면 네트워크를 생성해서 설정해주는 작업이 필요하다.

컨테이너간 통신

디폴트 네트워크 안에서 컨테이너간 통신은 서비스 이름이 호스트명으로 사용된다.
ex) builder,engine...

커스텀 네트워크

디폴트 네트워크 뿐만 아니라 다른 네트워크도 추가가 가능하다.

명령어

  • 네트워크 목록 : docker network ls
  • 컨테이너간 통신 확인 : docker-compose exec back ping front

docker compose

다중 컨테이너 Docker 애플리케이션을 정의하고 실행하기 위한 도구.
여러개의 컨테이너로부터 이루어진 서비스를 구축, 실행하는 순서를 자동으로 하여 관리를 간단하게 하는 것으로, 여러개의 컨테이너 설정 내용을 하나의 yaml 파일에 모아서 사용한다. 따라서 위에서 보았던 포트,네트워크, 볼륨 설정등을 yaml안에서 모두 작성가능하다.

docker file vs docker compose

도커파일을 사용하여 여러 컨테이너들을 띄어 하나의 플랫폼을 구축할 수도 있다. 하지만 컨테이너 수가 많다면 굉장히 귀찮은 작업일 것이다.
반면 compose 파일을 한번 작성해 둔다면, 한번의 명령으로 여러 컨테이너를 생성할 수 있다.
그리고 compose파일 내부에서 도커파일을 활용하여 빌드가 가능하다.

summary

이런 컨테이너 각각을 모아서 한번에 빌드하는 것이 compose이다.
단일 명령을 사용하여 모두 실행 또는 종료한다.

주요 명령어

up

이미지 빌드 & 컨테이너 실행

  • docker compose up -d
    • 네트워크 설정
    • 볼륨 생성
    • 이미지 풀
    • 이미지 빌드
    • 컨테이너 실행

down

실행중인 서비스를 삭제한다.
컨테이너와 네트워크를 삭제하며, 옵션에 따라 볼륨도 같이 삭제한다.

  • docker compose down
    • -v : 볼륨도 삭제

start,stop

컨테이너를 시작/종료

  • docker compose start
    • docker ps : 구동중인 컨테이너 리스트
    • docker ps -a : 모든 컨테이너 리스트

logs

output으로 나온 log들을 확인할 때 사용한다.

  • docker compose logs
    • -f : 실시간

.env 파일

docker compose자체를 여러환경에서도 사용할 수 있다.
각 실행환경에 따라 동적으로 변수를 담는 파일을 가질 수 있다.
기본적으로 up을 한 상태에서 .env파일을 찾아 내부에 있는 값을 환경 변수로 사용한다.

# 환경변수 파일
$ cat .env 
TAG=v1.5

# compose 파일
$ cat docker-compose.yml
version: '3'
services:
  web:
    image: "webapp:${TAG}"$

작성법 & 예시

기본적으로 docker-compose.yml파일을 설정 파일로 사용하는데 일반적으로 프로젝트 최상위 디렉토리에 위치시킨다.

간략 예시

version: "3.5"
services:
    # 1컨테이너 설정
    # 2컨테이너 설정
networks:
  # 네트워크 설정
volumes:
  # 볼륨 설정

예시 by 검색



version: "3.8"
services:
    //1. 빌더 컨테이너
    builder:
        //build를 통해 도커파일 경로(context),지정(dockerfile). 도커파일에서 사용하는 환경변수(.env파일)를 파라미터(args)로 지정
        build:
            context: .
            dockerfile: builder.Dockerfile
            args:
                USER_UID: ${USER_UID}
                USER_GID: ${USER_GID}
                DOCKER_UID: ${DOCKER_UID}
        user: "root"
        //컨테이너 안에서 작동하는 명령 지정. 어떤 프로그램을 이용하여 실행해야 하는지를 지정하는것으로 필수이며, 컨테이너가 꺼지는 현상을 방지한다.
        command: /bin/sh -c "sleep infinity"
        container_name: choi-dev
        working_dir: /workspace
        //2가지 방법(volume vs bind mount)
        volumes:
            - type: volume
              source: choi
              target: /home/vscode/.vscode-server
            - type: volume
              source: vscode-server-insiders-choi
              target: /home/vscode/.vscode-server-insiders
            - type: bind
              source: /var/run/docker.sock
              target: /var/run/docker.sock
            - type: bind
              source: ../
              target: /workspace
            - type: bind
              source: ~/.m2
              target: /home/vscode/.m2
            - type: bind
              source: ~/ent
              target: /ent
        //커스텀 네트워크 설정
        networks:
            - choi-net
    //2. vespa 컨테이너
    //image를 통해 이미지를 직접 빌드
    vespa-choi:
        image: engine:7.594.36
        container_name: choi
        hostname: choi-net
        //포트 포워딩 : 호스트와 컨테이너 포트를 바인딩. 컨테이너의 target포트와 호스트의 published 포트와 연결해준다.
        ports:
            - target: 19071
              published: 19072
              protocol: tcp
              mode: host
            - target: 8080
              published: 9091
              protocol: tcp
              mode: host
        //마운트할 볼륨 명 : 컨테이너 내부 경로
        volumes:
           - choi-data:/opt/engine/var
           - choi-logs:/opt/engine/logs
           - ~/ent:/ent
           - ~/payco/default-env.txt:/opt/engine/conf/engine/default-env.txt
        networks:
           - choi-net

//데이터 볼륨 정의
volumes:
    server-choi:
    vscode-server-insiders-choi:
    choi-data:
    choi-logs:

//bridge(많이 사용) : 하나의 호스트 컴퓨터 내에서 여러 컨테이너들이 서로 소통할 수 있도록 해줌
networks:
    choi-net:
        driver: bridge

참고

https://meetup.toast.com/posts/277

profile
Search & Backend Engineer

0개의 댓글