engal1991 / Docker-Kubernetes

0 stars 0 forks source link

[03장: 도커 스웜] 3.3 스웜 모드 #11

Open engal1991 opened 2 years ago

engal1991 commented 2 years ago

별도의 설치 없이 도커 엔진 자체에 내장되어있다. 기본적으로 스웜모드는 비활성화 되어있다.

3.3.1 도커 스웜 모드의 구조

매니저 노드

워커 노드

3.3.2 도커 스웜 모드 클러스터 구축

  1. docker swarm init --advertise-addr <manager node ip>
    • 매니저 역할을 할 서버에서 스웜 클러스터를 시작
  2. docker swarm join-token manager|worker
    • manager|worker에 추가하기위한 token 생성
    • 외부에 노출되지 않도록 주의
    • --rotate옵션을 사용하여 토큰 갱신 (매니저 노드에서 실행)
  3. docker swarm join --token <token>
    • 새로운 워커 노드를 스웜 클러스터에 추가
  4. docker node ls, docker info
    • 도커 서버가 정상적으로 스웜 클러스터에 추가됐는지 확인.
    • 매니저 노드에서 실행
  5. docker swarm leave && docker node rm <node name>
    • 추가된 워커 노드 삭제 (삭제할 워커 노드에서 실행)
    • 매니저 노드 삭제를 위해서는 --force 옵션 추가. (클러스터 데이터도 삭제되니 주의해야함)
    • leave만 수행하면 매니저 노드는 해당 워커 노드를 down 상태로만 인지하기 때문에 삭제도 수행 해야 함
  6. docker node promote <node name>
    • 워커 노드는 매니저 노드로 변경
  7. docker node demote
    • 매니저 노드를 워커 노드로 변경

3.3.3 스웜 모드 서비스

3.3.3.1 스웜 모드 서비스 개념

서비스

태스크

레플리카

롤링 업데이트

3.3.3.2 서비스 생성

첫 번째 서비스 생성해보기

  1. docker service create <image name> <option:command>
    • 서비스 생성하기
    • docker run의 옵션들과 비슷
    • --with-registry-auth 로 매니저 노드에서 로그인한 정보로 워커 노드에서 이미지 다운로드 가능
  2. docker service ls
    • 서비스 목록 확인
    • 서비스 이름이 무작위로 생성됨
  3. docker service ps <service name>
    • 서비스 정보 확인
  4. docker service rm <service name>
    • 서비스 삭제

nginx 웹 서버 서비스 생성하기

  1. docker service create --replicas 2 -p 80:80 <image name> <option:command>
    • replicaset을 2개 생성
    • 클러스터에 80 포트 개방 -> 매니저/워커 어떤 노드로 접근해도 nginx 접속 가능
    • 라운드 로빈 방식으로 요청을 어떤 컨테이너로 전달할지 결정

global 서비스 생성하기

  1. 글로벌 모드란?
    • 스웜 클러스터 내에서 사용할 수 있는 모든 노드에 컨테이너를 반드시 하나씩 생성
    • 레플리카셋 수를 별도로 지정하지 않음
    • 모니터링 에이전트에 적합
  2. docker service create --mode global <image name> <option:command>
    • --mode global 옵션 추가

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

복제 모드로 설정된 서비스의컨테이너가 정지하거나 특정 노드가 다운되면 스웜 매니저는 새로운 컨테이너를 생성해 자동으로 이를 복구한다. 다운됐던 노드를 다시 시작해 정상적인 상태를 회복해도 장애를 보국하기 위해 다른 노드로 옮겨진 컨테이너가 해당 노드에 자동으로 할당되지 않는다. (rebalancing 작업이 일어나지 않는다.) 서비스의 컨테이너 할당의 균형을 맞추기 위해서는 아래 명령어를 이용하면 된다. docker service scale <service name>=<num of service>

