Swarm Deployment KO - k-p2p-lab/kpl-v3 GitHub Wiki

Swarm ๋ฐฐํฌ์™€ ์šด์˜

Wiki home โ€บ ํ•œ๊ตญ์–ด ๋ฌธ์„œ ยท ์˜์–ด ์›๋ฌธ

๋ฌธ์„œ ์•ˆ๋‚ด ยท ์†Œ์Šค ์ €์žฅ์†Œ

ํ•˜๋‚˜ ์ด์ƒ์˜ Linux ์„œ๋ฒ„์—์„œ ํ™œ์„ฑ Swarm manager์˜ scripts/swarm.sh๋กœ stack.swarm.yaml์„ ๋ฐฐํฌยท๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Swarm์€ ์„ ํƒํ•œ ์„œ๋ฒ„๋งˆ๋‹ค Agent ํ•˜๋‚˜๋ฅผ ์œ ์ง€ํ•˜๊ณ , Controller๊ฐ€ ์‹คํ—˜์˜ Peer๋ฅผ Agent์— ๋ฐฐ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. Peer๋Š” ํ•ด๋‹น ์„œ๋ฒ„์˜ ๋…๋ฆฝ Docker ์ปจํ…Œ์ด๋„ˆ์ž…๋‹ˆ๋‹ค. Swarm ์„œ๋น„์Šค์ฒ˜๋Ÿผ Peer๋ฅผ ๋‹ค๋ฅธ ์„œ๋ฒ„๋กœ ์ž๋™ ์žฌ๋ฐฐ์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์‹คํ–‰ ๊ฐ€๋Šฅํ•œ ๋ฐฐํฌ ๊ทผ๊ฑฐ๋Š” stack.swarm.yaml, scripts/swarm.sh, scripts/swarm-config.sh์ž…๋‹ˆ๋‹ค. ์‹ค์ œ ์„œ๋น„์Šคยท๋„คํŠธ์›Œํฌ ๋Œ€์‘์€ v3 ์•„ํ‚คํ…์ฒ˜๋ฅผ, ๊ฐœ๋… ์•„ํ‚คํ…์ฒ˜๋Š” ๊ณตํ†ต ๊ฐœ๋…๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์Šคํƒ์€ Linux ๋…ธ๋“œ๋งˆ๋‹ค global resource-monitor ์„œ๋น„์Šค๋ฅผ ํ•จ๊ป˜ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. Agent ํ™œ์„ฑํ™”์™€ ๋…๋ฆฝ์ ์œผ๋กœ ControllerยทPrometheusยทGrafanaยท์ˆ˜์ง‘๊ธฐ ์ปจํ…Œ์ด๋„ˆ ์ž์›์„ ์ˆ˜์ง‘ํ•ฉ๋‹ˆ๋‹ค. ์›น Controller์—๋Š” Docker ์†Œ์ผ“์„ ๋งˆ์šดํŠธํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ˆ˜์ง‘๊ธฐ๊ฐ€ ๋กœ์ปฌ ์†Œ์ผ“์„ ์ฝ๊ณ  monitoring ๋„คํŠธ์›Œํฌ๋กœ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€์™€ ์Šคํƒ์„ ํ•จ๊ป˜ ๊ฐฑ์‹ ํ•ด์•ผ ์„œ๋น„์Šค ๋ผ๋ฒจ๊ณผ ์ƒˆ Grafana ์„ค์ •๊นŒ์ง€ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ˆ˜์ง‘๊ธฐ ๋กœ๊ทธ๋Š” sh scripts/swarm.sh logs resource-monitor --tail 100์œผ๋กœ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๊ด€๋ฆฌ ์„œ๋น„์Šค ์ž์› ์ธก์ •์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

๋ฐฐํฌ ์ „ ์ค€๋น„

Linux ์„œ๋ฒ„๋“ค์ด ์ด๋ฏธ ๊ฐ™์€ Swarm์— ๊ฐ€์ž…๋˜์–ด ์žˆ๊ณ , rootful Docker์™€ userns-remap ๋ฏธ์‚ฌ์šฉ ๊ตฌ์„ฑ์„ ๊ฐ–์ถ˜ ์ƒํƒœ์—์„œ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. manager์— kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ์™€ Docker CLI, coreutils์˜ timeout, -f๋ฅผ ์ง€์›ํ•˜๋Š” readlink, awk, ์ผ๋ฐ˜ POSIX ์…ธ ์œ ํ‹ธ๋ฆฌํ‹ฐ๋ฅผ ์ค€๋น„ํ•˜์‹ญ์‹œ์˜ค. ์ €์žฅ์†Œ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ํ˜„์žฌ Docker context๊ฐ€ ๊ฐ€๋ฆฌํ‚ค๋Š” active Swarm manager๋ฅผ ๋Œ€์ƒ์œผ๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. worker๋งˆ๋‹ค ์ €์žฅ์†Œ๋ฅผ ๋ณต์‚ฌํ•˜๊ฑฐ๋‚˜ Agent๋ฅผ ์ˆ˜๋™์œผ๋กœ ์‹œ์ž‘ํ•  ํ•„์š”๋Š” ์—†์Šต๋‹ˆ๋‹ค.

Swarm ๊ฐ€์ž…์€ ์ด๋ฏธ์ง€ registry ์ƒ์„ฑ์„ ์˜๋ฏธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. manager์™€ ๋ชจ๋“  ๋Œ€์ƒ ๋…ธ๋“œ์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” registry๊ฐ€ ํ•„์š”ํ•˜๋ฉฐ, ํ•„์š”ํ•œ ์ธ์ฆ๊ณผ HTTPS ์‹ ๋ขฐ ์„ค์ •์€ ๋ฏธ๋ฆฌ ์ค€๋น„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. helper๋Š” registry๋ฅผ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ Docker daemon์˜ ์ „์—ญ TLS/insecure-registry ์„ค์ •์„ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์˜ˆ๋ฅผ ๋“ค์–ด ๊ธฐ์กด registry๊ฐ€ ์žˆ๋‹ค๋ฉด ์•„๋ž˜ ์ด๋ฏธ์ง€ ๋Œ€์‹  172.20.4.171:5000/kpl-v3:v3๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. HTTP registry๋ผ๋ฉด ๊ด€๋ จ Docker daemon์ด ์ด๋ฅผ ์‚ฌ์šฉํ•˜๋„๋ก ์‚ฌ์ „์— ์„ค์ •๋˜์–ด ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์„œ๋ฒ„ ๊ฐ„ TCP 2377(manager), TCP/UDP 7946, UDP 4789 ํ†ต์‹ ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. control ๋…ธ๋“œ์˜ Prometheus๊ฐ€ ์„ ํƒ๋œ ๋ชจ๋“  Agent ๋…ธ๋“œ ์ฃผ์†Œ์˜ TCP KPL_AGENT_METRICS_PORT(๊ธฐ๋ณธ 9091)์—๋„ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์šด์˜์ž๊ฐ€ Agent metrics ๋งํฌ๋ฅผ ์ง์ ‘ ์—ด ๊ฒฝ์šฐ ์šด์˜์ž ๋ธŒ๋ผ์šฐ์ €๊ฐ€ ์†ํ•œ ์‹ ๋ขฐ ๊ด€๋ฆฌ๋ง์—์„œ๋„ ์ด ํฌํŠธ๋ฅผ ํ—ˆ์šฉํ•˜์‹ญ์‹œ์˜ค. VXLAN๊ณผ metrics ์ ‘๊ทผ์€ ์‹ ๋ขฐํ•˜๋Š” ๋„คํŠธ์›Œํฌ ์•ˆ์œผ๋กœ ์ œํ•œํ•˜๊ณ  VPNยทํด๋ผ์šฐ๋“œ๋ง์—์„œ๋Š” underlay MTU์™€ VXLAN overhead๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. smoke ์‹คํ—˜์—๋Š” ๋„คํŠธ์›Œํฌ ์กฐ๊ฑด ์ ์šฉ์„ ์œ„ํ•œ ์ปค๋„ ์ง€์›๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Docker overlay ์š”๊ตฌ์‚ฌํ•ญ

๋ถ„์‚ฐ smoke ๊ฒ€์ฆ์—๋Š” Agent๋ฅผ ์‹คํ–‰ํ•  ๋…ธ๋“œ๊ฐ€ ์ตœ์†Œ ๋‘ ๋Œ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. manager ํ•œ ๋Œ€์™€ worker ๋‘ ๋Œ€์ด๋ฉด --workers๋กœ manager๋ฅผ ์‹คํ—˜์—์„œ ์ œ์™ธํ•ฉ๋‹ˆ๋‹ค. manager ํ•œ ๋Œ€์™€ worker ํ•œ ๋Œ€์ด๋ฉด ๋Œ€์‹  --all์„ ์‚ฌ์šฉํ•ด ๋‘ ๋…ธ๋“œ์— Agent๋ฅผ ๋ฐฐ์น˜ํ•˜์‹ญ์‹œ์˜ค. ์ด ๊ฒฝ์šฐ manager๋„ ์‹คํ—˜๊ณผ CPUยท๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด ๊ณผ์ •์—์„œ ๊ฐ™์€ ์‚ฌ์šฉ์ž์™€ Docker context๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. Docker ์ ‘๊ทผ์— sudo๊ฐ€ ํ•„์š”ํ•˜๋‹ค๋ฉด init, login, publish, ๋ฐฐํฌ ๋ช…๋ น์„ ํฌํ•จํ•ด ์ผ๊ด€๋˜๊ฒŒ sudo sh scripts/swarm.sh ...๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

Linux ํ˜ธ์ŠคํŠธ์™€ Peer ๊ฒฉ๋ฆฌ ์š”๊ตฌ์‚ฌํ•ญ

Agent๋Š” ํ™œ์„ฑ Swarm ๋…ธ๋“œ์™€ ๋ช…์‹œ์ ์œผ๋กœ ์„ค์ •ํ•œ Docker ์ด๋ฏธ์ง€ ๋ฐ Peer ๋„คํŠธ์›Œํฌ๋ฅผ ์š”๊ตฌํ•ฉ๋‹ˆ๋‹ค. Peer ๋„คํŠธ์›Œํฌ๋Š” Swarm scope์˜ attachable overlay์—ฌ์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ Agent๋Š” ์ž๊ธฐ ๋…ธ๋“œ์˜ /var/run/docker.sock์œผ๋กœ standalone Peer ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. Rootless Docker์™€ userns-remap์€ ์ง€์›ํ•˜๋Š” ๋ฐฐํฌ ๊ธฐ์ค€์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Agent์™€ network-manager๋Š” 0:0์œผ๋กœ ์‹คํ–‰ํ•˜๋ฉฐ Docker socket์— ์ ‘๊ทผํ•ฉ๋‹ˆ๋‹ค. resource-monitor๋„ ๋กœ์ปฌ socket์„ ์ฝ์Šต๋‹ˆ๋‹ค. Socket ์ ‘๊ทผ์€ ํ•ด๋‹น ๋…ธ๋“œ์— ๋Œ€ํ•œ ๋„“์€ ์ œ์–ด ๊ถŒํ•œ์ด๋ฉฐ network manager๋Š” Swarm manager์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. Controller์—๋Š” socket์„ ์ œ๊ณตํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Peer๋„ ๋น„๊ณต๊ฐœ ์„ค์ •์„ ์ฝ๊ธฐ ์œ„ํ•ด 0:0์œผ๋กœ ์‹คํ–‰ํ•˜์ง€๋งŒ Docker socket, ํ˜ธ์ŠคํŠธ ๋””๋ ‰ํ„ฐ๋ฆฌ mount์™€ published host port๋ฅผ ๋ฐ›์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  ๊ธฐ๋ณธ capability๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  no-new-privileges๋ฅผ ํ™œ์„ฑํ™”ํ•˜๋ฉฐ ๋„คํŠธ์›Œํฌ ์กฐ๊ฑด์ด ์žˆ๋Š” Peer์—๋งŒ NET_ADMIN์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. Privileged ๋ชจ๋“œ๋ฅผ ๋ถ€์—ฌํ•˜๊ฑฐ๋‚˜ socket์„ ๋ˆ„๊ตฌ๋‚˜ ์“ธ ์ˆ˜ ์žˆ๋„๋ก ๋ฐ”๊พธ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. SELinux ๋˜๋Š” AppArmor ํ˜ธ์ŠคํŠธ์—์„œ๋Š” ์ „์—ญ enforcement๋ฅผ ๋„๊ฑฐ๋‚˜ ์‹œ์Šคํ…œ ๋””๋ ‰ํ„ฐ๋ฆฌ๋ฅผ relabelํ•˜์ง€ ๋ง๊ณ  ํ˜ธ์ŠคํŠธ ์ •์ฑ…์— ๋”ฐ๋ผ Agent socket ์ ‘๊ทผ์„ ํ—ˆ์šฉํ•˜์‹ญ์‹œ์˜ค.

๋„คํŠธ์›Œํฌ ์กฐ๊ฑด์—๋Š” Linux sch_prio, sch_netem, cls_u32์™€ TBF๋ฅผ ์‚ฌ์šฉํ•  ๋•Œ์˜ sch_tbf๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์ปค๋„์— ๋‚ด์žฅ๋  ์ˆ˜๋„ ์žˆ์œผ๋ฏ€๋กœ lsmod๋งŒ์œผ๋กœ ์ง€์› ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Peer๋Š” ํ˜ธ์ŠคํŠธ ์ปค๋„์— ๋ชจ๋“ˆ์„ ์ ์žฌํ•  ์ˆ˜ ์—†์œผ๋ฏ€๋กœ ์„ ํƒํ•œ ๋ชจ๋“  ๋…ธ๋“œ์˜ ์ปค๋„์„ ์ค€๋น„ํ•˜์‹ญ์‹œ์˜ค. tc ๋ช…๋ น์ด ์‹คํŒจํ•˜๋ฉด Peer ์‹œ์ž‘๋„ ๋ช…์‹œ์ ์ธ ์˜ค๋ฅ˜๋กœ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

Peer๋Š” overlay IPv4 ์ฃผ์†Œ์˜ TCP 20000์œผ๋กœ ํ†ต์‹ ํ•˜๋ฉฐ Peer ์ œ์–ด HTTP๋Š” TCP 18000์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ scope: p2p๋Š” Peer network namespace์˜ ์†ก์‹  TCP 20000 ํŠธ๋ž˜ํ”ฝ์„ ์ œ์–ดํ•˜๊ณ  scope: all์€ ์ œ์–ดยทtelemetry ํŠธ๋ž˜ํ”ฝ์—๋„ ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค. IPv6 ์ „์šฉ Peer ์‹คํ—˜์€ ์ง€์› ๊ธฐ์ค€ ๋ฐ–์ž…๋‹ˆ๋‹ค. ํ—ˆ์šฉํ•˜๋Š” ์ตœ๋Œ€ jitter๋Š” 2.147483647s์ด๋ฉฐ ์‹œ๋‚˜๋ฆฌ์˜ค seed๊ฐ€ ์ปค๋„ ํŒจํ‚ท ์กฐ๊ฑด๊ณผ ์Šค์ผ€์ค„๋ง๊นŒ์ง€ ๊ฒฐ์ •์ ์œผ๋กœ ๋งŒ๋“ค์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ง€์—ฐ์„ ๋น„๊ตํ•  ๋•Œ๋Š” ๋ชจ๋“  ํ˜ธ์ŠคํŠธ์˜ ์‹œ๊ณ„๋ฅผ chrony/NTP๋กœ ๋™๊ธฐํ™”ํ•˜์‹ญ์‹œ์˜ค.

๋‹จ์ผ ๋…ธ๋“œ Swarm

Linux ๋…ธ๋“œ ํ•˜๋‚˜์—์„œ๋„ ๊ฐ™์€ stack๊ณผ attachable overlay๋กœ ๊ฐœ๋ฐœ ๋˜๋Š” ์ž‘์€ ์‹คํ—˜์„ ์ˆ˜ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ํ™œ์„ฑ Swarm manager๋ฅผ ์ค€๋น„ํ•˜๊ณ  ์•„๋ž˜ init ๋ช…๋ น์˜ KPL_MIN_AGENTS=1์„ ์„ค์ •ํ•œ ๋’ค deploy --all์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. Controller, ๋ชจ๋‹ˆํ„ฐ๋ง ์„œ๋น„์Šค, Agent์™€ Peer๊ฐ€ ํ•ด๋‹น ํ˜ธ์ŠคํŠธ ์ž์›์„ ๊ณต์œ ํ•ฉ๋‹ˆ๋‹ค. Registry, ์ปค๋„, ์ธ์ฆ๊ณผ ์ •๋ฆฌ ์š”๊ตฌ์‚ฌํ•ญ์€ ๋™์ผํ•ฉ๋‹ˆ๋‹ค. Smoke ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ํ˜ธ์ŠคํŠธ ๊ฐ„ ๋ถ„์‚ฐ๊ณผ ์—ฐ๊ฒฐ์„ ๊ฒ€์ฆํ•˜๋ ค๋ฉด Agent ๋…ธ๋“œ๊ฐ€ ์ตœ์†Œ ๋‘ ๊ฐœ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

Bash ์ž๋™์™„์„ฑ

์ €์žฅ์†Œ ๋””๋ ‰ํ„ฐ๋ฆฌ์—์„œ ๋‹ค์Œ ๋ช…๋ น์œผ๋กœ ํ˜„์žฌ Bash์— ๋‹จ์ถ• ๋ช…๋ น๊ณผ ์ž๋™์™„์„ฑ์„ ํ™œ์„ฑํ™”ํ•ฉ๋‹ˆ๋‹ค.

source scripts/activate-swarm.sh

kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ์˜ scripts/swarm.sh๋ฅผ ์‹คํ–‰ํ•˜๋Š” swarm ์…ธ ํ•จ์ˆ˜๊ฐ€ ๋งŒ๋“ค์–ด์ง€๋ฉฐ ์ธ์ž๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ๋””๋ ‰ํ„ฐ๋ฆฌ๋กœ ์ด๋™ํ•ด๋„ ํ™œ์„ฑํ™”ํ•œ ์ €์žฅ์†Œ๋ฅผ ๊ณ„์† ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Tab์œผ๋กœ ๋ช…๋ นยท์ง€์› ์˜ต์…˜, init/configure ์„ค์ • ํ‚ค, ์‹œ๋‚˜๋ฆฌ์˜คยท์„ค์ • ํŒŒ์ผ ๊ฒฝ๋กœ, ๋…ธ๋“œ IDยทํ˜ธ์ŠคํŠธ๋ช…, Docker context ์ด๋ฆ„์„ ์™„์„ฑํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ <Tab>์€ ๋ฌธ์ž๋ฅผ ์ž…๋ ฅํ•˜๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋ผ Tab ํ‚ค๋ฅผ ๋ˆ„๋ฅด๋Š” ์œ„์น˜์ž…๋‹ˆ๋‹ค.

swarm lo<Tab>
swarm logs auth --<Tab>
swarm logs auth --context <Tab>
swarm deploy --<Tab>
swarm add-node worker-<Tab>
swarm configure KPL_IMAGE_<Tab>
swarm configure KPL_CONTROL_NODE_ID=<Tab>
swarm --env-file .env.<Tab>

๋ณ„๋„ bash-completion ํŒจํ‚ค์ง€๋Š” ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋…ธ๋“œยทcontext ํ›„๋ณด๋Š” ํ˜ธ์ถœ์ž์˜ ํ˜„์žฌ Docker context์—์„œ ์ฝ๊ธฐ ์ „์šฉ์œผ๋กœ ์กฐํšŒํ•˜๋ฉฐ, ์กฐํšŒ ์ œํ•œ์‹œ๊ฐ„์€ 1์ดˆ(์ข…๋ฃŒ๋˜์ง€ ์•Š์œผ๋ฉด 1์ดˆ ๋’ค ๊ฐ•์ œ ์ข…๋ฃŒ), ์บ์‹œ๋Š” 5์ดˆ์ž…๋‹ˆ๋‹ค. Docker๊ฐ€ ์‘๋‹ตํ•˜์ง€ ์•Š์œผ๋ฉด ๋™์  ํ›„๋ณด๋งŒ ์ƒ๋žตํ•˜๊ณ  ๋ช…๋ นยท์˜ต์…˜ยท๊ฒฝ๋กœ ์™„์„ฑ์€ ๊ณ„์† ๋™์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์ž๊ฒฉ ์ฆ๋ช… ํŒŒ์ผ์„ ์ฝ๊ฑฐ๋‚˜ ์ €์žฅ๋œ ๋น„๋ฐ€๋ฒˆํ˜ธ ๊ฐ’์„ ์ œ์•ˆํ•˜์ง€ ์•Š์œผ๋ฉฐ, shยทbash์˜ ๊ธฐ์กด ์ž๋™์™„์„ฑ์„ ๊ต์ฒดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋™์™„์„ฑ์€ swarm ๋‹จ์ถ• ๋ช…๋ น์—์„œ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

