kok202
도커 강의 정리 ( 2강 : 서비스, 클러스터 (Swarm) )

2019. 6. 7. 01:57[정리] 기능별 개념 정리/Docker

1강에서 만든 도커 이미지에 로드 밸런싱과 스케일링을 하고자한다.

이미지 -> 컨테이너 -> 서비스 -> 스택

그러기 위해선 서비스를 조작해야한다.

 

서비스는 실제 환경에서 쓰이는 컨테이너이다.

1. 어떤 이미지를 사용할 것 인가.

2. 그 이미지를 몇 개의 컨테이너로 중복해서 띄울 것인가.

3. 서버의 리소스는 얼마만큼 사용되어야 하는가.
4. 어떤 포트를 개방해야하는가.

 

서비스를 정의하기 위해선 스택이 하나 필요하다.

스택은 docker-compose.yml 안에서 정의한다.

docker-compose 를 설치해야한다.

보통 docker 를 설치하면 docker-compose 도 같이 설치된다.

 

docker-compose.yml 으로 스택을 정의한다.

docker-compose.yml 안에는 여러개의 서비스가 존재할 수 있다.

하나의 서비스는 하나의 이미지만을 가진다.

하나의 서비스는 여러 개의 컨테이너로 중복해서 띄울 수 있다.

컨테이너는 어떤 머신에든 들어가서 동작할 수 있다.

 

 

 

 

 

 

서비스

docker-compose.yml

version: "3"
services:
  # 서비스의 이름은 web이다.
  web:
    # 도커 허브에 올라간 kok202/myRepository:v0.0.1 이라는 이미지 정보를 사용한다.
    image: kok202/myRepository:v0.0.1
    
    deploy:
      # 5개의 인스턴스를 사용한다.
      replicas: 5
      resources:
        limits:
          # 5개의 컨테이너는 10% 에 해당하는 cpu를 쓴다
          cpus: "0.1"
          # 50MB 의 메모리를 사용한다.
          memory: 50M
      restart_policy:
        # 실패하면 재시작한다.
        condition: on-failure
    
    ports:
      # 포트 4000 번은 컨테이너의 80번으로 연결된다.
      - "4000:80"
    
    networks:
      # 웹 컨테이너들은 로드 밸런서를 통해서 80번 포트를 공유해야한다.
      # webnet 이라는 로드 밸런서 네트워크를 통해 공유한다.
      - webnet

networks:
  webnet:
    # webnet 은 기본 설정을 사용한다. (로드 밸런싱이 되는 overly network)

docker-compose.yml 스택이 있다.

docker-compose.yml 이라는 스택에는 web 이라는 1개의 서비스가 존재한다.

web 이라는 서비스는 kok202/myRepository:v0.0.1 이라는 이미지를 이용한다.

web 이라는 서비스는 5개의 컨테이너로 중복해서 사용한다.

 

 

 

 

 

서비스 띄우기

로드 밸런싱이 되는 이미지를 실행해본다.

docker swarm init

docker stack deploy 를 통해서 서비스를 띄우려고 하는데 이를 위해 docker swarm 이라는 도커 클러스터를 이용하고자한다. 일단은 최대한 쉽게 클러스터 환경으로 (로컬 머신 하나 + 로컬 노드 하나)를 이용해보자. (그냥 docker-compose up& 하면 될 것 같은데...?)

docker stack deploy -c docker-compose.yml myApplication

docker stack 을 이용하여 docker-compose.yml 을 띄운다.

이를 통해 docker-compose.yml 안에 정의한 네트워크와 서비스를 생성한다.

docker service ls

위 커맨드를 실행하면 myApplication_web 이라는 서비스가 띄워져있는 것을 확인할 수 있다.

_web 은 docker-compose.yml 에서 정의한 서비스 이름인 web에 의해 붙은 이름이다.

아래 커맨드를 실행하면 5개의 인스턴스가 띄워져 있는 것을 확인 할 수 있다.

docker service ps myApplication_web

http://localhost:4000 에 접근하면 로드 밸런서에의해 Hostname 이 계속 바뀌는 것을 확인할 수 있다.

 

 

 

 

 

커맨드 라인 정리

docker stack ls                                  # 스택, 어플리케이션 리스트를 출력
docker stack deploy -c docker-compose.yml myApp  # 해당 경로안의 docker-compose.yml 을 myApp 이라는 이름으로 실행시킨다.
docker service ls                                # 실행중인 서비스 리스트를 출력한다.
docker service ps myApp                          # 특정 서비스 안에 동작중인 태스크 리스트를 출력한다.
docker inspect <task or container>               # 특정 태스크나 컨테이너를 상세히 본다. 
docker container ls -q                           # 컨테이너 아이디 리스트를 출력한다.
docker stack rm myApp                            # 어플리케이션을 종료한다.
docker swarm leave --force                       # swarm 노드를 관리자로부터 떨어뜨린다.

 

 

 

 

 

