컨테이너를 단일 도커 호스트에만 배치하는 것은 간단하고 개발자가 관리하기도 쉽다. 그러나 많은 트래픽을 처리할 수 있는 실용적인 시스템은 여러 컨테이너가 각기 다른 호스트에 배치되는 경우가 많다. 또 컨테이너를 배치하는 방법과 하나 이상의 도커 호스트를 다루는 방법 역시 호스트 하나만을 다룰 때와는 달리 다양한 사항을 고려해야 한다.
도커 스웜이란 무엇인가?
도커 스웜은 여러 도커 호스트를 클러스터로 묶어 주는 컨테이너 오케스트레이션 도구의 한 종류이다.
컨테이너 오케스트레이션 도구없이는 도커 호스트 여러 대를 사용하는 확장성 있는 애플리케이케이션을 만들기가 어렵다. 도커 호스트에 어떤 컨테이너를 배치해야 하는지, 서로 다른 호스트에 위치한 컨테이너 간의 통신은 어떻게 제어하는지 등의 조율을 오케스트레이션 도구 없이 하기느 무리가 있기 때문이다.
종류
이름 | 역할 | 명령어 |
---|---|---|
컴포즈 | 여러 컨테이너로 구성된 도커 애플리케이션을 관리(주로 단일 호스트) | docker-compose |
스웜 | 클러스터 구축 및 관리(주로 멀티 호스트) | docker swarm |
서비스 | 스웜에서 클러스터 안의 서비스(컨테이너 하나 이상의 집합)을 관리 | docker service |
스택 | 스웜에서 여러 개의 서비스를 합한 전체 애플리케이션을 관리 | docker stack |
여러 대의 도커 호스트로 스웜 클러스터 구성하기
도커 인 도커(Docker in Docker, dind)라는 기능을 사용하면 도커 컨테이너 안에서 도커 호스트를 실행할 수 있다.(실습환경은 호스트가 한대이므로, 클라우드 환경과 비슷하게 구축이 필요하다.)
사용할 컨테이너 다음 3종류로 모두 합해 5개다.
- registry : 외부 도커에 저장된 이미지를 먼저 registry 컨테이너에 등록했다가 manager 및 worker 컨테이너가 받아감
- manager : 스웜 클러스터 전체를 제어하는 역할, 여러 대 실행되는 도커 호스트(worker)에 서비스가 담긴 컨테이너를 적절히 배치한다.
- worker
모든 manager 및 worker 컨테이너는 registry 컨테이너에 의존한다.
docker-compose.yml
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"
$ docker-compose up -d
$ docker container ls
컴포즈를 실행하면 registry 1대, manager 1대, worker 3대, 총 5대 컨테이너가 실행 상태가 된다. 아직은 dind 컨테이너를 여러 대 실행한 상태로, 모든 컨테이너가 서로 협조해 클러스터로 동작하는 상태는 아니다.
클러스터를 관리하는 manager가 필요하게 되는데, 호스트에서 manager 컨테이너에 docker swam init 명령을 실행해 스웜의 manager 역할을 맡긴다.
스웜 manager 등록 및 worker 등록하기
1. 스웜 manager 등록하기
swarm init 명령이 성공하면 도커 흐스트는 manager로 마킹되고 스웜 모드가활성화된다. 이제 여러 대의 worker 컨테이너를 등록해 클러스터를 형성할 차례다.
swarm init 명령을 실행하면 join 토큰이 생성되는데, 스웜 클러스터에 도커 호스트를 worker로 등록하려면 이 join 토큰이 필요하다.
$ docker container exec -it manager docker swarm init
Swarm initialized: current node (p820cx5970dl1sljg7pysuwnn) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-1gd6pby4gkbiwcpsslnwyxlkeq5zr7um42qlw3u9w8sstq66zt-d9fwfzbmf70knzsnb029mmsww 172.22.0.3:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
2. worker 등록하기
join 토큰을 사용해서 3대의 노드를 스웜 클러스터에 worker로 등록한다.(manager 및 모든 worker 컨테이너는 컴포즈로 생성한 기본 네트워크 위에서 실행된다. 따라서 이들끼리는 컨테이너 명으로 서로를 식별할 수 있다.)
아래와 같은 방법으로 worker01 ~ worker03를 등록한다.
$ docker container exec -it worker01 docker swarm join \
> --token SWMTKN-1-1gd6pby4gkbiwcpsslnwyxlkeq5zr7um42qlw3u9w8sstq66zt-d9fwfzbmf70knzsnb029mmsww 172.22.0.3:2377
This node joined a swarm as a worker.
worker 등록이 끝나면 manager에서 docker node ls를 실행하여 등록된 노드들을 볼 수있다.(manager, worker 3대 출력)
$ docker container exec -it manager docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
1j2o3evttyogt8jo3bclahg5x 29ef9ceb89f8 Ready Active 18.05.0-ce
ypkjgimcu3720zug8521jb4uv 68bcb8fe3ac7 Ready Active 18.05.0-ce
p820cx5970dl1sljg7pysuwnn * 69a541bfa400 Ready Active Leader 18.05.0-ce
x0qaba8u3rh7c9txrtir38bno ae98e56d70aa Ready Active 18.05.0-ce
도커 레지스트리에 이미지 등록하기
도커 레지스트리 역할을 할 registry 컨테이너가 실행중이므로 호스트에서 registry 컨테이너에 도커 이미지를 등록해보자.
=> 책에서 전에 생성한 이미지를 사용(example/echo)
외부 도커에서 빌드한 이미지는 레지스트리를 통해서만 안쪽 도커에서 사용이 가능하다. 그러므로 example/echo 이미지를 레지스트리에 등록해야 한다. 아래의 명령어를 실행시키자.
1.이미지 태그 생성
$ docker image tag example/echo:latest localhost:5000/example/echo:latest
# 태그 포멧 : [레지스트리_호스트/]레파지토리명[:태그]
# docker image build -t example/echo:latest .
2.registry 컨테이너에 이미지 등록
$ docker image push localhost:5000/example/echo:latest
# docker image push [push_대상_레지스트리_호스트/]레파지토리명[:태그명]
3.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
a8aec59f3f26: Pull complete
47d9abff94c0: Pull complete
Digest: sha256:feb33a296fcab7f8c4e6e0a763cc8d083c90ac2ad10bf1bce8b68659320da09b
Status: Downloaded newer image for registry:5000/example/echo:latest
# 도커이미지가 성공적으로 받아졌는지 확인한다.
$ docker container exec -it worker01 docker image ls
REPOSITORY TAG IMAGE ID CREATED SIZE
registry:5000/example/echo latest 2031a40371be 2 months ago 750MB
서비스
단일 도커 호스트에서 컨테이너를 배포하는 방법에는 2가지가 있다.
- docker container run 명령으로 컨테이너를 일일이 실행
- 컴포즈를 사용해 여러 컨테이너를 동시에 실행
스웜을 사용하는 경우에는 조금 다른 접근법을 취하는데, 스웜은 일부 컨테이너를 제어하기 위한 단위로 서비스 라는 개념을 사용한다.
1. 서비스 생성
서비스를 한번 만들어보자. 서비스는 manager 컨테이너에서 docker service create 명령으로 생성할 수 있다.
$ docker container exec -it manager \
docker service create --replicas 1 --publish 8000:8080 --name echo registry:5000/example/echo:latest
mdnkyw9oefkcu72hzwac3ji13
overall progress: 1 out of 1 tasks
1/1: running [==================================================>]
verify: Service converged
- —replicas 1 : 서비스 복제 옵션 (1개를 복제하겠다.)
- —publish : 외부 도커에서 접근 가능하게 포티를 지정, 외부도커에서 8000으로 요청이 들어오면 8080으로 토스
docerk service ls 명령으로 현재 생성된 서비스의 목록을 볼 수 있다. 목록을 보면 레플리카가 1개인 echo라는 이름의 서비스가 생성됐다.
$ docker container exec -it manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
mdnkyw9oefkc echo replicated 1/1 registry:5000/example/echo:latest *:8000->8080/tcp
docker service scale 명령으로 해당 서비스의 컨테이너 수를 늘리거나 줄일 수 있다. 컨테이너 수를 조정할 수 있으므로 스케일 아웃을 적용할 때 유용하다.
$ docker container exec -it manager docker service scale echo=6
echo scaled to 6
overall progress: 6 out of 6 tasks
1/6: running [==================================================>]
2/6: running [==================================================>]
3/6: running [==================================================>]
4/6: running [==================================================>]
5/6: running [==================================================>]
6/6: running [==================================================>]
verify: Service converged
$ docker container exec -it manager docker service ps echo | grep Running
d6rlx0saf1r5 echo.1 registry:5000/example/echo:latest 69a541bfa400 Running Running about a minute ago
wffnniytsiqp echo.2 registry:5000/example/echo:latest 29ef9ceb89f8 Running Running 21 seconds ago
zqvqrgje1we5 echo.3 registry:5000/example/echo:latest ae98e56d70aa Running Running 21 seconds ago
31hsgfomuc2a echo.4 registry:5000/example/echo:latest 68bcb8fe3ac7 Running Running 20 seconds ago
lsqs6idour4n echo.5 registry:5000/example/echo:latest 68bcb8fe3ac7 Running Running 19 seconds ago
7q8ar9oh7rsf echo.6 registry:5000/example/echo:latest 69a541bfa400 Running Running 21 seconds ago
$ docker container exec -it manager docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
mdnkyw9oefkc echo replicated 6/6 registry:5000/example/echo:latest *:8000->8080/tcp
# 서비스 제거
docker container exec -it manager docker service rm echo
서비스가 레플리카 수를 늘리라고 지시하면 자동으로 컨테이너를 복제하고 이를 여러 노드에 배치한다. 이러한 특성을 사용해 애플리케이션을 쉽게 스케일 아웃할 수 있다.
'프로그래밍 노트 > 도커' 카테고리의 다른 글
스웜(swarm)을 이용한 도커 컨테이너 배포_3 (스웜 클러스터 외부에서 서비스 사용하기) (0) | 2021.03.29 |
---|---|
스웜(swarm)을 이용한 도커 컨테이너 배포_2 (0) | 2021.03.27 |
실용적인 (도커)컨테이너 구축 및 배포를 위한 지식_1 (0) | 2021.01.30 |
도커 컴포즈(docker-compose) 네트워크 (0) | 2021.01.17 |
도커살펴보기_도커 컨테이너 다루기 (0) | 2021.01.17 |