ํ™œ์„ฑํ™” ์Šคํฌ๋ฆฝํŠธ๋Š” sh๋‚˜ bash๋กœ ์‹คํ–‰ํ•˜์ง€ ๋ง๊ณ  ๋ฐ˜๋“œ์‹œ source๋กœ ๋ถˆ๋Ÿฌ์˜ต๋‹ˆ๋‹ค. ํ˜„์žฌ ์…ธ์—๋งŒ ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ์ƒˆ ํ„ฐ๋ฏธ๋„์—๋„ ์ ์šฉํ•˜๋ ค๋ฉด ~/.bashrc์— source /์ €์žฅ์†Œ/์ ˆ๋Œ€๊ฒฝ๋กœ/kpl-v3/scripts/activate-swarm.sh๋ฅผ ์ถ”๊ฐ€ํ•˜์‹ญ์‹œ์˜ค(๊ณต๋ฐฑ์ด ์žˆ๋Š” ๊ฒฝ๋กœ๋Š” ๋”ฐ์˜ดํ‘œ๋กœ ๊ฐ์Œ‰๋‹ˆ๋‹ค). ํ˜„์žฌ ์…ธ์—์„œ ํ•ด์ œํ•˜๋ ค๋ฉด complete -r swarm, unset -f swarm์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์ž๋™์œผ๋กœ ๊ถŒํ•œ์„ ๋†’์ด์ง€ ์•Š์œผ๋ฏ€๋กœ Docker ์ ‘๊ทผ ๊ถŒํ•œ์€ ๊ธฐ์กด ์šด์˜ ๋ฐฉ์‹๋Œ€๋กœ ์ค€๋น„ํ•˜์‹ญ์‹œ์˜ค.

์ฒซ ๋ฐฐํฌ๋ถ€ํ„ฐ ์‹คํ—˜๊ณผ ๋‹ค์šด๋กœ๋“œ๊นŒ์ง€

1. ์„ค์ •๊ณผ ์ด๋ฏธ์ง€ ๊ฒŒ์‹œ

sh scripts/swarm.sh nodes
sh scripts/swarm.sh init KPL_IMAGE=registry.example.com/kpl-v3:v3 KPL_AGENT_CAPACITY=20 KPL_MIN_AGENTS=2
sh scripts/swarm.sh config
# registry๊ฐ€ ์ธ์ฆ์„ ์š”๊ตฌํ•  ๋•Œ๋งŒ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh login
sh scripts/swarm.sh publish

์ด๋ฏธ์ง€ ์ฐธ์กฐ๋ฅผ ์‹ค์ œ registry์™€ repository๋กœ ๋ฐ”๊พธ์‹ญ์‹œ์˜ค. init์€ ์ „๋‹ฌํ•œ ์„ค์ •์„ ๊ฒ€์ฆํ•˜๊ณ  ํ˜„์žฌ manager๋ฅผ ๊ธฐ๋ณธ control ๋…ธ๋“œ๋กœ ์„ ํƒํ•˜๋ฉฐ, ๊ธฐ์กด ํŒŒ์ผ์„ ๋ฎ์–ด์“ฐ์ง€ ์•Š๊ณ  ๋น„๊ณต๊ฐœ .env.swarm์„ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ๋Œ€์‹œ๋ณด๋“œ์™€ Grafana ์ž๊ฒฉ ์ฆ๋ช…์„ ๊ฐ๊ฐ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ ์„ค์ •์ด ์žˆ์œผ๋ฉด configure KEY=VALUE...๋กœ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค. config๋Š” ๋น„๋ฐ€ ๊ฐ’์„ ๊ฐ€๋ฆฐ ์œ ํšจ ์„ค์ •์„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

login์€ KPL_IMAGE์—์„œ registry๋ฅผ ์ถ”๋ก ํ•ด helper์™€ ๊ฐ™์€ ๊ณ„์ •์œผ๋กœ ๋Œ€ํ™”ํ˜• ๋กœ๊ทธ์ธ์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. publish๋Š” kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ๋ฅผ ๋นŒ๋“œํ•˜๊ณ  ์„ค์ •ํ•œ ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋กœ pushํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ์ด๋ฏธ์ง€๊ฐ€ ์ด๋ฏธ ๊ฒŒ์‹œ๋˜์–ด ์žˆ๋‹ค๋ฉด publish๋Š” ์ƒ๋žตํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ ๋นŒ๋“œ๋Š” native ํ”Œ๋žซํผ์„ ๋Œ€์ƒ์œผ๋กœ ํ•˜๋ฉฐ, ์•„ํ‚คํ…์ฒ˜๊ฐ€ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๋‹ค๋ฉด ํ•ด๋‹น ๋นŒ๋“œ๊ฐ€ ๊ฐ€๋Šฅํ•œ ๊ธฐ์กด Buildx builder์—์„œ manager๋ฅผ ํฌํ•จํ•œ ๋ชจ๋“  ๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜๋ฅผ ๊ฒŒ์‹œํ•˜์‹ญ์‹œ์˜ค.

sh scripts/swarm.sh publish --platforms linux/amd64,linux/arm64

helper๋Š” builder๋‚˜ CPU ์—๋ฎฌ๋ ˆ์ด์…˜์„ ์„ค์น˜ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. native ์‹คํ–‰์—๋Š” ๋…ธ๋“œ์˜ ์•„ํ‚คํ…์ฒ˜์— ๋งž๋Š” ์ด๋ฏธ์ง€๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Docker multi-platform ๋นŒ๋“œ

2. ๋ฐฐํฌ์™€ ํ™”๋ฉด ์ ‘์†

# manager ํ•œ ๋Œ€์™€ worker ํ•œ ๋Œ€์ธ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ๋Š” ๋Œ€์‹  --all์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh deploy --workers
sh scripts/swarm.sh check
sh scripts/swarm.sh status
sh scripts/swarm.sh access
sh scripts/swarm.sh credentials

deploy๋Š” ์ด๋ฏธ์ง€๋ฅผ ํ™•์ •ํ•˜๊ณ  ์„ ํƒํ•œ ๋…ธ๋“œ์— label์„ ์ถ”๊ฐ€ํ•˜๋ฉฐ, ํ•„์š”ํ•˜๋ฉด attachable Peer overlay๋ฅผ ์ƒ์„ฑํ•œ ๋’ค ๋ฐฐํฌ ๊ฒ€์‚ฌ์™€ stack ๋ฐฐํฌ๋ฅผ ์ ‘์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋“  ์„œ๋น„์Šค์™€ Agent๊ฐ€ ์ค€๋น„๋˜๊ธฐ ์ „์— ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. check๋Š” ๋ถˆ๋Ÿฌ์˜จ ์„ค์ •์œผ๋กœ ๊ตฌ์„ฑยท๋„คํŠธ์›Œํฌยท๋ฐฐ์น˜ ์‚ฌ์ „ ๊ฒ€์‚ฌ๋ฅผ ๋‹ค์‹œ ์ˆ˜ํ–‰ํ•˜๋ฉฐ, ์‹ค์ œ ์„œ๋ฒ„ ๊ฐ„ ํ†ต์‹ ์ด๋‚˜ ๋ชจ๋“  worker์˜ ์ปค๋„ ๊ทœ์น™ ์„ค์น˜๋ฅผ ๊ฒ€์ฆํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. status๋Š” Docker ์„œ๋น„์Šคยทtaskยท๋…ธ๋“œ ์ƒํƒœ์ด๋ฉฐ Controller ๋“ฑ๋ก ์ƒํƒœ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

access๊ฐ€ ์ถœ๋ ฅํ•œ Controller URL์„ ์—ฌ์‹ญ์‹œ์˜ค. Controller, Prometheus, Grafana ํฌํŠธ๋Š” ๋ช…๋ น์„ ์‹คํ–‰ํ•˜๋Š” manager์™€ ๋‹ค๋ฅผ ์ˆ˜ ์žˆ๋Š” ์ง€์ •๋œ control ๋…ธ๋“œ์— ๊ฒŒ์‹œ๋ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋ช…๋ น์€ ์„ ํƒ๋œ ๊ฐ Agent ๋…ธ๋“œ์˜ host-mode metrics URL๋„ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ๋ธŒ๋ผ์šฐ์ €์—์„œ Agent ๋งํฌ๋ฅผ ์—ด๋ ค๋ฉด ์šด์˜์ž ๊ธฐ๊ธฐ์˜ ์‹ ๋ขฐ ๊ด€๋ฆฌ๋ง์—์„œ ๊ฐ Agent ๋…ธ๋“œ๋กœ ์ง์ ‘ ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. control ๋…ธ๋“œ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ๋Š” ๊ธฐ๊ธฐ์—์„œ ๋Œ€์‹œ๋ณด๋“œ์˜ Online Agents๊ฐ€ 2 ์ด์ƒ์ด ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค. Agent status์—์„œ๋Š” online ํ–‰๋งŒ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. Peers๋Š” ์ ์œ ๋Ÿ‰ / ์šฉ๋Ÿ‰์ด๋ฉฐ, ์šฉ๋Ÿ‰์—์„œ ์ ์œ ๋Ÿ‰์„ ๋บ€ ์—ฌ์œ  ์Šฌ๋กฏ์˜ ํ•ฉ๊ณ„๊ฐ€ 6 ์ด์ƒ์ด์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์š”์•ฝ์˜ Available slots์—๋Š” offline Agent๋„ ํฌํ•จ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ด ์กฐ๊ฑด์€ ํ‘œ๋กœ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. Swarm task๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ผ๋Š” ์‚ฌ์‹ค๋งŒ์œผ๋กœ ๋“ฑ๋ก๊นŒ์ง€ ํ™•์ธ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘์— ๋ฌธ์ œ๊ฐ€ ์žˆ์œผ๋ฉด sh scripts/swarm.sh logs agent ๋˜๋Š” sh scripts/swarm.sh logs controller๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

credentials๋Š” ๋Œ€์‹œ๋ณด๋“œ์˜ KPL_USERยทKPL_PASSWORD์™€ ๋ณ„๋„ Grafana ๊ณ„์ •์„ ํ‰๋ฌธ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. Controller์—์„œ๋Š” Log in์œผ๋กœ ๋กœ๊ทธ์ธํ•˜์‹ญ์‹œ์˜ค. Grafana์˜ ๊ธฐ์กด ์‚ฌ์šฉ์ž๋ช…์€ ์œ ์ง€ํ•˜๋ฉฐ ์‹œ์ž‘ํ•  ๋•Œ ์›๋ž˜ ๊ด€๋ฆฌ์ž ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์„ค์ •๊ฐ’์œผ๋กœ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค.

3. ๋ถ„์‚ฐ smoke ์‹คํ—˜ ์‹คํ–‰

# examples/swarm-smoke.yaml์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. FILE์„ ์ง€์ •ํ•˜๋ฉด ํ•ด๋‹น ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh scenario

๋Œ€์‹œ๋ณด๋“œ์—์„œ Run experiment๋ฅผ ๋ˆ„๋ฅด๊ณ  YAML scenario ์ „์ฒด๋ฅผ ์ถœ๋ ฅ๋œ YAML๋กœ ๊ต์ฒดํ•œ ๋‹ค์Œ Run์„ ๋ˆ„๋ฅด์‹ญ์‹œ์˜ค. ์›น ํผ์˜ ๊ธฐ๋ณธ ์‹œ๋‚˜๋ฆฌ์˜ค๋Š” ๋‹ค๋ฅธ smoke ์‹คํ—˜์ด๋ฉฐ Swarm ์˜ˆ์ œ๋ฅผ ์ž๋™์œผ๋กœ ๋ถˆ๋Ÿฌ์˜ค์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์˜ˆ์ œ๋Š” boot Peer ํ•œ ๊ฐœ์™€ worker ๋‹ค์„ฏ ๊ฐœ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. worker์—๋Š” 25ms ์ง€์—ฐ, 2ms jitter, 0.5% loss๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. readiness ํ™•์ธ๊ณผ 20์ดˆ ๋Œ€๊ธฐ ํ›„ payloadSize: 4096์œผ๋กœ ๋ฉ”์‹œ์ง€ 50๊ฐœ๋ฅผ ๋ฐœํ–‰ํ•˜๊ณ , ์ˆ˜์ง‘์„ ์œ„ํ•ด 1๋ถ„ ๊ธฐ๋‹ค๋ฆฐ ๋’ค stop-all์„ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์šฉ๋Ÿ‰์ด ๊ฐ™๊ณ  ๋‹ค๋ฅธ ๋ถ€ํ•˜๊ฐ€ ์—†๋Š” Agent๋“ค์—์„œ๋Š” balanced ๋ฐฐ์น˜๊ฐ€ Peer๋ฅผ ๋ถ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. ์„œ๋กœ ๋‹ค๋ฅธ Agent์— Peer๊ฐ€ ๋‚˜ํƒ€๋‚˜๊ณ  publish/deliver ์ด๋ฒคํŠธ๊ฐ€ ๊ธฐ๋ก๋˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. readiness๋Š” ํ”„๋กœ์„ธ์Šค ์ดˆ๊ธฐํ™” ์™„๋ฃŒ ๊ธฐ์ค€์ด๋ฉฐ GossipSub mesh ์ˆ˜๋ ด์„ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ „๋‹ฌ ์ˆ˜๋Š” ์‹ค์ œ ์กฐ๊ฑด์— ๋”ฐ๋ผ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค.

๋ถ„์„ํ•˜๋ ค๋ฉด Grafana URL์—์„œ ๋กœ๊ทธ์ธํ•˜๊ณ  KP2PLab Experiment Analysis์˜ Run์— ํ•ด๋‹น ์‹คํ—˜์„ ์„ ํƒํ•˜์‹ญ์‹œ์˜ค. Agent์™€ Topic์œผ๋กœ ์„œ๋ฒ„์™€ ํŠธ๋ž˜ํ”ฝ์„ ๋น„๊ตํ•ฉ๋‹ˆ๋‹ค. ๋Œ€์‹œ๋ณด๋“œ ๋ฉ”์‹œ์ง€ ์š”์•ฝ์€ ์ตœ๊ทผ ์ด๋ฒคํŠธ ๋ฒ„ํผ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ์„ ํƒ ์‹คํ–‰ ์ „์ฒด๋ฅผ ๋ˆ„์ ํ•ฉ๋‹ˆ๋‹ค. ์‹ค์‹œ๊ฐ„ counter๋Š” Controller ์žฌ์‹œ์ž‘ ์‹œ ์ดˆ๊ธฐํ™”๋˜์ง€๋งŒ ์ €์žฅ ๋ถ„์„๊ณผ ZIP ์ง€ํ‘œ๋Š” ๊ธฐ๋ก ํŒŒ์ผ์—์„œ ๋‹ค์‹œ ๊ณ„์‚ฐํ•ฉ๋‹ˆ๋‹ค. Grafana๋Š” ๊ฐ ํŒจ๋„์˜ ํ•„ํ„ฐยท์ง‘๊ณ„ ๊ทœ์น™์„ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋‹ˆํ„ฐ๋ง ๊ฐ€์ด๋“œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

4. ๊ฒฐ๊ณผ ๋‹ค์šด๋กœ๋“œ ํ›„ ์ฒ ๊ฑฐ

์‹คํ—˜์ด ๋๋‚˜๊ณ  ํ•ด๋‹น Peer๋“ค์ด ์ข…๋ฃŒ๋˜์—ˆ๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๋‹ค๋ฅธ ์‹คํ—˜์ด ์—†๋‹ค๋ฉด Agent ์ ์œ ๋Ÿ‰์€ 0์œผ๋กœ ๋Œ์•„์™€์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ์ค‘์ธ ์‹คํ—˜์„ ์ทจ์†Œํ•˜๋ ค๋ฉด ํ•ด๋‹น ์‹คํ—˜์˜ Stop์„ ๋ˆ„๋ฅด๊ณ  ์ •๋ฆฌ๊ฐ€ ์™„๋ฃŒ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค.

์‹คํ—˜ ํ•ญ๋ชฉ์ด๋‚˜ Saved results์—์„œ Download results๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค. ZIP์—๋Š” scenario.yaml, experiment.json, events.jsonl, ์„ ํƒ์  observations.jsonl, metrics.json, export.json์ด ๋“ค์–ด๊ฐ‘๋‹ˆ๋‹ค. ์ˆ˜์ง‘๋œ ๊ด€์ธก ์š”์•ฝยทํ‘œ๋ณธ ๊ทธ๋ž˜ํ”„ยท๋Œ€์—ญํญ ์นด์šดํ„ฐ๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ์ตœ๊ทผ 300๊ฐœ ๋ฒ„ํผ์™€ ๋ณ„๊ฐœ๋กœ ์ „์ฒด ์ €์žฅ ๋กœ๊ทธ์™€ ๊ฐ™์€ ๊ฒฝ๊ณ„์—์„œ ์žฌ๊ณ„์‚ฐํ•œ ์ง€ํ‘œ๋ฅผ ํฌํ•จํ•˜๋ฉฐ Prometheus/Grafana DB๋Š” ํฌํ•จํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‹คํ–‰ ์ค‘ Download snapshot์€ ๋‹ค์šด๋กœ๋“œ ๊ฒฝ๊ณ„๊นŒ์ง€์˜ ๊ธฐ๋ก์ž…๋‹ˆ๋‹ค. Delete๋Š” ํ™•์ธ ํ›„ ๋น„ํ™œ์„ฑ ๊ฒฐ๊ณผ๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์šด๋กœ๋“œ ๊ตฌ์„ฑ๊ณผ ํ•œ๊ณ„

์ฒ ๊ฑฐํ•˜๋ฉด ์›น ํ™”๋ฉด๋„ ๋‚ด๋ ค๊ฐ€๋ฏ€๋กœ ๋จผ์ € ๋‹ค์šด๋กœ๋“œํ•œ ๋’ค ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

sh scripts/swarm.sh remove

์ฒ ๊ฑฐ๋Š” ์‹คํŒจ task, task ์ด๋ ฅ ๋ถ€์žฌ, offline worker๊ฐ€ ์žˆ์–ด๋„ stack ์„œ๋น„์Šค๋ฅผ ์ง์ ‘ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์‚ญ์ œ๋Š” clean exit๋ฅผ ์กฐ๊ฑด์œผ๋กœ ํ•˜์ง€ ์•Š์œผ๋ฉฐ ์ตœ์ข… ๋กœ๊ทธ๋‚˜ standalone Peer ์ •๋ฆฌ ์™„๋ฃŒ๋ฅผ ํ™•์ธํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Gateway ์ œ๊ฑฐ์—๋Š” ์•„๋ž˜์˜ ๋ณ„๋„ ์ข…๋ฃŒ ๊ฒ€์‚ฌ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์‹คํ—˜ยทPrometheusยทGrafana volume๊ณผ ์™ธ๋ถ€ Peer network๋Š” ๋‚จ์Šต๋‹ˆ๋‹ค. ๋ณด์กด๋œ volume์— ๋‹ค์‹œ ๋ฐฐํฌํ•  ๋•Œ๋Š” ๊ฐ™์€ ์„ค์ •์„ ์žฌ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์ดํ›„ Saved results์—์„œ ๊ธฐ์กด ๊ธฐ๋ก์„ ๋‹ค์‹œ ๋ณผ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ์‹คํ–‰ ์ค‘์ด๋˜ ๊ธฐ๋ก์€ interrupted๋กœ ํ‘œ์‹œํ•˜๋ฉฐ ์ž๋™ ์žฌ๊ฐœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ƒํƒœ๋Š” Peer ์ •๋ฆฌ ์™„๋ฃŒ๋ฅผ ๋œปํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

worker๊ฐ€ ๊ณ„์† ๋“ค์–ด์˜ค๊ณ  ์ˆ˜๋ช…์— ๋”ฐ๋ผ ๋‚˜๊ฐ€๋Š” ๋” ๊ธด ์‹คํ—˜์€ churn ์ค‘ ๋ฌด์ž‘์œ„ ๋ฐ˜๋ณต ๋ฐœํ–‰์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค. ์•ˆ์ •์ ์ธ bootstrap ๋‘ ๊ฐœ์™€ ๋ฐ˜๋ณต์ ์ธ ๋ฐœํ–‰ ๋Œ€์ƒ ์„ ํƒ, ๋งˆ์ง€๋ง‰ ์ˆ˜์ง‘ยท์ •๋ฆฌ ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌ helper๋Š” control ๋…ธ๋“œ ์ฃผ์†Œ์™€ ๊ฒŒ์‹œ ํฌํŠธ๋กœ Controller metrics ๋ฐ Prometheus ์ž์ฒด ๋งํฌ์˜ ๋ธŒ๋ผ์šฐ์ €์šฉ ์ฃผ์†Œ๋ฅผ ์ž๋™ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„์˜ .env.swarm ์„ค์ •์€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. Prometheus์—์„œ ํ•ด๋‹น ๋…ธ๋“œ์˜ KPL_HTTP_PORT์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์–ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ž์„ธํ•œ ๋‚ด์šฉ์€ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์„ค์ •๊ณผ ๋„คํŠธ์›Œํฌ

์ผ๋ฐ˜์ ์ธ ์„ค์ • ๋ณ€๊ฒฝ์€ helper๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

sh scripts/swarm.sh configure KPL_AGENT_CAPACITY=20 KPL_MIN_AGENTS=2 KPL_AGENT_METRICS_PORT=9091
# ์„ ํƒ ์‚ฌํ•ญ: Peer overlay๋ฅผ ์ƒ์„ฑํ•˜๊ธฐ ์ „์— ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” subnet์„ ์ง€์ •ํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh configure KPL_PEER_SUBNET=10.11.0.0/24
sh scripts/swarm.sh config

