Section3 도커스웜

image 시작하세요! 도커/쿠버네티스 책을 공부하면서 정리한 내용을 블로그에다 옮겨 적는 용도입니다

도커 스웜이란?

일단 내가 이해한 도커 스웜은

“여러 도커를 돌리고 싶은데, 서버내 확장의 한계가 있을 경우. 다른 서버에서 도커를 생성하고 그거를 한꺼번에 관리를 하는 개념”

으로 이해를 했다.

스웜 모드 vs 스웜 클래식

image

도커스웜

마스터노드 추가
docker swarm init --advertise-addr {host public ip} 

//아래와 같은 문구를 워커노드 서버에서 실행
To add a worker to this swarm, run the following command:

    docker swarm join --token SWMTKN-1-3aqv5tr857gawez19f4owzlp71or72bjhl71scoku2si1bcuw2-73eztw177e9pg9g7bggxdh8n6 43.201.19.46:2377

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

//2377 포트는 열어주기

스웜에서 떠나기
docker swarm leave
--->매니저 노드에서는 삭제로 안뜨기 때문에
매니저 노드에서는
docker node rm {HOSTNAME} 사용

매니저 노드 삭제
docker swarm leave --force

도커스웜내 노드 확인
docker node ls 

image

현재 내 도커 컴포즈에 들어와있는 마스터와 워커다. 둘 다 EC2내 서버에 있는 도커이다.

그리고 위와 같은 토큰은 어떻게 확인할까?

스웜 노드 추가 토큰 확인

docker swarm join-token manager //매니저 노드 추가
docker swarm join-token worker //워커노드 추가

스웜 노드 추가 토큰 변경

docker swarm join-token --rotate manager
docker swarm join-token --rotate worker

이렇게 하면 토큰이 바뀐다고 한다.

(단 ! 매니저 노드에서만 실행 가능)

$ docker info → 스웜 클러스터 정보 확인

노드 자격 변경

docker node promote {HOSTNAME} //워커노드를 매니저노드로 

docker node demote {HOSTNAME} //매니저노드를 워커노드로
!!단 매니저 노드가 하나일 경우에는 demote 불

스웜 모드 서비스

스웜 모드 서비스란?

스웜 모드에서 제어하는 단위는 컨테이너가 아닌 서비스

주요 키워드

  • Replica set
    • 정해진 레플리카 수가 유지되도록 노드에 컨테이너 할당(균등하게 할당 되는 보장 없음)
    • 레플리카가 있는 노드가 기능을 못하게 되면, 레플리카 수만큼 컨테이너를 다른 노드에서 생성
  • Rolling Update

    서비스는 컨테이너들의 이미지를 일괄적으로 데이트 할 때, 컨테이너들의 이미지를 순서대로 변경해 서비스 다운 방지 ⇒ 지속 서비스 가능

서비스 생성

서비스를 제어하는 도커 명령어는 모두 매니저 노드에서만 가능 !

docker service create {ubuntu:14.04} /bin/sh -c "while true; do echo hello world; sleep 1; done"

서비스 내의 컨테이너는 detached 모드.. -> 그러므로 프로세스를 실행시켜야 한다.
docker service create {ubuntu:14.04} -> 이 상태면 컨테이너가 정지된 상태라
서비스가 오류가 났다고 판단하여 계속 컨테이너를 재생성한다.

docker service ls / 서비스 목록 

docker service ps {서비스 NAME} / 동작중인 컨테이너나 할당된 노드 위치등 자세한 정보 출력

docker service rm {서비스 NAME} / 동작 유무 관계없이 서비스 삭제

docker service create --with-registry-auth / 프라이빗 저장소에서 이미지를 가져올 시
이를 추가하면 워커노드도 로그인 없이 가져올 수 있다 ! 

NGINX 서비스 생성 예시

docker service create --name myweb --replicas 2 -p 80:80 nginx 

이렇게 하면 myweb이라는 service에 노드들은 총 합 2개의 nginx 이미지의 컨테이너를 생성하게 되며, 호스트의 80번 포트로 접속하면 노드 중 하나의 컨테이너의 80번 포트로 포트포워딩을 하여 접속 가능해진다!

레플리카 셋 늘리기

docker service scale myweb=4

라운드-로빈은 CPU 스케쥴링에서 사용되는 용어로,

CPU 하나당 한번에 정해진 자원만큼 프로세스를 돌리고 그 이상 넘어가면 다른 CPU에게 넘기는 방식이다. 여기선 아마 노드가 CPU 역할이겠지?

Global 모드

글로벌 서비스는 스웜 클러스터내 사용할 수 있는 모든 노드에 컨테이너를 반드시 하나씩 생성하는 것을 원칙으로 한다. (스웜 클러스터를 모니터링하기 위한 에이전트 컨테이너 생성에 적합)

docker service create --name myweb --mode global nginx 

스웜모드의 서비스 장애복구

  • 컨테이너 다운 시 자동 생성
  • 노드 다운 시 컨테이너 자동 생성 ( ⇒ 이때 노드를 복구해도 컨테이너는 다시 돌아가지 않으므로 scale 작업 필요)

스웜 모드의 서비스 롤링 업데이트

docker service update --image {NAME:TAG} {SERVICE_NAME}
//순차적으로 업데이트

//서비스 생성시 업데이트 옵션
docker service create \
--replicas 4 \ 생성할 레플리카 
--name myweb \
--update-delay 10s\  업데이트 간격
--update-parallelism 2\ 동시 업데이트 할 컨테이너 수 
nginx:1.10 

//롤링업데이트 설정 확인 

docker service inspect / docker inspect --type service

On failure가 pause => 업데이트 중 오류 발생하면 롤링 업데이트 중지