3.3.3.4 서비스 롤링 업데이트

  1. docker service update --image <image name> <service name>
    • 생성된 서비스 각종 설정을 변경
    • serivce name이 \_로 시작하면 이전 버전으로 삭제된 컨테이너를 의미
  2. docker service inspect --pretty <service name>
    • 롤링 업데이트 설정 확인
  3. docker service rollback <serivce name>
    • 이전 버전으로 롤백

3.3.3.5 서비스 컨테이너에 설정 정보 전달하기 : config, secret

스웜모드와 같은 서버 클러스터에서 파일 공유를 위해 설정 파일을 호스트 마다 마련해두는 것은 매우 비효율적이다. 비밀번호 등 보안에 민감한 정보를 환경변수로 설정하는 거도 좋은 방법은 아니다. 이를 위해 스웜 모드는 config, secret 기능을 제공한다.

secret 사용하기

  1. docker secret create <secret name> <file name | ->
    • secret 생성
    • -는 stdin을 의미
  2. docker secret ls, docker secret inspect <secret name>
    • secret 확인
  3. 서비스 생성 시 secret 키 활용하기

    docker service create \
    --name <service name> \
    --replicas 1 \
    --secret source=<secret name>,target=<secret file name> \
    -e <env key>=<env value> \
    <image name>
    • secret key는 컨테이너의 /run/secrets/<target value>에 저장된다.

config 사용하기 config 사용 방법은 secret과 거의 동일하다.

  1. docker config create <config name> <config file>
    • config 생성
  2. docker config ls, docker config inspect <config name>
    • config 확인
  3. echo <config[0].Spec.Data> | base64 -d
    • docker config inspect의 결과 에서 Dada 값을 base64로 디코딩 하면 원본 내용을 확인할 수 있다.
  4. 서비스 생성 시 config 활용하기

    docker service create --name <service name> \
    --config source=<config name>,target=<config file path> \
    <image name>
    • config 값은 target value에 지정한 경로에 저장된다.

추가 secret, config의 값을 수정할 수는 없지만 서비스 컨테이너가 새로운 값을 사용해야 한다면 docker service update 명령어에 아래 옵션을 추가하면 된다. 이미지를 다시 빌드할 필요 없이 바로 적용된다.

3.3.3.6 도커 스웜 네트워크

스웜 모드는 여러 개의 도커 엔진에 같은 컨테이너를 분산해서 살당하기 때문에 각 도커 데몬의 네트워크가 하나로 묶인, 네트워크 풀이 필요하다. 또한 서비스를 외부로 노출했을 때 어느 노드로 접근하더라도 해당 서비스의 컨테이너에 접근할 수 있게 라우팅 기능이 필요하다.

네트워크 목록 확인 docker network ls

네트워크 종류 :

ingress 네트워크 스웜 클러스터를 생성하면 자동으로 등록되는 네트워크이다. docker network ls | grep ingressswarm 으로 설정되어있다.

image 어떤 스웜 노드에 접근하더라도 서비스 내의 컨테이너에 접근할 수 있게 설정하는 라우팅 메시를 구성하고, 서비스 내의 컨테이너에 대한 접근을 라운드 로빈 방식으로 분산하는 로드 밸런싱을 담당한다.

아래와 같이 호스트의 특정 포트를 노출할 수 있다. 하지만 어느 호스트에서 컨테이너 생성될지 알 수 없어 포트 및 서비스 관리가 어렵다. 가급적 ingress 네트워크를 사용해 외부로 서비스를 노출하는것이 바람직하다.

docker service create \
--publish mode=host,target=<container port>,published=<host port>,protocol=tcp \
-- name <service name> \
<image name>

오버레이 네트워크 여러 개의 도커 데몬을 하나의 네트워크 풀로 만드는 네트워크 가상화 기술이다. 도커에 오버레이 네트워크를 적용하면 여러 도커 데몬에 존재하는 컨테이너가 서로 통신할 수 있다.