configure๋Š” ๋ณ€๊ฒฝ ์‚ฌํ•ญ์„ ๊ฒ€์ฆํ•˜๊ณ  ์„ค์ • ํŒŒ์ผ์„ ์›์ž์ ์œผ๋กœ ๊ต์ฒดํ•˜๋ฉฐ, ๋ช…์‹œ์ ์œผ๋กœ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์€ ๊ธฐ์กด ์ž๊ฒฉ ์ฆ๋ช…์€ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ํŒŒ์ผ ์„ค์ •์— ์š”์ฒญํ•œ ๋ณ€๊ฒฝ๋งŒ ์ €์žฅํ•˜๊ณ  ๋ฌด๊ด€ํ•œ ํ™˜๊ฒฝ๋ณ€์ˆ˜์˜ ๋ฎ์–ด์“ฐ๊ธฐ ๊ฐ’์€ ์ €์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ€๊ฒฝํ•œ ์„ค์ •์€ ๋‹ค์Œ deploy์—์„œ ์„œ๋น„์Šค์— ์ ์šฉ๋˜๋ฉฐ ์‹คํ–‰ ์ค‘์ธ Peer๋ฅผ ์žฌ์„ค์ •ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŒŒ์ผ ๊ถŒํ•œ์€ 0600์ž…๋‹ˆ๋‹ค. init์€ ์ž๊ฒฉ ์ฆ๋ช…์„ ๋ช…์‹œ์ ์œผ๋กœ ์ง€์ •ํ•˜์ง€ ์•Š์œผ๋ฉด ๊ฐ๊ฐ 32๋ฐ”์ดํŠธ ๋‚œ์ˆ˜์˜ 64์ž๋ฆฌ hex๋กœ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. config๋Š” ๋น„๋ฐ€ ๊ฐ’์„ ๊ฐ€๋ฆฌ๊ณ  credentials๋งŒ ์˜๋„์ ์œผ๋กœ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค.

๊ธฐ๋ณธ stack ์ด๋ฆ„์€ kpl, helper์˜ ๊ธฐ๋ณธ Peer network๋Š” kpl-peers์ž…๋‹ˆ๋‹ค. KPL_PEER_SUBNET์€ ์„ ํƒ ์‚ฌํ•ญ์ด๋ฉฐ ์ƒ๋žตํ•˜๋ฉด overlay ์ƒ์„ฑ ์‹œ Docker๊ฐ€ subnet์„ ํ• ๋‹นํ•ฉ๋‹ˆ๋‹ค. ์ง€์ •ํ•œ๋‹ค๋ฉด ์„œ๋ฒ„ยทLANยทVPNยท๋‹ค๋ฅธ Docker ๋„คํŠธ์›Œํฌ์™€ ๊ฒน์น˜์ง€ ์•Š์•„์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด ๋„คํŠธ์›Œํฌ์˜ subnet์ด ๋‹ค๋ฅด๋ฉด ๋ฐฐํฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉฐ, ์„ค์ •์„ ๋ฐ”๊พผ๋‹ค๊ณ  ๊ธฐ์กด ๋„คํŠธ์›Œํฌ ํฌ๊ธฐ๊ฐ€ ๋ฐ”๋€Œ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. /16 ๊ฐ™์€ ๋” ํฐ subnet๋„ ์ž…๋ ฅํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ๋Œ€๊ทœ๋ชจ ์‹คํ—˜ ์ง€์›์„ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ์šฉ๋Ÿ‰ ํ•œ๊ณ„๋ฅผ ์ฐธ๊ณ ํ•˜๊ณ  ๋ณ„๋„ ๋ฐฐํฌ์—๋Š” ์„œ๋กœ ๋‹ค๋ฅธ stackยทPeer network ์ด๋ฆ„์„ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

KPL_CONTROL_NODE_ID๋Š” ๋ฐ์ดํ„ฐ volume์„ ๋ณด๊ด€ํ•˜๋Š” LinuxยทReadyยทActive Swarm manager์˜ ์ •ํ™•ํ•œ Node ID๋กœ ๊ณ ์ •ํ•˜์—ฌ Controllerยทnetwork-managerยทPrometheusยทGrafana๊ฐ€ ๋นˆ ๋กœ์ปฌ volume์„ ๊ฐ€์ง„ ๋‹ค๋ฅธ ์„œ๋ฒ„๋กœ ์ด๋™ํ•˜์ง€ ์•Š๊ฒŒ ํ•˜์‹ญ์‹œ์˜ค. nodes๋กœ ์„ ํƒํ•  ๋…ธ๋“œ๋ฅผ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. helper์˜ ๊ธฐ๋ณธ ์ตœ์†Œ Agent ์ˆ˜๋Š” 1์ด๋ฉฐ ์œ„ ์ ˆ์ฐจ์—์„œ๋Š” KPL_MIN_AGENTS=2๋ฅผ ๋ช…์‹œํ–ˆ์Šต๋‹ˆ๋‹ค. ์‚ฌ์ „ ๊ฒ€์‚ฌ์˜ ์ตœ์†Œ ์ˆ˜ ์กฐ๊ฑด์€ UI์—์„œ ์‹ค์ œ ๋“ฑ๋ก๊ณผ ์—ฌ์œ  ์Šฌ๋กฏ์„ ํ™•์ธํ•˜๋Š” ์ ˆ์ฐจ๋ฅผ ๋Œ€์ฒดํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

helper๋Š” .env.swarm์˜ ํ—ˆ์šฉ๋œ KEY=VALUE ํ•ญ๋ชฉ์„ ๋ฌธ์ž ๊ทธ๋Œ€๋กœ ์ฝ์œผ๋ฉฐ ํŒŒ์ผ์„ sourceํ•˜๊ฑฐ๋‚˜ ์…ธ ํ‘œํ˜„์‹์„ ์‹คํ–‰ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ”๊นฅ์ชฝ ํ•œ ์Œ์˜ ๋”ฐ์˜ดํ‘œ๋Š” ์ œ๊ฑฐํ•˜์ง€๋งŒ ๋ณ€์ˆ˜ยท๋ช…๋ น ์น˜ํ™˜ยทescape๋ฅผ ํ™•์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. export๋œ ํ™˜๊ฒฝ๋ณ€์ˆ˜๊ฐ€ ํŒŒ์ผ๋ณด๋‹ค ์šฐ์„ ํ•˜๋ฏ€๋กœ ํŒŒ์ผ ๋ณ€๊ฒฝ์ด ์ ์šฉ๋˜์ง€ ์•Š์€ ๊ฒƒ ๊ฐ™์œผ๋ฉด config๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. sudo๋Š” ํ™˜๊ฒฝ๋ณ€์ˆ˜๋ฅผ ์ œ๊ฑฐํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ™์€ ๊ณ„์ •์„ ์‚ฌ์šฉํ•˜๊ณ  ์ผ์ƒ ์„ค์ •์€ helper ํŒŒ์ผ์— ๋ณด๊ด€ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ํŒŒ์ผ์€ sh scripts/swarm.sh --env-file /path/to/lab.env config๋กœ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

publish์—์„œ ์‚ฌ์šฉ์ž ์ง€์ • ์„ค์ • ํŒŒ์ผ์„ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ์ €์žฅ์†Œ ๋ฐ–์ด๋‚˜ .dockerignore๊ฐ€ ์ œ์™ธํ•˜๋Š” ๋ฃจํŠธ์˜ .env.* ๊ฒฝ๋กœ์— ๋‘์‹ญ์‹œ์˜ค. helper๋Š” ๋นŒ๋“œ ์ „์— ์ง€์ • ๊ฒฝ๋กœ์™€ symlink์˜ ์ตœ์ข… ๋Œ€์ƒ์„ ๊ฒ€์‚ฌํ•˜๊ณ , ์ œ์™ธ ์—ฌ๋ถ€๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†๋Š” ์ €์žฅ์†Œ ๋‚ด๋ถ€ ๊ฒฝ๋กœ์™€ Dockerfile.dockerignore override๋ฅผ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด helper์˜ ์ž๊ฒฉ ์ฆ๋ช… ํŒŒ์ผ์ด ์ด๋ฏธ์ง€ build context์— ์ „๋‹ฌ๋˜์ง€ ์•Š๋„๋ก ํ•ฉ๋‹ˆ๋‹ค.

Agent๋Š” ๋ฐฐ์น˜๋œ ๋…ธ๋“œ์˜ ๋กœ์ปฌ Docker socket๋งŒ ์‚ฌ์šฉํ•˜๋ฉฐ manager API ์ ‘๊ทผ์ด ํ•„์š” ์—†์Šต๋‹ˆ๋‹ค. {{.Service.Name}}-{{.Node.ID}}๋กœ ID๋ฅผ ๋งŒ๋“ค๊ณ  ์ž์‹ ์˜ task๊ฐ€ ์—ฐ๊ฒฐ๋œ control overlay IPv4๋ฅผ advertise-url๊ณผ self-url๋กœ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น daemon์˜ Swarm NodeAddr๋ฅผ ์ฝ์–ด host-mode ํฌํŠธ๋ฅผ ํ†ตํ•œ ๋ณ„๋„ metrics URL๋„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. control API๋Š” overlay ๋‚ด๋ถ€ TCP 8090์— ์œ ์ง€๋˜๊ณ  ๊ฒŒ์‹œ๋˜์ง€ ์•Š์œผ๋ฉฐ Peer control ๋ฐ libp2p ํฌํŠธ๋„ ๊ฒŒ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋น„์Šค VIP๋‚˜ ๊ณตํ†ต DNSRR ์ฃผ์†Œ๋Š” ๊ฐœ๋ณ„ Agent๋ฅผ ์•ˆ์ •์ ์œผ๋กœ ์‹๋ณ„ํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Agent๋Š” ์‹œ์ž‘ ์‹œ ์‹ค์ œ ๋กœ์ปฌ image ID๋ฅผ ํ™•์ธํ•˜์—ฌ Peer ์ƒ์„ฑ์— ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ๊ฐ™์€ ๋…ธ๋“œ์˜ AgentยทPeer ๋ฐ”์ด๋„ˆ๋ฆฌ๊ฐ€ ์ผ์น˜ํ•ฉ๋‹ˆ๋‹ค. Swarm global ์„œ๋น„์Šค์™€ ํ…œํ”Œ๋ฆฟ

์ž๋™ ๋„คํŠธ์›Œํฌ ์ดˆ๊ธฐํ™”

์ œ๊ณต๋˜๋Š” stack์€ ๋ฐ˜๋ณต ํšŒ์ฐจ์™€ ์‹คํŒจ ์žฌ์‹œ๋„๋ฅผ ํฌํ•จํ•˜์—ฌ ๋งค Run ์ „์— ์ƒˆ Peer overlay๋ฅผ ์ค€๋น„ํ•ฉ๋‹ˆ๋‹ค. Controller์™€ Agent๋Š” stack์˜ attachable ${KPL_STACK_NAME}_control overlay๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ Peer๋Š” KPL_PEER_NETWORK์—๋งŒ ์—ฐ๊ฒฐํ•ฉ๋‹ˆ๋‹ค. network-manager ์„œ๋น„์Šค๋Š” ๊ณ ์ • control manager์—์„œ subnet/gateway๋ฅผ ๋ณด์กดํ•˜๋ฉฐ Peer network ID๋ฅผ ๊ต์ฒดํ•ฉ๋‹ˆ๋‹ค. ๊ฐ™์€ ๋…ธ๋“œ์˜ standalone network-gateway๋Š” ๋‘ overlay์— ์—ฐ๊ฒฐ๋˜์–ด Peer HTTP ์ œ์–ดยทtelemetryยทbootstrapยท์‹œ๊ฐ ์š”์ฒญ์„ ์ „๋‹ฌํ•ฉ๋‹ˆ๋‹ค. Libp2p ๋ฉ”์‹œ์ง€๋Š” Peer ์‚ฌ์ด์—์„œ ์ง์ ‘ ์ „๋‹ฌํ•˜๋ฉฐ Manager์™€ gateway ๋ชจ๋‘ ํ˜ธ์ŠคํŠธ ํฌํŠธ๋ฅผ ๊ณต๊ฐœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ดˆ๊ธฐํ™”๋Š” ๋น„ํ™œ์„ฑ Agent๋ฅผ ํฌํ•จํ•œ ๋“ฑ๋ก Agent ๋ชจ๋‘์˜ Peer ์ •๋ฆฌ ํ™•์ธ๊ณผ ์ƒˆ ์ž…์žฅ ์ฐจ๋‹จ์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ํ™•์ธ ์‘๋‹ต์ด ์—†๊ฑฐ๋‚˜ ์ดˆ๊ธฐํ™”๊ฐ€ ์‹คํŒจํ•˜๋ฉด phase๋ฅผ ์‹œ์ž‘ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  Agent ํ™œ์„ฑํ™” ํ›„ ์‹คํ—˜ ์‹œ๊ณ„๋ฅผ ์‹œ์ž‘ํ•ฉ๋‹ˆ๋‹ค. ์‹๋ณ„์žยท๋ณต๊ตฌยท์‹œ๊ฐ„ ์ œํ•œ์€ API ๊ณ„์•ฝ์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค. ๋ชจ๋“  Swarm ๋…ธ๋“œ๊ฐ€ Ready์—ฌ์•ผ ํ•˜๋ฉฐ Peer overlay์—๋Š” helper ์†Œ์œ ๊ถŒ label๊ณผ ๊ธฐ๋ณธ IPv4 ์„ค์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ๋˜๋Š” ์„œ๋น„์Šค๊ฐ€ ์—ฐ๊ฒฐ๋œ Peer network๋Š” ๊ฑฐ์ ˆํ•ฉ๋‹ˆ๋‹ค.

Manager๋Š” docker network ls --quiet --no-trunc์˜ ์ „์ฒด network ID๋ฅผ docker network inspect์™€ ๋น„๊ตํ•œ ๋’ค ๋„คํŠธ์›Œํฌ๋ฅผ ์ˆ˜๋ฝํ•ฉ๋‹ˆ๋‹ค. Docker๋Š” --quiet๋งŒ ์ง€์ •ํ•ด๋„ ๋ชฉ๋ก ID๋ฅผ ์ถ•์•ฝํ•˜๋ฏ€๋กœ Docker network ๋ชฉ๋ก ๋ฌธ์„œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค. ๊ฑฐ์ ˆ ์‹œ ์‹๋ณ„์žยทoverlay ์„ค์ •ยทIPAM ์„ค์ •์„ ๊ตฌ๋ถ„ํ•˜๊ณ  ๊ด€์ธกํ•œ ๊ฐ’์„ ํ•จ๊ป˜ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์‹๋ณ„์ž ๋ถˆ์ผ์น˜๋Š” attachable์ด๋‚˜ IPv4๊ฐ€ ๊บผ์กŒ๋‹ค๋Š” ์˜๋ฏธ๊ฐ€ ์•„๋‹™๋‹ˆ๋‹ค. ์†Œ์œ ๊ถŒยท์‚ฌ์šฉ์ž ์ง€์ • ์„ค์ •ยท์‚ฌ์šฉ ์ค‘ ๋„คํŠธ์›Œํฌ ๊ฒ€์‚ฌ๋Š” ๊ณ„์† ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

์ž๋™ ์ดˆ๊ธฐํ™” ์‹œ network inspect์—๋Š” ์‹คํ—˜ gateway์™€ ํ•จ๊ป˜ Docker ๋‚ด๋ถ€ lb-<network-name> sandbox๊ฐ€ ํ‘œ์‹œ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Manager๋Š” ํ•ด๋‹น Peer overlay์— ๋งž๋Š” ํ‚ค์™€ <network-name>-endpoint ์ด๋ฆ„, Docker ํ˜•์‹์˜ endpoint ID๊ฐ€ ๋ชจ๋‘ ์ผ์น˜ํ•˜๋Š” ๊ฒฝ์šฐ์—๋งŒ ๋‚ด๋ถ€ ํ•ญ๋ชฉ์œผ๋กœ ๊ตฌ๋ถ„ํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฅผ ์ผ๋ฐ˜ ์ปจํ…Œ์ด๋„ˆ๋กœ ์กฐํšŒํ•˜๊ฑฐ๋‚˜ ์‚ญ์ œํ•˜์ง€ ์•Š๊ณ  Docker๊ฐ€ ์ˆ˜๋ช…์ฃผ๊ธฐ๋ฅผ ๊ด€๋ฆฌํ•˜๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. ๋‚˜๋จธ์ง€ endpoint๋Š” ๊ณ„์† gateway ์†Œ์œ ๊ถŒ ๊ฒ€์‚ฌ๋ฅผ ๊ฑฐ์นฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ๋‚จ์•„ ์žˆ๊ฑฐ๋‚˜ ์กฐํšŒํ•  ์ˆ˜ ์—†์œผ๋ฉด ์ดˆ๊ธฐํ™”๋ฅผ ๊ฑฐ๋ถ€ํ•˜๋ฉฐ endpoint ํ‚คยท์ด๋ฆ„์„ ํ‘œ์‹œํ•˜๊ณ  ์กฐํšŒ ์˜ค๋ฅ˜๊ฐ€ ์žˆ์œผ๋ฉด ํ•จ๊ป˜ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์ฐธ์กฐ์™€ ์›๊ฒฉ attachment์— ๋Œ€ํ•œ ๊ฑฐ๋ถ€๋„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. Docker LB sandbox ๋ช…๋ช… ๊ตฌํ˜„์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์ž๋™ ๊ต์ฒด๋Š” Docker์˜ ์‚ญ์ œ ๋ฐ˜์˜ ์ง€์—ฐ์„ ๊ณ ๋ คํ•ด ์ด์ „ Peer network ์ด๋ฆ„์ด ์‚ฌ๋ผ์งˆ ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฐ ๋’ค ์ƒˆ ๋„คํŠธ์›Œํฌ๋ฅผ ๋งŒ๋“ญ๋‹ˆ๋‹ค. ์ผ์‹œ์ ์ธ network with name ... already exists ๊ฑฐ์ ˆ์€ ์ œํ•œ ์‹œ๊ฐ„ ์•ˆ์—์„œ ์ƒํƒœ๋ฅผ ํ™•์ธํ•˜๊ณ  ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์‹คํ–‰์˜ ๊ต์ฒด ๋„คํŠธ์›Œํฌ๊ฐ€ ๋‚˜ํƒ€๋‚˜๋ฉด ๊ทธ๋Œ€๋กœ ๋ณด์กดํ•˜๊ณ  ์ถฉ๋Œ๋กœ ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์‹œ๊ฐ„ ์ œํ•œ๊ณผ ์ƒ์„ฑ ์‘๋‹ต์ด ๋ถˆํ™•์‹คํ•œ ๊ฒฝ์šฐ์˜ ๋ณต๊ตฌ๋Š” ๋„คํŠธ์›Œํฌ ์ค€๋น„ API๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์œ ํœด ์ƒํƒœ์—์„œ ์—…๊ทธ๋ ˆ์ด๋“œ: ์‹คํ–‰ยท์˜ˆ์•ฝ ์‹คํ—˜์„ ์™„๋ฃŒํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•˜๊ณ  Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•œ ๋‹ค์Œ ์ด๋ฏธ์ง€๋ฅผ ์žฌ๋นŒ๋“œยท๊ฒŒ์‹œํ•˜๊ณ  ๊ฐฑ์‹ ํ•œ stack์„ ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. Controller/Agent ๋„คํŠธ์›Œํฌ ์—ฐ๊ฒฐ๊ณผ ์ƒˆ Manager ์„œ๋น„์Šค๋ฅผ ํ•จ๊ป˜ ๊ฐฑ์‹ ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Control ๋…ธ๋“œ๋Š” manager์—ฌ์•ผ ํ•˜๋ฉฐ ๋ณด์กด๋œ ๋ฐ์ดํ„ฐ volume์„ ์ด์ „ํ•˜์ง€ ์•Š๊ณ  ID๋ฅผ ๋ฐ”๊พธ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์†Œ์Šคยท์„ค์ • ํŒŒ์ผ๋งŒ ์ˆ˜์ •ํ•ด๋„ ํ˜„์žฌ ๋ฐฐํฌ๊ฐ€ ๋ฐ”๋€Œ์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. Preparing network ์‹คํŒจ ์‹œ sh scripts/swarm.sh logs network-manager๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ž‘์€ ํ˜ธ์ŠคํŠธ ๊ฐ„ ์‹คํ—˜๊ณผ ๋Œ€๊ทœ๋ชจ ๋ฐ˜๋ณต ์‹คํ–‰์€ ๋ณ„๋„ ์šด์˜ ๊ฒ€์ฆ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

network-manager-data๋Š” control ๋…ธ๋“œ์˜ /var/lib/kpl/network์— ํ• ๋‹น ์„ค์ •๊ณผ ์ค€๋น„ ์‹๋ณ„์ž๋ฅผ ์ €์žฅํ•ฉ๋‹ˆ๋‹ค. ์žฌ์‹œ์ž‘๊ณผ stack ์ œ๊ฑฐ ํ›„์—๋„ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. Gateway๋Š” ๋‹ค์Œ ์ •๋ฆฌ ํ™•์ธ ๋˜๋Š” ๊ฒ€์ฆ๋œ stack ์ œ๊ฑฐ๊นŒ์ง€ ์œ ์ง€๋˜์–ด ๋‚จ์€ Peer์˜ ํ†ต์‹ ์„ ์ง€์›ํ•˜๋ฉฐ ์ œ์–ด ์„œ๋น„์Šค ์ž์› ๋ชจ๋‹ˆํ„ฐ๋ง์— ํฌํ•จ๋ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์˜ reset-peer-network๋Š” ์œ ํœด ์œ ์ง€๋ณด์ˆ˜์šฉ์œผ๋กœ ๊ณ„์† ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๊ณ  Manager์˜ ์‹คํ–‰ ํ‘œ์‹๋„ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค.

