SW Engineering/DevOps, SRE

Docker Swarms

SungWookKang 2019. 3. 26. 03:27
반응형

Docker Swarms

 

·         Version : Docker

 

문서는 Docker 공식 문서를 번역한 내용이며 필자의 생각과 의견이 반영되어 있습니다. 자세한 내용은 원문을 참고 바랍니다.

 

Prerequisites

Docker Swarm 학습하기 전에 아래 사항이 선행되어야 한다.

·         Docker Install : https://docs.docker.com/install/

·         Docker Orientation : http://sqlmvp.kr/221419558020

·         Docker Containers : http://sqlmvp.kr/221423910065

·         레지스트리에 푸시하여 작성한 friendlyhello이미지를 게시했는지 확인한다. 이번 포스트에서는 레지스트리에 공유된 이미지를 사용한다.

·         이미지가 배포된 컨테이너가 작동하는지 확인한다. 아래 명령어를 사용하여 컨테이너를 실행하고 정상적으로 브라우저에서 접속이 되어야 한다. Username, reop 위치는 사용자에 따라 변경하여 사용한다.

docker run -p 4000:80 username/repo:tag

http://localhost:4000

 

·         Docker Services에서 다룬 docker-compose.yml 사본을 준비한다.

 

 

Introduction

이전 포스트(Docker Services)에서는 작성한 애플리케이션을 가져와서 서비스로 전환하여 프로덕션 환경에서 실행하는 방법을 정의하고 복제를 사용하여 5배로 서비스를 확장하는 방법에 대해서 살펴 보았다.

·         Docker Services : http://sqlmvp.kr/221428028083

 

이번 포스트에서는 클러스터를 만들어서 여러 머신에서 실행하는 환경을 만들어 본다. 다중 컨테이너, 다중  머신 응용 프로그램은 여러 대의 머신을 Swarm이라고 불리는 “Dockerized” 클러스터로 결합하여 사용 가능하다.

 

Understanding Swarm clusters

Swarm Docker 실행하고 클러스터에 합류한 컴퓨터 그룹이다. Swarm 관리자가 클러스터에서 Docker 명령을 실행한다. Swarm 조인된 머신을 노드라 부른다.

Swarm 관리자는 사용률이 낮은 머신을 컨테이너로 가득 채우는 “empties node” 같은 컨테이너를 실행하기 위한 가지 전략을 사용할 있다. 또는 “global” 전략으로   기계가 지정된 컨테이너의 인스턴스를 정확히 하나씩 가져온다. Swarm 관리자가 이미 사용하고 있는것과 마찬가지로 compose file 사용하도록 지시한다.

Swarm 관리자는 명령을 실행할 있는 Swarm 내의 유일한 머신이며,  다른 머신 Swarm 노드로 조인할 있는 권한을 부여한다. Worker 리소스를 제공하기 위해 존재하며 다른 머신에게  어떠한 영향도 있는 권한이 없다.

지금까지 로컬 시스템에서 단일 호스트 모드로 Docker 사용해 왔다. 그러나 Docker Swarm 모드로 전환되어 사용될 있다. Swarm 모드를 활성화하면 현재 시스템이 Swarm 매니저가 된다. 그때부터 Docker 현재 컴퓨터에서만 관리하는 것이 아니라 Swarm관리자에서 내리는 명령을 실행한다.

 

 

Set up your swarm

Swarm 여러 노드로 구성되며 물리적 또는 가상 시스템이 있다. 기본 개념은 간단하다. Docker swarm init모드를 활성화하고 현재 시스템을 Swarm 매니저로 설정한 다음 docker swarm join 실행하여 다른 시스템에서 Swarm worker 참여 시킨다.

 

 

Create a cluster

·         VMS ON YOUR LOCAL MACHINE [MAC, LINUX, WINDOWS 7 AND 8]

가상 머신(VM) 생성할 있는 하이퍼바이저가 필요하므로 해당 머신OS Oracle VirtualBox 설치한다.

