본문 바로가기

클라우드/도커

도커 스웜

반응형

컨테이너를 단일 도커 호스트에 배치하는 것은 쉽다. 그러나 많은 트래픽을 처리하는 시스템들은 대개 여러 컨테이너가 각기 다른 호스트에 배치된다. 

도터 스웜은 여러 도커 호스트를 클러스터로 묶어주는 컨테이너 오케스트레이션 도구의 한 종류다. 이런 컨테이너 오케스트레이션 도구 없이는 도커 호스트 여러 대를 사용하는 확장성 있는 애플리케이션을 만들기가 매우 어렵다. 어느 도커 호스트에 어떤 컨테이너를 배치해야 하는지, 서로 다른 호스트에 위치한 컨테이너 간의 통신은 어떻게 제어하는지 등의 조율을 오케스트레이션 도구 없이 하기 힘들다.

이름 역할 대응하는 명령어
컴포즈 여러 컨테이너로 구성된 도커 어플리케이션을 관리(주로 단일 호스트) docker-compose
스웜 클러스터 구축 및 관리(주로 멀티 호스트) docker swarm
서비스 스웜에서 클러스터 안의 서비스(컨테이너 하나 이상의 집합)를 관리 docker service
스택 스웜에서 여러 개의 서비스를 합한 전체 어플리케이션을 관리 docker stack

여러 대의 도커 호스트로 스웜 클러스터 구성하기

윈도우용/macOS용 도커를 설치하면 호스트가 1대뿐이므로 여러 대의 호스트를 갖추려면 클라우드 서비스 등을 사용해야 한다. 테스트를 위해서는 '도커 호스트 역할을 할 도커 컨테이너를 여러 개 실행하는 방법'인 도커 인 도커(Docker in Docker, dind)라는 기능을 사용해본다. 테스트에서 사용할 컨테이너는 다음 3 종류로 모두 합해 5개다.

- registry * 1 : 도커 레지스트리 역할을 할 컨테이너로, manager 및 worker 컨테이너가 사용하는 컨테이너다. dind환경에서는 외부 이미지를 dind 컨테이너 파일 시스템을 통해 사용할 수 없기 때문에, 외부 도커에 저장된 이미지를 먼저 registry 컨테이너에 등록했다가 여기서 manager 및 worker 컨테이너가 이미지를 받아가도록 한다. 

- manager * 1 : 스웜 클러스터 전체를 제어하는 역할을 한다. 여러 대 실행되는 도커 호스트(worker)에 서비스가 담긴 컨테이너를 적절히 배치한다.

- worker * 3 

docker-compose.yml 파일을 다음과 같이 작성한다. 위의 구조를 컴포즈로 정의한 것이다. 모든 manager 및 worker컨테이너는 registry 컨테이너에 의존한다. 또 도커 레지스트리에는 일반적으로 HTTPS를 사용하지만, 여기서는 HTTP를 사용하기 때문에 이 문제를 해결하기 위해 --insecure-registry registry:5000 값을 줘서 http로도 이미지를 내려받을 수 있게 한다. 

version: "3"
services:
  registry:
    container_name: registry
    image: registry:2.6
    ports:
      - 5000:5000
    volumes:
      - "./registry-data:/var/lib/registry"
  
  manager:
    container_name: manager
    image: docker:18.05.0-ce-dind
    privileged: true
    tty: true
    ports:
      - 8000:80
      - 9000:9000
    depends_on:
      - registry
    expose:
      - 3375
    command: "--insecure-registry registry:5000"
    volumes:
      - "./stack:/stack"
      
  worker01:
    container_name: worker01
    image: docker:18.05.0-ce-dind
    privileged: true
    tty: true
    depends_on:
      - manager
      - registry
    expose:
      - 7946
      - 7946/udp
      - 4789/udp
    command: "--insecure-registry registry:5000"
    volumes:
      - "./stack:/stack"
      
  worker02:
    container_name: worker02
    image: docker:18.05.0-ce-dind
    privileged: true
    tty: true
    depends_on:
      - manager
      - registry
    expose:
      - 7946
      - 7946/udp
      - 4789/udp
    command: "--insecure-registry registry:5000"
    
      
  worker03:
    container_name: worker03
    image: docker:18.05.0-ce-dind
    privileged: true
    tty: true
    depends_on:
      - manager
      - registry
    expose:
      - 7946
      - 7946/udp
      - 4789/udp
    command: "--insecure-registry registry:5000"

 