Agent ์‹œ์ž‘๊ณผ ์žฌ์—ฐ๊ฒฐ

Swarm ์ง„์ž… ์Šคํฌ๋ฆฝํŠธ๋Š” task ์ฃผ์†Œ, ๋…ธ๋“œ ์ฃผ์†Œ, ์ด๋ฏธ์ง€ ์กฐํšŒ๋ฅผ 2์ดˆ ๊ฐ„๊ฒฉ์œผ๋กœ ์ตœ๋Œ€ 5ํšŒ ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. ๊ฐ Docker ์กฐํšŒ์—๋Š” 5์ดˆ ์ œํ•œ๊ณผ ์ดํ›„ 1์ดˆ์˜ ๊ฐ•์ œ ์ข…๋ฃŒ ์œ ์˜ˆ๋ฅผ ์ ์šฉํ•ฉ๋‹ˆ๋‹ค. ์•„์ง ๋น„์–ด ์žˆ๋Š” ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ์žฌ์‹œ๋„ํ•˜๊ณ , ์ž˜๋ชป๋œ ์ฃผ์†Œ๋‚˜ ํฌํŠธ ์„ค์ •์€ ๋ช…์‹œ์ ์œผ๋กœ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์ดํ›„ Agent๊ฐ€ runtime์„ ๊ฒ€์‚ฌํ•˜๊ณ  ์ž์‹ ์˜ Agentยทnetwork ์†Œ์œ  ๋ฒ”์œ„์— ๋‚จ์€ Peer๋ฅผ ์ตœ๋Œ€ 4๊ฐœ์”ฉ ๋ณ‘๋ ฌ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ •๋ฆฌ์— ์„ฑ๊ณตํ•ด์•ผ Controller์— ๋“ฑ๋กํ•ฉ๋‹ˆ๋‹ค.

์„ ํƒํ•œ ๋…ธ๋“œ๊ฐ€ Agent status์— ์—†๋‹ค๋ฉด sh scripts/swarm.sh logs agent๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. Waiting for ...๋Š” ์ง€์—ฐ ์ค‘์ธ Docker ์กฐํšŒ ๋‹จ๊ณ„๋ฅผ ๋‚˜ํƒ€๋ƒ…๋‹ˆ๋‹ค. Agent๋Š” agent startup checking Docker runtime, agent startup cleaning previous Peer containers, ์†Œ์š” ์‹œ๊ฐ„์ด ํฌํ•จ๋œ agent startup cleanup complete, agent registered๋ฅผ ์ฐจ๋ก€๋กœ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. task๊ฐ€ ์‹คํ–‰ ์ค‘์ด์–ด๋„ ๋งˆ์ง€๋ง‰ ๋“ฑ๋ก ๋กœ๊ทธ๊ฐ€ ์—†๋‹ค๋ฉด ์•„์ง Controller์—์„œ ์‚ฌ์šฉํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. Peer ์ •๋ฆฌ์— ์‹คํŒจํ•˜๋ฉด ์˜ค๋ฅ˜๋ฅผ ์œ ์ง€ํ•˜๋ฉฐ ๋‚จ์€ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ๋นˆ ์šฉ๋Ÿ‰์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ผ์‹œ์ ์ธ heartbeat ํ†ต์‹  ์˜ค๋ฅ˜๋‚˜ HTTP 5xx ์‘๋‹ต์€ ์ด๋ฏธ ์ „๋‹ฌํ•œ Peer ์ด๋ ฅ์˜ ํ™•์ธ ์ƒํƒœ๋ฅผ ์œ ์ง€ํ•œ ์ฑ„ heartbeat๋ฅผ ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. Controller ์žฌ์‹œ์ž‘ ๋“ฑ์œผ๋กœ ๋“ฑ๋ก ์ถฉ๋Œ ์‘๋‹ต(HTTP 409)์„ ๋ฐ›์œผ๋ฉด ์žฌ๋“ฑ๋กํ•˜๊ณ  Peer ๋ชฉ๋ก์„ ๋‹ค์‹œ ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ์ผ์‹œ ์žฅ์•  ๋•Œ๋งˆ๋‹ค ์ข…๋ฃŒ๋œ Peer ์ „์ฒด๋ฅผ ๋ฐ˜๋ณต ์—…๋กœ๋“œํ•˜์ง€ ์•Š์œผ๋ฉด์„œ Controller์˜ ๋“ฑ๋ก ์ •๋ณด ์œ ์‹ค์—๋„ ๋ณต๊ตฌํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

Agent Status์˜ Refresh๋Š” Offline์„ ํฌํ•จํ•œ ๊ธฐ์กด ๋“ฑ๋ก ํ•ญ๋ชฉ์„ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ๋ชฉ๋ก์— ์—†๋Š” ์‹คํ–‰ ์ค‘ task๋ฅผ ์ฐพ๊ฑฐ๋‚˜ task ์ฃผ์†Œ๊ฐ€ ๋ฐ”๋€ Agent๋ฅผ ๋ณต๊ตฌํ•˜๋ ค๋ฉด More โ†’ Discover Agents๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. tasks.<stack>_agent๋ฅผ ์กฐํšŒํ•˜๊ณ  ์ œ์–ด API๋ฅผ ํ™•์ธํ•œ ๋’ค, ๋ฏธ๋“ฑ๋กยท๊ต์ฒด๋œ Agent๊ฐ€ ์„ค์ •๋œ Controller์— ์žฌ๋“ฑ๋กํ•˜๋„๋ก ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ์ƒˆ๋กœ ์ถ”๊ฐ€ํ•œ Agent ์ˆ˜์™€ ๊ฐœ๋ณ„ ์‹คํŒจ ์ด์œ ๋ฅผ ํ‘œ์‹œํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ์ค‘์ธ Peer์™€ ์ €์žฅ๋œ ์šฉ๋Ÿ‰ยท๋น„ํ™œ์„ฑํ™” ์„ค์ •์€ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. stack์ด KPL_AGENT_DISCOVERY_DNS๋ฅผ ์ž๋™ ์ง€์ •ํ•˜๋ฉฐ, ๋‹จ๋… Controller๋Š” --agent-discovery-dns๋กœ ์ ‘๊ทผ ๊ฐ€๋Šฅํ•œ Agent task DNS ์ด๋ฆ„์„ ์ง€์ •ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค(8090 ํฌํŠธ). ์ด ๋ณต๊ตฌ ๊ธฐ๋Šฅ์„ ์‚ฌ์šฉํ•˜๊ธฐ ์ „์— Controller์™€ Agent ์ด๋ฏธ์ง€๋ฅผ ๋ชจ๋‘ ๋นŒ๋“œํ•˜๊ณ  ์ˆ˜์ •๋œ stack ์„ค์ •์„ ์žฌ๋ฐฐํฌํ•˜์‹ญ์‹œ์˜ค.

Agent ํ”„๋กœ์„ธ์Šค๊ฐ€ ์‹คํ–‰ ์ค‘์ด๋ฉด ์ตœ์ดˆ ๋“ฑ๋ก์€ ์‹คํŒจ ํ›„ 2์ดˆ ์ฃผ๊ธฐ๋กœ ๊ณ„์† ์žฌ์‹œ๋„ํ•ฉ๋‹ˆ๋‹ค. DNSยท๋„คํŠธ์›Œํฌ ์žฅ์• ๋‚˜ ์ง„ํ–‰ ์ค‘ heartbeat๊ฐ€ ํ•ด์†Œ๋œ ๋’ค ํƒ์ƒ‰์„ ๋‹ค์‹œ ์‹คํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์‹œ์ž‘ ์‹คํŒจยท๋ฏธ๋ฐฐ์น˜ ์ปจํ…Œ์ด๋„ˆ๋ฅผ ์‹คํ–‰ํ•˜๊ฑฐ๋‚˜ ์‹œ์ž‘ ์‹œ Peer ์ •๋ฆฌ๋ฅผ ๊ฑด๋„ˆ๋›ฐ๋Š” ๊ธฐ๋Šฅ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์„ ํƒํ•œ ๋…ธ๋“œ๊ฐ€ ๊ณ„์† ๋ˆ„๋ฝ๋˜๋ฉด sh scripts/swarm.sh status์™€ sh scripts/swarm.sh logs agent๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. DNS์— ์ฃผ์†Œ๊ฐ€ ์—†๋Š” task๋Š” ๋ฐœ๊ฒฌํ•œ Agent ์ˆ˜์— ํฌํ•จํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค.

๋™์ผ ํƒœ๊ทธ๋กœ ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ

kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ๋ฅผ ๊ฐฑ์‹ ํ•œ ๋’ค ์ง„ํ–‰ ์ค‘ ์‹คํ—˜์„ ๋งˆ์น˜๊ณ  ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

sh scripts/swarm.sh publish
sh scripts/swarm.sh deploy
sh scripts/swarm.sh status

์„ค์ •์—๋Š” ๊ฐ™์€ ํƒœ๊ทธ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ digest์—์„œ ํƒœ๊ทธ๋กœ ๋ฐ”๊พธ๊ฑฐ๋‚˜ ๋‹ค๋ฅธ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜๋ ค๋ฉด ๋จผ์ € ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

sh scripts/swarm.sh configure KPL_IMAGE=registry.example.com/kpl-v3:v3

์ดํ›„ ๋™์ผํ•˜๊ฒŒ publish โ†’ deploy๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. publish์—๋Š” digest๊ฐ€ ์•„๋‹Œ ํƒœ๊ทธ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ์•„ํ‚คํ…์ฒ˜๊ฐ€ ํ˜ผํ•ฉ๋˜์–ด ์žˆ๋‹ค๋ฉด native ๋นŒ๋“œ ๋Œ€์‹  publish --platforms linux/amd64,linux/arm64๋กœ manager์™€ ๋ชจ๋“  ๋Œ€์ƒ ์•„ํ‚คํ…์ฒ˜๋ฅผ ํฌํ•จํ•˜์‹ญ์‹œ์˜ค.

๋งค ๋ฐฐํฌ๋งˆ๋‹ค ์„ค์ •๋œ ํƒœ๊ทธ๋ฅผ pullํ•˜๊ณ  ๊ฒฐ๊ณผ์˜ registry digest๋ฅผ ํ™•์ธํ•˜์—ฌ .env.swarm์„ ๋ฐ”๊พธ์ง€ ์•Š๊ณ  ์ด๋ฒˆ ๋ฐฐํฌ๋งŒ ํ•ด๋‹น digest๋กœ ๊ณ ์ •ํ•ฉ๋‹ˆ๋‹ค. pushํ•  ๋•Œ๋งˆ๋‹ค SHA๋ฅผ ์ˆ˜๋™์œผ๋กœ ๋ฐ”๊ฟ€ ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. pull์— ์‹คํŒจํ•˜๋ฉด ์˜ค๋ž˜๋œ ๋กœ์ปฌ ํƒœ๊ทธ๋ฅผ ์‚ฌ์šฉํ•˜์ง€ ์•Š๊ณ  ๋ฐฐํฌ๋ฅผ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. ๋ณ€๊ฒฝ๋˜์ง€ ์•Š๋Š” ๋ฒ„์ „์œผ๋กœ ๋ฐฐํฌํ•˜๋ ค๋ฉด ๊ธฐ์กด์ฒ˜๋Ÿผ repository@sha256:<digest>๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Docker pull๊ณผ digest ๊ณ ์ •

์ œํ•œ ์‹œ๊ฐ„์€ ์ดˆ ๋‹จ์œ„์ด๋ฉฐ ๊ธฐ๋ณธ๊ฐ’์€ KPL_IMAGE_BUILD_TIMEOUT=1800, KPL_IMAGE_PUSH_TIMEOUT=600, KPL_IMAGE_PULL_TIMEOUT=300์ž…๋‹ˆ๋‹ค. ๋ณ„๋„ push ์ œํ•œ์€ native ๊ฒŒ์‹œ์— ์ ์šฉํ•˜๋ฉฐ, Buildx์˜ ํ†ตํ•ฉ ๋นŒ๋“œยทpush์—๋Š” build ์ œํ•œ์ด ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. ํƒœ๊ทธ ํ™•์ธ์šฉ pull์€ manager ๋ฐ๋ชฌ์˜ native ํ”Œ๋žซํผ์„ ์‚ฌ์šฉํ•˜๊ณ  ํ•ด๋‹น pull์—์„œ๋งŒ DOCKER_DEFAULT_PLATFORM์„ ๋ฌด์‹œํ•˜๋ฉฐ, Docker๊ฐ€ ๋ฐ˜ํ™˜ํ•œ manifest/index digest๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. Agent ๊ต์ฒด ์‹œ ๋‹ด๋‹น Peer๊ฐ€ ์ข…๋ฃŒ๋  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๋ฐฐํฌ ํ›„ Agent ๋“ฑ๋ก์„ ๊ธฐ๋‹ค๋ฆฐ ๋’ค ๋‹ค์Œ ์‹คํ—˜์„ ์‹คํ–‰ํ•˜์‹ญ์‹œ์˜ค.

Manager์—์„œ Agent ์ถ”๊ฐ€ยท์ฒ ๊ฑฐ

๋ช…์‹œ์  NODE ๋ชฉ๋ก์—๋Š” Swarm node ID ๋˜๋Š” hostname์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. deploy, add-node, remove-node์—๋Š” ๋ชฉ๋ก ๋Œ€์‹  ๋‹ค์Œ ์„ ํƒ ์˜ต์…˜ ์ค‘ ํ•˜๋‚˜๋ฅผ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์„ ํƒ ์˜ต์…˜๋ผ๋ฆฌ ๋˜๋Š” ์„ ํƒ ์˜ต์…˜๊ณผ ๋ช…์‹œ์  ๋…ธ๋“œ ๋ชฉ๋ก์„ ์„ž์„ ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ์•„๋ž˜ ๋ช…๋ น์€ ์„œ๋ฒ„๋ฅผ Swarm์— ๊ฐ€์ž…์‹œํ‚ค๊ฑฐ๋‚˜ ํƒˆํ‡ด์‹œํ‚ค์ง€ ์•Š๊ณ , ํ•ด๋‹น stack์˜ Agent ๋ฐฐ์น˜๋งŒ ๋ณ€๊ฒฝํ•ฉ๋‹ˆ๋‹ค.

์„ ํƒ ์˜ต์…˜ ํ›„๋ณด ๋…ธ๋“œ
--all manager๋ฅผ ํฌํ•จํ•œ ์ „์ฒด ๋…ธ๋“œ
--all-excluding-self ํ˜„์žฌ Docker context๋กœ ์ ‘์†ํ•œ manager๋ฅผ ์ œ์™ธํ•œ ์ „์ฒด ๋…ธ๋“œ
--workers Swarm ์—ญํ• ์ด worker์ธ ๋…ธ๋“œ. manager๋Š” ์ œ์™ธ

self๋Š” ํ˜„์žฌ context๋กœ ์„ ํƒํ•œ Docker daemon์ด ๋ณด๊ณ ํ•˜๋Š” .Swarm.NodeID์ž…๋‹ˆ๋‹ค. KPL_CONTROL_NODE_ID๋‚˜ ๋ช…๋ น์„ ์ž…๋ ฅํ•˜๋Š” ์…ธ์˜ hostname์„ ๊ธฐ์ค€์œผ๋กœ ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. manager๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์ธ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ๋Š” --all-excluding-self๊ฐ€ ๋‹ค๋ฅธ manager๋ฅผ ์„ ํƒํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ๋ชจ๋“  manager๋ฅผ ์ œ์™ธํ•˜๋ ค๋ฉด --workers๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

์ž๋™ deploy/add-node๋Š” LinuxยทReadyยทActive ๋…ธ๋“œ๋งŒ ํฌํ•จํ•˜๋ฉฐ ์กฐ๊ฑด์— ๋งž์ง€ ์•Š๋Š” ํ›„๋ณด๋Š” ๊ฑด๋„ˆ๋›ฐ์—ˆ๋‹ค๊ณ  ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค. ์ž๋™ remove-node๋Š” ๋จผ์ € ์ด stack์˜ kpl.<stack>.agent=true label์ด ์žˆ๋Š” ๋…ธ๋“œ๋กœ ๋Œ€์ƒ์„ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค. ์ฒ ๊ฑฐ ๋Œ€์ƒ์ด ์ ‘๊ทผ ๋ถˆ๊ฐ€์ด๊ฑฐ๋‚˜ ์กฐ๊ฑด์— ๋งž์ง€ ์•Š์œผ๋ฉด ๊ฑด๋„ˆ๋›ฐ์ง€ ์•Š๊ณ  ์‹คํŒจํ•˜์—ฌ ๊ธฐ์กด ์ •๋ฆฌ ํ™•์ธ ์ ˆ์ฐจ๋ฅผ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ ๊ฒฐ๊ณผ๊ฐ€ ๋น„์–ด๋„ ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค.

๋ฐฐํฌยท์ถ”๊ฐ€๋Š” ๊ธฐ์กด ๋ฐฐ์น˜ label์— ๋Œ€์ƒ์„ ์ถ”๊ฐ€ํ•˜๋ฉฐ, ์„ ํƒ ๋ฐ–์˜ ๋…ธ๋“œ์—์„œ label์„ ์ œ๊ฑฐํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ธ์ž ์—†๋Š” deploy๋Š” ๊ธฐ์กด label์„ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์„ ํƒ ์˜ต์…˜์€ ํ•ด๋‹น ๋ช…๋ น ์‹คํ–‰ ์‹œ์—๋งŒ ํ‰๊ฐ€ํ•˜๋ฏ€๋กœ, ์ดํ›„ Swarm์— ๊ฐ€์ž…ํ•œ ๋…ธ๋“œ์— Agent๋ฅผ ์ž๋™ ๋ฐฐ์น˜ํ•˜๋Š” ์˜๊ตฌ ๊ทœ์น™์ด ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

# ์ƒˆ๋กœ ๊ฐ€์ž…ํ•œ worker๋ฅผ ํฌํ•จํ•˜์—ฌ ํ˜„์žฌ ์กฐ๊ฑด์— ๋งž๋Š” worker ์—ญํ•  ๋…ธ๋“œ๋ฅผ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh add-node --workers
# ํ•ด๋‹น ๋…ธ๋“œ์˜ ์‹คํ—˜์„ ๋งˆ์นœ ๋’ค ์ด stack์˜ ์„ ํƒ๋œ Agent๋ฅผ ์ข…๋ฃŒํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh remove-node --all-excluding-self

Makefile์€ NODES๋ฅผ ๊ทธ๋Œ€๋กœ ์ „๋‹ฌํ•˜๋ฏ€๋กœ make swarm-add-node NODES='--workers'๋„ ๊ฐ™์€ ๋Œ€์ƒ์„ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

