Notice
Recent Posts
Recent Comments
Link
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | 3 | 4 | 5 | ||
6 | 7 | 8 | 9 | 10 | 11 | 12 |
13 | 14 | 15 | 16 | 17 | 18 | 19 |
20 | 21 | 22 | 23 | 24 | 25 | 26 |
27 | 28 | 29 | 30 |
Tags
- docker
- EC2 인스턴스
- GNS3
- aws cloud
- KUBECTL
- aws saa
- aws cloud school
- EC2
- aws iam
- SAA-C03
- load balancer
- FTP
- aws cloud shcool 8
- Kubernetes
- Ebs
- IAM
- vyos
- aws SAA-c03
- Troubleshooting
- NAT
- ALB
- linux
- AWS
- DNS
- Firewall
- 쿠버네티스
- vmware
- 네트워크
- AWS 자격증
- tftp
Archives
- Today
- Total
나의 공부기록
[Docker] 07. Docker Swarm 본문
Docker Swarm
- 여러 Docker 호스트를 클러스터로 묶어 고가용성 및 확장성을 제공하는 오케스트레이션 도구
- 컨테이너 오케스트레이션 툴
👉 Docker Swarm, k8s ... - 오케스트레이션 : 지휘자 + 다수의 연주자 ➡️ clustering
- 컨테이너 오케스트레이션 툴
- 여러 개의 컨테이너를 관리하는 기술(스케일링, 헬스체크, 트래픽 제어 = 배포)
✅ Docker VS Docker Compose VS Docker Swarm
Docker : 단일 호스트, 단일 컨테이너
Docker Compose : 단일 호스트, 여러 종류의 컨테이너
Docker Swarm : 다수의 호스트(manager, worker..), 여러 종류의 컨테이너
Docker Swarm 실습 - 기본 구성
- 다른 호스트의 컨테이너끼리는 통신이 불가능하기 때문에
➡️ Overlay Network를 구성해서 통신이 가능하도록 해줌
더보기
1. 서버 생성
- ubun-tem 3개 복제(clone)
- manager(211.183.3.210) / worker1(211.183.3.220) / worker2(211.183.3.230)
2. Docker 설치
root@worker2:~# curl -fsSL https://get.docker.com -o get-docker.sh
root@worker2:~# ls
get-docker.sh snap
root@worker2:~# chmod +x get-docker.sh
root@worker2:~# ./get-docker.sh
# Executing docker install script, commit: 4c94a56999e10efcf48c5b8e3f6afea464f9108e
+ sh -c apt-get -qq update >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install ca-certificates curl >/dev/null
+ sh -c install -m 0755 -d /etc/apt/keyrings
+ sh -c curl -fsSL "https://download.docker.com/linux/ubuntu/gpg" -o /etc/apt/keyrings/docker.asc
+ sh -c chmod a+r /etc/apt/keyrings/docker.asc
+ sh -c echo "deb [arch=amd64 signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu focal stable" > /etc/apt/sources.list.d/docker.list
+ sh -c apt-get -qq update >/dev/null
+ sh -c DEBIAN_FRONTEND=noninteractive apt-get -y -qq install docker-ce docker-ce-cli containerd.io docker-compose-plugin docker-ce-rootless-extras docker-buildx-plugin >/dev/null
Docker Swarm - Manager(=Master Node) 구성
- control plane ➡️
더보기
1. 클러스터 초기화
- 해당 작업을 하면 control plane이 되는 것
- 아무 옵션을 주지 않으면 default 값으로 초기화됨
➡️ port : 2377
root@manager:~# docker swarm init
Swarm initialized: current node (0zmf33tzc9uoufogwuzt3itji) is now a manager.
# 🌟worker node가 되기 위한 명령어 명시
To add a worker to this swarm, run the following command:
docker swarm join --token SWMTKN-1-043ptfe5y08fava3t5nx0cgdrayz9i63pmlk6zeb5z8u92az42-70lth11d2v49iud517u603sm5 211.183.3.210:2377
To add a manager to this swarm, run 'docker swarm join-token manager' and follow the instructions.
➕ worker node 추가(하단의 "Docker Swarm - Worker Node 구성" 먼저 진행)
2. cluster node 확인
- HOSTNAME은 중복되면 안됨
root@manager:~# docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS ENGINE VERSION
0zmf33tzc9uoufogwuzt3itji * manager Ready Active Leader 28.0.2
ojwwis4dzo1kfpng0rmrmrt5x worker1 Ready Active 28.0.2
ian8j5eibt513rqoxkuvzdwpp worker2 Ready Active 28.0.2
Docker Swarm - Worker Node 구성
- data plane ➡️ 실제 컨테이너가 생성되는 곳
더보기
1. Manager의 클러스터에 Join
- worker1
root@worker1:~# docker swarm join --token SWMTKN-1-043ptfe5y08fava3t5nx0cgdrayz9i63pmlk6zeb5z8u92az42-70lth11d2v49iud517u603sm5 211.183.3.210:2377
This node joined a swarm as a worker.
- worker2
root@worker2:~# docker swarm join --token SWMTKN-1-043ptfe5y08fava3t5nx0cgdrayz9i63pmlk6zeb5z8u92az42-70lth11d2v49iud517u603sm5 211.183.3.210:2377
This node joined a swarm as a worker.
Docker Swarm - docker service : 한 가지 종류의 컨테이너를 여러 개 생성
- docker run으로 컨테이너를 생성하는 것과 비슷
더보기


