본문 바로가기
docker

docker swarm

by misankim 2023. 3. 6.
docker swarm

 

공식 사이트 문서

 

docker swarm 은 도커 엔진 기반이며, 설정이 빠르고 간단하며, 소형~중형 서비스에 적합
반면에 kubernetes 는 기본 구성 서비스의 종류가 많고 클러스터의 모든 설정을 yaml 파일로 구성 가능, 중형~대형 서비스에 적합

 

docker swarm 은 도커 엔진에 기본으로 포함되어 있어서 도커만 설치되어 있다면 바로 사용 가능



# swarm 활성화
-> 매니저 노드 역할을 수행할 도커 서버에서만 수행

 

docker swarm init

 

인터페이스가 여러개인 경우(매니저 노드의 아이피 지정)
docker swarm init --advertise-addr 192.168.2.10

 

swarm 모드 활성화 확인
docker info | grep Swarm

 

(참고) swarm 비활성화는 
docker swarm leave --force

 

(참고) docker swarm init 명령어 실행 시 출력되는 join 커맨드

 

[root@ip-10-0-10-146 ~]# docker swarm init
Swarm initialized: current node (d6manfiv3f3lmj3y42y1q4xiy) is now a manager.


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


docker swarm join --token SWMTKN-1-47g6dxdba328sahzqcia8mr9afpyye5i92i1n6xg3smwjlxl11-d6bdun9atw9bhynmlqrv3ve38 10.0.10.146:2377


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



# 노드 조인

 

워커 노드의 경우 매니저 노드에서 docker swarm init 시 출력된 아래와 같은 커맨드를 워커 노드에서 실행

 

docker swarm join --token SWMTKN-1-47g6dxdba328sahzqcia8mr9afpyye5i92i1n6xg3smwjlxl11-d6bdun9atw9bhynmlqrv3ve38 10.0.10.146:2377

 

매니저 노드의 경우 조인을 위한 토큰을 별도로 생성 후 출력되는 커맨드를 매니저 노드로 조인할 도커 호스트에서 실행

 

[root@ip-10-0-10-146 ~]# docker swarm join-token manager
To add a manager to this swarm, run the following command:


docker swarm join --token SWMTKN-1-47g6dxdba328sahzqcia8mr9afpyye5i92i1n6xg3smwjlxl11-1cp12ae22c2wu20gvu98ge6jt 10.0.10.146:2377



# 노드 확인

 