๋ช…๋ น ๋™์ž‘
sh scripts/swarm.sh deploy [NODE...] ๋…ธ๋“œ ๋ชฉ๋ก ๋˜๋Š” ์„ ํƒ ์˜ต์…˜ ํ•˜๋‚˜๋กœ ๋ฐฐํฌยท์—…๋ฐ์ดํŠธํ•˜๋ฉฐ, ๋‘˜ ๋‹ค ์—†์œผ๋ฉด ๊ธฐ์กด label ์žฌ์‚ฌ์šฉ. ์ด๋ฏธ์ง€ ํƒœ๊ทธ๋ฅผ pullยทํ™•์ •ํ•˜๊ฑฐ๋‚˜ ๋ช…์‹œ digest ์‚ฌ์šฉ
sh scripts/swarm.sh status Docker stack ์„œ๋น„์ŠคยทAgent taskยท์„ ํƒ๋œ ๋…ธ๋“œ ํ‘œ์‹œ. API readiness๋Š” ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์Œ
sh scripts/swarm.sh nodes ํ˜„์žฌ Swarm ๋…ธ๋“œ ๋ชฉ๋ก ์กฐํšŒ
sh scripts/swarm.sh init [KEY=VALUE...] ๊ฒ€์ฆ๋œ ๋น„๊ณต๊ฐœ ์„ค์ •๊ณผ ์ž๊ฒฉ ์ฆ๋ช… ์ƒ์„ฑ. ๊ธฐ์กด ํŒŒ์ผ์€ ๋ฎ์–ด์“ฐ์ง€ ์•Š์Œ
sh scripts/swarm.sh configure KEY=VALUE... ๋‹ค๋ฅธ ์„ค์ •๊ณผ ์ž๊ฒฉ ์ฆ๋ช…์„ ๋ณด์กดํ•˜๋ฉฐ ๊ฒ€์ฆ๋œ ๋ณ€๊ฒฝ์„ ์›์ž์ ์œผ๋กœ ์ €์žฅ
sh scripts/swarm.sh config / credentials ๋น„๋ฐ€ ๊ฐ’์„ ๊ฐ€๋ฆฐ ์œ ํšจ ์„ค์ • ์กฐํšŒ / APIยทGrafana ์ž๊ฒฉ ์ฆ๋ช… ๋ช…์‹œ์  ํ‘œ์‹œ
sh scripts/swarm.sh login ์„ค์ •๋œ ์ด๋ฏธ์ง€์—์„œ ์ถ”๋ก ํ•œ registry์— ๋Œ€ํ™”ํ˜• ๋กœ๊ทธ์ธ
sh scripts/swarm.sh publish [--platforms CSV] ์„ค์ • ํƒœ๊ทธ๋กœ ๋นŒ๋“œยทpush. ํ”Œ๋žซํผ ์ง€์ • ์‹œ ๊ธฐ์กด Buildx builder ์‚ฌ์šฉ
sh scripts/swarm.sh check ๋ถˆ๋Ÿฌ์˜จ ์„ค์ •์œผ๋กœ ๋ฐฐํฌ ์‚ฌ์ „ ๊ฒ€์‚ฌ ์žฌ์‹คํ–‰
sh scripts/swarm.sh access control ๋…ธ๋“œ URL๊ณผ ์„ ํƒ๋œ ๊ฐ Agent ๋…ธ๋“œ์˜ metrics URL ์ถœ๋ ฅ. ์ ‘๊ทผ ๊ฐ€๋Šฅ ์—ฌ๋ถ€๋‚˜ ์„œ๋น„์Šค readiness๋Š” ๊ฒ€์‚ฌํ•˜์ง€ ์•Š์Œ
sh scripts/swarm.sh logs [COMPONENT] [--tail N|all] ๊ธฐ๋ณธ ์ตœ๊ทผ 100์ค„. controllerยทagentยทprometheusยทgrafana ์„œ๋น„์Šค ๋กœ๊ทธ ๋˜๋Š” accessยทauth ์›น JSONL ํŒŒ์ผ ์กฐํšŒ
sh scripts/swarm.sh scenario [FILE] ์›น ํผ์— ๋„ฃ์„ YAML ์ถœ๋ ฅ. ๊ธฐ๋ณธ์€ ๋ถ„์‚ฐ smoke ์˜ˆ์ œ์ด๋ฉฐ ์‹คํ–‰ ์š”์ฒญ์€ ํ•˜์ง€ ์•Š์Œ
sh scripts/swarm.sh add-node worker-c ๊ธฐ์กด ์„œ๋น„์Šค์— Agent ๋ฐฐ์น˜ ๋…ธ๋“œ ์ถ”๊ฐ€. LinuxยทReadyยทActive ์ƒํƒœ ํ•„์š”
sh scripts/swarm.sh remove-node worker-b ์„œ๋น„์Šค์—์„œ ๋Œ€์ƒ ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•˜๊ณ  Agent ์ •์ƒ ์ข…๋ฃŒ ํ™•์ธ ํ›„ ๋ฐฐ์น˜ label ์ •๋ฆฌ
sh scripts/swarm.sh remove ๋น„์ •์ƒ task๊ฐ€ ์žˆ์–ด๋„ stack ์„œ๋น„์Šค ์ง์ ‘ ์‚ญ์ œ; ๋ฐ์ดํ„ฐ volumeยทPeer network ๋ณด์กด
sh scripts/swarm.sh reset-peer-network stack ์ œ๊ฑฐ ํ›„ ์‚ฌ์šฉํ•˜์ง€ ์•Š๋Š” helper ์†Œ์œ  Peer overlay๋ฅผ ์žฌ์ƒ์„ฑํ•˜๊ณ  ๊ธฐ์กด IPv4 ํ• ๋‹น ์„ค์ • ๋ณด์กด

์›น ์ ‘๊ทผยท๋กœ๊ทธ์ธ ๊ธฐ๋ก์€ logs access, logs auth๋กœ ์กฐํšŒํ•ฉ๋‹ˆ๋‹ค. Controller๊ฐ€ ๋‹ค๋ฅธ ๋…ธ๋“œ์— ์žˆ์œผ๋ฉด ํ˜ธ์ถœ์ž๋Š” manager์— ์—ฐ๊ฒฐํ•œ ์ƒํƒœ์—์„œ ํ•ด๋‹น ๋…ธ๋“œ์˜ Docker daemon์„ ๊ฐ€๋ฆฌํ‚ค๋Š” --context NAME์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ ์˜ˆ์™€ ํŒŒ์ผ ๋ณด์กด ๋ฐฉ์‹์€ ์›น ์ ‘๊ทผยท์ธ์ฆ ๋กœ๊ทธ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•˜๋ฉด ์ดํ›„ join๋ถ€ํ„ฐ ์ƒˆ ์šฉ๋Ÿ‰์„ ์‚ฌ์šฉํ•˜๋ฉฐ ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ Peer๋Š” ์ด๋™ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. remove-node๋Š” ํ•ด๋‹น ์„œ๋ฒ„ Agent๊ฐ€ ๊ด€๋ฆฌํ•˜๋Š” Peer๋ฅผ ์ข…๋ฃŒํ•˜๋ฏ€๋กœ ์ง„ํ–‰ ์ค‘ ์‹คํ—˜์— ์˜ํ–ฅ์„ ์ค๋‹ˆ๋‹ค. ๋‹ค๋ฅธ stack์˜ label์€ ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

์ „์ฒด remove๋Š” ํ•ด๋‹น stack์ด ์•Œ๋ ค์ง„ KPL ์„œ๋น„์Šค๋งŒ ํฌํ•จํ•˜๋Š”์ง€ ํ™•์ธํ•œ ๋’ค, ํ•ด๋‹น ์„œ๋น„์Šค ID๋ฅผ docker service rm์œผ๋กœ ์ง์ ‘ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์ด์–ด docker stack rm์œผ๋กœ stack ์†Œ์œ  config์™€ network๋ฅผ ์ œ๊ฑฐํ•˜๊ณ  ๋‚จ์€ stack ์„œ๋น„์Šค๊ฐ€ ์—†๋Š”์ง€ ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์‹คํŒจยทRejected task, ์ด๋ ฅ ๋ถ€์žฌ, offline worker๋Š” ์ด ๊ฒฝ๋กœ๋ฅผ ๋ง‰์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐฐ์น˜ label์€ ์„œ๋น„์Šค ์‚ญ์ œ ํ›„ ๊ฐ€๋Šฅํ•œ ๋ฒ”์œ„์—์„œ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. label ์กฐํšŒยท๋ณ€๊ฒฝ ์‹คํŒจ๋Š” ์•ˆ๋‚ดํ•˜๋ฉฐ, ๋‹ค์‹œ removeํ•˜๋ฉด ์„œ๋น„์Šค๊ฐ€ ์ด๋ฏธ ์—†์–ด๋„ ๋‚จ์€ stack ๋ฆฌ์†Œ์Šค์™€ label์„ ์žฌ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. Manager API ์˜ค๋ฅ˜๋‚˜ ์„œ๋น„์Šค๊ฐ€ ๊ณ„์† ๋‚จ๋Š” ๊ฒฝ์šฐ์—๋Š” ์‹คํŒจ๋ฅผ ๋ฐ˜ํ™˜ํ•ฉ๋‹ˆ๋‹ค. ์‹คํ—˜ยทPrometheusยทGrafana์˜ ๋ฐ์ดํ„ฐ volume๊ณผ ์™ธ๋ถ€ Peer network๋Š” ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค.

network-manager ์„œ๋น„์Šค๊ฐ€ ์žˆ์œผ๋ฉด ์ง€์ •๋œ control ๋…ธ๋“œ์˜ remove๋Š” ๋จผ์ € Manager/Agent์˜ ์ƒˆ task ๋ฐฐ์น˜๋ฅผ ๋ง‰๊ณ  task ์ด๋ ฅ์„ ์œ ์ง€ํ•œ ์ฑ„ ์ •์ƒ ์ข…๋ฃŒ๋ฅผ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ์ดํ›„ ์„œ๋น„์Šค๋ฅผ ์‚ญ์ œํ•˜๋ฉฐ ์ข…๋ฃŒ๋ฅผ ํ™•์ธํ•œ ๊ฒฝ์šฐ์—๋งŒ ์†Œ์œ ํ•œ standalone gateway๋„ ์ œ๊ฑฐํ•ฉ๋‹ˆ๋‹ค. Swarm์€ ์‚ญ์ œํ•œ ์„œ๋น„์Šค์˜ task ์ด๋ ฅ์„ ์ •๋ฆฌํ•  ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์ข…๋ฃŒ ํ™•์ธ์€ ์„œ๋น„์Šค ์‚ญ์ œ ์ „์— ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์‹คํŒจยท๋ˆ„๋ฝ๋œ ์ด๋ ฅ, ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋…ธ๋“œ, ๋‹ค๋ฅธ Docker daemon ๋˜๋Š” ๋กœ์ปฌ Peer ์ž”์กด ์‹œ์—๋Š” gateway๋ฅผ ์œ ์ง€ํ•˜๊ณ  ์ •๋ฆฌ ๋ฏธํ™•์ธ์„ ์•Œ๋ฆฝ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์‚ญ์ œ๋Š” ๊ณ„์† ์ง„ํ–‰ํ•˜๋ฉฐ ์—ฐ๊ฒฐ๋œ control network๋„ ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. remove๋ฅผ ๋ฐ˜๋ณตํ•ด๋„ ์‚ฌ๋ผ์ง„ task ์ด๋ ฅ์€ ๋ณต์›๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋‚จ์€ ๋ฆฌ์†Œ์Šค๋ฅผ ์ ๊ฒ€ํ•˜๊ฑฐ๋‚˜ ์žฌ๋ฐฐํฌํ•œ ๋’ค ๋ชจ๋“  Agent๊ฐ€ Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•ด์•ผ ๋‹ค์Œ ์ดˆ๊ธฐํ™”๊ฐ€ ๋ณต๊ตฌ๋ฅผ ์ง„ํ–‰ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

remove-node๋Š” ๊ธฐ์กด์ฒ˜๋Ÿผ Agent ์„œ๋น„์Šค์—์„œ ์„ ํƒ ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•˜๊ณ  clean container exit๋ฅผ ๊ธฐ๋‹ค๋ฆฐ ๋’ค ๋ฐฐ์น˜ label๊ณผ ์ž„์‹œ ์ œ์™ธ ์กฐ๊ฑด์„ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. label๋ถ€ํ„ฐ ์ œ๊ฑฐํ•˜๋ฉด ์ •์ƒ ์ข…๋ฃŒ๋„ Swarm์ด Rejected๋กœ ๊ธฐ๋กํ•  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ž…๋‹ˆ๋‹ค. offline ๋…ธ๋“œ, ๋ณด์กด๋œ ๊ณผ๊ฑฐ ์ด๋ ฅ์„ ํฌํ•จํ•œ ์‹คํŒจ task, ์ด๋ ฅ ๋ถ€์žฌ๋กœ Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•  ์ˆ˜ ์—†์œผ๋ฉด ์ด ๋ช…๋ น์€ ์ค‘๋‹จํ•ฉ๋‹ˆ๋‹ค. ์ด๋ฏธ ์ˆ˜ํ–‰ํ•œ ๋ฐฐ์น˜ ๋ณ€๊ฒฝ์€ ์ž๋™ ๋ณต๊ตฌํ•˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์˜ค๋ฅ˜์— ๋‚˜์˜จ task์™€ ๋…ธ๋“œ๋ฅผ ์ ๊ฒ€ํ•œ ๋’ค ์žฌ์‹œ๋„ํ•˜์‹ญ์‹œ์˜ค. ๋‹ค์‹œ Agent๋ฅผ ์‹คํ–‰ํ•˜๋ ค๋Š” ๊ฒฝ์šฐ add-node๊ฐ€ ๋‚จ์€ ์ œ์™ธ ์กฐ๊ฑด๋„ ํ•ด์ œํ•ฉ๋‹ˆ๋‹ค.

์œ ์ง€๋ณด์ˆ˜ ์ค‘ Peer overlay ์žฌ์ƒ์„ฑ

์ปจํ…Œ์ด๋„ˆ ์ƒ์„ฑยท์‚ญ์ œ๋ฅผ ๋ฐ˜๋ณตํ•˜๋ฉด Docker overlay ๋™๊ธฐํ™” ๋ฌธ์ œ๊ฐ€ ๋“œ๋Ÿฌ๋‚  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ปจํ…Œ์ด๋„ˆ ์‹œ์ž‘ ์‹œ IP ํ• ๋‹น ์‹คํŒจ์™€ ์ด๋ฏธ Ready์ธ Peer ์‚ฌ์ด์˜ TCP timeout์€ ๊ตฌ๋ถ„ํ•ด์„œ ์ง„๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ํ˜ธ์ŠคํŠธ์˜ Docker daemon ๋กœ๊ทธ์—์„œ ๋ฐ˜๋ณต๋˜๋Š” peerDbAdd ์ถฉ๋Œ, Neighbor entry already present, bulk-sync ์‹คํŒจ์™€ NetworkDB ๋Œ€๊ธฐ์—ด ์ฆ๊ฐ€๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์ปจํ…Œ์ด๋„ˆ ์ •๋ฆฌ ์™„๋ฃŒ๊ฐ€ ์›๊ฒฉ overlay ํ…Œ์ด๋ธ”์˜ ์ˆ˜๋ ด์„ ๋ณด์žฅํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. IP ํ• ๋‹น์€ Docker IPAM์ด ๋‹ด๋‹นํ•˜๋ฉฐ KPL์ด modulo IP ํ• ๋‹น๊ธฐ๋ฅผ ๊ตฌํ˜„ํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค.

์‹คํ—˜๊ณผ ์˜ˆ์•ฝ ์ œ์ถœ์„ ์™„๋ฃŒํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•œ ๋’ค Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋ณด์กดํ•˜์‹ญ์‹œ์˜ค. remove๋Š” Agent ๋ฐฐ์น˜ label์„ ์ง€์šฐ๋ฏ€๋กœ ์„œ๋น„์Šค ์ œ๊ฑฐ ์ „์— ๊ธฐ์กด Agent ๋…ธ๋“œ ์„ ํƒ์„ ๊ธฐ๋กํ•ฉ๋‹ˆ๋‹ค. ์•ž์˜ ์ ˆ์ฐจ์— ๋”ฐ๋ผ stack์„ ๋ณ„๋„๋กœ ์ œ๊ฑฐํ•œ ๋’ค, ๋ชจ๋“  Swarm ๋…ธ๋“œ๊ฐ€ Ready์ด๊ณ  ๊ธฐ์กด network๊ฐ€ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ์ƒํƒœ์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.

sh scripts/swarm.sh reset-peer-network
# ๊ธฐ์กด์— ์„ ํƒํ•œ ๋…ธ๋“œ์˜ ์‹ค์ œ ID/์ด๋ฆ„์„ ์ง€์ •ํ•˜์—ฌ ๋ณ„๋„๋กœ ์žฌ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค.
sh scripts/swarm.sh deploy worker-a worker-b

reset ๋ช…๋ น์€ ๋ถˆ๋Ÿฌ์˜จ KPL_STACK_NAME๊ณผ KPL_PEER_NETWORK๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ์œ ํœด Controller๋ฅผ ํฌํ•จํ•˜์—ฌ ํ•ด๋‹น stack์˜ ์„œ๋น„์Šค๊ฐ€ ํ•˜๋‚˜๋ผ๋„ ๋‚จ์•„ ์žˆ์œผ๋ฉด ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉํ•  ์ˆ˜ ์—†๋Š” ๋…ธ๋“œ, ๋กœ์ปฌ์— ์—ฐ๊ฒฐ๋œ ์ปจํ…Œ์ด๋„ˆ, ์—†๊ฑฐ๋‚˜ ๋ชจํ˜ธํ•œ network, ๋‹ค๋ฅด๊ฑฐ๋‚˜ ๋ˆ„๋ฝ๋œ ์†Œ์œ ๊ถŒ label, ์กฐํšŒ ์‹คํŒจ๋„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. Docker์˜ ์‚ญ์ œ API๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ์˜ ์„œ๋น„์Šค ์ฐธ์กฐ์™€ ํ™œ์„ฑ network-attachment task๋„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ์ ๊ฒ€์ด ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ์ž ๊ทธ์ง€๋Š” ์•Š์œผ๋ฏ€๋กœ reset๊ณผ ๋ฐฐํฌยท๋‹ค๋ฅธ network ์œ ์ง€๋ณด์ˆ˜๋ฅผ ๋™์‹œ์— ์‹คํ–‰ํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค.

์ง€์› ๋ฒ”์œ„๋Š” helper๊ฐ€ ๋งŒ๋“œ๋Š” ๊ธฐ๋ณธ ๊ตฌ์„ฑ์ž…๋‹ˆ๋‹ค. Swarm ๋ฒ”์œ„์˜ attachable IPv4 overlay, ๊ธฐ๋ณธ IPAM, subnet ํ•˜๋‚˜, KPL ์†Œ์œ ๊ถŒ label ๋‘ ๊ฐœ์™€ ์„ ํƒ์ ์ธ io.kpl.execution ํ‘œ์‹๋งŒ ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ์‚ฌ์šฉ์ž ์ง€์ • driver/IPAM ์˜ต์…˜, IP ๋ฒ”์œ„, ๋ณด์กฐ ์ฃผ์†Œ, ์ถ”๊ฐ€ label์ด ์žˆ์œผ๋ฉด ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. Docker๊ฐ€ ์ƒ์„ฑํ•œ VXLAN ID๋Š” ์ƒˆ๋กœ ๋ฐœ๊ธ‰๋ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ ๋‹น์‹œ KPL_PEER_SUBNET์„ ์ƒ๋žตํ–ˆ์–ด๋„ ๊ธฐ์กด subnet๊ณผ gateway๋ฅผ ๋ณด์กดํ•˜๋ฉฐ, ํ˜„์žฌ ์„ค์ •ํ•œ subnet์ด ๋‹ค๋ฅด๋ฉด ์‚ญ์ œ ์ „์— ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ •ยท์•”ํ˜ธํ™” network๋Š” ์„ค์ •์„ ๊ฒ€ํ† ํ•œ ๋ณ„๋„ ์žฌ์ƒ์„ฑ ์ ˆ์ฐจ๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ช…๋ น์€ ์กฐ๊ฑด์„ ์žฌํ™•์ธํ•˜๊ณ , ์บก์ฒ˜ํ•œ network ID๋ฅผ ์‚ญ์ œํ•œ ๋’ค ๋‹ค์‹œ ์ƒ์„ฑํ•˜์—ฌ ์„ค์ •๊ณผ ์ƒˆ ID๋ฅผ ๊ฒ€์ฆํ•ฉ๋‹ˆ๋‹ค. ์„œ๋น„์Šค ์ค‘์ง€, ์ปจํ…Œ์ด๋„ˆ ์—ฐ๊ฒฐ ํ•ด์ œ, Docker ์žฌ์‹œ์ž‘, ์„ค์ •ยท๋ฐฐ์น˜ label ๋ณ€๊ฒฝ, volume ์‚ญ์ œ์™€ ์ž๋™ ๋ฐฐํฌ๋Š” ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ฐ์ดํ„ฐ ๋ณด์กด์€ ์ €์žฅ์†Œ ๊ณ„์•ฝ์„ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ๊ฐ•์ œ ์‹คํ–‰ ์˜ต์…˜์€ ์—†์œผ๋ฉฐ ๊ฐ Docker ํ˜ธ์ถœ์€ KPL_DOCKER_TIMEOUT์œผ๋กœ ์ œํ•œํ•ฉ๋‹ˆ๋‹ค.

์‚ญ์ œ ์ „์— ์ •ํ™•ํ•œ ์žฌ์ƒ์„ฑ ๋ช…๋ น์„ ์ถœ๋ ฅํ•ฉ๋‹ˆ๋‹ค. ์‚ญ์ œยท์ƒ์„ฑยท๊ฒ€์ฆ ์ค‘ ์‹คํŒจํ•˜๋ฉด ์„ฑ๊ณต์œผ๋กœ ์ฒ˜๋ฆฌํ•˜์ง€ ์•Š๊ณ  ๋ฏธํ™•์ธ ๋˜๋Š” ๋ฏธ์™„๋ฃŒ ์ƒํƒœ๋ฅผ ์•ˆ๋‚ดํ•ฉ๋‹ˆ๋‹ค. timeout์ด ๋‚œ ์š”์ฒญ๋„ ์ด๋ฏธ ์ ์šฉ๋์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ์žฌ์‹œ๋„ ์ „์— network๋ฅผ ์กฐํšŒํ•˜์‹ญ์‹œ์˜ค. network๊ฐ€ ์—†์„ ๋•Œ๋งŒ ์ถœ๋ ฅ๋œ ์žฌ์ƒ์„ฑ ๋ช…๋ น์„ ์‚ฌ์šฉํ•˜๋ฉฐ, ์žฌ์‹œ๋„ํ•˜๋ ค๊ณ  ๊ธฐ์กด replacement๋ฅผ ์‚ญ์ œํ•˜์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ์žฌ๋ฐฐํฌ ํ›„ ์ž‘์€ ์‹คํ—˜์œผ๋กœ ํ˜ธ์ŠคํŠธ ๊ฐ„ ํ†ต์‹ ์„ ํ™•์ธํ•œ ๋‹ค์Œ ๋Œ€๊ทœ๋ชจ ๋ฐ˜๋ณต ์‹คํ–‰์œผ๋กœ ๋Œ์•„๊ฐ€์‹ญ์‹œ์˜ค. overlay ์žฌ์ƒ์„ฑ์€ ๋ณต๊ตฌ ์ž‘์—…์ด๋ฉฐ Docker ๋™๊ธฐํ™” ๋ฌธ์ œ์˜ ์žฌ๋ฐœ ๋ฐฉ์ง€๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ด ์ˆ˜๋™ reset ๋ช…๋ น๋งŒ ์‚ฌ์šฉํ•  ๋•Œ๋Š” KPL ์ด๋ฏธ์ง€ ์žฌ๋นŒ๋“œ๊ฐ€ ํ•„์š”ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ž๋™ ์ดˆ๊ธฐํ™”์—๋Š” ๊ฐฑ์‹ ํ•œ ์ด๋ฏธ์ง€์™€ stack์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ ๋กœ๊ทธ์ธ

