Programming-[Infra]/Docker

도커 교과서(엘튼 스톤맨, 심효섭) - 6. 도커 컴포즈, 스케일 관리 및 환경설정

컴퓨터 탐험가 찰리 2023. 3. 23. 10:04
728x90
반응형

1. 도커 컴포즈

도커 컴포즈는 YAML 파일로 작성한다. 이 파일은 애플리케이션을 구성하는 각 컴포넌트(컨테이너)가 어떤 상태여야 하는지를 기술하는 파일이다.

 

간단한 교재의 도커 컴포즈 파일 스크립트를 살펴보자.

version: '3.7'

services:
  
  todo-web:
    image: diamol/ch06-todo-list
    ports:
      - "8020:80"
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat

 

  • version: 도커 컴포즈 파일의 형식 버전. 각 형식 버전별로 문법이 약간씩 달라질 수 있다.
  • services: 애플리케이션을 구성하는 모든 컴포넌트를 열거하는 부분이다.
  • networks: 서비스 컨테이너가 연결될 모든 도커 네트워크를 열거하는 부분이다. 서비스가 구성될 네트워크의 이름은 app-net이며 이 네트워크는 nat이라는 이름의 외부 네트워크로 연결된다. 이미 앞선 장에서 nat이라는 네트워크를 만들었으므로 external 필드를 주어서 nat 네트워크가 이미 존재하므로 새로 생성하지 말라고 알려주었다.

-> 리눅스 컨테이너는 도커 컴포즈가 네트워크를 대신 관리해주지만, 윈도 컨테이너는 도커를 설치할 때 자동으로 생성되는 기본 네트워크 nat을 사용해야한다. nat으로 이름지어서 만들면 둘 다 잘 작동한다.

 

아래 명령어들을 입력하여 도커 컴포즈로 애플리케이션을 시작해본다.

docker network create nat
cd ./ch07/exercises/todo-list
docker-compose up

ASP.net 코어로 구현된 애플리케이션이 시동된다.

 

localhost:8020에 접속하면 todo-list 애플리케이션이 잘 실행되는 것을 확인할 수 있다. Dockerfile의 스크립트 코드를 통해서가 아니라 docker-compose 파일에 정의된 옵션을 따라서 앱ㅇ르 구동시켰다. 컴포즈 파일을 통해서 애플리케이션의 구성 및 옵션을 상술하고, 이를 github등 형상관리도구를 이용하여 관리하면 따로 애플리케이션의 구성에 대해 설명할 필요가 없게된다.

 

 

2. 여러 컨테이너로 된 애플리케이션 실행하기, 스케일 관리

 

4장에서 학습했던 image-gallery 애플리케이션을 도커 컴포즈로 실행해본다.

 

version: '3.7'

services:

  accesslog:
    image: diamol/ch04-access-log
    networks:
      - app-net

  iotd:
    image: diamol/ch04-image-of-the-day
    ports:
      - "80"
    networks:
      - app-net

  image-gallery:
    image: diamol/ch04-image-gallery
    ports:
      - "8010:80" 
    depends_on:
      - accesslog
      - iotd
    networks:
      - app-net

networks:
  app-net:
    external:
      name: nat

 

app-net 네트워크로 연결하되, 각 이미지별로 설정이 조금씩 다르다. iotd는 REST API이므로 80번 포트를 호스트 컴퓨터의 아무 포트에나 공개하였다. 그리고 image-gallery는 depends_on 옵션을 통해 accesslog와 iotd 서비스에 의존하도록 만들어진다. 이렇게 하면 반드시 accesslog와 iotd가 image-gallery 서비스보다 먼저 실행된다.

 

이번엔 detach 옵션으로 백그라운드로 실행해본다.

docker-compose up --detach

순서대로 실행된다. localhost:8010으로 접속 시 잘 작동한다.

 

 

스케일 아웃

상태가 없는 API 컨테이너는 컨테이너의 개수를 늘려도 상관없다.

docker-compose up -d --sacle iotd=3

 

scale 옵션을 사용해서 iotd의 컨테이너를 3개로 늘릴 수 있다. --tail=1 파라미터는 각 iotd 컨테이너의 마지막 로그를 출력한다. 사이트를 여러 번 새고로침 한 뒤 로그를 출력하는 명령어를 입력해본다.

 

docker-compose logs --tail=1 iotd

 

컨테이너별로 뒤에 '-숫자'가 붙은 것을 볼 수 있다.

 

중단은 아래 명령어로 할 수 있다. 중단된 컨테이너는 메모리나 CPU를 사용하진 않지만, 컨테이너의 파일 시스템은 그대로 유지된다. 다시 시작 명령을 입력하면 기존에 중지되었던 컨테이너가 재기동된다.

docker-compose stop
docker-compose start

 

 

도커 엔진은 도커 컴포즈의 구성을 알지 못한다.

