1. 도커 스웜

도커 스웜은 여러 도커 호스트를 클러스터로 묶어주는 컨테이너 오케스트레이션 도구의 한 종류입니다.

앞서 배웠던 도커 컴포즈와 비슷한 역할을 하지만 주로 멀티 호스트 상황에서 쓰입니다.

이번에는 dind를 이용해서 테스트를 진행 해 보도록 하겠습니다.

dind

dind(docker in docker)는 도커 호스트 역할을 할 도커 컨테이너를 여러개 실행하는 방법입니다. 가상머신 등의 리소스가 많이드는 작업이 아니기 때문에 굉장히 유용합니다. 이번 장에서는 크게 3가지 컨테이너를 사용하려고 합니다.

  • registry x1 : 도커 레지스트리 역할을 할 컨테이너로 manager 및 worker 컨테이너가 사용하는 컨테이너입 니다. dind 환경에서는 외부 도커의 이미지를 가져올 수 없으므로 registry 컨테이너에 등록 했다가 manager 및 worker 컨테이너에서 이미지를 받아가는 역할을 합니다.

  • manager x1 : 스웜 클러스터 전체를 제어하는 역할을 합니다. 여러 대 실해오디는 도커 호스트(worker)에 서비스가 담긴 컨테이너를 적절히 배치합니다.

  • worker x3 : 서비스가 담긴 컨테이너를 수행해주는 컨테이너입니다.

dind 설치하기

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"

  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"

위와 같은 yml 파일을 만들어주고 docker-compose up -d명령으로 실행 해 줍니다.

docker container ls 명령으로 총 4개가 정상적으로 실행되는것을 확인 할 수 있습니다.

그 후에 docker container exec -it manager docker swarm init 명령으로 마스터와 워커들간 연결을 위한 키를 발급받습니다.

그 후 워커들과 키를 이용해 연결해 줍니다.

 docker container exec -it worker01 docker swarm join --token SWMTKN-1-1ztmzkbz1j4a0fonsy5msw37pojxk7laxaoo1wker0h4sdqgvm-d918kykw8z3zk9l7f5fge4o9r 172.18.0.3:2377
 docker container exec -it worker02 docker swarm join --token SWMTKN-1-1ztmzkbz1j4a0fonsy5msw37pojxk7laxaoo1wker0h4sdqgvm-d918kykw8z3zk9l7f5fge4o9r 172.18.0.3:2377
 docker container exec -it worker03 docker swarm join --token SWMTKN-1-1ztmzkbz1j4a0fonsy5msw37pojxk7laxaoo1wker0h4sdqgvm-d918kykw8z3zk9l7f5fge4o9r 172.18.0.3:2377

docker container exec -it manager docker node ls 명령으로 연결된 노드를 확인 할 수 있습니다.

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

위에서 설명한 것처럼, dind 환경에서는 외부 도커 이미지를 사용할 수 없습니다. 그렇기 때문에 이미지를 registry에 등록해 주는 작업이 필요합니다.

docker image tag dydtjr1128/go-server:latest localhost:5000/dydtjr1128/go-server:latest

여기서 태그를 붙히는 방법이 이전까지와는 다른데, [레지스트리_호스트/]레포지토리명[:태그] 형식으로 붙이게 되었습니다. 왜냐하면 레지스트리_호스트에 해당하는 내용이 localhost:5000 이고 이는 registry를 뜻하기 때문입니다.

docker image push localhost:5000/dydtjr1128/go-server:latest

위와 같이 내부 registry에 이미지를 push 할 수 있습니다.

그렇다면 registry에는 이미지가 들어가 있을 테고, worker01 의 입장에서 이미지를 가져오기 위해서는 localhost가 아닌 registry로 적어서 pull 해오면 됩니다.

docker container exec -it worker01 docker image pull registry:5000/dydtjr1128/go-server:latest

서비스

서비스는 어플리케이션을 구성하는 일부 컨테이너를 제어하기 위한 단위를 뜻합니다. 서비스는 manager 컨테이너에서 docker service create 명령으로 생성 할 수 있습니다.

docker container exec -it manager docker service create --replicas 1 --publish 8000:8080 --name echo registry:5000/dydtjr1128/go-server:latest

실행 확인은 다음과 같이 할 수 있습니다.

docker container exec -it manager docker service ls

서비스를 제어하는 레플리카 수를 다음과 같이 변경해 보았습니다.

docker container exec -it manager docker service scale echo=6

다음 명령어로 동작중인 6개의 레플리카를 확인 할 수 있습니다.

docker container exec -it manager docker service ps echo | grep Running

또한 다음과 같이 서비스를 제거 할 수도 있습니다.

docker container exec -it manager docker service rm echo

스택

스택은 위에서 공부한 서비스를 묶는내용으로 하나 이상의 서비스를 그룹으로 묶은 단위를 뜻합니다. 유명한 스택으로는 ELK스택이 있습니다. ELK는 ElasticSearch + LogStash + Kibana를 뜻하며 각각의 서비스를 묶었습니다. 서비스는 어플리케이션 이미지를 하나밖에 다루지 못하지만 여러 서비스가 협조해 동작하는 형태로는 다양한 어플리케이션을 구성 할수 있습니다. 이를 스택이라고 부릅니다.

스택은 앞서배운 컴포즈와 굉장히 비슷하면서 다릅니다. 스택은 스웜에서 동작하느 스케일 인, 스케일 아웃, 제약조건 부여가 가능한 컴포즈라고 생각 할 수 있습니다. 스택을 이용해 배포된 서비스 그룹은 overlay 네트워크에 속하게 되는데, overlay 네트워크는 여러 도커 호스트에 걸쳐 배포된 컨테이너 그룹을 같은 네트워크에 배치하기 위한 기술을 말합니다.

docker container exec -it manager docker network create --driver=overlay --attachable my_net

위의 코드로 my_net이라는 공유 네트워크를 구성하였습니다.

스웜 클러스터에 존재하는 컨테이너 그룹들이 어떤 노드에 배치되어있는지를 시각화 해 보여주는 visualizer를 예로 들어 스택으로 실행 해보겠습니다.

version: "3"
services:  
  # 클러스터 환경을 확인할 수 있는 gui 툴
  visualizer:
    image: dockersamples/visualizer
    ports:
      - "9000:8080"
    volumes:
      - "/var/run/docker.sock:/var/run/docker.sock"
    deploy:
      mode: global
      placement:
        constraints: [node.role == manager]

위와 같은 파일을 manager 컨테이너 내부 stack 폴더에 만들어 준뒤 다음의 명령어를 실행해 줍니다.

docker container exec -it manager docker stack deploy -c /stack/visualizer.yml visualizer

정상적으로 실행 된다면 다음과 같이 도커 내부의 컨테이너들의 실행 목록을 확인 할 수있습니다.

요약

물리적인 1대의 호스트(컴퓨터) 에서 여러대의 호스트를 실행하기 위해 docker-compose로 1개의 registry, 1개의 manager, 3개의 worker를 생성하였습니다. 각각의 worker를 manager와 연결 해 주었고, 워커에 이미지를 받아오도록 하였으며, 서비스 및 스택에 대한 테스트를 해 보았습니다.

Last updated