컴포즈를 실행하면 registry 컨테이너 1대, manager 컨테이너 1대, worker컨테이너가 01번부터 03번까지 3대 총 5대가 실행된다. 

 

 ✘ bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker-compose up -d
WARNING: Found orphan containers (master, slave01) for this project. If you removed or renamed this service in your compose file, you can run this command with the --remove-orphans flag to clean it up.
Pulling registry (registry:2.6)...
2.6: Pulling from library/registry
486039affc0a: Pull complete
ba51a3b098e6: Pull complete
470e22cd431a: Pull complete
1048a0cdabb0: Pull complete
ca5aa9d06321: Pull complete
Digest: sha256:c4bdca23bab136d5b9ce7c06895ba54892ae6db0ebfc3a2f1ac413a470b17e47
Status: Downloaded newer image for registry:2.6
Pulling manager (docker:18.05.0-ce-dind)...
18.05.0-ce-dind: Pulling from library/docker
911c6d0c7995: Pull complete
aff9b9c51076: Pull complete
9500841639b7: Pull complete
7224669f3f31: Pull complete
0134575d2ad9: Pull complete
e7d8d8ae52f7: Pull complete
59aca5a093a6: Pull complete
20b8e97b3cda: Pull complete
fb591ac9922a: Pull complete
779ddcf362b3: Pull complete
Digest: sha256:b813c414ee36b8a2c44b45295698df6bdc3bdee4a435481dbb892e1b44e09d3b
Status: Downloaded newer image for docker:18.05.0-ce-dind
Creating registry ... done
Creating manager  ... done
Creating worker02 ... done
Creating worker03 ... done
Creating worker01 ... done
 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker container ls
CONTAINER ID   IMAGE                    COMMAND                  CREATED              STATUS              PORTS                                                                                                  NAMES
ce8f7af60cff   docker:18.05.0-ce-dind   "dockerd-entrypoint.…"   About a minute ago   Up About a minute   2375/tcp, 4789/udp, 7946/tcp, 7946/udp                                                                 worker03
760fa825ec6b   docker:18.05.0-ce-dind   "dockerd-entrypoint.…"   About a minute ago   Up About a minute   2375/tcp, 4789/udp, 7946/tcp, 7946/udp                                                                 worker01
7e4ff2b8f9d5   docker:18.05.0-ce-dind   "dockerd-entrypoint.…"   About a minute ago   Up About a minute   2375/tcp, 4789/udp, 7946/tcp, 7946/udp                                                                 worker02
469231dcd4dc   docker:18.05.0-ce-dind   "dockerd-entrypoint.…"   About a minute ago   Up About a minute   2375/tcp, 3375/tcp, 0.0.0.0:9000->9000/tcp, :::9000->9000/tcp, 0.0.0.0:8000->80/tcp, :::8000->80/tcp   manager
a50dd2f3575e   registry:2.6             "/entrypoint.sh /etc…"   About a minute ago   Up About a minute   0.0.0.0:5000->5000/tcp, :::5000->5000/tcp                                                              registry

 

호스트에서 manager 컨테이너에 docker swarm init 명령을 실행해 스웜의 manager 역할을 맡긴다.

swarm init 명령이 성공하면 해당 도커 호스트는 매니저로 마킹되고 스웜 모드가 활성화된다. 이제 여러 대의 worker 컨테이너를 등록해 클러스터를 형성할 차례다. 앞에서 swarm init 명령을 실행할 때 join 토큰이 생성돼 표준 출력으로 출력됐다. 스웜 클러스터에 worker로 등록하려면 join 토큰이 필요 하다. 

매니저와 워커끼리는 컴포즈로 생성한 기본 네트워크 위에서 실행되므로 서로 컨테이너 명으로 식별 가능하다. 

 

 docker container exec -it manager docker swarm init