image

docker_gwbridge 네트워크 외부로 나가는 통신 및 오버레이 네트워크의 트래픽 종단점(VTEP) 역할을 담당

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

  1. docker network create --subnet <ip band> -d <driver type:overlay, bridge etc..> <network name>
    • 오버레이 네트워크 생성
    • 스웜 모드의 오버레이 네트워크를 사용하기 위해서는 --attatchable 옵션 추가
  2. docker service create --name <service name> --network <network name> --replicas <num> <image name>
    • 오버레이 네트워크를 서비스에 적용한 컨테이너 생성

3.3.3.6 서비스 디스커버리

같은 컨테이너를 여러 개 만들어 사용할 때 새로 생성된 컨테이너의 발견 혹은 삭제된 컨테이너의 감지가 중요하다. 동일한 서비스에는 같은 VIP를 발급하여 서비스가 추가되어도 문제없이 동작한다. VIP외에 서비스 생성 시 --endpoint-mode dnsrr 옵션으로 도커 내장 DNS 서버를 기반으로 라운드 로빈을 사용할 수 있다. 그런데 이 경우 애플리케이션에 따라 캐시 문제로 인해 서비스 발견이 정상적으로 작동하지 않을 때가 있으므로 가급적 VIP를 사용하는 것이 좋다.

docker service create --name <service name> \
--replicas <num> \
--network <overlay network name> \
--endpoint-mode dnsrr \
<image name>

3.3.3.7 스웜 모드 볼륨

volume 타입의 볼륨 생성 도커 내부적으로 관리해주는 볼륨 타입.

docker service create \
  --name <service name> \
  --replicas <num> \
  --mount type=volume,source=<volume name>,destination=<container directory>,volume-label=<label name>, volume-nocopy \
  <image name>

bind 타입의 볼륨 생성 호스트와 디렉터리를 공유할 때 사용함.

docker service create \
  --name <service name> \
  --replicas <num> \
  --mount type=bind,source=<host directory>,destination=<container directory>,volume-label="color=red",volume-label="shape=round", volume-nocopy \
  <image name>

스웜 모드에서 볼륨의 한계점 서비스를 할당받을 수 있는 모든 노드가 볼륨 데이터를 가지고 있어야 하기 때문에 사용하기가 까다롭다. 따라서 여러 개의 도커 데몬을 관리해야하는 스웜 모드에서는 도커 보륨, 또는 호스트와의 볼륨 사용이 적합하지 않을 수 있다. 이를 위해서 호스트와 컨테이너와 별개로 외부에 존재해 네트워크로 마운트하는 스토리지인 퍼시스턴스 스토리지를 사용할 수 있다. 또는 라벨로 서비스 제한을 할 수 있지만, 좋은 방법은 아니다.

3.3.4 도커 스웜 모드 노드 다루기

3.3.4.1 노드 AVAILABILITY 변경하기

특정 노드의 AVAILABILITY를 설정하여 컨테이너의 할당 가능 여부를 변경할 수 있다. docker node update --avalability <active|drain|pause> <node name>

Active 노드가 서비스의 컨테이너를 할당받을 수 있는 상태

Drain 컨테이너를 해당 노드에 할당하지 않음 해당 노드에서 실행중이던 서비스의 컨테이너는 전부 중지되고 Active 상태의 노드로 다시 할당

Pause 컨테이너를 해당 노드에 할당하지 않음 실행 중인 컨테이너가 중지되지 않음 (pause와 차별점)

3.3.4.2 노드 라벨 추가

특정 노드에 라벨을 추가하면 서비스를 할당랗 때 컨테이너를 생성할 노드의 그룹을 선택하는 것이 가능.

노드 라벨 추가 docker node update --label-add <key>=<value> <node name>

서비스 제약 설정

docker service create --name <service name> \
--constraint '<key> == <value>'
--constraint '<key> != <value>'
...
<image name>