KPL_USERยทKPL_PASSWORD๊ฐ€ KPL_API_TOKEN์„ ๋Œ€์ฒดํ•ฉ๋‹ˆ๋‹ค. init์˜ ๊ธฐ๋ณธ ์‚ฌ์šฉ์ž๋ช…์€ admin์ด๋ฉฐ ๋Œ€์‹œ๋ณด๋“œ์™€ Grafana ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ๊ฐ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. credentials๋Š” ๋‘ ๋กœ๊ทธ์ธ ์ •๋ณด๋ฅผ ๋ช…์‹œ์ ์œผ๋กœ ํ‘œ์‹œํ•˜๊ณ  config๋Š” ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ๊ฐ€๋ฆฝ๋‹ˆ๋‹ค. Controller์˜ Log in ํ™”๋ฉด์—์„œ ํ•œ ๋ฒˆ ๋กœ๊ทธ์ธํ•˜๋ฉด ์‹คํ—˜ ์‹คํ–‰ยท์ค‘์ง€, ์‹œ๋‚˜๋ฆฌ์˜ค ์ €์žฅ, ๊ฒฐ๊ณผ ์‚ญ์ œ, ๋ถ„์„ยท๋‹ค์šด๋กœ๋“œ๋Š” ์„ธ์…˜์„ ์žฌ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Log out์œผ๋กœ ์ข…๋ฃŒํ•˜๋ฉฐ ์„ธ์…˜์€ 12์‹œ๊ฐ„ ๋’ค ๋งŒ๋ฃŒ๋ฉ๋‹ˆ๋‹ค. Controller ์žฌ์‹œ์ž‘ ํ›„์—๋Š” ๋‹ค์‹œ ๋กœ๊ทธ์ธํ•ฉ๋‹ˆ๋‹ค. ๋ณ„๋„ API token ์ž…๋ ฅ๋ž€์€ ์—†์Šต๋‹ˆ๋‹ค.

๊ธฐ์กด ํ† ํฐ ์„ค์ •์€ volume์„ ๋‹ค์‹œ ๋งŒ๋“ค์ง€ ์•Š๊ณ  ์ „ํ™˜ํ•ฉ๋‹ˆ๋‹ค.

sh scripts/swarm.sh configure KPL_USER=admin
sh scripts/swarm.sh credentials

์ „ํ™˜ ์‹œ ํ๊ธฐ๋œ ํ† ํฐ ํ•ญ๋ชฉ์„ ์ œ๊ฑฐํ•˜๊ณ  ๋‹ค๋ฅธ ์„ค์ •์„ ๋ณด์กดํ•˜๋ฉฐ, KPL_PASSWORD๊ฐ€ ์—†์„ ๋•Œ๋งŒ ์ƒˆ ๋น„๋ฐ€๋ฒˆํ˜ธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ์ด์ „ ํ† ํฐ์„ ๋น„๋ฐ€๋ฒˆํ˜ธ๋กœ ์žฌ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ์ง€์ •ํ•˜๋ ค๋ฉด configure KPL_USER=... KPL_PASSWORD=...๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ๋ฐฐํฌ ์‹œ ํ™˜๊ฒฝ๋ณ€์ˆ˜ ์šฐ์„ ์ˆœ์œ„๋Š” ์œ ์ง€๋ฉ๋‹ˆ๋‹ค. ์‹คํ—˜๊ณผ ์ž”์กด Peer๋ฅผ ์ •๋ฆฌํ•œ ๋’ค ์ƒˆ ์ด๋ฏธ์ง€๋ฅผ publishํ•˜๊ณ  ControllerยทAgent๋ฅผ ํ•จ๊ป˜ deployํ•˜์‹ญ์‹œ์˜ค. ๋‚ด๋ถ€ ์„œ๋น„์Šค ํ‚ค๋Š” ๋กœ๊ทธ์ธ ์„ค์ •์—์„œ ์ž๋™ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ๋ธŒ๋ผ์šฐ์ €์— ์ž…๋ ฅํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค.

๋Œ€์‹œ๋ณด๋“œ ๋ฐ์ดํ„ฐ, SSE, ๊ฒ€์ฆยท๋ถ„์„ยท๋‹ค์šด๋กœ๋“œ์—๋Š” ๋ชจ๋‘ ๋กœ๊ทธ์ธ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๋ชจ๋‹ˆํ„ฐ๋ง์šฉ health/์‹œ๊ฐ, Prometheus metricsยทtarget discovery๋งŒ ๊ณต๊ฐœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‚ด๋ถ€ ๋“ฑ๋กยทtelemetry์™€ Peer discovery์—๋Š” ์„œ๋น„์Šค ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋ฉฐ Peer ์„ค์ • JSON ๊ถŒํ•œ์€ 0600์ž…๋‹ˆ๋‹ค. Grafana๋Š” ๋ณ„๋„ ๊ณ„์ •์ž…๋‹ˆ๋‹ค. HTTP๋Š” ์•”ํ˜ธํ™”๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์‹ ๋ขฐ ๊ด€๋ฆฌ๋ง ๋˜๋Š” HTTPS proxy๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ์„ธ์…˜ ์ฟ ํ‚ค๋ฅผ ์‚ฌ์šฉํ•˜๋Š” curl ์˜ˆ์ œ๋Š” API ์ธ์ฆ์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์ด์ „ v3 stack์—์„œ ์ „ํ™˜

Legacy ์˜ˆ์™ธ: ์‹ ๊ทœ ๋ฐฐํฌ๋ผ๋ฉด ์ด ์ ˆ์ฐจ๋ฅผ ๊ฑด๋„ˆ๋›ฐ์‹ญ์‹œ์˜ค. ์•„๋ž˜ ์ง์ ‘ Docker ๋ช…๋ น์€ ํ‘œ์‹œ๊ฐ€ ์—†๋Š” ์ด์ „ stack์„ ํ•œ ๋ฒˆ ์ „ํ™˜ํ•  ๋•Œ๋งŒ ์‚ฌ์šฉํ•˜๋ฉฐ, ์œ„์˜ ์ผ๋ฐ˜ ์šด์˜ ์ ˆ์ฐจ๋Š” helper๋กœ ์ง„ํ–‰ํ•ฉ๋‹ˆ๋‹ค. helper์˜ ์†Œ์œ ๊ถŒ ๊ฒ€์‚ฌ๋ฅผ ์šฐํšŒํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

helper๋Š” ๊ธฐ์กด ์„œ๋น„์Šค๊ฐ€ ${KPL_STACK_NAME}_{controller,agent,prometheus,grafana}์ด๊ณ  io.kpl.application=kp2plab-v3 ์„œ๋น„์Šค label์ด ์žˆ์„ ๋•Œ๋งŒ ๊ด€๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํ‘œ์‹œ๊ฐ€ ์—†๋Š” ์ด์ „ v3 stack์€ ๊ฐ™์€ ์ด๋ฆ„์ด์–ด๋„ ๋ณ€๊ฒฝ์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค.

๋จผ์ € ๊ธฐ์กด ์‹คํ—˜์„ ์ข…๋ฃŒํ•˜๊ณ  Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ๊ธฐ์กด stack ์ด๋ฆ„, control Node ID, Peer network ์ด๋ฆ„, ์ด๋ฏธ์ง€ ์ฐธ์กฐ์™€ ์ž๊ฒฉ ์ฆ๋ช…์„ ๊ทธ๋Œ€๋กœ ์…ธ์— exportํ•œ ๋’ค, ์ตœ์‹  stack.swarm.yaml์„ ํ•œ ๋ฒˆ ์ง์ ‘ ์žฌ๋ฐฐํฌํ•ฉ๋‹ˆ๋‹ค. .env.swarm์€ Docker๊ฐ€ ์ง์ ‘ ์ฝ์ง€ ์•Š์œผ๋ฏ€๋กœ ํŒŒ์ผ์˜ ์‹ค์ œ ๊ฐ’์„ ํ™˜๊ฒฝ์— ๋ช…์‹œํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

# ์œ„์˜ ๊ธฐ์กด ๋ฐฐํฌ ๋ณ€์ˆ˜๊ฐ€ export๋œ manager์—์„œ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค.
docker node update --label-add "kpl.${KPL_STACK_NAME}.agent=true" worker-a
docker node update --label-add "kpl.${KPL_STACK_NAME}.agent=true" worker-b
control_address=$(docker node inspect --format '{{.Status.Addr}}' "$KPL_CONTROL_NODE_ID")
case "$control_address" in *:*) control_address=[$control_address] ;; esac
export KPL_CONTROLLER_METRICS_URL="http://$control_address:${KPL_HTTP_PORT:-8080}/metrics"
export KPL_PROMETHEUS_EXTERNAL_URL="http://$control_address:${PROMETHEUS_PORT:-9090}/"
docker stack config --compose-file stack.swarm.yaml >/dev/null
docker stack deploy --with-registry-auth --compose-file stack.swarm.yaml "$KPL_STACK_NAME"
sh scripts/swarm.sh status

์ƒˆ ๋ฐฐ์น˜๋Š” ๊ณต์šฉ kpl.agent ๋Œ€์‹  stack๋ณ„ kpl.<stack>.agent label์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด Peer network๊ฐ€ kpl-swarm-peers์˜€๋‹ค๋ฉด ๊ทธ ์ด๋ฆ„์„ .env.swarm์—๋„ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค. helper ๊ธฐ๋ณธ ์ด๋ฆ„์œผ๋กœ ๋ฐ”๊พธ๋ฉด ์ด์ „ Peer ์†Œ์œ  ๋ฒ”์œ„์™€ ๋‹ฌ๋ผ์ง‘๋‹ˆ๋‹ค. ์ดํ›„ ๋ฐฐํฌยท์ถ”๊ฐ€ยท์ฒ ๊ฑฐ๋Š” helper๋ฅผ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ถ„๋ฐฐ์™€ ์šฉ๋Ÿ‰

์‹œ์ž‘ ๊ธฐ๋ณธ๊ฐ’๊ณผ Agent๋ณ„ UI ์˜ˆ์™ธ๋Š” Agent ์šฉ๋Ÿ‰๊ณผ ๋ฐฐ์น˜์—์„œ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. ํ•ด๋‹น ๋ฌธ์„œ์—์„œ balanced/random/๊ณ ์ • ๋ฐฐ์น˜, ๋น„๋ก€ ํ• ๋‹น, ์ƒ์„ฑ ํ—ˆ์šฉ๊ณผ ์ •๋ฆฌ ์ค‘ ์ ์œ ๋ฅผ ์„ค๋ช…ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜๋Š” ๋ฐฐํฌ ๋„คํŠธ์›Œํฌ ์ œ์•ฝ์ž…๋‹ˆ๋‹ค.

Docker๋Š” ์ผ๋ฐ˜์ ์ธ overlay์— /24 ๊ทœ๋ชจ๋ฅผ ๊ถŒ์žฅํ•ฉ๋‹ˆ๋‹ค. ์ฃผ์†Œ์—๋Š” Peer๋ฟ ์•„๋‹ˆ๋ผ ์„œ๋น„์Šค taskยทendpoint๋„ ํฌํ•จ๋˜๋ฏ€๋กœ ์„œ๋ฒ„ ์ˆ˜ ร— capacity๋ฅผ ์ฃผ์†Œ ์ˆ˜๋งŒํผ ๊ฝ‰ ์ฑ„์šฐ์ง€ ๋งˆ์‹ญ์‹œ์˜ค. ๊ธฐ๋ณธ 20์€ ์‹œ์ž‘์šฉ ์„ค์ •์ด๋ฉฐ ์„ฑ๋Šฅ ๋ณด์žฅ์ด ์•„๋‹™๋‹ˆ๋‹ค. v2์˜ /16์„ ๊ทธ๋Œ€๋กœ ํ™•๋Œ€ํ•˜๊ฑฐ๋‚˜ capacity๋งŒ ์˜ฌ๋ฆฌ๋Š” ๋ฐฉ์‹์œผ๋กœ ์ˆ˜์ฒœ Peer ์ง€์›์„ ์ฃผ์žฅํ•  ์ˆ˜ ์—†์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ตฌ์„ฑ์€ ๋‹จ์ผ ๊ณตํ†ต Peer overlay๋ฅผ ์‚ฌ์šฉํ•˜๋ฏ€๋กœ ์ˆ˜๋ฐฑยท์ˆ˜์ฒœ Peer์—๋Š” ์—ฌ๋Ÿฌ ๋„คํŠธ์›Œํฌ ๊ฐ„ ๋„๋‹ฌ์„ฑ ์„ค๊ณ„์™€ ๋ณ„๋„ ๋ถ€ํ•˜ ์‹œํ—˜์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Swarm overlay ํฌ๊ธฐ ์ œํ•œ

Peer๋Š” Agent๋กœ ํ–ฅํ•˜๋Š” ๊ฒฝ๋กœ์˜ overlay IPv4๋งŒ libp2p์— ๊ด‘๊ณ ํ•ฉ๋‹ˆ๋‹ค. ๋‹ค๋ฅธ ์„œ๋ฒ„์—์„œ ์ ‘๊ทผํ•  ์ˆ˜ ์—†๋Š” docker_gwbridge ์ฃผ์†Œ๊ฐ€ bootstrap/Identify์— ์„ž์ด์ง€ ์•Š๊ฒŒ ํ•ฉ๋‹ˆ๋‹ค. tc ์ง€์—ฐยท์†์‹ค์€ Peer namespace์˜ ์†ก์‹ ์— ์ ์šฉ๋˜๋ฉฐ, ์‹ค์ œ NICยทVXLANยท์„œ๋ฒ„ ๋ถ€ํ•˜์˜ ์ถ”๊ฐ€ ์ง€์—ฐ์€ ๊ทธ๋Œ€๋กœ ์กด์žฌํ•ฉ๋‹ˆ๋‹ค. ํ˜ธ์ŠคํŠธ ๊ฐ„ one-way latency ๋น„๊ต์—๋Š” ์‹œ๊ณ„ ๋™๊ธฐํ™”๋„ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

๋ถ„์„๊ณผ ์šด์˜

Prometheus๋Š” 5์ดˆ๋งˆ๋‹ค Controller์˜ HTTP service-discovery endpoint์— ๋“ฑ๋ก๋œ Agent metrics URL์„ ์š”์ฒญํ•ฉ๋‹ˆ๋‹ค. ๊ฐ Agent๋Š” ์ž์‹ ์˜ Swarm node ์ฃผ์†Œ์™€ ์„ค์ •๋œ host-mode metrics ํฌํŠธ๋ฅผ ์•Œ๋ฆฌ๋ฏ€๋กœ ์ˆ˜์ง‘์ด service VIP๋ฅผ ํ†ต๊ณผํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. task๊ฐ€ Controller์— ๋“ฑ๋ก๋œ ๋’ค์—๋งŒ target์ด ๋ฉ๋‹ˆ๋‹ค. Grafana๋Š” KP2PLab ๋Œ€์‹œ๋ณด๋“œ๋ฅผ ์ž๋™ ๊ตฌ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๋‹ค์Œ ํ•ญ๋ชฉ์„ ํ•จ๊ป˜ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

  • up{job="kpl-agent"} ๋Œ€์ƒ ์ˆ˜์™€ ์‹ค์ œ Agent task ์ˆ˜
  • Controller์˜ kpl_agent_active_nodes, kpl_agent_capacity, kpl_agent_up
  • Agent์˜ kpl_local_cleanup_pending, kpl_local_telemetry_queue_events
  • ์‹คํ—˜์˜ ์‹ค์ œ ready/started ์‹œ๊ฐ, ์‹คํŒจ ์ˆ˜ ๋ฐ ์„œ๋ฒ„๋ณ„ CPUยท๋ฉ”๋ชจ๋ฆฌยท๋„คํŠธ์›Œํฌ ์‚ฌ์šฉ๋Ÿ‰

Go process ์ง€ํ‘œ๋Š” ControllerยทAgent ์ž์ฒด๋งŒ ๋‚˜ํƒ€๋‚ด๋ฉฐ Peer ์ „์ฒด์˜ ์ž์› ์‚ฌ์šฉ๋Ÿ‰์ด ์•„๋‹™๋‹ˆ๋‹ค. Agent Status์™€ Grafana์˜ KPL CPUยท๋ฉ”๋ชจ๋ฆฌ ์ง€ํ‘œ๋Š” Agent ์ปจํ…Œ์ด๋„ˆ์™€ ์†Œ์† Peer๋ฅผ ํ•ฉ์‚ฐํ•˜๋ฉฐ ๊ธฐ์กด ํ”„๋กœ์„ธ์Šค ๋‹จ๋… ์ง€ํ‘œ๋„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ์ˆ˜์ง‘ยท๋‚ด๋ณด๋‚ด๊ธฐ ์„ค์ •์€ KPL ๋ฆฌ์†Œ์Šค ์ธก์ •์„ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค. ์ „์ฒด ๋…ธ๋“œ ์ƒํƒœ ๋ณด๊ณ ยทController ์ €์žฅ/์ง‘๊ณ„ยท์ค‘์•™ HTTP ์ˆ˜์ง‘, Docker CLI์˜ ์ƒ์„ฑ/์‚ญ์ œ ๋น„์šฉ๋„ ํ™•์žฅ ํ•œ๊ณ„์ž…๋‹ˆ๋‹ค. ์ข…๋ฃŒ๋œ ๋…ธ๋“œ ๊ธฐ๋ก๊ณผ ์‹คํ–‰๋ณ„ Prometheus series๊ฐ€ ์œ ์ง€๋˜๋ฏ€๋กœ ๊ธด churn ์‹คํ—˜์€ ๋ฉ”๋ชจ๋ฆฌ์™€ ์ˆ˜์ง‘ ์ง€์—ฐ์„ ํ•จ๊ป˜ ์ธก์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ด stack์€ host mode๋กœ control ๋…ธ๋“œ์˜ 8080ยท9090ยท3000๊ณผ ์„ ํƒ๋œ ๋ชจ๋“  Agent ๋…ธ๋“œ์˜ KPL_AGENT_METRICS_PORT(๊ธฐ๋ณธ 9091)๋ฅผ ๊ฒŒ์‹œํ•ฉ๋‹ˆ๋‹ค. Agent metrics ํฌํŠธ๋Š” ๋ชจ๋“  ๋Œ€์ƒ ๋…ธ๋“œ์—์„œ ๋น„์–ด ์žˆ์–ด์•ผ ํ•˜๋ฉฐ ๊ฐ™์€ ๋…ธ๋“œ๋ฅผ ๊ณต์œ ํ•˜๋Š” ๋ณ„๋„ stack์—๋Š” ์„œ๋กœ ๋‹ค๋ฅธ ํฌํŠธ๋ฅผ ์ง€์ •ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๋˜ํ•œ KPL_HTTP_PORT, PROMETHEUS_PORT, GRAFANA_PORT ๋ฐ Swarm TCP ํฌํŠธ 2377ยท7946๊ณผ ๋‹ฌ๋ผ์•ผ ํ•˜๋ฉฐ config helper์™€ ๋ฐฐํฌ ์‚ฌ์ „๊ฒ€์‚ฌ๊ฐ€ ์ด๋Ÿฌํ•œ ์ถฉ๋Œ์„ ๊ฑฐ๋ถ€ํ•ฉ๋‹ˆ๋‹ค. control ๋…ธ๋“œ์™€, ์ง์ ‘ ๋ธŒ๋ผ์šฐ์ € ์ ‘๊ทผ์ด ํ•„์š”ํ•œ ๊ฒฝ์šฐ ์šด์˜์ž์˜ ์‹ ๋ขฐ ๊ด€๋ฆฌ๋ง์—์„œ ์ด ํฌํŠธ๋ฅผ ํ—ˆ์šฉํ•˜์‹ญ์‹œ์˜ค. metrics endpoint๋Š” ์ฝ๊ธฐ ์ „์šฉ์ด์ง€๋งŒ ์ธ์ฆ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์‹ ๋ขฐํ•˜์ง€ ์•Š๋Š” ์ถœ๋ฐœ์ง€๋Š” ์ฐจ๋‹จํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. Agent control API 8090๊ณผ Peer ํฌํŠธ๋Š” ๋‚ด๋ถ€์— ์œ ์ง€ํ•˜๋ฉฐ ๊ฒŒ์‹œํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. control ๋…ธ๋“œ ํฌํŠธ๋Š” ๊ด€๋ฆฌ๋ง ๋ฐฉํ™”๋ฒฝ์ด๋‚˜ ์ธ์ฆ reverse proxy๋กœ ์ ‘๊ทผ์„ ์ œํ•œํ•˜์‹ญ์‹œ์˜ค. ๋Œ€์‹œ๋ณด๋“œ ์กฐํšŒยท๋ณ€๊ฒฝ์€ ๋กœ๊ทธ์ธ์œผ๋กœ ๋ณดํ˜ธํ•˜๋ฉฐ ๋ชจ๋‹ˆํ„ฐ๋ง endpoint๋Š” ๊ณต๊ฐœ๋กœ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. Grafana ์ต๋ช… ์ ‘์†์€ ์ด stack์—์„œ ๋น„ํ™œ์„ฑํ™”ํ–ˆ์Šต๋‹ˆ๋‹ค. Swarm host mode ๊ฒŒ์‹œ

