Docker Swarm 환경 구성 방법
1. 구성도
예시
- 이해를 돕기 위한 참고 사진이며, 실제 구축한 테스트 환경과는 차이가 있습니다.
- 실제 구축 환경
- Master Node: 1
- Worker Node: 2
- Replicas: 3
- 실제 구축 환경
2. Docker Swarm 설치
2-1) Master / Worker Node 공통
사전 설치 환경 구성
👇 hostname 변경
# Master Node Server
[root@hyunseok ~]# hostnamectl set-hostname hyunseok.master.node
[root@hyunseok ~]# hostname
hyunseok.master.node
# Worker Node Server
[root@hyunseok ~]# hostnamectl set-hostname hyunseok.worker.node
[root@hyunseok ~]# hostname
hyunseok.worker.node
👇 selinux 끄기
# selinux 상태 확인 (예: enabled 상태)
[root@hyunseok ~]# setstatus
SELinux status: enabled
SELinuxfs mount: /sys/fs/selinux
SELinux root directory: /etc/selinux
Loaded policy name: trageted
Current mode: enforcing
Mode from config file: enforcing
Policy MLS status: enabled
Policy deny_unknown status: allowed
Max kernel policy version: 28
# 끄는 방법
SELinux status: enabled -> disabled 로 변경 후 저장
[root@hyunseok ~]# reboot
[root@hyunseok ~]# sestatus (예: disabled 상태)
SELinux status: disabled
👇 swap 끄기
# 명령어 수행
[root@hyunseok ~]# swapoff -a
# /etc/fstab 파일 수정
[root@hyunseok ~]# vi /etc/fstab
#
# /etc/fstab
# Created by anaconda on Mon Nov 16 13:44:40 2020
#
# Accessible filesystems, by reference, are maintained under '/dev/disk'
# See man pages fstab(5), findfs(8), mount(8) and/or blkid(8) for more info
#
/dev/mapper/centos-root / xfs defaults 0 0
UUID=281f8916-8dda-4194-8b6c-5bef589e8d99 /boot xfs defaults 0 0
/dev/mapper/centos-home /home xfs defaults 0 0
#/dev/mapper/centos-swap swap swap defaults 0 0 해당 라인 주석 처리
👇 방화벽 끄기
# CentOS/RHEL의 경우
[root@hyunseok ~]# systemctl stop firewalld
[root@hyunseok ~]# systemctl disable firewalld
# Ubuntu의 경우
[root@hyunseok ~]# systemctl stop ufw
[root@hyunseok ~]# systemctl disable ufw
👇 Docker 설치
# CentOS/RHEL의 경우
[root@hyunseok ~]# yum install -y docker
[root@hyunseok ~]# systemctl start docker
[root@hyunseok ~]# systemctl enable docker
# Ubuntu의 경우
[root@hyunseok ~]# apt update
[root@hyunseok ~]# apt install apt-transport-https ca-certificates curl software-properties-common
[root@hyunseok ~]# curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo apt-key add -
[root@hyunseok ~]# add-apt-repository "deb [arch=amd64] https://download.docker.com/linux/ubuntu bionic stable"
[root@hyunseok ~]# apt update
[root@hyunseok ~]# apt-cache policy docker-ce
[root@hyunseok ~]# apt install docker-ce
2-2) Master Node
- Master only 명령어
- --advertise-addr
- Master Node Server IP
- --advertise-addr
👇 Docker Swarm init
[root@hyunseok ~]# docker swarm init --advertise-addr [Master Node Server IP]
Swarm initialized: current node (pm5wht6yr3j1kya1x5fw4sw76) is now a manager.
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-5ffatin2e5y4erez3a7frqxo5061upb7hhw7y5c2rslm5slydd-4o4zy702xoydt8l15llxedor2 192.168.188.101:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
위 명령어 수행 후 표기되는 "docker swarm join ~" 내용 복사
2-3) Worker Node
- Worker only 명령어
- 위에서 복사한 "docker swarm join ~" 붙여넣기
# Master Node에 소속되기
[root@hyunseok ~]# docker swarm join --token SWMTKN-1-5ffatin2e5y4erez3a7frqxo5061upb7hhw7y5c2rslm5slydd-4o4zy702xoydt8l15llxedor2 192.168.188.101:2377
- 소속 여부 확인
- Master Node에서 아래 명령어 수행
[root@hyunseok ~]# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
pm5wht6yr3j1kya1x5fw4sw76 * hyunseok.docker.master Ready Active Leader 19.03.13
fvj8wpgmpggfsjsem4t05gc0o hyunseok.docker.worker1 Ready Active 19.03.13
z0uvi0405iuf7z7v4mjf5wwj1 hyunseok.docker.worker2 Ready Active 19.03.13
3. 테스트 환경 구성 가이드
3-1) Docker Registry 구축
각 Docker Host Node에 같은 이미지를 배포하는 두 가지 방법이 있습니다.
- DockerHub
- Registry
필자는 사설 Registry를 활용하여 테스트 환경을 구축하였으며, 그 방법에 대해 서술합니다.
👇 Docker registry 구축 방법
# registry 이미지 가져오기
[root@hyunseok ~]# docker pull registry
# 이미지 확인하기
[root@hyunseok ~]# docker images
# registry 실행하기
[root@hyunseok ~]# docker run -dit --name docker-registry -p 5000:5000 registry
3-2) Docker Image Push 방법 (on localhost)
👇 이미지 Build 및 Push 관련 명령어
# 이미지가 없으니 본 Docs의 첨부 파일을 사용하여 Build 먼저 수행한다.
[root@hyunseok ~]# docker build -t hyunseok:v1 .
# 이미지 Tag 변경 방법
[root@hyunseok ~]# docker tag hyunseok:v1 localhost:5000/hyunseok:v1
# 이미지 Push 방법
[root@hyunseok ~]# docker push localhost:5000/hyunseok:v1
# 이미지 확인 방법
[root@hyunseok ~]# curl -X GET http://localhost:5000/v2/_catalog
{"repositories":["hyunseok"]}
위 설정까지만 완료하여도, 해당 이미지를 통해 서비스 실행이 가능합니다.
하지만 Worker Node에 까지 해당 이미지를 통해 서비스를 실행하려면 사설 Registry와 통신이 가능하게끔 설정을 해줘야 합니다.
3-3) Docker Image Push 방법 (on Remote server: registry 서비스가 실행되지 않는 서버)
이미지 태그명을 보면 localhost/~ 로 되어 있는 것을 볼 수 있습니다.
하지만 Remote server (이하 '원격지')에서는 특정 도메인 또는 IP로 접근을 하기 때문에 localhost, 127.0.0.1을 사용할 수 없습니다.
도메인을 통해 접근 할 수 있도록 아래 작업을 선 수행합니다.
👇 vi /etc/hosts
# localhost, 원격지 공통
[root@hyunseok ~]# cat /etc/hosts
192.168.188.111 hyunseok.pri-registry.com
원격지에서 이미지를 Push 해봅니다.
👇 이미지 Push -> Fail
# 테스트용 이미지를 pull 한다.
[root@hyunseok ~]# docker pull hello-world
# 설정한 도메인으로 Tag를 변경한다.
[root@hyunseok ~]# docker tag hello-world hyunseok.pri-registry.com:5000/hello-world
# 이미지가 생성되었는지 확인한다.
[root@hyunseok ~]# docker images
# 이미지를 Push -> 실패한다.
[root@hyunseok ~]# docker push hyunseok.pri-registry.com:5000/hello-world
Get https://hyunseok.pri-registry.com:5000/v1/_ping: http: server gave HTTP response to HTTPS client
실패한 이유는, Docker Registry는 로컬 머신에서 사용하는 것이 아니라면 https만을 지원하기 때문입니다.
원격지에서 접속하기 위해서는 insecure-registries 옵션을 설정하여 인증되지 않은 registry를 사용 할 수 있도록 해야 합니다.
Remote Server Only
👇 vi /etc/docker/daemon.json
# insecure-registries 옵션 설정
[root@hyunseok ~]# cat /etc/docker/daemon.json
{
"insecure-registries" : ["hyunseok.pri-registry.com:5000"]
}
# Docker service 재실행
[root@hyunseok ~]# systemctl restart docker
위 작업을 마친 후 다시 Push 하면 정상 동작함을 확인 할 수 있습니다.
3-4) 서비스 배포
Nodes가 사설 registry를 사용 할 수 있게 설정을 완료했다면, 생성한 images를 이용해서 Docker Swarm Mode로 서비스를 배포합니다.
👇 서비스 배포 관련 명령어
# 서비스 배포
[root@hyunseok ~]# docker service create --name hyunseok -p 80:80 hyunseok.pri-registry.com:5000/hyunseok:v1
# 서비스 시작 중
[root@hyunseok ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
me0v9wcnkfhw hyunseok replicated 0/1 hyunseok.pri-registry.com:5000/hyunseok:v1 *:80->80/tcp
# 서비스 시작 완료
[root@hyunseok ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
me0v9wcnkfhw hyunseok replicated 1/1 hyunseok.pri-registry.com:5000/hyunseok:v1 *:80->80/tcp
# hyunseok 서비스 확인
[root@hyunseok ~]# docker service ps hyunseok
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
prpe0rpvsqu4 hyunseok.2 hyunseok.pri-registry.com:5000/hyunseok:v1 hyunseok.docker.master Running Running 1 minutes ago
3-5) 서비스 복제
컨테이너 1개로 서비스를 하기에는 안정성이 떨어집니다.
안정성 확보 및 성능 향상을 위해 컨테이너를 복제합니다.
👇 service scale 명령어
# docker service scale [서비스 이름]=[복제하기 원하는 개수]
[root@hyunseok ~]# docker service scale hyunseok=3
# 서비스 확인 1
[root@hyunseok ~]# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
me0v9wcnkfhw hyunseok replicated 3/3 hyunseok.pri-registry.com:5000/hyunseok:v1 *:80->80/tcp
# 서비스 확인 2
[root@hyunseok ~]# docker service ps hyunseok
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
nhmb93qrcpb8 hyunseok.1 hyunseok.pri-registry.com:5000/hyunseok:v1 hyunseok.docker.worker1 Running Running 24 minutes ago
prpe0rpvsqu4 hyunseok.2 hyunseok.pri-registry.com:5000/hyunseok:v1 hyunseok.docker.master Running Running 24 minutes ago
3u9dnslh9ox1 hyunseok.3 hyunseok.pri-registry.com:5000/hyunseok:v1 hyunseok.docker.worker2 Running Running 24 minutes ago
4. 테스트 환경 구축 완료
결과 확인
아래와 같이 동작한다면 정상적으로 환경이 구축되었다고 할 수 있습니다.
👇 동일한 도메인명으로 curl 명령어를 수행하지만 pod name이 바뀌는 것을 확인 할 수 있습니다.
Web Server 접속
👇 동일한 도메인명으로 접속하지만 pod name이 바뀌는 것을 확인 할 수 있습니다.