💡Manager에서 실행
1. 서비스 생성 및 클러스터에 배포
# --replicas : 컨테이너 개수
# etoile0320/ipnginx : 이미지 이름
root@manager:~# docker service create --replicas 2 -p 7979:80 --name myweb oolralra/ipnginx
12cb80vnw9vn52r0h9osrml3g
overall progress: 2 out of 2 tasks
1/2: running
2/2: running
verify: Service 12cb80vnw9vn52r0h9osrml3g converged
2. 서비스 목록 확인
root@manager:~# docker service ls
ID NAME MODE REPLICAS IMAGE PORTS
12cb80vnw9vn myweb replicated 2/2 oolralra/ipnginx:latest *:7979->80/tcp
3. 서비스 배포 결과 확인
- 로드밸런싱이 잘 되는 것을 확인 가능

- 외부에서 들어오는 트래픽을 아래 그림과 같이 분산해서 처리함 - 개념적인 그림

- 컨테이너 분산이 되어 있음을 확인 가능 - 실제 분산 확인
root@manager:~# docker service ps myweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ij71cmtde56r myweb.1 oolralra/ipnginx:latest worker2 Running Running about a minute ago
r87h19qenruu myweb.2 oolralra/ipnginx:latest worker1 Running Running about a minute ago
- docker swarm을 하면 자동으로 overlay network를 구성한 것을 확인 가능
root@manager:~# docker network ls
NETWORK ID NAME DRIVER SCOPE
720eb18977c9 bridge bridge local
b07f37b1b8d6 docker_gwbridge bridge local
e57d3909e5b8 host host local
9fwclx5zwhab ingress overlay swarm # DRIVER : overlay ➡️ overlay network 생성
43cbf02a57ec none null local
root@manager:~# docker network inspect ingress
[
{
"Name": "ingress",
"Id": "9fwclx5zwhabkhi33i0qgqztl",
"Created": "2025-03-25T01:22:54.524035513Z",
"Scope": "swarm",
"Driver": "overlay",
"EnableIPv4": true,
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
# 🌟 도커 네트워크 대역
"Config": [
{
"Subnet": "10.0.0.0/24",
"Gateway": "10.0.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": true,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"ingress-sbox": {
"Name": "ingress-endpoint",
"EndpointID": "702736f4896aa8713ccd1038a33bb95ae57f62ff389f47050a3598a098d93da5",
"MacAddress": "02:42:0a:00:00:02",
"IPv4Address": "10.0.0.2/24",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.driver.overlay.vxlanid_list": "4096"
},
"Labels": {},
# 🌟 Peer를 통해 Overlay Network 자동 구성
"Peers": [
{
"Name": "70b1307bad6a",
"IP": "211.183.3.210"
},
{
"Name": "1f5bff428822",
"IP": "211.183.3.220"
},
{
"Name": "d77ec580c606",
"IP": "211.183.3.230"
}
]
}
]
4. 컨테이너 개수 증가 - 업데이트
- 분산 배치된 것을 확인 가능
root@manager:~# docker service scale myweb=3
myweb scaled to 3
overall progress: 3 out of 3 tasks
1/3: running
2/3: running
3/3: running
verify: Service myweb converged
root@manager:~# docker service ps myweb
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
4xstysy6y5uu myweb.1 oolralra/ipnginx:latest manager Running Running 41 seconds ago
ij71cmtde56r \_ myweb.1 oolralra/ipnginx:latest worker2 Shutdown Shutdown 35 seconds ago
r87h19qenruu myweb.2 oolralra/ipnginx:latest worker1 Running Running 10 minutes ago
7ak0ejk9yyo2 myweb.3 oolralra/ipnginx:latest manager Running Running about a minute ago
Docker Swarm - docker stack deploy : 클러스터 내에서 애플리케이션 스택을 배포
- docker compose up과 비슷
- docker-compose.yml 파일 필요
더보기
1. docker-compose.yml 파일 생성
- 기존의 compose파일에 추가된 내용 존재
➡️ 노드 배치, 컨테이너 수 등..
root@manager:~# mkdir stack_deploy
root@manager:~# cd stack_deploy/
root@manager:~/stack_deploy# vi docker-compose.yml
services:
ip-nginx:
image: oolralra/ipnginx
deploy:
# deploy : 배포
replicas: 2
# 컨테이너 수 : 2
placement:
# 비치 - 어떤 노드에 둘지
constraints: [node.role != manager]
# constraints : 제약 조건
# node = host
2. docker stack deploy
- 네트워크 명시 ❌ ➡️ 네트워크 자동 생성
# docker stack deploy -c <컴포즈파일> <stack이름>
root@manager:~/stack_deploy# docker stack deploy -c docker-compose.yml ip-stack
3. 결과 확인
- manager node를 제외하고 분산 배치되었음
root@manager:~/stack_deploy# docker stack ps ip-stack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
o6rfo5qzd9iv ip-stack_ip-nginx.1 oolralra/ipnginx:latest worker2 Running Running 24 seconds ago
k9sskkn4rsvj ip-stack_ip-nginx.2 oolralra/ipnginx:latest worker1 Running Running 24 seconds ago
- 검증 - 컨테이너 개수 수정
# 🌟 컨테이너 개수 수정
root@manager:~/stack_deploy# vi docker-compose.yml
services:
ip-nginx:
image: oolralra/ipnginx
deploy:
# deploy : 배포
replicas: 4
# 컨테이너 수 : 2
placement:
# 비치 - 어떤 노드에 둘지
constraints: [node.role != manager]
# constraints : 제약 조건
# node = host
- 검증 - docker stack 업데이트
root@manager:~/stack_deploy# docker stack deploy -c docker-compose.yml ip-stack
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
Updating service ip-stack_ip-nginx (id: xcjcz9nizdjp9wbve4de2wzzy)
- 검증 - stack 확인
➡️ manager는 제외하고 생성된 것을 확인 가능
root@manager:~/stack_deploy# docker stack ps ip-stack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
o6rfo5qzd9iv ip-stack_ip-nginx.1 oolralra/ipnginx:latest worker2 Running Running 4 minutes ago
k9sskkn4rsvj ip-stack_ip-nginx.2 oolralra/ipnginx:latest worker1 Running Running 4 minutes ago
z3xt0g6qqw4f ip-stack_ip-nginx.3 oolralra/ipnginx:latest worker2 Running Running 27 seconds ago
9rtq6bb24g3d ip-stack_ip-nginx.4 oolralra/ipnginx:latest worker1 Running Running 27 seconds ago
4. Docker Stack 삭제
root@manager:~/stack_deploy# docker stack rm ip-stack
Removing service ip-stack_ip-nginx
Removing network ip-stack_default
호스트에 띄워진 컨테이너 시각화하는 앱 배포
더보기

1. docker-compose.yml 생성
- 각 호스트에 띄워진 컨테이너를 시각화하기 위한 정보는 manager node에 있기 때문에,
manager node에 띄움
root@manager:~/stack_deploy# vi visual.yml
services:
visual:
image: dockersamples/visualizer
ports:
- '5656:8080'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
placement:
constraints: [node.role == manager]
2. docker stack 배포
root@manager:~/stack_deploy# docker stack deploy -c visual.yml visual
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
Creating network visual_default
Creating service visual_visual
3. 결과 확인
- 사이트 연결 불가

- dockersamples/visualizer라는 이미지가 없기 때문에, health check를 해서 삭제와 생성을 반복함
root@manager:~/stack_deploy# docker stack ps visual
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
bpc2jiq7lxx9 visual_visual.1 dockersamples/visualizer:latest manager Ready Preparing 2 seconds ago
1j0grfc59uj6 \_ visual_visual.1 dockersamples/visualizer:latest manager Shutdown Rejected 3 seconds ago "No such image: dockersamples/…"
j1ai4zm062sn \_ visual_visual.1 dockersamples/visualizer:latest manager Shutdown Rejected 8 seconds ago "No such image: dockersamples/…"
crm1vi173nsa \_ visual_visual.1 dockersamples/visualizer:latest manager Shutdown Rejected 13 seconds ago "No such image: dockersamples/…"
78dq9rr1ad7l \_ visual_visual.1 dockersamples/visualizer:latest manager Shutdown Rejected 18 seconds ago "No such image: dockersamples/…"
➕ 실습 - 02에서 연달아서 실습할 예정
실습 - 01
문제
ECR 퍼블릭 갤러리의 이미지로 wordpress - mysql:8을 docker stack deploy 해보세요. 단, DB는 manager에 1개만, wordpress는 worker 노드에 2개 띄워보세요. 12345 포트로 접속 가능하도록 만드세요.
ECR 퍼블릭 갤러리 - https://gallery.ecr.aws/
풀이
더보기


0. 이미지 선택


1. compose 파일 생성
root@manager:~/stack_deploy# vi wp-my-stack.yml
wp:
image: public.ecr.aws/docker/library/wordpress:php8.1-apache
ports:
- '12345:80'
environment:
- WORDPRESS_DB_HOST=dbdb
- WORDPRESS_DB_USER=wpuser
- WORDPRESS_DB_PASSWORD=1234
- WORDPRESS_DB_NAME=wpdb
depends_on:
- dbdb
deploy:
replicas: 1
placement:
constraints: [node.role != manager]
dbdb:
image: public.ecr.aws/docker/library/mysql:8.0.41-bookworm
restart: always
environment:
- MYSQL_DATABASE=wpdb
- MYSQL_USER=wpuser
- MYSQL_PASSWORD=1234
- MYSQL_ROOT_PASSWORD=1234
deploy:
replicas: 1
placement:
constraints: [node.role == manager]
2. docker stack 배포
root@manager:~/stack_deploy# docker stack deploy -c wp-my-stack.yml wp-stack
3. docker stack 확인
root@manager:~/stack_deploy# docker stack ps wp-stack
ID NAME IMAGE NODE DESIRED STATE CURRENT STATE ERROR PORTS
ogto33syadz6 wp-stack_dbdb.1 public.ecr.aws/docker/library/mysql:8.0.41-bookworm worker1 Running Running 8 seconds ago
mzlj7pcmqhw9 wp-stack_wp.1 public.ecr.aws/docker/library/wordpress:php8.1-apache worker2 Running Running 4 seconds ago
4. 결과 확인

실습 - 02
문제
root@manager:~/stack_deploy# curl 61.254.18.30:5000/v2/_catalog {"repositories":["nginx","visualizer"]}
위의 사설 저장소에서 visualizer를 가져와서 호스트에 띄워진 컨테이너 시각화하는 앱 배포 해보세요.
풀이
더보기


1. HTTP 설정 허용
root@worker2:~/stack_deploy# vi /etc/docker/daemon.json
{
"insecure-registries":["61.254.18.30:5000"]
}
root@worker2:~/stack_deploy# systemctl restart docker
2. compose 파일 생성
root@manager:~/stack_deploy# vi visual.yml
services:
visual:
image: 61.254.18.30:5000/visualizer
ports:
- '5656:8080'
volumes:
- /var/run/docker.sock:/var/run/docker.sock
deploy:
placement:
constraints: [node.role == manager]
3. docker stack 배포
root@manager:~/stack_deploy# docker stack deploy -c visual.yml visual
Since --detach=false was not specified, tasks will be created in the background.
In a future release, --detach=false will become the default.
Creating network visual_default
Creating service visual_visual

4. 결과 확인

실습 - 03
문제
https://github.com/pcmin929/mon이라는 레포지토리에
간단한 텔레그래프 설정파일과 그라파나 대시보드 파일이 있습니다.
그라파나이미지 grafana/grafana를 제 사설저장소 61.254.18.30:5000/grafana로 올리겠습니다.
텔레그래프이미지 telegraf:1.3을 제 사설저장소 61.254.18.30:5000/telegraf:1.3로 올리겠습니다.
텔레그래프이미지 influxdb:1.2를 제 사설저장소 61.254.18.30:5000/influxdb:1.2로 올리겠습니다.
텔레그래프 설정파일은 /etc/telegraf/telegraf.conf에 위치해야 합니다.
또한, 텔레그래프 설정파일을 보면 아시겠지만
vm_metrics와 docker_metrics라는 두 개의 데이터베이스에 수집된 자료를 저장시킨다.
위 내용을 토대로 docker stack deploy를 해서
grafana를 통해 각 docker swarm 호스트 및 컨테이너의 정보를 시각화해 보세요.
그라파나 대시보드는 dashboard.json의 내용을 복붙 해서 넣으시면 됩니다.
➡️ https://github.com/pcmin929/mon/blob/main/dashboard.json
풀이
더보기




1. 파일 다운로드
root@manager:~/stack_deploy# git clone https://github.com/pcmin929/mon
2. 이미지 pulling
- 만약에 워커노드에 컨테이너가 띄워진다면, 각 워커노드들 전부 사설저장소에 대한 insecure 설정이되어 있어야 함
root@worker2:~/stack_deploy# vi /etc/docker/daemon.json
{
"insecure-registries":["61.254.18.30:5000"]
}
3. compose 파일 생성
- volumes 옵션을 사용하려면 해당 디렉토리와 파일이 실행되는 호스트에 존재해야 함
➡️ configs 옵션(설정파일을 컨테이너에 삽입 가능)을 사용하는 것을 추천 - 컨테이너를 호스트에 마운트하기 위해서는 해당 컨테이너가 띄워지는 호스트에 마운트가 된다.
➡️ manager 노드에 파일이 존재해도, 워커노드에 컨테이너가 띄워진다면 manager 노드에 있는 파일에 접근불가 (telegraf에서 manager에 mount를 바로 할 수 없어서, worker1과 worker2에 mount point가 존재해야 한다.)
➡️ 워커노드에도 파일을 복사하거나 접근 가능하게 해야한다.
root@manager:~/stack_deploy# vi grafana.yml
version: '3.8'
services:
grafana:
image: 61.254.18.30:5000/grafana
volumes:
- grafana_data:/var/lib/grafana
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "3000:3000"
deploy:
placement:
constraints:
- node.role == manager
influx:
image: 61.254.18.30:5000/influxdb:1.2
deploy:
placement:
constraints:
- node.role == manager
depends_on:
- telegraf
volumes:
- influx_data:/var/lib/influxdb
- /var/run/docker.sock:/var/run/docker.sock
ports:
- "8086:8086"
telegraf:
image: 61.254.18.30:5000/telegraf:1.3
volumes:
- /root/stack_deploy/mon/telegraf.conf:/etc/telegraf/telegraf.conf:ro
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- influx
deploy:
mode: global
restart: always
volumes:
grafana_data:
influx_data:
➕ configs 옵션
- 해당 옵션을 사용하면 각 호스트마다 볼륨 구성을 하지 않아도 된다.

4. telegraf.conf 파일 수정
root@worker1:~/stack_deploy# vi mon/telegraf.conf
[global_tags]
environment="swarm"
# Read metrics about CPU usage
[[inputs.cpu]]
percpu = false
totalcpu = true
fieldpass = [ "usage*" ]
name_suffix = "_vm"
# Read metrics about disk usagee
[[inputs.disk]]
interfaces = [ "eth0" ]
fielddrop = [ "icmp*", "ip*", "tcp*", "udp*" ]
name_suffix = "_vm"
# Read metrics about memory usage
[[inputs.mem]]
name_suffix = "_vm"
# Read metrics about swap memory usage
[[inputs.swap]]
name_suffix = "_vm"
# Read metrics about system load & uptime
[[inputs.system]]
name_suffix = "_vm"
# Read metrics from docker socket api
[[inputs.docker]]
endpoint = "unix:///var/run/docker.sock"
container_names = []
name_suffix = "_docker"
# 데이터베이스 컨테이너 서비스명 수정
[[outputs.influxdb]]
database = "vm_metrics"
urls = ["http://influx:8086"]
namepass = ["*_vm"]
[[outputs.influxdb]]
database = "docker_metrics"
urls = ["http://influx:8086"]
namepass = ["*_docker"]
5. docker stack 배포
root@manager:~/stack_deploy# docker stack deploy -c grafana.yml monitor
6. 데이터베이스 생성
- 경로는 <서비스명> 사용
➡️ 내부에서 찾아가는 것


7. Dashboard 생성


8. 결과 확인

'CS > Docker' 카테고리의 다른 글
[Docker] 06. Docker Compose (0) | 2025.03.24 |
---|---|
[Docker] 05. Multi-Stage Build(멀티 스테이지 빌드) (0) | 2025.03.24 |
[Docker] 04. App 배포 - Java & NodeJS & Python (0) | 2025.03.20 |
[Docker]03. Container Registry (0) | 2025.03.20 |
[Docker]02. Docker Image - Dockerfile 명령어 (1) | 2025.03.18 |