참고 : Windows 10 같이 Hyper-V 설치된 Windows 시스템을 사용하는 경우 VirtualBox 설치할 필요가 없으므로 대신 Hyper- V 사용해야 한다.

 

이제 VirtualBox 드라이버를 사용하여 docker-machine 사용하여 가지 VM 만든다.

docker-machine create --driver virtualbox myvm1

docker-machine create --driver virtualbox myvm2

 

 

·         VMS ON YOUR LOCAL MACHINE [WINDOWS 10]

먼저 가상 시스템(VM) 공유할 있도록 가상 스위치를 생성한다.

1.       Hyper-V 관리자 시작

2.       오른쪽 메뉴에서 Virtual Switch Manager클릭

3.       외부 가상 스위치 만들기 클릭

4.       이름을 myswitch 지정하고 호스트 컴퓨터의 활성 네트워크 어댑터 공유를 선택

노드 관리 도구인 docker-machine 사용하여 VM 생성한다.

docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1

docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm2

 

 

 

LIST THE VMS AND GET THEIR IP ADDRESSES

위에서 myvm1 myvm2라는 개의 VM 생성되었다. 아래 명령을 사용하면 생성된 VM 시스템의 IP 주소를 가져온다.

docker-machine ls

 

 

아래는 VirtualBox 사용했을 때의 출력 예이다.

NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS

myvm1   -        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce

myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce

 

 

INITIALIZE THE SWARM AND ADD NODES

번째 머신은 관리자로서의 역할을 수행하며 관리 명령을 실행하고 작업자를 인증하여 Swarm 가입시키며, 번째 머신은 작업자(Worker)이다.

docker-machine ssh 사용하여 VM 명령을 보낼 있다. myvm1에게 docker swarm init swarm manager 되도록 지시한다. 명령 실행 나타나는 결과물에서 “docker swarm join…”구문을 복사해 놓는다. 토큰은 나중에 Swarm 조인에 사용된다.

docker-machine ssh myvm1 “docker swarm init --advertise-addr 10.77.253.120”

 

 

아래와 같은 결과를 확인할 있다.

$ docker-machine ssh myvm1 "docker swarm init --advertise-addr <myvm1 ip>"

Swarm initialized: current node <node ID> is now a manager.

 

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

 

  docker swarm join \

  --token <token> \

  <myvm ip>:<port>

 

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

 

[Port 2377 and 2376]

항상 docker swarm init docker swarm join 포트 2377 (swarm 관리포트) 결합 시키거나 포트를 전혀 사용하지 않고 기본값으로 설정한다. docker-machine ls 의해 반환된 컴퓨터 IP 주소는 Docker 데몬 포트인 2376 포함한다. 포트를 사용하면 오류가 발생할 있다.

 

[Having trouble using SSH? Try the –native-ssh flag]

Docker Machine에는 Swarm 관리자에게 명령을 보내는데 문제가 있는 경우 사용자 시스템의 SSH 사용할 있는 옵션이 있다. ssh 명령을 호출 할때 –native-ssh 플래그를 지정하면 된다.

Ex) docker-machine --native-ssh ssh myvm1 ...

 

위에 잠깐 언급하였듯이 docker swarm init 대한 출력결과에는 추가하려는 노드에서 실행할 있도록 미리 구성된 docker swarm join 명령이 포함되어 있다. 명령을 복사하여 docker-machine ssh 통해 myvm2 Swarm 작업자로 참여 시킨다.

docker-machine ssh myvm2 "docker swarm join --token SWMTKN-1-4ho0uf7g5lw0t1jj9i3chv364edmt1dt9q5jb1vqbhlz6li86m-ajbkydx8gees9t6hez7tmcf7y 10.77.253.120:2377"

 

 

$ docker-machine ssh myvm2 "docker swarm join \

--token <token> \

<ip>:2377"

 

This node joined a swarm as a worker.

 

