在容器中使用飞网
1 飞网镜像仓库
拉取DockerHub中存储的飞网镜像: docker pull gmzta/gmzta:latest
拉取阿里云中存储的飞网镜像: docker pull registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
提示
飞网默认发布多架构镜像,容器程序将自动拉取匹配您系统架构的版本,目前内置的架构包括: linux/amd64
, linux/arm64
, linux/arm/v7
, linux/386
2 选择TUN模式或Gvisor模式
飞网支持TUN或Gvisor两种网络模式。
- TUN模式工作在系统空间,飞网将自动创建TUN设备(即虚拟网卡或虚拟网络接口),并利用TUN设备的编程接口接管和处理(如:加解密)IP数据报文。TUN模式需要容器具备相应的启动权限,该模式具备较高的处理性能,以及较好的程序兼容性。
- Gvisor模式工作在用户空间,通过接管飞网程序进程中的网络调用实现报文代理和转发,无需配置特殊的启动权限。此时处于相同网络命名空间(Network Namespace)中的服务端程序可以正常收发来自飞网网络的报文;但处于相同网络命名空间中的客户端程序仍然需要通过该网络命名空间收发报文,即默认不会进入飞网网络。如需在相同网络命名空间中的客户端程序通过飞网收发报文,则该客户端程序需要指定飞网程序作为其通信代理。
以下分别展示了普通模式、TUN模式和Gvisor模式下操作系统处理流量转发的流程示意图:
通过数据包报文结构分析,Gvisor模式采用传输层封装加密,TUN模式则采用网络层封装加密。
3 使用docker命令启动飞网
3.1 TUN模式启动
请参考此配置按需调整参数。
docker run -d \
--name=gmzta-docker \
-v /var/lib:/var/lib \
-v /dev/net/tun:/dev/net/tun \
--network=host \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
--env GM_TOKEN=gmzta-authkey-123-456789abcdef \
--env GM_Gvisor=false \
-v $(pwd)/gmzta/state:/var/lib/gmzta \
registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
3.2 Gvisor模式启动
docker run -d \
--name=gmzta-docker \
--hostname=gmzta \
--network=bridge \
--env GM_TOKEN=gmzta-authkey-123-456789abcdef \
--env GM_STATE_DIR=/var/lib/gmzta \
--env GM_GMZTAD_EXTRA_ARGS="--socks5=127.0.0.1:1080 --httpproxy=127.0.0.1:1080" \
-v $(pwd)/gmzta/state:/var/lib/gmzta \
--cap-add=NET_ADMIN \
registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
命令参数解释:
● --name=gmzta-docker
设置容器名称为gmztad,便于后续管理和操作。
● --network=host
使用主机网络模式,容器直接共享主机的网络栈,避免网络隔离带来的复杂性,适合需要高性能网络处理的场景。
● --network=bridge
容器通过网桥独立运行,有隔离,适合需要灵活通信和管理的应用。
● --cap-add=NET_ADMIN
授予容器网络管理权限,以便飞网程序能够配置和管理虚拟网络接口(TUN模式必需)。
● --cap-add=NET_RAW
授予容器处理原始网络数据包的权限,支持飞网对数据包的加解密和转发。
● --env GM_TOKEN=gmkey-auth-123-456789abcdef
设置环境变量GM_TOKEN(
详见授权密钥文档),用于节点身份验证。建议根据实际需求替换为真实的密钥值(例如gmkey-auth-123-456789abcdef),以确保节点安全接入飞网网络。
● --env GM_GMZTAD_EXTRA_ARGS="--socks5=127.0.0.1:1080 --httpproxy=127.0.0.1:1080"
设置环境变量GM_GMZTAD_EXTRA_ARGS,用于指定额外的gmztad参数。
● --env GM_STATE_DIR=/var/lib/gmzta
设置环境变量GM_STATE_DIR,用于指定飞网状态存储目录。
● -v $(pwd)/gmzta/state:/var/lib/gmzta
将主机上的gmzta/state目录挂载到容器内的/var/lib/gmzta目录,用于存储飞网状态数据,防止容器重启导致设备数据丢失。
● -v /var/lib:/var/lib
将主机的/var/lib目录挂载到容器内的同名目录,用于持久化存储飞网相关数据。
● -v /dev/net/tun:/dev/net/tun
将主机的/dev/net/tun设备挂载到容器内,使飞网能够以TUN模式创建虚拟网络接口。若容器环境不支持此设备,则需切换至Gvisor模式。
3.3 查看飞网设备
docker exec gmzta-docker gmzta info
命令参数解释:
docker exec [容器名] gmzta [子命令]
3.4 注意事项
● 持久性
建议将容器配置为使用持久性存储,例如通过 -v /var/lib/gmzta:/var/lib/gmzta 将 GM_STATE_DIR 设置为持久存储的挂载路径,并使用 -e GM_STATE_DIR=/var/lib/gmzta 指定环境变量。
● 权限与兼容性
在国内云环境中部署飞网时,需提前确认容器是否支持/dev/net/tun设备。若不支持,建议直接采用Gvisor模式以避免配置复杂性。
● 网络性能
TUN模式因直接与底层网络栈交互,延迟更低、吞吐量更高,适合独立服务器或虚拟机;Gvisor模式则因代理机制可能引入额外开销,适用于轻量级或受限环境。
● 安全性
使用GM_TOKEN进行身份验证时建议定期更新密钥并避免在公开环境中泄露。
● 为什么入站连接可以工作而出站连接不行? 为了支持任意使用 Linux 套接字的进程,gmztad 需要访问 /dev/net/tun 设备,而许多容器默认并不提供该设备。默认情况下,Dockerfile 以Gvisor模式运行,在这种模式下,隧道传入的入站连接会被转发到本地的相同端口,但发起新的出站连接则需要使用 SOCKS5 或 HTTP 代理。
要支持任意套接字应用的出站连接,需要以下条件:
容器必须提供一个 TUN 设备,例如通过参数 -v /dev/net/tun:/dev/net/tun。 GM_GVISOR 必须设置为 false,例如通过环境变量 -e GM_GVISOR=0。
4 飞网容器支持的环境变量
以下是一些常见的环境变量及其作用:
环境变量 | 说明 |
---|---|
GM_TOKEN | 设置 授权密钥。 |
GM_AUTH_ONCE | 仅在尚未登录且未配置 GM_TOKEN 时尝试登录。默认为 False ,即每次容器启动时都会强制重新登录。 |
GM_HOSTNAME | 指定节点的 主机名。 |
GM_DNS | 是否接受控制中心下发的全局 DNS 策略,默认不接受。 |
GM_DEST_IP | 将所有访问飞网容器的流量重定向到指定的IP,此变量用于权限更加严格的场景,如k8s中pod无法直接配置net.ipv4.ip_forward 等SYS_ADMIN权限,但又需开启子网网关功能。 |
GM_KUBE_SECRET | 在 Kubernetes 运行时,存储飞网状态的 Kubernetes 密钥名称,默认值为 gmzta 。 |
GM_SUBNETNODE | 开启子网网关功能。要接受其他设备的子网,请使用 GM_EXTRA_ARGS 传入 --subnet 参数。 |
GM_SOCKET | 指定 Gmzta 二进制文件使用的 Unix 套接字路径,gmztad 的 LocalAPI 套接字默认位于 /var/run/gmzta/gmztad.sock 。 |
GM_STATE_DIR | 存储 gmztad 状态的目录。此目录需要在容器重启时保持不变,否则设备会被识别为新设备。 |
GM_GVISOR | 启用 Gvisor 模式(默认启用),替代 TUN 模式。 |
GM_SOCKS5_SERVER | 开启SOCK5代理,指定SOCK5代理运行的IP地址和端口,格式如:localhost:1080. |
GM_OUTBOUND_HTTP_PROXY_LISTEN | 开启HTTP代理,指定HTTP代理运行的IP地址和端口,格式如:localhost:1080。 |
GM_EXTRA_ARGS | 传递额外的 gmzta set 命令行参数。 |
GM_GMZTAD_EXTRA_ARGS | 传递额外的 gmztad 命令行参数。 |
5 以docker compose启动飞网
请参考此配置按需调整参数。
使用vi 命令在当前目录创建compose.yaml文件,内容如下:
vi compose.yaml
5.1 TUN模式
---
version: "3.7"
services:
gmzta-docker:
image: registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
container_name: gmzta-docker # 设置容器名称为 gmzta-docker
hostname: gmzta-docker # 设置容器内的主机名为 gmzta-docker
environment:
- GM_TOKEN=gmzta-authkey-123-456789abcdef # 设置身份验证密钥,用于节点接入飞网网络
- GM_STATE_DIR=/var/lib/gmzta # 指定飞网状态数据的存储目录
- GM_Gvisor=false # 禁用用户空间模式(即启用 TUN 模式而非 Gvisor 模式)
volumes:
- ${PWD}/gmzta-docker/state:/var/lib/gmzta # 将当前目录下的 gmzta-docker/state 挂载到容器内的 /var/lib/gmzta,用于持久化存储
devices:
- /dev/net/tun:/dev/net/tun # 挂载主机的 /dev/net/tun 设备到容器,支持 TUN 模式的虚拟网络接口
cap_add:
- net_admin # 授予容器网络管理权限,用于配置 TUN 虚拟网络接口
restart: unless-stopped # 设置容器重启策略,除非手动停止,否则始终尝试重启
networks:
- default # 显式配置默认桥接网络,可省略
nginx-test:
image: nginx # 使用官方 nginx 镜像
network_mode: service:gmzta-docker # 使用 gmzta-docker 的网络栈,与其共享网络命名空间
networks:
default:
driver: bridge # 显式声明默认网络为桥接模式,可省略
5.2 Gvisor模式
---
version: "3.7"
services:
gmzta-docker:
image: registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
container_name: gmzta-docker # 设置容器名称为 gmzta-docker
hostname: gmzta-docker # 设置容器内的主机名为 gmzta-docker
environment:
- GM_TOKEN=gmzta-authkey-123-456789abcdef # 设置身份验证密钥,用于节点接入飞网网络
- GM_STATE_DIR=/var/lib/gmzta # 指定飞网状态数据的存储目录
- GM_GMZTAD_EXTRA_ARGS=--socks5=127.0.0.1:1080 --httpproxy=127.0.0.1:1080 # 配置 Gvisor 模式的代理参数,启用 SOCKS5 和 HTTP 代理
volumes:
- ${PWD}/gmzta-docker/state:/var/lib/gmzta # 将当前目录下的 gmzta-docker/state 挂载到容器内的 /var/lib/gmzta,用于持久化存储
cap_add:
- NET_ADMIN # 授予容器网络管理权限,尽管 Gvisor 模式不依赖 TUN,但可能用于其他网络配置
restart: unless-stopped # 设置容器重启策略,除非手动停止,否则始终尝试重启
networks:
- default # 显式配置默认桥接网络,可省略
nginx-test:
image: nginx # 使用官方 nginx 镜像
network_mode: service:gmzta-docker # 使用 gmzta-docker 的网络栈,与其共享网络命名空间,方便通过代理访问
environment:
- ALL_PROXY=socks5://127.0.0.1:1080 # 设置全局 SOCKS5 代理,指向 gmzta-docker 的代理服务
- HTTP_PROXY=http://127.0.0.1:1080 # 设置 HTTP 代理,适用于部分支持代理的工具
networks:
default:
driver: bridge # 显式声明默认网络为桥接模式,可省略
5.3 启动docker compose容器
docker compose up -d
以Nginx为例,大多数情况Nginx既作为服务端又作为客户端,如Nginx作为客户端时需要访问飞网资源,就需要配置Socks代理。