[Infra] 도커(docker)(6) 도커 컴포즈(docker compose)를 활용한 여러 개의 Flask, Nginx 배포
업데이트:
도커(docker)(6) 도커 컴포즈(docker compose)를 활용한 여러 개의 Flask, Nginx 배포
참고링크
참고 링크
- (0)도커의 개념
- (1)도커 설치하기, hello world!
- (2)도커 컨테이너 조작 기초(pull, run, ps)
- (3)도커 이미지 변경 후 저장(commit)
- (4)도커 컨테이너 네트워크
- (5)도커 API 이미지 빌드 및 컨테이너 실행
- (6)도커 컴포즈를 활용한 여러 개의 Flask, Nginx 배포
- (7)도커 볼륨을 이용한 데이터 관리
- (1)쿠버네티스 구조
- (2)쿠버네티스 설치
- (3)쿠버네티스 서비스 배포하기
- (4)컨테이너 IP와 파드 IP의 관계
- (5)퍼시스턴트 볼륨 스토리지
1. 개요
1-1. 구조 설계
먼저 이 작업을 하게 된 계기는 두 가지 프로젝트를 동시에 컨테이너로 띄워야해서 이걸 어떻게 해야하나하고 생각해보았습니다.
그래서 처음에 생각한 구조는 위 그림과 같이 ngnix 하나에 두 가지 앱이 물린 상태에서 돌아가는 형태였는데, 위와 같이 만들 경우, 앱 개수가 늘어나면 관리하기 어려워질것 같다는 생각이 들었습니다.
그래서 생각한 것이 위 그림과 같은 구조입니다. nginx 또한 여러 개의 컨테이너로 띄워서 각 앱에 물리게 설정하면 각 프로젝트는 다른 프로젝트에 영향을 받지 않고 돌아갈수 있고, 수정 배포가 용이할 것이라고 생각했습니다.
1-2. 폴더 구성
실습 폴더는 위와 같이 생겼습니다. kpt_supply_chain, kpt_intelli_design 두 프로젝트를 컨터이너화 해서 띄울 예정입니다.
2. 도커 컴포즈(docker compose)
2.1. 도커 컴포즈(docker compose)란?
도커 컴포즈(docker compose)는 여러 개의 컨테이너를 한번에 관리할 수 있는 도구입니다. 도커 컴포즈를 안쓰고 컨테이너를 올린다면 각각의 컨테이너를 일일히 올려야하고, 연동시켜야할 컨테이너가 있으면 손수 연동시켜줘야하는데, 도커 컴포즈를 쓰면 이런 작업들을 한번에 할수 있습니다.
2.2 도커 컴포즈(docker compose) 설치(마지막 수정 2022.12.15)
도커 컴포즈(docker compose)는 설치 관련 매뉴얼을 보고 설치했습니다. 저는 우분투에 설치했습니다. 다음은 홈페이지 상에 나와있는 코드입니다.
$ mkdir -p ~/.docker/cli-plugins/
$ curl -SL https://github.com/docker/compose/releases/download/v2.14.0/docker-compose-linux-x86_64 -o ~/.docker/cli-plugins/docker-compose
$ chmod +x ~/.docker/cli-plugins/docker-compose
$ docker compose version
Docker Compose version v2.14.0
참고로 도커 컴포즈는 버전1이냐 2냐에 따라 명령어 실행 방식이 조금 다릅니다. 이 점 주의해주세요.
3. 프로젝트1-kpt_intelli_design
3.1. kpt_intelli_design 폴더
다음 파일은 main.py 파일 입니다.
from urllib.parse import unquote
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
args = request.json
print(args)
sentence = args['review']
sentence = urllib.parse.unquote(a)
return sentence
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5002)
다음은 Dockerfile 입니다.
FROM python:3.8.5
WORKDIR /kpt_intelli_design
COPY . .
RUN python -m pip install --upgrade pip
RUN pip install -r requirements.txt
RUN pip install --upgrade protobuf==3.20.0
# server
CMD main:app gunicorn --bind 0.0.0.0:5002 --
다음은 requirements.txt 파일입니다.
Flask==2.0.1
gunicorn
3.2. nginx 폴더
다음은 Dockerfile 입니다.
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d/
CMD ["nginx", "-g", "daemon off;"]
다음은 default.conf 파일입니다.
upstream kpt_int{
server kpt_intelli_design:5002;
}
server{
listen 8002;
server_name 10.1.55.220;
location /{
proxy_pass http://kpt_int;
}
}
위 코드 처럼 upstream을 이용해 짜거나 다음 코드처럼 짤수도 있습니다.
server{
listen 8002;
server_name 10.1.55.220;
location /{
proxy_pass http://kpt_intelli_design:5002;
}
}
만약 타임아웃을 설정하고 싶다면 다음과 같이 default.conf 파일을 만들어줍니다.
upstream kpt_int{
server kpt_intelli_design:5002;
}
server{
listen 8002;
server_name 10.1.55.220;
location /{
proxy_read_timeout 3000;
proxy_connect_timeout 3000;
proxy_send_timeout 3000;
send_timeout 3000;
proxy_pass http://kpt_int;
}
}
만약 upstream을 사용하고 싶지 않다면 다음과 같이 작성합니다.
server{
listen 8002;
server_name 10.1.55.220;
location /{
proxy_read_timeout 3000;
proxy_connect_timeout 3000;
proxy_send_timeout 3000;
send_timeout 3000;
proxy_pass http://kpt_intelli_design:5002;
}
}
참고로 쿠버네티스로 돌릴때는 다음과 같이 작성합니다.
default.conf
server{
listen 8002;
server_name 10.1.55.220;
location /{
proxy_read_timeout 3000;
proxy_connect_timeout 3000;
proxy_send_timeout 3000;
send_timeout 3000;
proxy_pass http://127.0.0.1:5002;
}
}
3.3. docker-compose.yml 파일
다음은 docker-compose.yml 파일입니다. 만약 도커 컴포즈 버전이 v2.27.0 미만이라면 다음과 같이 version 태그를 적어줍니다.
version: "3"
services:
kpt_intelli_design:
build: ./kpt_intelli_design
container_name: kpt_intelli_design
restart: always
expose:
- "5002"
nginx:
build: ./nginx
container_name: nginx-kpt-intelli
restart: always
ports:
- "8002:8002"
depends_on:
- kpt_intelli_design
만약 도커 컴포즈 버전이 v2.27.0 이상이라면 다음과 같이 version 태그를 삭제해줍니다.
services:
kpt_intelli_design:
build: ./kpt_intelli_design
container_name: kpt_intelli_design
restart: always
expose:
- "5002"
nginx:
build: ./nginx
container_name: nginx-kpt-intelli
restart: always
ports:
- "8002:8002"
depends_on:
- kpt_intelli_design
3.4. 빌드 및 실행
$ docker compose up -d --build
...(중략)
[+] Running 3/3
⠿ Network kpt_intelli_design_default Created
⠿ Container kpt_intelli_design Started
⠿ Container nginx-kpt-intelli Started
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd8aad18b4ac kpt_intelli_design_nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp, 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp nginx-kpt-intelli
7504fb5725bf kpt_intelli_design_kpt_intelli_design "/bin/sh -c 'gunicor…" 2 minutes ago Up 2 minutes 5002/tcp kpt_intelli_design
4. 프로젝트2 - kpt_supply_chain
4.1. kpt_supply_chain 폴더
from urllib.parse import unquote
from flask import Flask, request, jsonify
app = Flask(__name__)
@app.route('/test', methods=['POST'])
def test():
args = request.json
print(args)
sentence = args['review']
sentence = urllib.parse.unquote(a)
return sentence
if __name__ == '__main__':
app.run(host='0.0.0.0', port=5001)
다음은 Dockerfile 입니다.
FROM python:3.8.5
WORKDIR /kpt_intelli_design
COPY . .
RUN python -m pip install --upgrade pip
RUN pip install -r requirements.txt
RUN pip install --upgrade protobuf==3.20.0
# server
CMD main:app gunicorn --bind 0.0.0.0:5001 --timeout 3000
다음은 requirements.txt 파일입니다.
Flask==2.0.1
gunicorn
4.2. nginx 폴더
다음은 Dockerfile 입니다.
FROM nginx
RUN rm /etc/nginx/conf.d/default.conf
COPY default.conf /etc/nginx/conf.d/
CMD ["nginx", "-g", "daemon off;"]
다음은 default.conf 파일입니다.
upstream kpt_sup{
server kpt_supply_chain:5001;
}
server{
listen 8001;
server_name 10.1.55.220;
location /{
proxy_pass http://kpt_sup;
}
}
만약 타임아웃을 설정하고 싶다면 다음과 같이 default.conf 파일을 만들어줍니다.
upstream kpt_sup{
server kpt_supply_chain:5001;
}
server{
listen 8001;
server_name 10.1.55.220;
location /{
proxy_read_timeout 3000;
proxy_connect_timeout 3000;
proxy_send_timeout 3000;
send_timeout 3000;
proxy_pass http://kpt_sup;
}
}
4.3. docker-compose.yml 파일
다음은 docker-compose.yml 파일입니다.
version: "3"
services:
kpt_intelli_design:
build: ./kpt_supply_chain
container_name: kpt_supply_chain
restart: always
expose:
- "5001"
nginx:
build: ./nginx
container_name: nginx-kpt-supply
restart: always
ports:
- "8001:8001"
depends_on:
- kpt_supply_chain
4.4. 빌드 및 실행
$ docker compose up -d --build
...(중략)
[+] Running 3/3
⠿ Network kpt_supply_chain_default Created
⠿ Container kpt_supply_chain Started
⠿ Container nginx-kpt-supply Started
실행중인 컨테이너 확인
$ docker container ls
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
dd8aad18b4ac kpt_intelli_design_nginx "/docker-entrypoint.…" 2 minutes ago Up 2 minutes 80/tcp, 0.0.0.0:8002->8002/tcp, :::8002->8002/tcp nginx-kpt-intelli
7504fb5725bf kpt_intelli_design_kpt_intelli_design "/bin/sh -c 'gunicor…" 2 minutes ago Up 2 minutes 5002/tcp kpt_intelli_design
8d527613280d kpt_supply_chain_nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 80/tcp, 0.0.0.0:8001->8001/tcp, :::8001->8001/tcp nginx-kpt-supply
8c822fb89350 kpt_supply_chain_kpt_supply_chain "/bin/sh -c 'gunicor…" 7 minutes ago Up 7 minutes 5001/tcp kpt_supply_chain
컨테이너를 다 지우고 싶다면?
$ docker compose down
[+] Running 4/4
⠿ Container nginx-server Removed
⠿ Container kpt_intelli_design Removed
⠿ Container kpt_supply_chain Removed
⠿ Network work_default Removed