Swarm initialized: current node (l7omjz98sql0b2b4tptlvmexw) is now a manager.

To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-1ljvxz69jcqzlolcsoqk3qj8dp6axjustwkdnni9bsiu25u6q1-cp4ma6msyv5g1u1mftullhzer 172.20.0.3:2377

To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.


worker 컨테이너에서는 manager:2377에 대하여 join 토큰을 전송하면 된다. 

 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker container exec -it worker01 docker swarm join \
> --token SWMTKN-1-1ljvxz69jcqzlolcsoqk3qj8dp6axjustwkdnni9bsiu25u6q1-cp4ma6msyv5g1u1mftullhzer manager:2377
This node joined a swarm as a worker.
 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker container exec -it worker02 docker swarm join \
--token SWMTKN-1-1ljvxz69jcqzlolcsoqk3qj8dp6axjustwkdnni9bsiu25u6q1-cp4ma6msyv5g1u1mftullhzer manager:2377
This node joined a swarm as a worker.
 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker container exec -it worker03 docker swarm join \
--token SWMTKN-1-1ljvxz69jcqzlolcsoqk3qj8dp6axjustwkdnni9bsiu25u6q1-cp4ma6msyv5g1u1mftullhzer manager:2377
This node joined a swarm as a worker.

그리고 스웜 클러스터의 상태를 확인해보자. manager에서 docker node ls를 실행하면 다음과 같이 출력된다.

 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker container exec -it manager docker node ls
ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS      ENGINE VERSION
8xnyye1ym5ka2qb4nembqm62p     7e4ff2b8f9d5        Ready               Active                                  18.05.0-ce
9tdwny5m75l82dlvyusuv4xlx     760fa825ec6b        Ready               Active                                  18.05.0-ce
l7omjz98sql0b2b4tptlvmexw *   469231dcd4dc        Ready               Active              Leader              18.05.0-ce
29bz5nzp54c4okutknt66u91t     ce8f7af60cff        Ready               Active                                  18.05.0-ce

 

도커 레지스트리에 이미지 등록하기

도커 이미지는 앞서 빌드한 example/echo를 사용하기 위해 레지스트리에 먼저 등록한다. 먼저 다음과 같이 docker image tag 명령을 실행한다. 

 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker image tag example/echo:latest localhost:5000/example/echo:latest

태그 포맷은 [레지스트리_호스트/]리포지토리명[:태그] 인데, 여기서 레지스트리_호스트는 이미지를 등록하거나 내려받는 레지스트리를 의미한다. 지금 만든 registry 컨테이너는 호스트에서 localhost:5000과 같이 접근할 수 있으므로 리포지토리명 앞에 이 주소를 붙였다. 아래 명령어로 컨테이너에 이미지를 등록한다.

 bohyun  ~/Desktop/Work/study/docker-study   master ±
 docker image push localhost:5000/example/echo:latest

docker image pull  명령어로 worker에서 이미지를 받는다.

 docker container exec -it worker01 \
> docker image pull registry:5000/example/echo:latest
latest: Pulling from example/echo
55cbf04beb70: Pull complete
1607093a898c: Pull complete
9a8ea045c926: Pull complete
d4eee24d4dac: Pull complete
9c35c9787a2f: Pull complete
8b376bbb244f: Pull complete
0d4eafcc732a: Pull complete
186b06a99029: Pull complete
2a2033f8fdec: Pull complete
817cf70d5a43: Pull complete
Digest: sha256:dbdf912b346917e66c648688911624029f0fb3597c985bb1b6b1fd2f8f90f88b
Status: Downloaded newer image for registry:5000/example/echo:latest

호스트에서 본 레지스트리는 localhost:5000이었지만, worker01에서 보면 registry 라는 이름이므로 이름으로 선언한다.

이제 worker01 컨테이너에서 example/echo:latest 이미지를 사용할 준비가 끝났다.

다음 블로그 글에서는 서비스와 스택에 대하서 설명을 이어가겠습니다.

반응형