도커 컴포즈
이는 간단하게 docker-compose.yml YAML파일을 통해서 명시적으로 관리할 수 있게 도와줍니다. 프로젝트 단위로 격리된 환경을 제공할 수도 있고, 프로젝트 단위에서 도커 네트워크와 볼륨도 관리가 가능하게 됩니다. 그리고 서비스들간의 의존성도 손쉽게 관리할 수 있다는 장점이 있게 됩니다.
그리고 서비스 S1이 S2를 호출할 때, 내부 도메인을 사용하면 좋을것 입니다. 이를 위해서 저희는 이전에 bridge network를 통해서 net_alias설정을 통해서 진행해 주었었습니다. 도커 컴포즈에서는 각각의 서비스명으로 해당 서비스를 네트워크 상에서 호출할 수 있습니다. 이를 서비스 디스커버리라고 합니다.
또한 컨테이너의 수평 확장이 쉽게 되는데, 만약 웹서비스를 하는 서비스를 S1이라고 하면 이를 수평적으로 확장이 용이하게 됩니다.
프로젝트 / 서비스 / 컨테이너
이제 docker-compose.yml은 프로젝트를 명세하는 파일이라고 볼 수 있습니다. 그리고 그 안에 services라는 키가 있게 됩니다. 프로젝트 안에 여러 서비스를 명시하게 됩니다. 그리고 서비스 하나당 이미지를 이용해서 빌드하게 됩니다.
서비스는 말 그대로 도커 컴포즈에서 컨테이너를 관리하기 위한 단위이며 scale을 통해서 서비스 컨테이너의 수를 확장 가능하게 됩니다.
docker-compose.yml
docker-compose파일은 version, services, networks, volumes총 4개의 최상위 옵션을 가지고 있습니다. 여기서 우리는 version을 먼저 볼 필요가 있습니다. 현재 기준으로 3버전이 최신버전입니다. docker-compose는 가능한 최신 버전의 docker-compose를 사용하기를 권장하고 있습니다. 왜냐하면 버전 3부터는 Docker Swarm과 호환되기 때문입니다.
Docker Swarm이란 Kubernetes와 동일하게 클러스터를 형성하여 컨테이너를 관리하는 컨테이너 오케스트레이션 시스템입니다. 다만 인기를 끌지못했습니다. 따라서 docker-compose.yml파일을 작성할 때, 이게 docker swarm에서 사용되는 것인지 잘 봐야 합니다.
https://docs.docker.com/compose/compose-file/#deploy
그리고 servies는 프로젝트 내에 구성되는 여러 서비스를 subkey들을 통해서 관리할 수 있습니다. 또한 networks, volumes는 프로젝트마다 독립되어 존재하게 됩니다. 따라서 프로젝트에서 사용할 docker volume은 volumes키에 적어주면 됩니다. 그리고 프로젝트 내에서 사용할 네트워크 목록은 netowkrs키를 통해 명시해주면 됩니다.
또한 networks의 경우 default라는 이름으로 기본 네트워크가 bridge모드로 생성이 됩니다.
실습
바로 이전에 배운 개념을 토대로 실습을 진행해 보도록 하겠습니다.
우선 기존에 작성한 Dockerfile을 보도록 하겠습니다. python:3.7-alpine을 사용하는 것을 보실 수 있습니다. 그리고 WORKDIR도 설정해주고 환경변수도 주입해주고, alpine의 패키지 매니저로 필요한 패키지도 설치해 주었습니다. 또한 의존성도 COPY해주고 최종적으로 flask서버를 실행했습니다.
또한 우리가 빌드할 Flask서버는 위와 같습니다. 여기에서는 redis client도 사용하였는데, 캐싱을 위한 컨테이너를 하나 더 만들기 위함입니다.
또한 docker-compose.yml파일입니다. 버전을 맨 위에 명시하고 우리는 web, redis라는 서비스를 만들어 주었습니다. web service는 flask web service이고 build 파일은 위에서 알아본 Dockerfile을 .로 참조해줍니다. 그리고 port는 5000번을 사용해 주었습니다.
또한 redis는 그냥 redis:alpine이미지를 활용해 주었습니다. 이제 docker compose up명령어를 통해 진짜 컨테이너를 구동해보도록 하겠습니다.
빌드가 순차적으로 진행됩니다. 그리고 맨 마지막에 유심해서 봐야할 것이 있습니다. 우리는 network는 명시하지 않았지만, build_default네트워크가 생성되었습니다. build는 프로젝트 디렉토리 이름입니다.
그리고 build-web-1, build-redis-1컨테이너가 생성된 것을 보실 수 있습니다. 이름 짖는 법은 딱 센스있게 이해합시다~
또한 docker-compsoe에 -p옵션을 주면 프로젝트 명을 바꿀 수도 있고, -d를 주면 데몬으로 백그라운드에서 동작하게 할 수도 있습니다.
또한 이제 docker-compose의 프로젝트 리스트를 볼 수 있고, -a옵션을 주어 중단된 프로젝트도 볼 수 있게 됩니다.
docker-compose 명령: 실행/종료
이를 실습하기 위해, wordpress프로젝트로 이동했습니다. 여기에서의 docker-compose.yml을 보게되면, 여기에서는 version, services, volumes, networks키워드가 다 있는 것을 보실 수 있습니다. volumes는 db라는 이름으로 db서비스에 /var/lib/mysql과 마운트 했습니다. 그래고 networks로는 wordpress라는 이름으로 db, wordpress에 지정해주었습니다.
이제 이를 docker-compose up -d해보겠습니다.
그럼 성공적으로 docker-compose up이 끝나게되고, Network로는 wordpress_wordpress가 생성되게 됩니다. 그리고 Volume도 wordpress_db가 생성됩니다. 접두사는 프로젝트 이름인거 아시죠? 그 외에도 wordpress-db-1, wordpress-wordpress-1서비스 컨테이너가 생성되는 것을 보실 수 있습니다.
그리고 이제 생성한 docker-compose 프로젝트를 docker-compose down을 통해 삭제해 보겠습니다. 그냥 아무 옵션도 주지 않게되면 volume은 삭제하지 않게됩니다. volume까지 싹다 삭제하고 싶다면 docker-compose down에 -v옵션을 주면 됩니다.
docker-compose 명령어: 서비스 확장
docker-compose에서 수평확장을 하기위해서는 --scale옵션으로 [ 프로젝트 이름 ] = 개수 형식으로 입력해 주어야 합니다.
이번에는 build프로젝트의 web서비스를 scale out해보도록 하겠습니다.
간단히 scale out이 되는 것을 보실수 있습니다. 이제 진짜 잘 동작하는지 ec2 publicIP로 접속해 보도록 하겠습니다.
sclae out도 잘 된 것을 보실 수 있습니다.
docker-compose 명령어
우선 logs명령어로 프로젝트의 로그정보를 확인할 수 있습니다.
그리고 -f옵션을 주면 스트리밍 형식으로 확인할 수도 있습니다.
또한 docker-compose events로 실시간 이벤트를 스트리밍 형식으로 확인할 수도 있습니다.
그 외에도 docker-compose images로 프로젝트에서 사용된 이미지 목록을, ps로 컨테이너 목록을 확인할 수 있습니다.
또한 top명령어로 프로젝트 안에서 사용하는 프로세스 목록을 확인할 수 있습니다.
추가 주의사항
depends_on keyworkd가 있습ㅂ니다. 이는 느낌이 오겠지만 컨테이너가 실행되는 순서를 지정해줄 수 있습니다. db컨테이너가 띄워지고 wordpress서비스가 띄워질 수 있게끔 말이죠, 다만 주의해야할 점이 있습니다. 이는 앞선 서비스가 준비완료 되었음을 보장하지는 않습니다. 따라서 준비완료되었는지 체킹하는 스크립트를 작성해서 계속 체크해주어야 합니다.
주요 사용 목적
이제 마지막으로 docker-compose를 왜 사용하는지 중요한 이유에 대해 설명해보도록 하겠습니다. 기존에 협업을 할 때, 깃에서 프로젝트를 다운받는다고 해 봅시다. 그런데 해당 프로젝트가 외부 의존성 서비스를 많이 사용합니다. 캐시 서비스로 Redis, 디비 서비스로 MySQL, 메세지 큐 서비스로 Kafka를 사용한다고 해 봅시다.
이렇다면 위와같은 의존성 서비스를 로컬 환경에 구축해야합니다. 참여하는 프로젝트 수가 많을 수록 이러한 외부 의존성 서비스의 관리가 어렵게 됩니다. 그런데 compose파일을 프로젝트와 같이 관리하게 된다면, 해당 프로젝트에 대한 의존성을 docker-compose를 띄우는 것으로 끝낼 수 있게 됩니다.
또한 CI/CD파이프 라인에서 격리된 테스트 환경을 구축할 수 있으며, 테스팅도 진행ㄹ할 수 있게 할 수 있습니다.
마지막으로 단일 호스트 내 컨테이너를 선언적으로 관리할 수 있다는 점입니다.
'DevOps > AWS Architecture' 카테고리의 다른 글
[ Docker && Kubernetes ] - 쿠버네티스를 이용한 컨테이너 오케스트레이션: 쿠버네티스 소개 (0) | 2022.09.05 |
---|---|
[ Docker && Kubernetes ] - 도커 컨테이너 다루기:도커 컴포즈를 이용하여 Grafana_MySQL 구성 (0) | 2022.09.04 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기:도커 데몬 디버깅 (0) | 2022.09.04 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기:이미지 경량화 전략 (0) | 2022.09.04 |
[ Docker && Kubernetes ] - 도커 컨테이너 다루기:AWS ECR 저장소 이용 (0) | 2022.09.04 |