๋ชจ๋‹ˆํ„ฐ๋ง ์„ค์ •์€ Swarm configs๋กœ ์ „๋‹ฌํ•˜๋ฏ€๋กœ ๋ชจ๋“  ์„œ๋ฒ„์— ์ €์žฅ์†Œ๋ฅผ ๋ณต์‚ฌํ•  ํ•„์š”๊ฐ€ ์—†์Šต๋‹ˆ๋‹ค. Swarm config๋Š” immutable์ด๋ฏ€๋กœ ์„ค์ • ํŒŒ์ผ ๋ณ€๊ฒฝ ์‹œ stack.swarm.yaml์˜ config key์™€ ํ•ด๋‹น ์ฐธ์กฐ๋ฅผ ํ•จ๊ป˜ ๋ฒ„์ „๋ช…์œผ๋กœ ๋ฐ”๊พธ์–ด ์ƒˆ config๋ฅผ ๋ฐฐํฌํ•˜์‹ญ์‹œ์˜ค. ๋ฐ์ดํ„ฐ volume์€ ๊ฐ™์€ control Node ID์—์„œ ์œ ์ง€๋ฉ๋‹ˆ๋‹ค.

์žฅ์• ยท์—…๋ฐ์ดํŠธยท์ข…๋ฃŒ

Agent update/rollback์€ stop-first์ž…๋‹ˆ๋‹ค. start-first๋กœ ๋ฐ”๊พธ๋ฉด ๊ฐ™์€ ์„œ๋ฒ„ยทAgent ID์˜ ๋‘ task๊ฐ€ ๋™์‹œ์— ์‹คํ–‰๋˜์–ด ์ด์ „ Peer ์ •๋ฆฌ์™€ ์ถฉ๋Œํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. Agent ๊ต์ฒด ์‹œ ๋‹ด๋‹น Peer๊ฐ€ ์ข…๋ฃŒ๋˜๋ฏ€๋กœ ์ง„ํ–‰ ์ค‘์ธ ์‹คํ—˜์˜ ๋ฌด์ค‘๋‹จ ์—…๊ทธ๋ ˆ์ด๋“œ๋ฅผ ๋ณด์žฅํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์„œ๋ฒ„๋ฅผ ์ถ”๊ฐ€ํ•ด๋„ ์ด๋ฏธ ์‹คํ–‰ ์ค‘์ธ Peer๋ฅผ ์˜ฎ๊ธฐ์ง€ ์•Š์œผ๋ฉฐ, ์ดํ›„ join๋ถ€ํ„ฐ ์ƒˆ ์šฉ๋Ÿ‰์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋…ธ๋“œ drain์€ Swarm ์„œ๋น„์Šค task์— ์ ์šฉ๋ฉ๋‹ˆ๋‹ค. v3 Peer๋Š” standalone ์ปจํ…Œ์ด๋„ˆ์ด๋ฏ€๋กœ Swarm์ด ์ง์ ‘ ์ด์ „ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ •์ƒ Agent ์ข…๋ฃŒ์—์„œ Peer๋ฅผ ์ •๋ฆฌํ•˜๊ณ , ๋น„์ •์ƒ ์ข…๋ฃŒ ํ›„์—๋Š” ๋™์ผ Agent IDยทPeer network name์œผ๋กœ ๊ฐ™์€ ๋…ธ๋“œ์—์„œ ์žฌ์‹œ์ž‘ํ•  ๋•Œ ์ž”์กด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํšŒ์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ๋…ธ๋“œ ์žฌ๊ฐ€์ž…, stack/service ์ด๋ฆ„ ๋ณ€๊ฒฝ ๋˜๋Š” ๋„คํŠธ์›Œํฌ ์ด๋ฆ„ ๋ณ€๊ฒฝ ์‹œ ์ด์ „ ์†Œ์œ  ๋ฒ”์œ„์˜ ์ž”์กด Peer๋Š” ํ•ด๋‹น ์„œ๋ฒ„์—์„œ label์„ ํ™•์ธํ•ด ๋ณ„๋„๋กœ ์ •๋ฆฌํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด ํ˜ธ์ŠคํŠธ ์ •์ง€ยท๋„คํŠธ์›Œํฌ ๋‹จ์ ˆ์„ ๋‹ค๋ฅธ ์„œ๋ฒ„์˜ Peer ์žฌ์ƒ์„ฑ์œผ๋กœ ์ˆจ๊ธฐ์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

Controller๋Š” ๋‹จ์ผ ์ธ์Šคํ„ด์Šค์ด๋ฉฐ ๊ณต์œ  DB/leader election์„ ๊ตฌํ˜„ํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. replicas: 1์„ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค. control ๋…ธ๋“œ ์žฅ์•  ์‹œ ์ž๋™์œผ๋กœ ๋นˆ ๋กœ์ปฌ volume์„ ์“ฐ๋Š” ๋‹ค๋ฅธ ๋…ธ๋“œ๋กœ ์ด๋™ํ•˜์ง€ ์•Š์œผ๋ฉฐ, ๋ฐฑ์—… ๋ณต์›๊ณผ ์ƒˆ Node ID ์ง€์ •์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. Controller๋Š” ์‹ค์‹œ๊ฐ„ ์‹คํ—˜ ์ƒํƒœยทcounter๋ฅผ ์‹œ์ž‘ ์‹œ ๋ฉ”๋ชจ๋ฆฌ์— ๋ณต์›ํ•˜๊ฑฐ๋‚˜ ์‹คํ–‰ ์ค‘ ์‹คํ—˜์„ ์ž๋™ ์žฌ๊ฐœํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณด์กด๋œ ํŒŒ์ผ์€ ์žฌ์‹œ์ž‘ ํ›„์—๋„ ๋Œ€์‹œ๋ณด๋“œ์˜ Saved results์™€ ๊ฒฐ๊ณผ ๋‹ค์šด๋กœ๋“œ API์—์„œ ๋ฐ›์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์ด์ „์— ์‹คํ–‰ ์ค‘์ด์—ˆ๋˜ ๊ธฐ๋ก์€ interrupted๋กœ ํ‘œ์‹œํ•˜์ง€๋งŒ Peer ์ •๋ฆฌ๋ฅผ ํ™•์ธํ•œ ์ƒํƒœ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

Controller crash๋งŒ์œผ๋กœ Agent์˜ Peer๊ฐ€ ์ข…๋ฃŒ๋˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์ •์ƒ Controller ์ข…๋ฃŒ๋Š” ํ™œ์„ฑ run์„ ์ทจ์†Œํ•œ ๋’ค ๋“ฑ๋ก๋œ Agent์— ๋‚จ์€ Peer ์ œ๊ฑฐ๋ฅผ ์š”์ฒญํ•˜๋ฉฐ, stop-all์„ ์ƒ๋žตํ•œ ์™„๋ฃŒ๋œ ๋‹จ์ผ run์˜ Peer๋„ ํฌํ•จํ•ฉ๋‹ˆ๋‹ค. ๊ณ„ํš๋œ ์—…๋ฐ์ดํŠธ ์ „์—๋Š” ํ™œ์„ฑ run์„ ์™„๋ฃŒํ•˜๊ฑฐ๋‚˜ ์ทจ์†Œํ•˜๊ณ  ์ด ์ •๋ฆฌ๊ฐ€ ๋๋‚  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ์‹ญ์‹œ์˜ค. Agent์— ์—ฐ๊ฒฐํ•  ์ˆ˜ ์—†๊ฑฐ๋‚˜ ์ •๋ฆฌ๊ฐ€ ์‹คํŒจํ•˜๋ฉด ์ข…๋ฃŒ ์˜ค๋ฅ˜๋ฅผ ๋ณด๊ณ ํ•˜๋ฏ€๋กœ ํ•ด๋‹น ํ˜ธ์ŠคํŠธ์˜ ์ž”์กด ์ปจํ…Œ์ด๋„ˆ๋ฅผ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

์ „์ฒด ์ฒ ๊ฑฐ์™€ ๋น„์ •์ƒ ์„œ๋น„์Šค ๋ณต๊ตฌ์—๋Š” sh scripts/swarm.sh remove๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. ControllerยทAgent ์ •๋ฆฌ๋ฅผ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š๊ณ  ์„œ๋น„์Šค ์ •์˜๋ฅผ ์‚ญ์ œํ•ฉ๋‹ˆ๋‹ค. ์‹ค์ œ ์ปจํ…Œ์ด๋„ˆ ์ข…๋ฃŒ๋Š” Docker๊ฐ€ ์„ค์ •๋œ ์ข…๋ฃŒ ์œ ์˜ˆ์— ๋”ฐ๋ผ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ๋ช…๋ น ์„ฑ๊ณต์€ Manager์— stack ์„œ๋น„์Šค๊ฐ€ ๋‚จ์ง€ ์•Š์•˜๋‹ค๋Š” ๋œป์ด๋ฉฐ, offline ํ˜ธ์ŠคํŠธ์˜ ๋ชจ๋“  ์ปจํ…Œ์ด๋„ˆ๊ฐ€ ์ข…๋ฃŒ๋˜์—ˆ๋‹ค๋Š” ๋œป์€ ์•„๋‹™๋‹ˆ๋‹ค. Agent ๋น„์ •์ƒ ์ข…๋ฃŒ ํ›„ standalone Peer๊ฐ€ ๋‚จ์„ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ํ•ด๋‹น ํ˜ธ์ŠคํŠธ๋ฅผ ์ ๊ฒ€ํ•˜๊ฑฐ๋‚˜ ๊ฐ™์€ ์†Œ์œ  ๋ฒ”์œ„๋กœ ์žฌ์‹œ์ž‘ํ•˜์—ฌ ํšŒ์ˆ˜ํ•˜์‹ญ์‹œ์˜ค. ๊ณ„ํš๋œ ์ข…๋ฃŒ๋ผ๋ฉด ์ฒ ๊ฑฐ ์ „์— ์‹คํ—˜์„ ์™„๋ฃŒยท์ทจ์†Œํ•˜๊ณ  ๊ฒฐ๊ณผ๋ฅผ ๋‹ค์šด๋กœ๋“œํ•˜์‹ญ์‹œ์˜ค.

SIGTERM์„ ๋ฐ›์œผ๋ฉด Controller๋Š” ์ƒˆ ์‹คํ—˜ ์ˆ˜๋ฝ์„ ์ค‘๋‹จํ•˜๊ณ  HTTP ์—ฐ๊ฒฐ, ์‹คํ—˜ job, Peer ์ •๋ฆฌ์™€ ์ตœ์ข… ์ƒํƒœ ์ €์žฅ์„ ๊ธฐ๋‹ค๋ฆฝ๋‹ˆ๋‹ค. ๊ธฐ๋ณธ jobShutdownTimeout: 3m์€ job ์ข…๋ฃŒ์™€ Peer ์ •๋ฆฌ์— ๊ฐ๊ฐ ์ ์šฉ๋˜๋ฏ€๋กœ stack์€ Controller ์ข…๋ฃŒ ์œ ์˜ˆ๋ฅผ 10m๋กœ ์„ค์ •ํ•ฉ๋‹ˆ๋‹ค. Agent์—๋Š” ์ตœ๋Œ€ 175์ดˆ์˜ Peer ์ •๋ฆฌ, HTTP handler ์ข…๋ฃŒ์™€ ์ œํ•œ๋œ telemetry drain์„ ํฌํ•จํ•˜๋Š” 4m๋ฅผ ์ œ๊ณตํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋‚˜๋ฆฌ์˜ค์˜ jobShutdownTimeout์„ ๋Š˜๋ฆฌ๋ฉด Controller ์œ ์˜ˆ๋„ ํ•จ๊ป˜ ๋Š˜๋ฆฌ๊ณ  ์™ธ๋ถ€ ์„œ๋น„์Šค ๊ด€๋ฆฌ์ž๊ฐ€ ์ด ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•˜์ง€ ์•Š๋„๋ก ํ•˜์‹ญ์‹œ์˜ค.

Controller๋Š” ์‹คํ–‰ ์ทจ์†Œ ํ›„์—๋„ Agent ์ด๋ฒคํŠธ ์ˆ˜์‹ ์„ ์œ ์ง€ํ•˜๊ณ , ์™„๋ฃŒ๋œ ์‹คํ—˜์ด ๋‚จ๊ธด Peer์™€ Agent ์ „์†ก ํ๊นŒ์ง€ ์ •๋ฆฌํ•œ ๋’ค HTTP๋ฅผ ๋‹ซ์Šต๋‹ˆ๋‹ค. ์ด ์ตœ์ข… Agent ์ •๋ฆฌยท์ „์†ก์—๋Š” ์ตœ๋Œ€ 190์ดˆ๋ฅผ ์ถ”๊ฐ€๋กœ ํ—ˆ์šฉํ•ฉ๋‹ˆ๋‹ค. ์ „์ฒด remove๋Š” ์ด ๊ณผ์ •์„ ๊ธฐ๋‹ค๋ฆฌ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. KPL_CONTROLLER_STOP_TIMEOUT์€ ๊ธฐ์กด ์„ค์ • ํ˜ธํ™˜์„ ์œ„ํ•ด ์ฝ์ง€๋งŒ ๋” ์ด์ƒ ์‚ฌ์šฉํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. KPL_AGENT_STOP_TIMEOUT์€ remove-node์˜ ์ •๋ฆฌ ํ™•์ธ๊ณผ ๊ฐ Docker ์กฐํšŒ์— ์ ์šฉํ•˜๋ฉฐ, KPL_DOCKER_TIMEOUT์€ ์‚ญ์ œ ๋ช…๋ น๊ณผ ์„œ๋น„์Šค ์ œ๊ฑฐ ํ™•์ธ ๋Œ€๊ธฐ์— ์ ์šฉํ•ฉ๋‹ˆ๋‹ค.

๋ฐ์ดํ„ฐ ์ €์žฅ์†Œ์™€ ์žฌ์‹œ์ž‘

Controller ๊ธฐ๋ก, Prometheus ์‹œ๊ณ„์—ด๊ณผ Grafana ๋ฐ์ดํ„ฐ๋Š” KPL_CONTROL_NODE_ID์˜ ๋ณ„๋„ named volume์— ์ €์žฅ๋ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ์„œ๋น„์Šค ์žฌ์ƒ์„ฑ๊ณผ swarm.sh remove๋Š” ์ด volume์„ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. ์‹œ๋‚˜๋ฆฌ์˜ค, ์‹คํ–‰ ๊ธฐ๋ก๊ณผ ์‚ญ์ œ ํ‘œ์‹์„ ์œ ์ง€ํ•˜๋ ค๋ฉด Controller ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ ์ „์ฒด๋ฅผ ๋ณด์กดํ•˜๊ณ  Prometheus ์ด๋ ฅ๊ณผ Grafana ์„ค์ •์ด ํ•„์š”ํ•˜๋ฉด ๋ณ„๋„๋กœ ๋ฐฑ์—…ํ•˜์‹ญ์‹œ์˜ค. Volume ์‚ญ์ œ๋Š” ์ผ๋ฐ˜ ์ข…๋ฃŒ ์ ˆ์ฐจ์— ํฌํ•จ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์‚ฌ์šฉ์ž ์ง€์ • ์ €์žฅ์†Œ๋‚˜ bind mount๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์ปจํ…Œ์ด๋„ˆ UID/GID์˜ ์“ฐ๊ธฐ ๊ถŒํ•œ์„ ํ™•์ธํ•˜๊ณ  ๊ฒฝ๋กœ๊ฐ€ Docker daemon ํ˜ธ์ŠคํŠธ์—์„œ ํ•ด์„๋จ์„ ๊ณ ๋ คํ•˜์‹ญ์‹œ์˜ค.

Controller ๋ฐ์ดํ„ฐ volume์€ ๋กœ์ปฌ์— ์œ ์ง€ํ•˜๊ณ  ํ•„์š”ํ•˜๋ฉด /var/lib/kpl/data/runs ํ•˜์œ„ ๋””๋ ‰ํ„ฐ๋ฆฌ๋งŒ NAS์— ๋งˆ์šดํŠธํ•˜์‹ญ์‹œ์˜ค. ์‹คํ–‰ ์ค‘ ๊ธฐ๋ก๊ณผ ์ž‘์€ ๋ณด๊ด€ ์ธ๋ฑ์Šค๋Š” /var/lib/kpl/data/current-run์„ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. NAS ๋ณต์‚ฌยท๊ฒ€์ฆยท์‚ญ์ œ๋Š” ์‹คํ—˜ ์ €์žฅ๊ณผ ๋…๋ฆฝ์ ์œผ๋กœ ์ฒ˜๋ฆฌํ•˜๋ฉฐ ๋ฏธ๋ณด๊ด€ ํŒŒ์ผ์€ ์„œ๋น„์Šค ์žฌ์ƒ์„ฑ ํ›„์—๋„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค. ๋‘ ๋””๋ ‰ํ„ฐ๋ฆฌ์™€ ์ˆจ๊น€ ์ €์žฅยท์‚ญ์ œ manifest๋ฅผ ํ•จ๊ป˜ ๋ฐฑ์—…ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์กด NAS ๊ฒฐ๊ณผ๋Š” ์žฌ์‹œ์ž‘ ํ›„ ๋น„๋™๊ธฐ ์ธ๋ฑ์Šค๋กœ ๋ฐœ๊ฒฌํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ ์ €์žฅ์†Œ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

KPL_RUN_MIN_FREE_BYTES ๊ธฐ๋ณธ๊ฐ’์€ 1073741824(1 GiB)์ด๋ฉฐ swarm.sh configure๋กœ ๋ณด์กดํ•ฉ๋‹ˆ๋‹ค. NAS ์šฉ๋Ÿ‰์ด ์•„๋‹Œ Run ์‹œ์ž‘ ์ „๊ณผ ์‹คํ–‰ ์ค‘ ๋กœ์ปฌ ์—ฌ์œ  ๊ณต๊ฐ„์„ ๊ฒ€์‚ฌํ•ฉ๋‹ˆ๋‹ค. ๊ธฐ์ค€๋ณด๋‹ค ์ž‘์œผ๋ฉด ๋ฐฐ์น˜๋Š” Run ์‚ฌ์ด์—์„œ ๋Œ€๊ธฐํ•˜๊ณ , ํ™œ์„ฑ Run์—์„œ ๊ณต๊ฐ„ ๋ถ€์กฑยท๊ธฐ๋ก ์˜ค๋ฅ˜๋ฅผ ๊ฐ์ง€ํ•˜๋ฉด ์‹คํŒจ ์ฒ˜๋ฆฌ์™€ ์ •๋ฆฌ๋ฅผ ์ˆ˜ํ–‰ํ•ฉ๋‹ˆ๋‹ค. 0์€ ์—ฌ์œ  ๊ณต๊ฐ„ ๊ฒ€์‚ฌ๋งŒ ๋„๋ฉฐ ์“ฐ๊ธฐ ์˜ค๋ฅ˜๋Š” ๊ณ„์† ์‹คํŒจ๋กœ ์ฒ˜๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์„ค์ • ๋ณ€๊ฒฝ์€ ์ •์ƒ ๋ฐฐํฌ ์ ˆ์ฐจ๋กœ ๋ฐ˜์˜ํ•˜์‹ญ์‹œ์˜ค. NAS ์žฅ์•  ๋™์•ˆ ๋ฏธ๋ณด๊ด€ ๊ฒฐ๊ณผ๊ฐ€ ๋กœ์ปฌ์— ์Œ“์ผ ์ˆ˜ ์žˆ์œผ๋ฏ€๋กœ ๊ฐ€์žฅ ํฐ Run๊ณผ ์˜ˆ์ƒ ๋Œ€๊ธฐ ๋ถ„๋Ÿ‰์„ ์ˆ˜์šฉํ•˜๋„๋ก ๋กœ์ปฌ volume์„ ์ค€๋น„ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

Controller ๋ฐ์ดํ„ฐ ๋””๋ ‰ํ„ฐ๋ฆฌ์— ์“ธ ์ˆ˜ ์—†์œผ๋ฉด ์‹œ์ž‘์ด ์‹คํŒจํ•ฉ๋‹ˆ๋‹ค. ์‹คํ–‰ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๋Š” ์ž„์‹œ ํŒŒ์ผ์— ์“ด ๋’ค ๊ฐ™์€ ํŒŒ์ผ์‹œ์Šคํ…œ์—์„œ renameํ•˜์—ฌ ๋ถ€๋ถ„ JSON ์ฝ๊ธฐ๋ฅผ ๋ฐฉ์ง€ํ•˜๋ฉฐ ์ด๋ฒคํŠธ batch๋Š” append ํ›„ ๋””์Šคํฌ ๋™๊ธฐํ™”๋ฅผ ๋งˆ์ณ์•ผ ์ˆ˜์‹  ํ™•์ธํ•ฉ๋‹ˆ๋‹ค. ์ ‘์ˆ˜ ์˜ˆ์•ฝยทAgent ์†Œ์œ  ์ •๋ณดยท์ œ์ถœ ํ‚ค๋Š” ํ™•์ • ๊ฒฝ๊ณ„์—์„œ ๋™๊ธฐํ™”ํ•˜๊ณ  Run ์ข…๋ฃŒ ์‹œ ์›๋ณธ ๋กœ๊ทธ๋„ ๋™๊ธฐํ™”ํ•ฉ๋‹ˆ๋‹ค. ๊ฐœ๋ณ„ ์ง„ํ–‰ ์ƒํƒœ ๊ฐฑ์‹ ์„ ๋ชจ๋‘ ๊ฐ•์ œ ๋™๊ธฐํ™”ํ•˜์ง€๋Š” ์•Š์œผ๋ฏ€๋กœ ๊ฐ‘์ž‘์Šค๋Ÿฌ์šด ์ „์› ์žฅ์•  ์‹œ ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ interrupted๋กœ ๋‚จ์„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค. ์žฌ์‹œ์ž‘ ํ›„ ๋ณด์กด ๊ฒฐ๊ณผ์— ์ ‘๊ทผํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ์‹ค์‹œ๊ฐ„ ์‹คํ–‰๊ณผ counter๋Š” ๋ณต์›ํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค.

