이 글은 기존 운영했던 WordPress 블로그인 PyxisPub: Development Life (pyxispub.uzuki.live) 에서 가져온 글 입니다. 모든 글을 가져오지는 않으며, 작성 시점과 현재 시점에는 차이가 많이 존재합니다.
작성 시점: 2020-02-29
언젠가 현실 친구 채팅방에서 '우리 다같이 한 것이 뭐가 있었냐?' 하면서 이야기가 있었는데, 갑자기 마인크래프트 이야기가 나오게 되어 구축하게 되었다.
...는 마인크래프트 서버 구축이 처음은 아니었는데, 지금으로부터 10개월 전에 EC2라는 모드를 넣고 구축한 적이 있었다. 다만, 오래 못 갈 뿐이었다.
하지만, 이번에는 바닐라 기반으로 하자는 이야기가 나왔고, 약 6일 정도 운영하게 되었다.
6일 정도 운영하다보니 나름대로 문제와 이를 해결하기 위한 여러 방안을 구축해서 사용했고, 그 결과 현재는 다음과 같은 구조를 가지게 되었다.
먼저, 마인크래프트 서버라고 해서 단순히 마인크래프트만 돌린다는 것은 전혀 아니다. 그럴 수도 있지만, 가령 아래와 같은 문제가 발생하게 된다.
따라서, minecraft 컨테이너 외에 여러 컨테이너들을 동시에 운영하게 되었고, 각각의 역할은 다음과 같다.
tls pyxis@uzuki.live
라고 적어두면 Let's Encrypt로 통해 인증서를 받아와서 Signing한다는 것이다.구축에 사용된 서버는 Vultr 4vCPU 8GB 사양이다.
Ubuntu 기준이며, https://docs.docker.com/install/linux/docker-ce/ubuntu/ 를 참고한다.
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg-agent software-properties-common
curl -fsSL <a href="https://download.docker.com/linux/ubuntu/gpg">https://download.docker.com/linux/ubuntu/gpg</a> | sudo apt-key add -
sudo apt-key fingerprint 0EBFCD88
sudo add-apt-repository "deb [arch=amd64] <a href="https://download.docker.com/linux/ubuntu">https://download.docker.com/linux/ubuntu</a> bionic stable"
sudo apt update
sudo apt install docker-ce docker-ce-cli <a href="http://containerd.io">containerd.io</a>
sudo curl -L "<a href="https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$">https://github.com/docker/compose/releases/download/1.25.4/docker-compose-$</a>(uname -s)-$(uname -m)" -o /usr/local/bin/docker-compose
sudo chmod +x /usr/local/bin/docker-compose
여기까지 9개의 Command를 실행하여 Docker-CE 버전과 docker-compose를 설치할 수 있다.
version: '2'
services:
minecraft:
image: itzg/minecraft-server:adopt11
container_name: "minecraft"
ports:
- ...
environment:
- EULA=TRUE
- ENABLE_RCON=TRUE
- RCON_PASSWORD=...
- MEMORY=7G
- TYPE=PAPER
- VERSION=1.15.2
- SERVER_PORT=...
restart: always
rcon:
image: itzg/rcon
container_name: "rcon"
links:
- minecraft
networks:
- nodap-mc-network
networks:
nodap-mc-network:
external: true
만약 Forge 기반의 모드를 사용하고자 하면 TYPE=FORGE로 통해 Forge 기반 서버로 사용할 필요가 있다. 처음에 Forge 기반으로 사용했었으나 메모리 사용량이나 서버가 급격하게 무거워지는 문제가 있었기에, PaperMC 를 사용하게 되었다.
rcon 에 연결된 networks인 nodap-mc-network 는 후술할 예정이지만 Caddy가 각 컨테이너로 연결할 수 있게 묶어주는 역할을 한다. TCP로 연결되어 따로 네트워크를 묶을 필요가 없는 minecraft는 기재하지 않았다.
Portainer 서버는 상기하였듯이 컨테이너의 관리를 웹 UI로 할 수 있다.
version: '2'
services:
portainer:
image: portainer/portainer
restart: always
container_name: "portainer-app"
command: -H unix:///var/run/docker.sock
volumes:
- /var/run/docker.sock:/var/run/docker.sock
networks:
- nodap-mc-network
networks:
nodap-mc-network:
external: true
여기에서도 nodap-mc-network로 묶어주었다.
모니터링 스택은 상기하였듯이 컨테이너의 CPU/메모리/네트워크 사용량을 볼 수 있게 한다.
cAdvisor 서버 (google/cadvisor)
cadvisor: image: google/cadvisor:latest container_name: cadvisor volumes: - /:/rootfs:ro - /var/run:/var/run:ro - /sys:/sys:ro - /var/lib/docker/:/var/lib/docker:ro - /dev/disk/:/dev/disk:ro restart: always networks: - nodap-mc-network
cAdvisor 등이 외부에 노출될 필요는 없으나 필요할 경우, 8080:8080
포트를 추가하여 웹 UI를 볼 수 있다.
Prometheus 서버 (prom/prometheus)
prometheus:
image: prom/prometheus
container_name: prometheus
restart: always
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
networks:
- nodap-mc-network
설정에 필요한 prometheus.yml는 다음과 같다.
global:
scrape_interval: 15s
external_labels:
monitor: 'nodap-mc-monitor'
scrape_configs:
- job_name: 'cAdvisor'
scrape_interval: 5s
static_configs:
- targets: ['cadvisor:8080']
Grafana 서버 (grafana/grafana)
grafana:
image: grafana/grafana
container_name: grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=
volumes:
- grafana-storage:/var/lib/grafana
depends_on:
- prometheus
networks:
- nodap-mc-network
그리고, Grafana Alerts를 이용하여 알림 기능을 구현하였는데, 위 Memory Usage 의 빨간색 부분이 기준치이다.
알림 룰은 간단하게 진행하였는데, 매 20분마다 5분간의 평균 메모리 사용량이 7301444403 Bytes (= 6.8GiB) 를 넘으면 Notification을 보내주는 규칙이다.
이 세 서버를 모두 정의하면 다음과 같다.
version: '2'
services:
cadvisor:
image: google/cadvisor:latest
container_name: cadvisor
volumes:
- /:/rootfs:ro
- /var/run:/var/run:ro
- /sys:/sys:ro
- /var/lib/docker/:/var/lib/docker:ro
- /dev/disk/:/dev/disk:ro
restart: always
networks:
- nodap-mc-network
prometheus:
image: prom/prometheus
container_name: prometheus
restart: always
volumes:
- ./prometheus.yml:/etc/prometheus/prometheus.yml
command:
- '--config.file=/etc/prometheus/prometheus.yml'
networks:
- nodap-mc-network
grafana:
image: grafana/grafana
container_name: grafana
environment:
- GF_SECURITY_ADMIN_PASSWORD=
volumes:
- grafana-storage:/var/lib/grafana
depends_on:
- prometheus
networks:
- nodap-mc-network
volumes:
grafana-storage:
networks:
nodap-mc-network:
external: true
Caddy는 Go로 작성된 웹 서버로 간단한 사용법으로 TLS certificate 관리, 리버스 프록시, 정적 파일 호스팅 등의 많은 기능을 제공한다.
version: '2'
services:
caddy:
image: abiosoft/caddy
container_name: caddy
ports:
- '80:80'
- '443:443'
volumes:
- .Caddyfile:/etc/Caddyfile
- .caddy:/root/.caddy
restart: always
networks:
- nodap-mc-network
networks:
nodap-mc-network:
external: true
그리고, 설정 파일이기도 한 Caddyfile는 다음과 같다.
***1.uzuki.live {
proxy / portainer:9000
tls pyxis@uzuki.live
}
***2.uzuki.live {
proxy / grafana:3000
tls pyxis@uzuki.live
}
***3.uzuki.live {
proxy / rcon:4326
tls pyxis@uzuki.live
}
[1~3].uzuki.live 가 하나의 사이트로 인식하게 되며, 각 사이트는 컨테이너:포트 로의 proxy 기능과 tls pyxis@uzuki.live
를 가지게 된다.
개인적으로.. 되게 존경스럽고 멋있는 것 같습니다..