스택 (Swarm)

이 어플리케이션을 클러스터 환경에서 띄우고자 한다.

Swarm 이라고 불리는 도커 클러스터에서 배포할 수 있다.

Swarm Manager : 여러 컨테이너들을 어떻게 실행할지에 대한 전략 관리 머신

  • 머신이 3개고 컨테이너가 6개인 경우 
  • emptiest node 전략 : 머신 1개당 컨테이너 3개를 띄울 수 있다면 2개의 머신에 컨테이너 6개가 띄워진다.
  • global 전략 : 머신 1개당 최소 컨테이너 1개는 무조건 띄우는 것을 보장한다.
  • 등 ....

Swarm 모드를 활성화 시키면 (docker swarm init) 현재의 머신이 Swarm manager 가 된다. 그렇게 되면 앞으로의 docker 명령은 Swarm manger 에게 명령을 시키게 된다. docker swarm init 하면 밖의 머신에서 swarm 에 join 할 수 있다.

 

$ 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 ssh myvm1 "docker swarm init --advertise-addr 192.168.99.100"

myvm1 을 Swarm manager로 만든다.

docker-machine ssh myvm2 "docker swarm join --token <token> 192.168.99.100:2377"

myvm2 를 Swarm node 로 만들고 Swarm manager 와 연결한다. (token 은 Swarm manager가 생성될 때 출력해준다.)

docker-machine ssh myvm1 "docker node ls"

myvm1 을 통해서 myvm2 가 노드로 제대로 들어왔는지 확인한다.

 

 

 

 

 

매번 docker-machine ssh myvm1 을 달아주는 것이 힘들다.

그리고 docker-compose.yml 을 Swarm manager에서 실행시키기 위해선 myvm1 에 docker-compose.yml 을 다시 만들어 주거나 vm 으로 로컬에서 만든 docker-compose.yml 을 옮겨줘야한다. 현재 세션을 Swarm manager와 연결해서 docker-compose.yml 을 로컬에서 만들었던 것 그대로 사용해보자.

docker-machine env myvm1
eval $(docker-machine env myvm1)

이제 이 세션은 Swarm-manager와 연결되어있다.

docker stack deploy -c docker-compose.yml myApplication

myvm1 에서 서비스를 실행했다.

docker service ps myApplication_web

서비스의 컨테이너가 머신에 제대로 설치 되어있는지 확인한다.

 

http://192.168.99.100 에 접속해서 확인해본다.

docker stack rm myApplication

스택을 내릴 수 있다.

eval $(docker-machine env -u)

세션을 Swarm manager 와 끊는다.

 

 

 

 

 

커맨드 라인 정리

docker-machine create --driver virtualbox myvm1               # myvm1 이라는 VM 을 만든다.
docker-machine create --driver virtualbox myvm1               # myvm2 이라는 VM 을 만든다.
docker-machine env myvm1                                      # myvm1 에 대한 기본 정보를 본다.
docker-machine ssh myvm1 "docker node ls"                     # myvm1 에 docker node ls 커맨드를 실행 시킨다.
docker-machine ssh myvm1 "docker node inspect <node ID>"      # myvm1 에 연결된 특정 노드의 정보를 본다
docker-machine ssh myvm1 "docker swarm join-token -q worker"  # myvm1 의 docker swarm에 연결하기위한 토큰이 무엇인지 확인한다. 
docker-machine ssh myvm1                                      # myvm1 에 연결된 SSH 세션을 연다. 
docker node ls                                                # docker swarm 에 연결된 노드를 확인한다.
docker-machine ssh myvm2 "docker swarm leave"                 # myvm2 를 docker swarm 에서 떠나게 한다.
docker-machine ssh myvm1 "docker swarm leave -f"              # myvm1 (master) 를 docker swarm 에서 떠나게 하고 swarm 을 종료시킨다.
docker-machine ls                                             # 도커 머신 VM 리스트를 출력한다.
docker-machine start myvm1                                    # VM myvm1 을 실행시킨다.
docker-machine env myvm1                                      # myvm1 에 있는 시스템, 환경변수를 출력한다.
eval $(docker-machine env myvm1)                              # 현재 터미널의 세션을 myvm1 과 연결한다.
docker stack deploy -c <file> <app>                           # 어플리케이션을 배포한다. 이 과정에서 docker stack deploy 하는 세션은 반드시 swarm manger와 연결 되어있어야한다.
eval $(docker-machine env -u)                                 # 세션을 VM 에서 때어낸다. 
docker-machine stop $(docker-machine ls -q)                   # 모든 VM 을 종료한다.
docker-machine rm $(docker-machine ls -q)                     # 모든 VM 을 삭제하고 디스크 이미지도 삭제한다