myvm1에서 swarm생성 토큰이 생각나지 않을 myvm1에서 아래  명령을 실행해서 토큰을 확인할 있다.

docker swarm join-token worker

 

 

이제 번째 Swarm 만들어 졌다. Swarm 등록된 노드를 보려면 Swarm 관리자에서 docker node ls 실행한다.

 


$ docker-machine ssh myvm1 "docker node ls"

ID                            HOSTNAME            STATUS              AVAILABILITY        MANAGER STATUS

brtu9urxwfd5j0zrmkubhpkbd     myvm2               Ready               Active

rihwohkh3ph38fhillhhb84sk *   myvm1               Ready               Active 

 

[Leaving a swarm]

현재 Swarm그룹에서 탈퇴 하려면 노드에서 docker swarm leave 실행할 있다.

 

 

Deploy your app on the swarm cluster

Swarm구성이 완료되었다. 프로세스를 Swarm 배치하기만 하면 된다. myvm1 같은 Swarm 관리자만 docker 명령을 실행한다. Worker 단지 리소스만 제공한다.

 

Configure a docker-machine shell to the swarm manager

지금까지 docker-machine ssh에서 Docker명령을 랩핑하여 VM 대화했다. 다른 옵션은 docker-machine env <machine> 실행하여 현재 쉘을 구성하여 VM Docker 데몬과 통신하는 명령을 실행하는 것이다. 방법은 로컬의 docker-compose.yml 파일을 사용하여 어디서나 복사하지 않고도 원격으로 응용 프로그램을 배포할 있으며 다음 단계에서 작동한다. Docker-machine env myvm1 입력한 다음 출력의 마지막 줄에 제공된 명령을 복사하여 붙여넣고 실행하여 쉘이 myvm1관리자인 myvm1 통신하도록 구성한다. 쉘을 구성하는 명령은 Mac, Linux또는Windows 따라 다르므로 아래를 참고 한다.

·         [Docker Machine Shell Environment On Mac or Linux]

docker-machine env myvm1 실행하여 myvm1 통신하도록 쉘을 구성하는 명령을 얻는다.

docker-machine env myvm1

 

$ docker-machine env myvm1

export DOCKER_TLS_VERIFY="1"

export DOCKER_HOST="tcp://192.168.99.100:2376"

export DOCKER_CERT_PATH="/Users/sam/.docker/machine/machines/myvm1"

export DOCKER_MACHINE_NAME="myvm1"

# Run this command to configure your shell:

# eval $(docker-machine env myvm1)

 

주어진 명령을 실행하여 쉘이 myvm1 통신하도록 구성한다.

eval $(docker-machine env myvm1)

 

docker-machine ls 실행하여 옆에 별표가 표시된 myvm1 현재 활성 시스템이다.

$ docker-machine ls

NAME    ACTIVE   DRIVER       STATE     URL                         SWARM   DOCKER        ERRORS

myvm1   *        virtualbox   Running   tcp://192.168.99.100:2376           v17.06.2-ce

myvm2   -        virtualbox   Running   tcp://192.168.99.101:2376           v17.06.2-ce

 

·         [Docker Machine Shell Environment On Windows]

docker-machine env myvm1 실행하여 myvm1 통신하도록 쉘을 구성하는 명령을 얻는다.

docker-machine env myvm1

 

PS C:\Users\sam\sandbox\get-started> docker-machine env myvm1

$Env:DOCKER_TLS_VERIFY = "1"

$Env:DOCKER_HOST = "tcp://192.168.203.207:2376"

$Env:DOCKER_CERT_PATH = "C:\Users\sam\.docker\machine\machines\myvm1"

$Env:DOCKER_MACHINE_NAME = "myvm1"

$Env:COMPOSE_CONVERT_WINDOWS_PATHS = "true"

# Run this command to configure your shell:

# & "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression

 

주어진 명령을 실행하여 쉘이 myvm1 통신하도록 구성한다.

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression

 

docker-machine ls 실행하여 옆에 별표가 표시된 myvm1 현재 활성 시스템이다.

