1. Docker Stack, Swarm, Service의 개념
이때까지 만들어왔던 container는 다음 한계점이 있다.
- 이미지를 새로 배포할때마다 계속 환경설정을 해줘야한다.
- container가 갑자기 꺼지거나 삭제될 수 있다. 만약 꺼지면 자동으로 재부팅이라도 돼야한다.
Docker Stack, Swarm
이런 문제점들을 해결하기 위한 개념이 Stack과 Service이다. Docker Stack은 여러 container들을 생성할 때 필요한 환경설정 정보를 하나의 .yml 파일로 묶어서 관리한다. 따라서 예를 들어 만약 앞서 살펴봤던 djangon-nginx-mariadb container 연결구조를 같은 환경으로 1개 더 배포해야될 상황이라면 Stack에서 자유롭게 갯수를 늘릴 수 있다.
이렇게 scale up되어 여러 container들이 묶인 하나의 서버를 Node라고 부른다. 그리고 이런 Node가 여러 개 모여서 관리되는 것을 Docker Swarm이라는 개념으로 정의한다.
Docker Compose라는 tool도 있다. 그러나 Stack과 달리 배포 용도가 아니라 여러 컨테이너들을 관리하는 용도로 사용한다고 한다.
Docker Service
Service는 각 container들을 묶어서 상태 관리를 해준다. 예를 들어 만약 어떤 container가 갑자기 중단된다면 Docker Service가 해당 container를 auto restart 해준다.
2. Docker Swarm, Stack 생성해보기
Stack용 .yml 파일 생성
docker stack에서 관리하는 모든 컨테이너들의 공통 환경설정값을 .yml 파일로 만들어서 관리할 것이다. 그리고 이런 docker stack 환경설정 파일을 만들기 위해서는 Docker Swarm을 설정해주어야 한다. node가 되는 서버 컴퓨터에서 swarm을 시작한다. 이때까지 localhost가 node가 되도록 했으므로 cmd에서 루트 디렉토리로 이동 후 아래 명령어를 입력하면 된다.
'docker swarm init'
강의에서는 vultr 가상화 서버에 접속해서 /home/djang_course에서 위 명령어를 실행했는데, 이 부분이 nginx.conf 파일이 들어가도록 했던 곳이므로 나는 동일한 원리로 C:\Users\chang\PycharmProjects\pragmatic 위치에서 실행하면 될 것 같다. (꼭 여기서 해야되는건지, 문제는 없는건지는 잘 모르겠다...)
Swarm이 성공적으로 initalized 되고, 해당 node가 manager가 되었음을 알려준다. node들에는 manager node가 있고, 그 외 일반 node가 있다. swarm을 최초로 init한 node가 manager가 되는 것이다.
이제 해당 node의 portainer로 접속하면(새로고침) 기존에는 없던 Stacks, Services, Secrets, Swarm이라는 메뉴가 추가로 생성된 것을 볼 수 있다.
Swarm에 들어가보면 docker desktop이라는 이름, manager 권한으로 swarm이 생성된 것을 볼 수 있다.
그리고 go to cluster visualizer에 들어가보면 swarm에 어떤 node들이 구동하고 있는지 볼 수 있다.
테스트용으로 stack 환경설정 .yml 파일을 만들어보자. 프로젝트의 루트 디렉토리에서 docker-compose.yml 파일을 만들고 아래처럼 작성한다.
pragmatic/docker-compose.yml
version: "3.7"
services:
django:
image: django_image_test:3
ports:
- 8000:8000
docker-compose 3.7 버전을 사용하며, 해당 stack에 포함되는 service는 django_image_test:3 으로 지정해줬다. 테스트용으로 이전 버전 이미지를 지정했다.
Stack 생성, Scale 조절
stacks에서 add stack으로 stack을 만들 수 있다. image를 만들 때와 마찬가지로 upload 방식으로 docker-compose.yml 설정파일을 올려주고 deploy를 하면 된다.
Services에 보면 생성한 stack에 따른 service를 볼 수 있고, Scheduling Mode에서 Scale 버튼으로 scale을 조절할 수 있다. 기본적으로 1개가 생성됬으나, 2개로 늘려보았다.
Containers 화면에서 생성된 2개의 컨테이너를 확인할 수 있었다.
swarm의 cluster visualizer 에서도 container가 확인된다.
3. Stack 설정 파일/Stack 생성
Stack 설정 파일 : docker-compose.yml
이제 기존대로 nginx-django-mariaDB로 구성되는 stack의 통합 환경설정을 해본다. 상기 작성하였던 docker-compose.yml 파일을 알맞게 수정할 것이다.
대부분 내용이 앞서 배웠던 내용들이다. 마치 각 container들에 흩어져있던 설정 정보들을 하나로 모아준 것과 같다고 보면 된다. 주석문을 주로 참고하자.
version: "3.7"
services:
nginx:
image: nginx:1.22.0
networks:
- network
volumes:
- C:\Users\chang\PycharmProjects\pragmatic\nginx.conf:/etc/nginx/nginx.conf #nginx.conf bind volume
# volume 이름:node상 디렉토리 위치
- static-volume:/data/static
- media-volume:/data/media
ports:
- 80:80
django_container_gunicorn: #network로 묶이기 때문에 name-space 정보로 넣어줘야한다. django로 넣으면 안된다.
image: django_image_test:4
networks:
- network
volumes:
- static-volume:/home/inflearn_study_django_pinterest/staticfiles
- media-volume:/home/inflearn_study_django_pinterest/media
mariadb:
image: mariadb:10.5
networks:
- network
volumes:
- maria-database:/var/lib/mysql
environment:
MYSQL_ROOT_PASSWORD: password1234
MYSQL_DATABASE: django
MYSQL_USER: django
MYSQL_PASSWORD: password1234
#상기 선언한 network와 volume들을 변수처럼? 명기
networks:
network:
volumes:
static-volume:
media-volume:
maria-database:
- nginx는 1.22.0 버전으로 이 글을 작성하는 시점에 최신이면서 안정적인 버전으로 명기해주었다.
- 각 volume 및 디렉토리 위치가 헷갈리면 안된다! 노드에서의 경로를 잘 확인하고, 각 container에서의 경로를 cmd에서 docker exec 명령어로 들어가서 직접 확인해보자(경로가 없는 경우 자동으로 재생성되긴 하지만).
Stack 생성
Portainer의 stacks 메뉴에서 docker-compose.yml 파일을 upload 하여 스택을 생성해보자. 아래 그림들처럼 Stack, Services, Containers가 차례대로 생성되는 것을 확인할 수 있다.
Stopped Container가 생성될 수도 있다.
각 Stack, Services, Containers가 정상적으로 생성되었다. 혹시 container가 Stopped State로 여러 개 생성된다면 그것은 container 생성 순서 때문일 수 있다. mariaDB container -> django -> nginx 순서대로 각 container의 base가 되는 container가 생성되야만 그 다음 container가 생성될 수 있는 구조이다. 그런데 예를 들어 docker가 nginx container 부터 생성하여 기반이 되는 django container 연결정보를 못찾는다면 해당 nginx container는 Stopped되고 새로운 nginx Container를 만들면서 다시 django container와 연결을 시도하는 방식이기 때문이다. Stopped된 container가 있다면 "Quick Actions"의 맨 왼쪽, Log 아이콘을 눌러서 무슨 문제가 있었는지 확인해보는 것이 좋다.
마지막으로 localhost:80(포트 생략) 으로 접속 시, 정상적으로 서비스 이용이 가능함을 확인해보자!
참조
1. 작정하고 장고! Django로 Pinterest 따라만들기 : 바닥부터 배포까지-박형석님 인프런 강의