๊ฐ Agent๋Š” ๋…ธ๋“œ ๋กœ์ปฌ <stack>_agent-data volume์„ /var/lib/kpl/agent์— ๋งˆ์šดํŠธํ•ฉ๋‹ˆ๋‹ค. telemetry-spool/์— ์ˆ˜๋ฝํ–ˆ์ง€๋งŒ Controller ์ˆ˜์‹  ํ™•์ธ ์ „์ธ ์ด๋ฒคํŠธ๋ฅผ ๋ณด์กดํ•˜์—ฌ ์„œ๋น„์Šค ๊ต์ฒดยท์žฌ์‹œ์ž‘ ๋’ค ์žฌ์ „์†กํ•ฉ๋‹ˆ๋‹ค. ๋กœ์ปฌ ์˜๊ตฌ ์ €์žฅ์†Œ์— ๋‘๊ณ  ๋…ธ๋“œ ๋ฐฑ์—…์— ํฌํ•จํ•˜๋ฉฐ task ๊ต์ฒด ์‹œ ์œ ์ง€ํ•˜์‹ญ์‹œ์˜ค. ๋‹ค๋ฅธ Swarm ๋…ธ๋“œ๋กœ ๋ณต์ œํ•˜๋Š” volume์€ ์•„๋‹™๋‹ˆ๋‹ค. ๊ธฐ์กด ๋งˆ์šดํŠธ ์—†๋Š” Agent์˜ ๋ฉ”๋ชจ๋ฆฌ ํ๋Š” ์†Œ๊ธ‰ ๋ณด์กด๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ์—…๋ฐ์ดํŠธ ๋•Œ ์ •์ƒ ์ข…๋ฃŒ๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค.

๋กœ์ปฌ ๋””์Šคํฌ ๋™๊ธฐํ™”๋Š” Agent์™€ Controller ์–‘์ชฝ์— I/O ๋น„์šฉ์„ ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค. telemetry ์†๋„์— ๋งž๋Š” ์ €์žฅ์†Œ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์“ฐ๊ธฐ ์ง€์—ฐ์„ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์‹คํ—˜์— ์˜ํ–ฅ์ด ์ „ํ˜€ ์—†์Œ์„ ๋ณด์žฅํ•˜์ง€ ์•Š์œผ๋ฉฐ NAS๋Š” ๊ณ„์† runs/์—๋งŒ ์‚ฌ์šฉํ•ฉ๋‹ˆ๋‹ค. Agent ์ˆ˜๋ฝ ์ „ Peer ๊ฐ•์ œ ์ข…๋ฃŒ, volume ์œ ์‹ค, ๋™๊ธฐํ™”๋ฅผ ์ง€ํ‚ค์ง€ ์•Š๋Š” ์ €์žฅ์†Œ์—์„œ์˜ ์œ ์‹ค์€ ๋ณต๊ตฌํ•˜์ง€ ๋ชปํ•ฉ๋‹ˆ๋‹ค. ๊ฒฐ๊ณผ์˜ ๋ฌด๊ฒฐ์„ฑ ์ƒํƒœ์™€ ๋ถ„์„ ๊ทผ๊ฑฐ๋ฅผ ํ•จ๊ป˜ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค.

๋ฐฑ๊ทธ๋ผ์šด๋“œ ๋ถ„์„์˜ ์ƒํƒœยท์™„๋ฃŒ JSONยท๋น„๊ต ์š”์•ฝ๋„ Controller ๋ณผ๋ฅจ์— ๋ณด์กด๋ฉ๋‹ˆ๋‹ค. ์™„๋ฃŒ ๊ฒฐ๊ณผ๋Š” ์žฌ์‹œ์ž‘ ํ›„ ์žฌ์‚ฌ์šฉํ•˜๋ฉฐ ๋ฏธ์™„๋ฃŒยท์ทจ์†Œ ์ž‘์—…์€ ๋‹ค์‹œ ์ ‘์ˆ˜ํ•ฉ๋‹ˆ๋‹ค. ์ผ๋ฐ˜ ์‹คํ–‰ ZIP์—๋Š” ์ด ๋ถ„์„ ์บ์‹œ๊ฐ€ ํฌํ•จ๋˜์ง€ ์•Š์œผ๋ฏ€๋กœ ๋ณด์กด ๊ฒฝ๊ณ„๋Š” ๋ถ„์„ ํŒŒ์ผ๊ณผ ์ด๋ฏธ์ง€๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

๊ฒ€์ฆ ๋ฒ”์œ„

ํ˜„์žฌ Go ํšŒ๊ท€ suite์™€ ์…ธ ํšŒ๊ท€ ๋„ค ๊ฐœ์ธ test-swarm-agent.sh, test-check-swarm.sh, test-swarm-config.sh, test-swarm.sh๋Š” make test-linux ๋˜๋Š” docker build --target test -t kpl-v3:test .๋กœ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์…ธ ํ…Œ์ŠคํŠธ๋Š” Docker ์‘๋‹ต์„ ๋ชจ์‚ฌํ•˜์—ฌ ๋น„์ •์ƒ taskยทoffline ๋…ธ๋“œยท์ด๋ ฅ ๋ถ€์žฌ์—๋„ ์ง์ ‘ ์ฒ ๊ฑฐ, ๋‹ค๋ฅธ stack ๋ณ€๊ฒฝ ๋ฐฉ์ง€, ์‚ญ์ œยท์กฐํšŒ ์˜ค๋ฅ˜, ๋ถ€๋ถ„ ์ •๋ฆฌ ํ›„ ์žฌ์‹œ๋„, remove-node ์ •์ƒ ์ข…๋ฃŒ ํ™•์ธ๊ณผ ์„ค์ • ํŒŒ์ผ ์ฒ˜๋ฆฌ๋ฅผ ๊ฒ€์ฆํ•˜๋ฉฐ ์‹ค์ œ ํด๋Ÿฌ์Šคํ„ฐ๋ฅผ ๋ฐฐํฌํ•˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ๋ณ„๋„ ๋ธŒ๋ผ์šฐ์ € ํ…Œ์ŠคํŠธ์™€ ๋ช…์‹œ์ ์œผ๋กœ ํ™œ์„ฑํ™”ํ•˜๋Š” ์ปค๋„ ํ…Œ์ŠคํŠธ๋Š” ๊ฐœ๋ฐœ ๊ฒ€์‚ฌ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

์ด์ „ ๊ฒ€์ฆ ๊ธฐ๋ก์€ ๋ณ„๋„ Docker 29.7.2 daemon์—์„œ SIGTERM ์ข…๋ฃŒ์šฉ ControllerยทAgent ํ…Œ์ŠคํŠธ ์„œ๋น„์Šค๋กœ remove-node, add-node, ์ „์ฒด remove๋ฅผ ์‹คํ–‰ํ–ˆ๋‹ค๊ณ  ๋ณด๊ณ ํ•ฉ๋‹ˆ๋‹ค. ์ •์ƒ ์ข…๋ฃŒ์˜ shutdown / PID 0 / exit 0, ์žฌ๋ฐฐ์น˜ ํ›„ ์ƒˆ task, ์ตœ์ข… stack ์„œ๋น„์Šค 0๊ฐœ, ๋‹ค๋ฅธ ๋…ธ๋“œ๋ฅผ ์ œ์™ธํ•  ๋•Œ ์˜ํ–ฅ ์—†๋Š” ์‹คํ–‰ ์ค‘ task ID ์œ ์ง€๊ฐ€ ๊ธฐ๋ก๋˜์–ด ์žˆ์Šต๋‹ˆ๋‹ค. ์›๋ณธ ์‹คํ–‰ ์‚ฐ์ถœ๋ฌผ์€ kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ์— ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์œผ๋ฏ€๋กœ ํ˜„์žฌ checkout์ด๋‚˜ ์ „์ฒด registryยทPeer ์‹คํ—˜์˜ ๊ฒ€์ฆ ๊ฒฐ๊ณผ๊ฐ€ ์•„๋‹Œ ๊ณผ๊ฑฐ ๋ณด๊ณ ์ž…๋‹ˆ๋‹ค. ์ด ๊ธฐ๋ก์€ ํ˜„์žฌ remove์˜ ์„œ๋น„์Šค ์ง์ ‘ ์‚ญ์ œ ๋ฐฉ์‹์œผ๋กœ ๋ณ€๊ฒฝํ•˜๊ธฐ ์ „ ๋ณด๊ณ ์ž…๋‹ˆ๋‹ค. ํ˜„์žฌ ๊ตฌํ˜„์€ scripts/swarm.sh์™€ mock ํ…Œ์ŠคํŠธ๋ฅผ ์ฐธ๊ณ ํ•˜์‹ญ์‹œ์˜ค.

Swarm ์‚ฌ์ „ ๊ฒ€์‚ฌ๋Š” sh scripts/swarm.sh check๋ฅผ ์‚ฌ์šฉํ•˜์‹ญ์‹œ์˜ค. helper๊ฐ€ ์„ค์ •์„ ๋ถˆ๋Ÿฌ์™€ ๋ฐฐํฌ ๊ฒ€์‚ฌ๋ฅผ ์‹คํ–‰ํ•ฉ๋‹ˆ๋‹ค. ์„ค์ •ยท๋ฐฐ์น˜ยทoverlay๋ฅผ ๊ฒ€์‚ฌํ•˜์ง€๋งŒ ๋ชจ๋“  Agent ๋…ธ๋“œ์— ์ปค๋„ ๊ทœ์น™์„ ์„ค์น˜ํ•˜๊ฑฐ๋‚˜ ํ˜ธ์ŠคํŠธ ๊ฐ„ ํŠธ๋ž˜ํ”ฝ์„ ๊ฒ€์ฆํ•˜์ง€๋Š” ์•Š์Šต๋‹ˆ๋‹ค. ์‹ค์ œ ๋„คํŠธ์›Œํฌ ์กฐ๊ฑด์€ ์„ ํƒํ•œ Swarm ๋…ธ๋“œ์—์„œ ์‹œ๋‚˜๋ฆฌ์˜ค๋ฅผ ์‹คํ–‰ํ•ด ๊ฒ€์ฆํ•˜์‹ญ์‹œ์˜ค. ๋ฐฐํฌ ์‚ฌ์ „ ๊ฒ€์‚ฌ๋‚˜ ํŒจํ‚ค์ง€ ํ…Œ์ŠคํŠธ๋งŒ์œผ๋กœ ๋ถ„์‚ฐ smoke ์‹คํ—˜ยท์‹ค์ œ cross-host VXLAN ํ†ต์‹ ยท์ฒ˜๋ฆฌ๋Ÿ‰ ์ธก์ •์„ ๋Œ€์ฒดํ•  ์ˆ˜๋Š” ์—†์Šต๋‹ˆ๋‹ค.

์ตœ์†Œ ๋‘ ์„œ๋ฒ„์—์„œ ๋ถ„์‚ฐ ์‹คํ—˜ ์˜ˆ์ œ๋ฅผ ์‹คํ–‰ํ•ด ์„œ๋กœ ๋‹ค๋ฅธ Agent์— ready Peer๊ฐ€ ์ƒ๊ธฐ๋Š”์ง€, ๊ด‘๊ณ  ์ฃผ์†Œ๊ฐ€ Peer overlay์— ์†ํ•˜๋Š”์ง€, publish/deliver๊ฐ€ ์–‘์ชฝ ์„œ๋ฒ„์—์„œ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•˜์‹ญ์‹œ์˜ค. ์˜ˆ์ œ๋Š” boot 1๊ฐœ์™€ worker 5๊ฐœ๋ฅผ ์ƒ์„ฑํ•˜๋ฏ€๋กœ ์ด capacity 6 ์ด์ƒ์ด ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค. ๊ทธ ๋’ค ๋ชฉํ‘œ Peer ์ˆ˜๋ฅผ ๋‹จ๊ณ„์ ์œผ๋กœ ์˜ฌ๋ ค ready ์ง€์—ฐยท์‹คํŒจ์œจยท๋ถ„๋ฐฐยท์ž์› ์‚ฌ์šฉ๋Ÿ‰์„ ๊ธฐ๋กํ•˜์‹ญ์‹œ์˜ค. ๋„คํŠธ์›Œํฌ ๋‹จ์ ˆ/Agent ์žฌ์‹œ์ž‘ ์‹œ stale ์ œ์™ธยท์ž”์กด ์ปจํ…Œ์ด๋„ˆ ์ •๋ฆฌ์™€ Prometheus ๋Œ€์ƒ ๊ต์ฒด๋„ ํ™•์ธํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค.

2026-09-04 ๊ธฐ์กด stack ์‹คํ–‰ ๊ฒ€์ฆ

์•„๋ž˜ ๊ณผ๊ฑฐ ๊ธฐ๋ก์€ manager ๊ด€๋ฆฌ CLI scripts/swarm.sh ์ถ”๊ฐ€ ์ „์ด๋ฉฐ ์›๋ณธ ์‹คํ–‰ ์•„์นด์ด๋ธŒ๋Š” kpl-v3 ์†Œ์Šค ์ €์žฅ์†Œ์— ํฌํ•จ๋˜์–ด ์žˆ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ checkout์ด๋‚˜ CLI์˜ init/deploy/add-node/remove-node/remove ์ „์ฒด ๊ฒฝ๋กœ๋ฅผ ์‹ค์ œ ํด๋Ÿฌ์Šคํ„ฐ์—์„œ ๊ฒ€์ฆํ•œ ๊ฒฐ๊ณผ๋Š” ์•„๋‹™๋‹ˆ๋‹ค.

๊ฒ€์ฆ ํ™˜๊ฒฝ์€ ๋™์ผ WSL2 Linux ์ปค๋„ ์œ„์˜ ๊ฒฉ๋ฆฌ๋œ Docker ๋ฐ๋ชฌ ๋‘ ๊ฐœ์ž…๋‹ˆ๋‹ค. Docker 29.7.2์˜ managerยทworker์™€ ์‹ค์ œ attachable overlay๋ฅผ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ๊ธฐ์กด ํ˜ธ์ŠคํŠธ์˜ Swarm ์ƒํƒœ๋Š” ๋ณ€๊ฒฝํ•˜์ง€ ์•Š์•˜์Šต๋‹ˆ๋‹ค. ์ด๋Š” ๋‘ ๋ฐ๋ชฌ ์‚ฌ์ด์˜ ๋ฐฐ์น˜ยทVXLANยท์„œ๋น„์Šค ํƒ์ƒ‰ ๊ฒ€์ฆ์ด๋ฉฐ, ์„œ๋กœ ๋‹ค๋ฅธ ๋ฌผ๋ฆฌ ์„œ๋ฒ„์˜ NICยทMTUยท์žฅ์• ยท๋Œ€๊ทœ๋ชจ ์ฒ˜๋ฆฌ๋Ÿ‰ ๊ฒ€์ฆ์€ ์•„๋‹™๋‹ˆ๋‹ค. ์ด๋ฏธ์ง€๋Š” ์–‘์ชฝ ๋ฐ๋ชฌ์— ๊ฐ™์€ ๋กœ์ปฌ ์ด๋ฏธ์ง€๋ฅผ ๋ฏธ๋ฆฌ ์ ์žฌํ–ˆ์œผ๋ฉฐ registry ์ธ์ฆยทpull ๊ฒฝ๋กœ๋Š” ๋ณ„๋„ ๊ฒ€์ฆ ๋Œ€์ƒ์ž…๋‹ˆ๋‹ค.

ํ•ญ๋ชฉ ๊ฒฐ๊ณผ
Linux ์ฝ”๋“œ ๊ฒ€์ฆ ์ „์ฒด Go ํ…Œ์ŠคํŠธ ํ†ต๊ณผ. ๋งˆ์ง€๋ง‰ ์‹œ๊ฐ„ ์˜ˆ์‚ฐ ์ˆ˜์ • ํ›„ Agent ํŒจํ‚ค์ง€์™€ Swarm shell ํšŒ๊ท€ ํ…Œ์ŠคํŠธ ์žฌ๊ฒ€์ฆ ํ†ต๊ณผ
Swarm ๋ฐฐํฌ global Agent 2๊ฐœ, Controller 1๊ฐœ, Prometheus 1๊ฐœ, Grafana 1๊ฐœ ์ •์ƒ ์‹คํ–‰. ์‹ค์ œ manager์—์„œ ์‚ฌ์ „ ๊ฒ€์‚ฌ ํ†ต๊ณผ
๋…ธ๋“œ ๋ถ„๋ฐฐ capacity 4์ธ Agent ๋‘ ๊ฐœ์— Peer 6๊ฐœ๋ฅผ 3๊ฐœ์”ฉ ๋ฐฐ์น˜, ๋ชจ๋‘ ready ๋ฐ ์ƒํ˜ธ ์—ฐ๊ฒฐ ํ™•์ธ
Peer ์ฃผ์†Œ ๋ชจ๋“  ๊ด‘๊ณ  ์ฃผ์†Œ๊ฐ€ Peer overlay IPv4์˜ TCP 20000 ํ•œ ๊ฐœ. gateway bridge ์ฃผ์†Œ ๋ฏธํฌํ•จ
๋„คํŠธ์›Œํฌยท๋ฐœํ–‰ worker 25ms ์ง€์—ฐยท2ms jitterยท0.5% ์†์‹ค, 4096-byte payload 50ํšŒ ๋ฐœํ–‰, ์ˆ˜์‹  300ํšŒ(Agent๋ณ„ 150ํšŒ)
๋ชจ๋‹ˆํ„ฐ๋ง Prometheus์˜ Agent ๋Œ€์ƒ 2๊ฐœ์™€ Controllerยท์ž๊ธฐ ์ˆ˜์ง‘ ๋ชจ๋‘ UP. Grafana ๋Œ€์‹œ๋ณด๋“œ UID kpl-experiments์™€ ๋ฐ์ดํ„ฐ์†Œ์Šค API ์—ฐ๊ฒฐ OK
task ๊ต์ฒด ์ด๋ฏธ์ง€ ์—…๋ฐ์ดํŠธ ํ›„ Node ๊ธฐ๋ฐ˜ Agent ID ์œ ์ง€, task IP ๋ณ€๊ฒฝ ๋ฐ Prometheus ๋Œ€์ƒ ๊ฐฑ์‹  ํ™•์ธ
์ •์ƒ ์ข…๋ฃŒ run-20260904T040249Z-34d32bbb9559adbba6519a558c6cc107 completed, ์–‘์ชฝ activeNodes 0, ์‹ค์ œ ์ž”์กด Peer ์ปจํ…Œ์ด๋„ˆ ๊ฐ๊ฐ 0๊ฐœ

์œ„ ๊ณผ๊ฑฐ ๋ฐœํ–‰ยท์ˆ˜์‹  ์ˆ˜๋Š” ๋ˆ„์  kpl_events_total ๊ธฐ์ค€์ด๋ฉฐ ๋‹น์‹œ snapshot ์š”์•ฝ์€ ์ตœ๊ทผ ์ด๋ฒคํŠธ ๋ฒ„ํผ๋ฅผ ์‚ฌ์šฉํ–ˆ์Šต๋‹ˆ๋‹ค. ํ˜„์žฌ v3 ์‹คํ–‰ ์š”์•ฝ์€ ์ด ๋ฒ„ํผ์™€ ๋…๋ฆฝ์ ์œผ๋กœ ๋ˆ„์ ํ•˜๋ฉฐ ์‹คํ—˜ ์ง€ํ‘œ์˜ ์ •์˜๋ฅผ ๋”ฐ๋ฆ…๋‹ˆ๋‹ค. ์ฒซ ๋ถ€ํ•˜ ์‹คํ–‰์—์„œ ์ƒ์„ฑยท์‹œ์ž‘ ์ „์ฒด์˜ ๊ณต์œ  45์ดˆ ์ œํ•œ์ด Peer๋ฅผ ์ข…๋ฃŒ์‹œํ‚ค๋Š” ๋ฌธ์ œ๋ฅผ ๋ฐœ๊ฒฌํ•ด ๋‹จ๊ณ„๋ณ„ ์˜ˆ์‚ฐ์œผ๋กœ ์ˆ˜์ •ํ•œ ๋’ค ์œ„ ๊ฒฐ๊ณผ๋ฅผ ํ™•์ธํ–ˆ์Šต๋‹ˆ๋‹ค.

โš ๏ธ **GitHub.com Fallback** โš ๏ธ