Profile picture

[Docker Compose] Scale 확장

JaehyoJJAng2022년 04월 21일

프로젝트 개요

  • 접속 시 hit count가 증가하는 flask 기반 파이썬 프로젝트
  • redis 연동
  • 스케일 확장을 통한 유연성 테스트

Directory tree

$ tree .

.
├── docker-compose.yml
└── python-app
    ├── Dockerfile
    ├── app.py
    └── requirements.txt

app.py

from flask import Flask
from typing import Optional
import redis

app : Flask = Flask(__name__)
cache : redis.Redis = redis.Redis(host='redis', port=6379)

def get_hit_count() -> int:
    retries = 5
    while True:
        try:
            return cache.incr('hits')
        except redis.exceptions.ConnectionError as exc:
            if retries == 0:
                raise exc
            retries -= 1
            time.sleep(0.5)

@app.route('/')
def hello() -> str:
    count = get_hit_count()
    return 'Hello World! I have been seen {} times.\n'.format(count)

Dockerfile

# Set base image
FROM python:3.8-alpine

# Set working directory
WORKDIR /app

# Set Environment
ENV FLASK_APP=app.py
ENV FLASK_RUN_HOST=0.0.0.0

RUN apk add --no-cache gcc musl-dev linux-headers

# Copy requirements.txt
COPY ./requirements.txt ./requirements.txt

# Install dependencies
RUN pip install --upgrade pip
RUN pip install -r requirements.txt

# Set Container Port
ARG PORT=5000
EXPOSE ${PORT}

# Copy project files
COPY . .

CMD ["flask", "run"]

docker-compose.yml

version: "3.8"
services:
  web:
    depends_on:
      - "redis"
    build: ./python-app
    restart: always
    ports:
      - "5000"
    volumes:
      - "./python-app:/app"
  
  redis:
    image: "redis:alpine"
    container_name: redis

앱 배포

$ docker-compose -p my-project up -d --build
$ docker-compose ls -a

컨테이너 로그 확인

flask 컨테이너 로그

$ docker-compose logs flask

flask-app  |  * Serving Flask app 'app.py'
flask-app  |  * Debug mode: off
flask-app  | WARNING: This is a development server. Do not use it in a production deployment. Use a production WSGI server instead.
flask-app  |  * Running on all addresses (0.0.0.0)
flask-app  |  * Running on http://127.0.0.1:5000
flask-app  |  * Running on http://172.24.0.3:5000
flask-app  | Press CTRL+C to quit
flask-app  | 172.24.0.1 - - [08/May/2023 13:25:32] "GET / HTTP/1.1" 200 -
flask-app  | 172.24.0.1 - - [08/May/2023 13:25:32] "GET /favicon.ico HTTP/1.1" 404 -

redis 컨테이너 로그

$ docker-compose logs redis

redis  | 1:C 08 May 2023 13:24:59.122 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
redis  | 1:C 08 May 2023 13:24:59.122 # Redis version=7.0.11, bits=64, commit=00000000, modified=0, pid=1, just started
redis  | 1:C 08 May 2023 13:24:59.122 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
redis  | 1:M 08 May 2023 13:24:59.123 * monotonic clock: POSIX clock_gettime
redis  | 1:M 08 May 2023 13:24:59.124 * Running mode=standalone, port=6379.
redis  | 1:M 08 May 2023 13:24:59.124 # Server initialized
redis  | 1:M 08 May 2023 13:24:59.126 * Ready to accept connections

도커 컴포즈 목록

  • 도커 컴포즈 활성화 목록 확인
$ docker-compose ls -a

NAME                STATUS              CONFIG FILES
build               running(2)          /Users/jaehyolee/git/fastcampus-devops/docker-practice/08_docker-compose/build/docker-compose.yml

scale 확장하기

my-project 에 속한 도커 컴포즈 프로세스 확인

$ docker-compose -p my-project ps

NAME                IMAGE               COMMAND                  SERVICE             CREATED             STATUS              PORTS
flask-app           my-project-flask    "flask run"              flask               11 seconds ago      Up 11 seconds       0.0.0.0:80->5000/tcp
redis               redis:alpine        "docker-entrypoint.s…"   redis               11 seconds ago      Up 11 seconds       6379/tcp

스케일 확장

$ docker-compose -p my-project down -v # 기존 도커 컴포즈 삭제
$ docker-compose -p my-project up --scale web=3 -d

트러블슈팅

스케일 확장 시 아래 도커 컴포즈 옵션들을 유의하도록 하자

services:
  web:
    container_name: web

위 옵션처럼 container_name 옵션을 준 상태에서는 스케일 확장이 불가능해지기 때문에 해당 옵션은 주석처리하거나 삭제해주어야 한다


services:
  web:
    ports:
      - "80:5000"

위 옵션처럼 ports 옵션에 특정한 호스트 포트를 지정해주게 되면 스케일 확장 시 스케일 된 컨테이너들의 포트 충돌이 일어나므로
포트가 랜덤으로 배정되어 각 스케일된 컨테이너에 지정될 수 있도록 아래처럼 바꿔주어야 한다

services:
  web:
    ports:
      - "5000"

스케일 확장 결과

$ docker-compose -p my-project ps

NAME                IMAGE               COMMAND                  SERVICE             CREATED              STATUS              PORTS
my-project-web-1    my-project-web      "flask run"              web                 About a minute ago   Up About a minute   0.0.0.0:62136->5000/tcp
my-project-web-2    my-project-web      "flask run"              web                 About a minute ago   Up About a minute   0.0.0.0:62135->5000/tcp
my-project-web-3    my-project-web      "flask run"              web                 About a minute ago   Up About a minute   0.0.0.0:62137->5000/tcp
redis               redis:alpine        "docker-entrypoint.s…"   redis               About a minute ago   Up About a minute   6379/tcp

프로젝트 관련 명령어

프로젝트 내 서비스 로그 확인

$ doker-compose -p my-project logs

프로젝트 내 컨테이너 이벤트 확인

$ docker-compose -p my-project events

프로젝트 내 이미지 목록

$ docker-compose -p my-project images

프로젝트 내 컨테이너 목록

$ docker-compose -p my-project ps

프로젝트 내 실행중인 프로세스 목록

$ docker-compose -p my-project top

Loading script...