[Docker] Docker Compose 환경 구축, AWS EC2 도커 구축 실습

2020. 12. 9. 02:55Docker

1. Docker Compose

1) Docker Compose

일반적인 시스템은 단일 애플리케이션으로 구동하지 않는다. 여러 개의 애플리케이션이 서로 의존성 있게 구성되어 시스템이 이뤄져 있다. 따라서 하나의 컨테이너가 하나의 애플리케이션을 담당한다고 하면, 여러 개의 컨테이너가 필요하다. 이때 필요한 기술이 Docker Compose이다. Docker Compose는 YAML 포맷으로 작성되며 여러 개의 컨테이너의 실행을 한 번에 관리를 할 수 있게 해준다.

 

Docker Compose 파일에는 기본적으로 version, service (image, ports)로 구성되어 있다. version은 docker-compose.yml 파일을 해석하기 위한 문법 버전(3은 안전한 버전)을 뜻한다. service를 구성할 때에는 서비스명을 정의하고, 그 서비스의 이미지와 포트를 정의해준다.

# 버전 지정
version: "3"

# 서비스 정의
services:
  webserver:
    image: ubuntu
    ports:
      - "80:80"
    networks:
      - webnet

  redis:
    image: redis
    networks:
      - webnet

# 네트워크 정의
networks:
  webnet:

# 데이터 볼륨 정의
volumes:
  data-volume:
// '-d' 옵션을 붙일 경우 백그라운드로 실행
docker-compose up

// 컨테이너 종료
docker-compose down

예시 1)

version: '3.7'

services:
  web:
    image: nginx
    ports:
      - 80:80/tcp
  
  database:
    image: mariadb
    ports:
      - 3306:3306
    volumes:
      - ./data:/var/lib/mysql # 컨테이너에 데이터 저장할 경우
      - /Volume/Data:/var/lib/mysql # 호스트 컴퓨터에 데이터를 저장할 경우
    enviroment:
      MYSQL_ROOT_PASSWORD: [비밀번호]
      TZ: Asia/Seoul

예시 2) [참고] www.44bits.io/ko/post/almost-perfect-development-environment-with-docker-and-docker-compose

version: '3'

services:
  db:
    image: postgres
    volumes:
      - ./docker/data:/var/lib/postgresql/data
    environment:
      - POSTGRES_DB=sampledb
      - POSTGRES_USER=sampleuser
      - POSTGRES_PASSWORD=samplesecret
      - POSTGRES_INITDB_ARGS=--encoding=UTF-8

  django:
    build: # Dockerfile을 이용한 이미지 빌드
      context: .
      dockerfile: ./compose/django/Dockerfile-dev
    environment:
      - DJANGO_DEBUG=True
      - DJANGO_DB_HOST=db
      - DJANGO_DB_PORT=5432
      - DJANGO_DB_NAME=sampledb
      - DJANGO_DB_USERNAME=sampleuser
      - DJANGO_DB_PASSWORD=samplesecret
      - DJANGO_SECRET_KEY=dev_secret_key
    ports:
      - "8000:8000"
    command: 
      - python manage.py runserver 0:8000
    volumes:
      - ./:/app/

※ version의 정보는 깃허브(github.com/docker/compose/releases?after=1.22.0)에서 확인할 수 있다.

 

 

 

2. AWS EC2 인스턴스 도커 구축

1) EC2 인스턴스 생성

인스턴스 생성

2) 도커 설치

sudo yum -y upgrade
sudo yum -y install docker
docker -v

3) 도커 실행 및 사용자 추가

도커를 실행하고 사용자인 ec2-user를 그룹에 추가해준다.

sudo service docker start
sudo usermod -aG docker $USER

4) Docker Compose 설치

깃허브(github.com/docker/compose/releases/)에 공개된 가장 최신 버전을 찾아 curl을 이용하여 설치해주고 실행 권한을 추가해준다.

sudo curl -L https://github.com/docker/compose/releases/download/1.27.4/docker-compose-`uname -s`-`uname -m` | sudo tee /usr/local/bin/docker-compose > /dev/null
  
sudo chmod +x /usr/local/bin/docker-compose
sudo ln -s /usr/local/bin/docker-compose /usr/bin/docker-compose
docker-compose -v

Docker Compose 깃 허브

5) Docker Machine 설치

Docker Machine은 가상 환경이나 클라우드 등에서 호스트OS의 커맨드만으로 도커를 사용하기 위한 가상 환경을 생성해주고 관리할 수 있는 기능을 제공한다. 즉, 원격 시스템에서 도커 호스트를 프로비저닝하고 관리할 수 있는 기능을 갖추고 있다. 각 OS마다 설치하는 명령어가 다르니 주의해야한다.

 

깃 허브(github.com/docker/machine/releases/)에 공개된 가장 최신 버전을 찾아 인스턴스에 설치해준다.

- Mac OS

base=https://github.com/docker/machine/releases/download/v0.16.2 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/usr/local/bin/docker-machine &&
chmod +x /usr/local/bin/docker-machine

docker-machine -v

- Linux

base=https://github.com/docker/machine/releases/download/v0.16.2 &&
curl -L $base/docker-machine-$(uname -s)-$(uname -m) >/tmp/docker-machine &&
sudo install /tmp/docker-machine /usr/local/bin/docker-machine

- Windows (Git Bash)

base=https://github.com/docker/machine/releases/download/v0.16.2 &&
mkdir -p "$HOME/bin" &&
curl -L $base/docker-machine-Windows-x86_64.exe > "$HOME/bin/docker-machine.exe" &&
chmod +x "$HOME/bin/docker-machine.exe"

Docker Machine 깃 허브

6) Docker Machine AWS 드라이버 사용