PS C:PATH> docker-machine ls

NAME    ACTIVE   DRIVER   STATE     URL                          SWARM   DOCKER        ERRORS

myvm1   *        hyperv   Running   tcp://192.168.203.207:2376           v17.06.2-ce

myvm2   -        hyperv   Running   tcp://192.168.200.181:2376           v17.06.2-ce

 

 

Deploy the app on the swarm manager

이제 myvm1에서 myvm1 swarm manager 권한을 사용하여 이전에서 사용한 것과 동일한 docker stack deploy 명령을 myvm1 사용하고 docker-compose.yml 로컬 복사본을 사용하여 응용 프로그램을 배포할 있다. docker-compose.yml 명령을 완료하는데 초가 걸릴 있으며 배포 시간이 걸릴 있다. Swarm manager에서 docker service ps <service_name> 명령을 사용하여 모든 서비스에 재배포 되었는지 확인한다.

docker-machine 구성을 사용하여 myvm1 연결되어 있고 로컬 호스트의 파일에 계속 액세스할 있다. 이전에 만든 docker-compose.yml 파일을 포함하여 이전과 같은 디렉토리에 있는지 확인한다. 이전과 마찬가지로 myvm1 app 배포하려면 다음 명령을 실행한다.

docker stack deploy -c docker-compose.yml getstartedlab

 

참고 : 이미지가 Docker hub대신 개인 레지스트리에 저장되어 있는 경우 docker login <your-registry> 사용하여 docker login <your-registry> 해야하며 명령에 –with-registry-auth 플래그를 추가해야한다.

Ex)

docker login registry.example.com

docker stack deploy --with-registry-auth -c docker-compose.yml getstartedlab

 

그러면 암호화된 WAL 로그를 사용하여 로컬 클라이언트의 서비스가 배포된 swarm 노드로 로그인 토큰이 전달된다. 정보로 노드는 레지스트리에 로그인하여 이미지를 가져올 있다.

 

이제 이전에서 사용한 것과 같은 Docker 명령을 사용할 있다. 서비스( 관련 컨테이너) myvm1 myvm2사이에 분산되어 있다.

docker stack ps getstartedlab

 

 

$ docker stack ps getstartedlab

 

ID            NAME                  IMAGE                   NODE   DESIRED STATE

jq2g3qp8nzwx  getstartedlab_web.1   gordon/get-started:part2  myvm1  Running

88wgshobzoxl  getstartedlab_web.2   gordon/get-started:part2  myvm2  Running

vbb1qbkb0o2z  getstartedlab_web.3   gordon/get-started:part2  myvm2  Running

ghii74p9budx  getstartedlab_web.4   gordon/get-started:part2  myvm1  Running

0prmarhavs87  getstartedlab_web.5   gordon/get-started:part2  myvm2  Running

 

[Connecting to VMs with docker-machine env and docker-machine ssh]

·         쉘을 myvm2 같은 다른 시스템과 통신하도록 설정하려면 동일하거나 다른 쉘에서 docker-machine env 다시 실행한 다음 주어진 명령을 실행하여 myvm2 가리킨다. 이것은 항상 현재 쉘에만 적용된다. 구성되지 않은 쉘로 변경하거나 쉘을 열면 명령을 다시 실행해야 한다. docker-machine ls 사용하여 머신을 나열하고 그들이 어떤 상태인지 파악하고 IP주소를 얻고 연결되어 있는 경우 어떤 것이 있는지 찾아본다. 자세한 내용은 아래 링크를 참고 한다.

https://docs.docker.com/machine/get-started/#create-a-machine

·         Docker명령을 docker-machine ssh <machine> “<command>” 형식으로 랩핑할 수도 있다. docker-machine ssh <machine> “<command>” VM 직접 기록하지만 로컬 호스트 파일에 즉시 액세스할 없다.