도커 컴포즈로 컨테이너들을 실행한 뒤 도커 명령행으로 직접 애플리케이션을 수행하면 실제 실행되는 애플리케이션과 컴포즈 파일의 내용이 불일치할 수 있다. 앞서 스케일을 늘릴때는 컴포즈 파일을 수정하고 컨테이너들을 완전히 내렸다가 다시 실행시킨 것이 아니라 --scale 옵션을 이용해서 명령행으로 직접 스케일을 늘렸기 때문에 실제 애플리케이션상 iotd 서비스는 3개가 실행되지만, 컴포즈 파일에는 여전히 1개만 실행하는 구성으로 기록되어있다. 이것은 달리말해 도커엔진은 클라이언트에서 실행하는 컴포즈 파일과는 무관하게 명령이 들어오면 실행할 뿐이라는 것이다. 구성에 대한 내용은 컴포즈 파일만 알고 있다.

 

docker-compose down
docker-compose up -d
docker container ls

 

down 부명령으로 컴포즈로 실행한 애플리케이션을 중지하고 컨테이너들을 모두 제거한다. 이 때 external 옵션이 있지 않다면 네트워크와 볼륨도 모두 제거하게 된다. 다시 up 부명령으로 애플리케이션을 실행하면 iotd 서비스는 1개 컨테이너만 작동한다. 즉 명령어로 직접 스케일 아웃한 내용은 컴포즈 파일에 없으므로 1개 컨테이너만 실행된 것이다. 애플리케이션의 구성은 컴포즈 파일에 의존하는 것을 알 수 있다.

 

 

3. 컨테이너간 통신

 

도커도 DNS(Domain Name Service)를 제공한다. 각 컨테이너별로 IP주소가 할당되며 이 주소들은 각 서비스의 이름을 통해 조회할 수 있다. 애플리케이션의 생애주기 동안 컨테이너가 교체되면 IP 주소도 변경된다. 그러나 IP 주소가 변경돼도 애플리케이션에 문제가 없도록 도커에서 DNS를 이용하여 서비스 디스커버리 기능을 제공한다.

 

docker-compose up -d --scale iotd=3
docker container exec -it image-of-the-day-image-gallery-1 sh # 리눅스 컨테이너
docker container exec -it image-of-the-day-image-gallery-1 cmd #윈도우 컨테이너
nslookup accesslog
nslookup iotd
exit

 

iotd 서비스의 컨테이너를 3개로 늘리고 애플리케이션 컨테이너에 접속한 뒤, nslookup으로 accesslog, iotd의 ip 주소를 서비스 이름으로 검색하였다. nslookup은 애플리케이션의 기반이미지에 들어있는 유틸리티다.

 

 

 

4. 도커 컴포즈를 통한 애플리케이션 설정값 지정

 

다음과 같이 postgreSQL 데이터베이스를 활용하는 todo-web 애플리케이션이 있다고 가정해본다. 도커 컴포즈 파일의 예제이다.

services:
  todo-db:
    image: diamol/postgres:11.5
    ports:
      - "5433:5432"
    networks:
      - app-net

  todo-web:
    image: diamol/ch06-todo-list
    ports:
      - "8030:80"
    environment:
      - Database:Provider=Postgres
    depends_on:
      - todo-db
    networks:
      - app-net
    secrets:
      - source: postgres-connection
        target: /app/config/secrets.json

networks:
  app-net:

secrets:
  postgres-connection:
    file: ./config/secrets.json

 

todo-db라는 이름으로 데이터베이스를 정의하였다.

 

todo-web 서비스의 environment로 Database:Provider의 값이 Postgres를 가리키도록 하였다. 이 웹 앱은 Postgres의 기능을 기반으로 동작한다고 설정하고 알려주는 것이다. secrets 값으로 postgres-connection이라는 이름을 갖고 컨테이너 내의 /app/config/secrets.json 파일을 참조하는 비밀값을 지정해주었다. 데이터베이스의 Host, Name, Password 등이 여기에 저장될 것이다.

 

로컬 컴퓨터의 파일을 secret 값으로 지정할 수도 있다.

secrets:
	postgres-connection:
    	file: ./config/secrets.json

보통 실제 서비스에서는 이런 환경설정 정보를 Cloud나 클러스터 환경 같은 곳에 저장해놓고 컴포즈 파일에서 이를 참조하도록 한다. 이렇게 해서 환경설정을 바꿔가면서 애플리케이션을 실행할 수 있을 것이다.

 

 

 

 

도커 컴포즈의 한계

도커 컴포즈는 도커 스웜이나 쿠버네티스 같은 완전한 컨테이너 플랫폼이 아니다. 애플리케이션이 지속적으로 정의된 상태를 유지하도록 하는 기능은 없다. 일부 컨테이너가 오류를 일으키거나 강제로 종료되더라도 docker-compose up 명령으로 애플리케이션의 상태를 원래대로 돌이킬 수 없다.

728x90
반응형