Hermes Docker 容器接入 Tailscale 手册

Hermes Docker 容器接入 Tailscale 手册

记录 Hermes H02 Docker 容器通过 Tailscale userspace-networking 模式加入 tailnet 的完整流程。

架构概述

组件说明
容器Hermes H02 (Debian 13, aarch64), Docker bridge 网络 (ghost_net)
Tailscale 模式--tun=userspace-networking — 无需 tun 设备、无需 root、无需 NET_ADMIN cap
节点名hermes-h02
Tailnettail9e6317.ts.net
IP100.80.53.25
Auth key预生成 member key,存于 .env 环境变量,不在脚本中硬编码

关键设计原则:

  • Auth key 只出现在 .env 中,任何启动脚本都通过 $TAILSCALE_AUTH_KEY 引用
  • State 文件持久化在 Docker volume (/opt/data/tailscale/),容器重启后无需重新认证
  • Watchdog 每 10 分钟静默检查 daemon 存活,挂了自动拉起

安装流程

  1. 下载最新版静态二进制

    curl -sL "https://pkgs.tailscale.com/stable/tailscale_$(VERSION)_$(ARCH).tgz" -o /tmp/tailscale.tgz
    tar -xzf /tmp/tailscale.tgz -C /tmp/

    VERSION 从 GitHub API 获取:curl -sL "https://api.github.com/repos/tailscale/tailscale/releases/latest" | grep -o '"tag_name": *"[^"]*"'。ARCH = arm64 / amd64 对应容器架构。

  2. 安装到用户路径

    mkdir -p ~/bin
    cp /tmp/tailscale_$(VERSION)_$(ARCH)/tailscale{,d} ~/bin/
    chmod +x ~/bin/tailscale ~/bin/tailscaled
  3. 存储 Auth Key

    写入 /opt/data/.env(不要在任何脚本中硬编码):

    # Tailscale auth key for Hermes tailnet join
    export TAILSCALE_AUTH_KEY="tskey-auth-..."
  4. 启动 daemon (userspace 模式)

    mkdir -p /opt/data/tailscale
    tailscaled \
      --tun=userspace-networking \
      --state=/opt/data/tailscale/tailscaled.state \
      --socket=/opt/data/tailscale/tailscaled.sock
  5. 认证加入

    source /opt/data/.env
    tailscale --socket=/opt/data/tailscale/tailscaled.sock up \
      --hostname=hermes-h02 \
      --authkey="$TAILSCALE_AUTH_KEY" \
      --ssh=false --accept-routes=false --accept-dns=false

文件分布

/opt/data/
├── .env                          ← TAILSCALE_AUTH_KEY (唯一存放位置)
├── home/bin/
│   ├── tailscale                 ← 二进制 (v1.98.8)
│   ├── tailscaled                ← 二进制 (v1.98.8)
│   ├── ts                        ← CLI 封装 (自动指向正确 socket)
│   ├── tailscale-start.sh        ← 一键启动/重启脚本
│   └── tailscale-watchdog.sh     ← 守护脚本 (cron 调用)
└── tailscale/
    ├── tailscaled.state          ← 持久化状态 (容器重启后保留)
    ├── tailscaled.sock           ← Unix socket
    └── tailscaled.log            ← daemon 日志

CLI 使用

命令用途
~/bin/ts status查看 tailnet 节点状态
~/bin/ts ip显示本机 tailnet IP
~/bin/ts ping <peer>测试到 peer 的连通性
~/bin/ts whois <ip>查看节点信息
~/bin/tailscale-start.sh重启整个 tailscale 服务

Watchdog 机制

通过 Hermes cron 系统创建,每 10 分钟运行一次:

cronjob action=create name=tailscale-watchdog no_agent=true schedule="every 10m" script=tailscale-watchdog.sh

Watchdog 检查:

  1. pgrep -f "tailscaled.*userspace-networking" — 进程是否存在
  2. tailscale --socket=... status — socket 是否正确响应

任一检查失败则自动调用 tailscale-start.sh 重启。静默模式 (no_agent=true),正常时不产生任何消息。

恢复指南

容器重启后 tailscale 未连上

  1. 检查 daemon 是否运行:ps aux | grep tailscaled
  2. 运行:~/bin/tailscale-start.sh
  3. 验证:~/bin/ts status

State 文件损坏或丢失

  1. 清理:rm -f /opt/data/tailscale/tailscaled.state*
  2. 确保 .env 中有有效 auth key
  3. 运行:~/bin/tailscale-start.sh

Auth key 过期

  1. 在 Tailscale admin console 生成新 key
  2. 更新 /opt/data/.env 中的 TAILSCALE_AUTH_KEY
  3. 同上清理 state + 重启

注意事项

  • TS_AUTHKEY 环境变量不被 tailscale up 支持 — 必须使用 --authkey 参数
  • Auth key 的隐私性--authkey 会在 ps aux 中短暂可见,但对 member key 是可接受的(一次性或短期有效)
  • userspace 模式的限制:不支持 MagicDNS 和 Tailscale SSH,但可以实现节点间直连和基于 tailnet IP 的通信
  • Docker 重启策略:watchdog 会处理 daemon 崩溃,但若整个容器重建且未挂载 state 文件,需手动重新认证

参考