Access Key와 Secret Key는 AWS의 CLI 도구나 API를 사용할 때 인증을 위하여 사용되는 수단이다. Access Key와 Secret Key를 발급받기 위해서는 AWS 콘솔에서 상단 우측의 자신이 이름으로 된 버튼을 클릭하고 '보안 자격 증명'을 클릭한다. 이 후 Access Key를 발급받고 생성된 키를 이용하여 인스턴스에 등록해준다.

aws configure
AWS Access Key ID [None]: [your-AWS-Access-Key-ID]
AWS Secret Access Key [None]: [your-AWS-Secret-Access-Key]
Default region name [None]: ap-northeast-2 
Default output format [None]: 

※ AWS 계정의 Access Key와 Secret Key를 가지고 사용하게 된다면 AWS의 모든 권한을 획득하게 되는 것으로 IAM User를 생성하고 그에 따라 권한을 제한할 것을 권장한다. 또한 Access Key와 Secret Key를 가진다면 AWS의 자원을 제어할 수 있으므로 노출되지 않도록 특별히 신경 써야 한다.


[참고] AWS - Practice - Practitioner IAM

[참고] docs.aws.amazon.com/ko_kr/general/latest/gr/aws-access-keys-best-practices.html

7) Docker Machine을 이용한 EC2 인스턴스 노드 생성

EC2 인스턴스 노드 생성을 하기 위해서는 Access Key와 Secrete Key가 등록되어있어야 가능하다. (노드 생성할 때 시간 소요)

docker-machine create --driver amazonec2 [노드명]
docker-machine create --driver amazonec2 aws-node1
docker-machine create --driver amazonec2 aws-node2
docker-machine create --driver amazonec2 aws-node3

docker-machine ls

8) Docker Swarm (미해결)

도커에는 클러스터링 기능을 제공하는 Swarm 모드가 있다. Swarm 모드를 이용하여 여러 개의 컨테이너를 멀티 호스트 환경에서 작동시키고, 그 컨테이너를 모아 하나의 명령으로 조작할 수 있다.

 

생성한 노드중 하나를 Manager, 나머지는 Worker로 설정해준다. 각 노드의 IP는 'docker-machine ls' 명령으로 확인할 수 있다.

docker-machine ssh aws-node1
sudo docker swarm init --advertise-addr [Manager IP]

Manager로 설정한 결과에 나온 명령어를 이용하여, 나머지 노드에 접속해 worker로 설정한다. 이를 위해 2377 포트가 열려 있어야한다.

docker swarm join --token SWMTKN-1-0qukebnsbmy21nawry6w1qkwt06wjtrobpkrvwbc28q8yaz3er-emo4ys4wbdbn7sggrvw1lmjn8 100.26.32.126:2377

Worker 설정을 하면서, 'Error response from daemon: Timeout was reached before node joined. The attempt to join the swarm will continue in the background. Use the "docker info" command to see the current swarm status of your node.' 문제를 해결 못했습니다.

 

구글링 결과, Swarm을 설정할 때, IP와 포트번호를 지정하면 기본값으로 2377 포트가 지정되며, 같은 내부망에 없을 경우에 '--advertise-addr [퍼빌릭 IP]' 옵션을 이용하여 제작하고, 2377 포트만이 아닌 다른 포트 방화벽을 허용해주어야 한다고 합니다. (2376은 docker-machine 포트)

 

  • 2377(TCP) : 클러스터 매니지먼트(스웜 조인과 같은)에서 사용
  • 7946(TCP/UDP) : 노드간 통신
  • 4789(UDP) : 오버레이 네트워크 간 트래픽 통신

구글링의 힘을 빌려 AWS 보안 그룹에서 포트 허용, 메인 인스턴스에서 iptables, firewall-cmd 등 다양한 설정을 시도하였으나 동일한 문제가 발생함을 확인할 수 있었습니다. 혹시 해결방안에 아시는 분이 계시다면 댓글부탁드립니다ㅠ

 

아래의 참고 링크는 다른 블로그의 Docker Swarm 구축 방법입니다.

[참고] www.skyer9.pe.kr/wordpress/?p=1416


9) 서비스 구성 (미해결) - Docker Swarm이 구축되었다는 전제하에 가능

Manager에서 서비스를 구축한다.

sudo docker service create --name web httpd
sudo docker service ls
sudo docker service ps web

이 후 서비스를 복제하여, Docker Swarm으로 노드가 잘 분산이 되었는지 확인한다.

sudo docker service scale [서비스명]=[복제수]
sudo docker service scale web=3
sudo docker service ps web

분산된 서비스를 지울 경우 'rm' 명령으로 쉽게 해결할 수 있다.

sudo docker service rm [서비스명]

그 외에 시도할 수 있는 항목은 아래의 링크를 참고하면 된다.

 

[참고] megazonedsg.github.io/1-Make-Docker/

 

- 서비스 Rolling Test

  • Update할 서비스 생성
  • 서비스 Update
  • Update하기 전 상태로 서비스 Rollback

 

- 서비스 상태 전환

  • Drain 상태로 전환
  • Down 상태로 전환

- 고가용성 테스트

  • Worker 노드 신분 상승
  • Leader 노드 Kill
  • Manager 노드 Kill
  • Manager 노드 3개 생성 및 Kill
  • Force 옵션으로 강제 균형 조정

 

 

 

3. Amazon Elastic Container Service

직접 인스턴스에 도커를 설치하여 운영하는 것이 아닌 Amazon에서 지원해주는 ECS 서비스를 활용해보는 것도 좋다.

 

[참고] docs.aws.amazon.com/ko_kr/AmazonECS/latest/developerguide/docker-basics.html

728x90