Agent 节点部署 (Security Hardened)¶
[!CAUTION] 前置条件:必须先完成 安全基线与加固。 特别是防火墙:Swarm 的 Global Mode 端口 (9001) 无法绑定特定 IP,必须依赖 UFW 或 Oracle Security List 拦截公网流量。若防火墙未生效,严禁执行本部署。
Part 1: 伦敦 Swarm 集群 (London 1/2/3)¶
0. 安全前置检查 (在所有节点执行)¶
# 1. 确认 UFW 状态为 Active
sudo ufw status verbose
# 必须看到: Status: active, Default: deny (incoming)
# 2. [新增] 确认 ufw-docker 已安装
ufw-docker status
# 应该能看到 Docker 相关的规则链
# [!] 如果未安装,请执行 (每台服务器都在本地安装,与Swarm无关):
# sudo wget -O /usr/local/bin/ufw-docker https://github.com/chaifeng/ufw-docker/raw/master/ufw-docker
# sudo chmod +x /usr/local/bin/ufw-docker
# sudo ufw-docker install
# sudo ufw reload
# 3. 确认仅允许 Tailscale 和 SSH
# - 22/tcp (SSH) -> ALLOW
# - 41641/udp (Tailscale) -> ALLOW
# - Anywhere on tailscale0 -> ALLOW
# - ❌ 9001/tcp -> 必须没有 ALLOW 规则 (即默认被 Deny)
1. 初始化 Docker & Swarm¶
1.1 初始化 Manager (London 1)¶
# 务必指定内网 IP
docker swarm init --advertise-addr 10.0.0.218 --data-path-addr 10.0.0.218
1.2 加入 Worker (London 2/3)¶
在 Manager 节点 (London 1) 查看加入 Worker 所需的完整命令与 Token: docker swarm join-token worker
docker swarm join --token <TOKEN> 10.0.0.218:2377
2. 部署 Tailscale (网络层)¶
# 准备目录
sudo mkdir -p /opt/infra/bootstrap && cd /opt/infra/bootstrap
docker-compose.yml (Security Optimized)¶
services:
net-tailscale:
image: tailscale/tailscale:latest
container_name: net-tailscale
hostname: london1 # <--- 每台机器需修改 (london2, london3)
network_mode: host
restart: always
cap_add:
- NET_ADMIN
- SYS_MODULE
volumes:
- ./tailscale-data:/var/lib/tailscale
- /dev/net/tun:/dev/net/tun
environment:
- TS_AUTHKEY=${TS_AUTHKEY}
- TS_STATE_DIR=/var/lib/tailscale
- TS_USERSPACE=false
- TS_EXTRA_ARGS=--accept-routes
启动:
echo "TS_AUTHKEY=tskey-auth-xxxxx" > .env
docker compose up -d
3. 部署 Portainer Agent (全集群)¶
仅在 Manager (London 1) 执行:
agent-stack.yml¶
services:
agent:
image: portainer/agent:latest
environment:
AGENT_CLUSTER_ADDR: tasks.agent
volumes:
- /var/run/docker.sock:/var/run/docker.sock
- /var/lib/docker/volumes:/var/lib/docker/volumes
networks:
- agent_network
ports:
- target: 9001
published: 9001
mode: host
# ⚠️ 警告:Swarm 会在 0.0.0.0:9001 监听。
# 安全性完全依赖宿主机防火墙 (UFW/Oracle Security List)。
# 必须确保 9001 端口不对 Public Internet 开放!
deploy:
mode: global
placement:
constraints: [node.platform.os == linux]
networks:
agent_network:
driver: overlay
attachable: true
部署:
docker stack deploy -c agent-stack.yml portainer
4. 最终接入¶
回到 Portainer (Chuncheon 1),添加 Environment 时:
* Environment URL: <London1-Tailscale-IP>:9001
* 由于我们已经在 UFW 允许了 bind on tailscale0,且 Deny 了 Public IP,所以只有通过 Tailscale 隧道才能访问 9001。完美。
Part 2: 春川2 独立节点 (Standalone)¶
Deployment¶
docker-compose.yml (Standalone Security)¶
[!SECURE] Standalone 模式:我们可以明确绑定 Agent 到内网 IP (Tailscale IP)。
前提:你需要先知道该机器的 Tailscale IP(假设是 100.x.y.z)。如果不确定,可以分两步走:先启动 Tailscale,看 IP,再更新 Compose。
或者,更为通用的做法是:绑定到 Localhost,然后利用 Tailscale 的 Subnet Router 功能或 Socat 转发。
但最简单的防扫描方案是:继续依赖防火墙 (UFW)。
services:
net-tailscale:
# ... 同上 ...
ops-portainer-agent:
image: portainer/agent:latest
network_mode: host # 必须 Host 模式监听 Tailscale IP
volumes:
- /var/run/docker.sock:/var/run/docker.sock
depends_on:
- net-tailscale
# ⚠️ 自保护机制:
# Agent 默认监听 9001。依赖 UFW 拦截公网访问。
高级玩家选项 (Edge Agent): 推荐在 Portainer 使用 "Edge Agent" 模式。 1. Portainer 生成 Edge Key。 2. Agent 启动参数加入
EDGE_ID和EDGE_KEY。 3. Agent 主动连回 Portainer,完全不需要开启 9001 端口。这是最安全的方案。 * 注意:虽然 Edge Agent 不用开 9001,但如果它需要连接公网 (如拉取 Docker 镜像),依然受ufw-docker的出站规则影响 (默认 Allow Out)。无需额外配置。