[root@ip-10-0-10-146 ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
d6manfiv3f3lmj3y42y1q4xiy * ip-10-0-10-146.ap-northeast-2.compute.internal Ready Active Leader 20.10.5
pkomna26sfaxtrqlak43l3uj9 ip-10-0-10-152.ap-northeast-2.compute.internal Ready Active 20.10.5

 

(참고) 노드 간 통신에 사용하는 포트

 

클러스터 관리 통신을위한 TCP 포트 2377
노드 간 통신을위한 TCP 및 UDP 포트 7946
오버레이 네트워크 트래픽을위한 UDP 포트 4789

 

(참고) 매니저 노드 운영 가이드(고가용성 구성 등)

 



# swarm 노드 제거

 

노드 리스트 확인
docker node ls

 

스웜에서 제거될 노드에서
docker swarm leave

 

매니저 노드에서 대상 노드 제거
docker node rm 노드_ID



# 예제1 - bootcamp 서비스 생성

 

서비스 생성
docker service create -p 8080:8080 --name bootcamp gcr.io/google-samples/kubernetes-bootcamp:v1

 

서비스 리스트 확인
docker service ls

 

서비스 상태 확인
docker service ps bootcamp

 

서비스 상세 내용 확인
docker service inspect bootcamp --pretty

 

서비스 삭제
docker service rm bootcamp

 

스케일 아웃
docker service scale bootcamp=4



# 롤링 업데이트

 

--update-parallelism 0 은 한번에 모든 컨테이너 교체

 

docker service update --update-parallelism 1 --image jocatalin/kubernetes-bootcamp:v2 bootcamp



# 롤백

 

docker service update --rollback bootcamp



# 예제2 - bootcamp 스택 생성

 

 

스택은 여러 서비스를 묶은 단위 -> docker-compose 로 배포하는 것과 유사

 

스택 배포를 위한 yaml 파일 작성

 

vim bootcamp-stack.yaml

 

version: '3.7'
services:
    bootcamp:
        image: gcr.io/google-samples/kubernetes-bootcamp:v1
        deploy:
            mode: replicated
            replicas: 4
        ports:
            - "8080:8080"

 

스택 배포
docker stack deploy -c bootcamp-stack.yaml bootcamp
docker stack ls
docker service ls

 

접속 테스트(각 노드의 아이피로 접속 가능, 노드간 트래픽 로드밸런싱)
http://노드_아이피주소:8080/

 

스택 삭제
docker stack rm bootcamp

 

(참고) 프라이빗 도커 레지스트리에서 이미지를 풀링하려면 docker login 과 더불어 docker stack deploy 명령어 실행 시 --with-registry-auth 옵션 필요

 

docker stack deploy -c docker-compose.yaml gnuboard --with-registry-auth



# swarm 네트워크 설정

 

 

overlay 네트워크는 여러 도커 호스트 사이에서 통신하기 위한 네트워크 드라이버
오버레이 네트워크로 컨테이너가 실행 중인 호스트로 트래픽 전달

 

서비스 생성 시 기본으로 ingress 라는 오버레이 네트워크를 사용함

 

스택 생성 시 기본으로 "스택이름_default" 라는 이름의 오버레이 네트워크가 생성됨

 

compose 파일에 networks 옵션으로 특정 네트워크 이름으로 지정하면 "스택이름_네트워크이름" 라는 이름의 오버레이 네트워크 생성됨



# 예제 - zabbix 스택 생성

 

[root@ip-10-0-10-146 zabbix]# cat docker-compose.yml 
version: '3.3'
services:
    zabbix:
        networks:
            - zabbix-overlay
        environment:
            - DB_SERVER_HOST=mysql
            - MYSQL_USER=zabbix
            - MYSQL_PASSWORD=password
        image: 'zabbix/zabbix-server-mysql:centos-4.0-latest'
    zabbix-web:
        ports:
            - '8080:8080'
            - '8443:8443'
        networks:
            - zabbix-overlay
        environment:
            - ZBX_SERVER_HOST=zabbix
            - ZBX_SERVER_PORT=10051
            - DB_SERVER_HOST=mysql
            - MYSQL_USER=zabbix
            - MYSQL_PASSWORD=password
            - PHP_TZ=Asia/Seoul
        image: 'zabbix/zabbix-web-apache-mysql:centos-4.0-latest'
    mysql:
        volumes:
            - '/var/lib/mysql:/var/lib/mysql'
        networks:
            - zabbix-overlay
        environment:
            - MYSQL_ROOT_PASSWORD=password
            - MYSQL_DATABASE=zabbix
            - MYSQL_USER=zabbix
            - MYSQL_PASSWORD=password
        image: 'mysql:5.7'
        command: --max_allowed_packet=64M --log-bin=/var/lib/mysql/bin.log --binlog_cache_size=2M --max_binlog_size=512M --expire_logs_days=7 --server-id=1 --skip-character-set-client-handshake --character-set-server=utf8 --collation-server=utf8_general_ci

networks:
  zabbix-overlay:
docker stack deploy -c docker-compose.yml zabbix



# nfs 볼륨 설정

 

 

## nfs 서버 및 클라이언트에 설치

 

yum install -y nfs-utils

 

## nfs 서버 세팅(aws efs 를 사용하는 경우 스킵)

 

mkdir /nfsvol
chown nfsnobody:nfsnobody /nfsvol
chmod 777 /nfsvol
echo "/nfsvol *(rw,async,no_root_squash)" > /etc/exports.d/nfs.exports


systemctl start nfs-server && systemctl enable nfs-server


systemctl status nfs-server


exportfs -v

 

## 서비스를 위한 볼륨 디렉토리 생성

 

nfs 서버에서
mkdir /nfsvol/DB_data

 

## nfs 볼륨을 사용하는 서비스 생성

 

192.168.2.30 -> nfs 서버의 아이피
:/nfsvol/DB_data -> nfs 서버의 경로
/var/lib/mysql -> 볼륨을 마운트할 컨테이너 내부 경로
DB_data -> docker volume 이름

 

docker service create -d \
 --name mysql \
 --mount 'type=volume,source=DB_data,target=/var/lib/mysql,volume-driver=local,volume-opt=type=nfs,volume-opt=device=:/nfsvol/DB_data,"volume-opt=o=addr=192.168.2.30,rw,nfsvers=4,async"' \
 -e MYSQL_ROOT_PASSWORD=password \
 -e MYSQL_DATABASE=gnuboard \
 -e MYSQL_USER=gnu \
 -e MYSQL_PASSWORD=board \
 mysql:5.7

 

## 볼륨과 서비스 따로 만들기

 

docker volume create --driver local \
  --opt type=nfs \
  --opt o=addr=192.168.2.30,rw,nfsvers=4,async \
  --opt device=:/nfsvol/DB_data \
  DB_data

docker service create -d \
 --name mysql \
 --mount "type=volume,source=DB_data,destination=/var/lib/mysql" \
 -e MYSQL_ROOT_PASSWORD=password \
 -e MYSQL_DATABASE=gnuboard \
 -e MYSQL_USER=gnu \
 -e MYSQL_PASSWORD=board \
 mysql:5.7

 

## docker-compose 로 스택 생성

 

vim docker-compose.yaml

 

version: "3.2"
services:
    mysql:
        volumes:
        - type: volume
            source: DB_data
            target: /var/lib/mysql
        environment:
            - MYSQL_ROOT_PASSWORD=password
            - MYSQL_DATABASE=gnuboard
            - MYSQL_USER=gnu
            - MYSQL_PASSWORD=board
        image: 'mysql:5.7'

volumes:
    DB_data:
        driver: local
        driver_opts:
            type: "nfs"
            o: addr=192.168.2.30,rw,nfsvers=4,async
            device: ":/nfsvol/DB_data"
docker stack deploy -c docker-compose.yaml mysql






'docker' 카테고리의 다른 글

Alpine Linux로 Docker 이미지 빌드  (0) 2023.03.13
Docker buildx를 통한 멀티 플랫폼 이미지 빌드  (0) 2023.03.11
traefik 리버스 프록시 로드밸런서  (1) 2023.03.06
docker buildx  (0) 2023.03.06