--update-failure-action continue // 업데이트 중 오류 발생해도 롤링 업데이트 지

롤백 기능

docker service rollback myweb 

SECRET 과 CONFIG

secret 생성하기
docker secret create my_mysql_password -

secret 목록 확인하기
docker secret ls

docker secret inspect my_mysql_password 
  • Secret은 암호화된 상태로 저장하여 확인해도 값을 확인 못한다
  • Secret은 메모리에 저장되기 때문에, 서비스를 삭제하면 Secret도 사라진다.
docker config create registry-config config.yml

도커 네트워크

Ingress 네트워크

ingress 네트워크는 스웜을 생성하면 모든 노드에 생성되어 자동 등록되는 네트워크

역할

  • 라우팅 메시 구성(사용자가 어떤 노드에 접근하더라도 서비스 내 컨테이너롤 들어갈 수 있게 함)
  • 서비스 내 컨테이너에 대한 접근을 라운드-로빈으로 분산하는 로드밸런싱 담당
docker network ls | grep ingress
docker service create --name hostname -p 80:80 --replicas=4 alicek106/book:hostname
이후
docker service ps {servicename}으로 서비스 모니터링 
**ingress 네트워크를 사용하는 것이 포트 및 서비스 관리에 용이** 

사용하지 않고 외부에 개방 시 어느 호스트에 컨테이너가 생성되는지 알 수 없음

ex)ingress 네트워크를 사용안하고 외부 개방 예시
docker service create --publish mode=host , target=80, published=8080, protocol=tcp --name web nginx

오버레이 네트워크

오버레이 네트워크는 여러 개의 도커데몬을 하나의 네트워크 풀로 만드는 네트워크 가상화 기술

따로 포트포워딩을 안해도 컨테이너간 통신이 가능하다.

  • Trouble Shooting

    컨테이너의 private ip로 핑을 전송하면 이런 오류가 뜨고

    image

    퍼블릭 IP로 접근하면 이런 오류가 뜨는데 뭘까…

    image

    예측하자면 보안규칙에서 포트개방의 문제일 가능성이 크다.

사용자 정의 오버레이 네트워크

myoverlay라는 사용자 정의 오버레이 네트워크 생성
docker network create --subnet 10.0.9.0/24 -d overlay myoverlay

**--attachable 옵션을 추가하면 docker run --net {network_name} {image} 로 도커를 구동 시
스웜 모드의 오버레이 네트워크를 사용할 수 있다.**

사용자 정의 네트워크를 적용하고 컨테이너 생성
docker service create --name {SERVICE NAME}\
--network {NETWORK_NAME} \
--replicas 2 \
{username/image:tag}

여기서 -p를 명시해주지 않으면 외부에 노출이 안되기 때문에, ingress 및 docker_gwbridge 네트워크를 사용하지 않게 된다.

SERVICE DISCOVERY

스웜 모드 볼륨

Docker 데몬에서는

호스트와 디렉터리 공유
docker run -i -t --name host_dir_case -v /root:/root ubuntu:14.04

도커 볼륨을 사용하는 경우
docker run -i -t --name volume_case -v myvolume:/root ubuntu:14.04

볼륨생성

스웜 모드에서 도커볼륨을 사용하는 서비스를 만들기 위해서는 source, target 옵션이 필요하다.

source는 사용할 볼륨 그리고 target은 컨테이너 내부에 마운트될 디터리의 위치

docker service create --name ubuntu \
--mount type=volume, source=myvol, target=/root \
ubuntu:14.04 \
ping docker.com

**source 옵션을 명시하지 않을 16진수의 익명의 볼륨이 생성된다**

볼륨은 호스트 내부에 공간을 차지하고, 해당 볼륨으로 컨테이너를 생성할 시에는 컨테이너의 target에 명시한 디렉터리에 있는 파일을 볼륨으로 복사하게 된다.

docker service create --name ubuntu \
--mount type=volume, source=test, target=/etc/vim \
ubuntu:14.04 \
ping docker.com

만약 볼륨에 복사하는 걸 방지하고 싶을 시, volume-nocopy 옵션 추

docker service create --name ubuntu \
--mount type=volume, source=test, target=/etc/vim, volume-nocopy \
ubuntu:14.04 \
ping docker.com

Bind 타입의 볼륨 생성

바인드 타입은 호스와 디렉터리를 공유할 때 사용


컨테이너의 root/container에 호스트의 /root/host 디렉터리가 마운팅 된다.

docker service create --name ubuntu \
--mount type=bind, source=/root/host, target=/root/container \
ubuntu:14.04 \
ping docker.com

문제점

  • 서비스를 할당받을 수 있는 모든 노드가 볼륨데이터를 가지고 있어야 한다.
  • 어느 노드에서든 접근 가능한 퍼시스턴트 스토리지 사용이 요구된다.
  • But 도커가 자체적으로 제공하지 않으므로, 서드파티를 이용해 구성해야한다.

도커 노드

도커 노드 AVAILABILITY

  • ACTIVE

    ACTIVE 상태가 아닌 노드를 ACTIVE 상태로

      docker node update \
      --availability active \
      swarm-worker1
    
  • DRAIN

    특정 NODE에 컨테이너 할당 방지, 노드 내 기존 컨테이너 중지되고 ACTIVE 노드로 할당

      docker node update \
      --availability drain \
      swarm-worker1
    
  • PAUSE

    DRAIN과 기능은 유사하지만, 노드 내 컨테이너 중지되지 않음

      docker node update \
      --availability pause \
      swarm-worker1
    

노드 라벨

노드 라벨 추가

docker node update \
--label-add storage=ssd \
swarm-worker1

설정된 라벨은 docker node inspect {CONTAINER_NAME} 으로 확인 가