·         Mac Linux에서는 docker-machine scp <file> <machine> : ~ 사용하여 여러 컴퓨터에서 파일을 복사할 있지만 Windows 사용자는 Git bash 같은 Linux 터미널 에뮬레이터가 필요하다.

 

튜토리얼은 docker-machine CLI 통해 모든 플랫폼에서 사용할 있으므로 docker-machine ssh docker-machine env 모두 데모한다.

 

 

 

Accessing your cluster

myvm1 또는 myvm2 IP 주소에서 직접 앱에 액세스 있다. 사용자가 만든 네트워크는 네트워크 간에 공유되며 로드 균형 조정을 수행한다. docker-machine ls 실행하여 VM IP 주소를 얻고 브라우저에서 해당 주소로 방문하여 새로 고침(또는 그냥  curl 넣기)한다.

 


모든 사이클링 가능한 임의의 5개의 컨테이너ID 로드밸런싱을 보여준다. IP 주소가 작동하는 이유는 무리의 노드가 수신 라우팅 메쉬에 참여 한다는 것이다. 이렇게 하면 실제로 컨테이너를 실행중인 노드가 무엇이든 관계 없이 swarm 특정 포트에 배포된 서비스가 항상 해당 포트를 소유하도록 있다. 아래 그림은 3노드 Swarm에서 포트 8080 게시된 my-web이라는 서비스용 라우팅 메시가 어떻게 보이는지에 대한 다이어그램이다.

 


[Having connectivity trouble?]

Swarm 모드를 활성화 하기 전에 swarm에서 수신 네트워크를 사용하려면 swarm 노드간에 다음 포트를 열어야 한다.

·         컨테이너 네트워크 검색을 위한 포트 7946 TCP/UDP

·         컨테이너 수신 네트워크용 포트 4789 UDP

 

 

Iterating and scaling your app

docker-compose.yml 파일에서 응용 프로그램의 크기를 변경할 있다. docker-compose.yml 파일을 편집하여 응용 프로그램 동작을 변경한 다음 이미지를 다시 작성하고 푸시한다. (이렇게 하려면 이전 앱을 제작하고 이미지를 게시하는데 사용한 것과 동일한 단계를 따라야한다.) 경우 모두 간단하게 docker stack deploy 다시 실행하여 이러한 변경 사항을 배포한다. myvm2에서 사용한 동일한 docker swarm join 명령을 사용하여 실제 또는 가상머신을 swarm 조인 시킬 있으며 클러스터에 용량이 추가 된다. 나중에 docker stack deploy 실행하면 앱이 새로운 리소스를 이용할 있다.

 

Cleanup and reboot

docker stack rm 명령을 사용하여 스택을 해제할 있다.

docker stack rm getstartedlab

 

[Keep the swarm or remove it?]

Swarm 제거 하고 싶다면 아래 명령을 사용한다.

Docker-machine ssh myvm2 “docker swarm leave”

Docker-machine ssh myvm1 “docker swarm leave –f”

 

아래 명령으로 현재 쉘에서 docker-machine 환경 변수를 설정 해제 있다.

[Mac or Linux]

eval $(docker-machine env -u)

 

[Windows]

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env -u | Invoke-Expression

 

이렇게 하면 docker-machine 만든 가상 컴퓨터와 셀의 연결이 끊어지며 동일한 셀에서 계속 작업할 있다. 예를 들어 Mac Docker또는 Windows Docker 같은 기본 docker 명령을 사용한다. 자세한 내용은 아래 링크를 참고 한다.

·         Use Machine to run Docker containers :  https://docs.docker.com/machine/get-started/#create-a-machine

 

Restarting Docker machines

로컬 호스트를 종료하면 Docker 시스템이 중지된다. docker-machine ls 실행하여 머신의 상태를 확인할 있다.

docker-machine ls

 

$ docker-machine ls

NAME    ACTIVE   DRIVER       STATE     URL   SWARM   DOCKER    ERRORS

myvm1   -        virtualbox   Stopped                 Unknown

myvm2   -        virtualbox   Stopped                 Unknown

 

중지된 시스템을 다시 시작하려면 docker-machine start <machine-name> 명령을 실행한다.

$ docker-machine start myvm1

Starting "myvm1"...

(myvm1) Check network to re-create if needed...

(myvm1) Waiting for an IP...

Machine "myvm1" was started.

Waiting for SSH to be available...

Detecting the provisioner...

Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

 

$ docker-machine start myvm2

Starting "myvm2"...

(myvm2) Check network to re-create if needed...

(myvm2) Waiting for an IP...

Machine "myvm2" was started.

Waiting for SSH to be available...

Detecting the provisioner...

Started machines may have new IP addresses. You may need to re-run the `docker-machine env` command.

 

 

Recap and cheat sheet [optional]

이번 포스트에서 다룬 내용은 아래와 같다.(동영상)

·         https://asciinema.org/a/113837

 

이번 포스트에서는 Swarm 무엇인지, Swarm 노드가 관리자 또는 작업자가 있는지, Swarm 만들어서 어떻게 응용 프로그램을 배포 하는지를 배웠다. Docker 네트워킹 기능이 실제로 다른 시스템에서 실행 중이더라도 컨테이너간에 로드 균형 조정 요청을 보냈다. 마지막으로 클러스터에서 앱을 반복하고 크기를 조정하는 방법을 배웠다.

아래는 Swarm VM 상호작용하기 위해 실행할 있는 가지 명령이다.

docker-machine create --driver virtualbox myvm1 # Create a VM (Mac, Win7, Linux)

docker-machine create -d hyperv --hyperv-virtual-switch "myswitch" myvm1 # Win10

docker-machine env myvm1                # View basic information about your node

docker-machine ssh myvm1 "docker node ls"         # List the nodes in your swarm

docker-machine ssh myvm1 "docker node inspect <node ID>"        # Inspect a node

docker-machine ssh myvm1 "docker swarm join-token -q worker"   # View join token

docker-machine ssh myvm1   # Open an SSH session with the VM; type "exit" to end

docker node ls                # View nodes in swarm (while logged on to manager)

docker-machine ssh myvm2 "docker swarm leave"  # Make the worker leave the swarm

docker-machine ssh myvm1 "docker swarm leave -f" # Make master leave, kill swarm

docker-machine ls # list VMs, asterisk shows which VM this shell is talking to

docker-machine start myvm1            # Start a VM that is currently not running

docker-machine env myvm1      # show environment variables and command for myvm1

eval $(docker-machine env myvm1)         # Mac command to connect shell to myvm1

& "C:\Program Files\Docker\Docker\Resources\bin\docker-machine.exe" env myvm1 | Invoke-Expression   # Windows command to connect shell to myvm1

docker stack deploy -c <file> <app>  # Deploy an app; command shell must be set to talk to manager (myvm1), uses local Compose file

docker-machine scp docker-compose.yml myvm1:~ # Copy file to node's home dir (only required if you use ssh to connect to manager and deploy the app)

docker-machine ssh myvm1 "docker stack deploy -c <file> <app>"   # Deploy an app using ssh (you must have first copied the Compose file to myvm1)

eval $(docker-machine env -u)     # Disconnect shell from VMs, use native docker

docker-machine stop $(docker-machine ls -q)               # Stop all running VMs

docker-machine rm $(docker-machine ls -q) # Delete all VMs and their disk images

 

 

 

[참고자료]

https://docs.docker.com/get-started/part4/#recap-and-cheat-sheet-optional

 

 

2018-12-28 / Sungwook Kang / http://sqlmvp.kr

 

 

swarmscaleclustermachinevmmanagerworkerdeploysshorchestration

반응형

'SW Engineering > DevOps, SRE' 카테고리의 다른 글

Docker Deploy  (0) 2019.03.26
Docker Stack  (0) 2019.03.26
Docker Services  (0) 2019.03.26
Build an image and run it as one container  (0) 2019.03.26
Docker Orientation and Setup  (0) 2019.03.26