在容器中使用飞网
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. 飞网容器支持的环境变量
以下是飞网容器支持的环境变量及其功能说明:
环境变量 | 说明 |
---|---|
GM_TOKEN | 用于配置 授权密钥。为空则使用交互式登录模式,该模式需在60秒内完成登录认证,否则容器将因超时关闭,您可以使用如下命令查看登录地址:docker logs -f [容器id] |
GM_AUTH_ONCE | 控制飞网的登录行为:只在容器第一次启动时认证(true),或是容器每次启动时都需要认证(false,默认)。 |
GM_HOSTNAME | 指定飞网节点的 主机名。 |
GM_DNS | 是否接受控制中心下发的全局 DNS 策略,默认不接受。 |
GM_DEST_IP | 将所有访问飞网容器的流量重定向到指定的IP,此变量用于无法直接配置net.ipv4.ip_forward的场景,如k8s中pod无法直接配置net.ipv4.ip_forward 等SYS_ADMIN权限,但又需将飞网流量转发至某固定IP。 |
GM_KUBE_SECRET | 在 Kubernetes 运行时,存储飞网配置文件的 Kubernetes 机密信息键名,默认值为 gmzta 。 |
GM_SUBNETNODE | 开启飞网子网网关功能。若需接受其他设备的子网配置,请使用 GM_EXTRA_ARGS 传入 subnet 参数。 |
GM_SOCKET | 指定 gmztad 二进制文件使用的 Unix 套接字路径,gmztad 的 LocalAPI 套接字默认位于 /var/run/gmzta/gmztad.sock 。 |
GM_CONFIG_DIR | 指定存储飞网客户端程序配置文件的目录,配置文件默认为仅内存中使用。此目录文件在容器启动时加载,将该文件映射至外部存储,可防止该设备被识别为新设备。 |
GM_TUN | 默认为Gvisor模式(即默认值 false ),启用TUN模式需将该值设置为true 。 |
GM_SOCKS5PROXY | 开启SOCK5代理,指定SOCK5代理运行的IP地址和端口,格式如:localhost:1080. |
GM_HTTPPROXY | 开启HTTP代理,指定HTTP代理运行的IP地址和端口,格式如:localhost:1080。 |
GM_GMZTA_EXTRA_ARGS | 传递额外的 gmzta set 命令行参数。 |
GM_GMZTAD_EXTRA_ARGS | 传递额外的 gmztad 命令行参数。 |
4. 使用docker命令启动飞网
4.1 TUN模式启动
请参考此配置按需调整参数。
docker run -d \
--name=gmzta-docker \
--hostname=gmzta \
--network=host \
--cap-add=NET_ADMIN \
--cap-add=NET_RAW \
--env GM_TOKEN=gmzta-authkey-123-456789abcdef \
--env GM_TUN=true \
--env GM_CONFIG_DIR=/var/lib/gmzta \
-v /var/lib/gmzta:/var/lib/gmzta \
-v /dev/net/tun:/dev/net/tun \
registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
4.2 Gvisor模式启动
docker run -d \
--name=gmzta-docker \
--hostname=gmzta \
--network=bridge \
--env GM_TOKEN=gmzta-authkey-123-456789abcdef \
--env GM_TUN=false \
--env GM_CONFIG_DIR=/var/lib/gmzta \
--env GM_HTTPPROXY="127.0.0.1:1080" \
-v /var/lib/gmzta:/var/lib/gmzta \
registry.cn-beijing.aliyuncs.com/gmzta/gmzta:latest
4.2 命令参数解释:
命令参数 | 说明 |
---|---|
--name=gmzta-docker | 设置容器名称,便于后续管理和操作。 |
--hostname=gmzta | 设置容器内部主机名,该容器第一次启动且未配置GM_HOSTNAME时,飞网会优先使用该名称作为节点名称,建议您设置唯一的名称用于区别不同的节点。 |
--network=host | 主机网络模式,该容器的网络栈不会与Docker主机隔离(容器共享主机的网络命名空间),并且容器不会获得自己的IP地址分配。 |
--network=bridge | 桥接网络模式(默认值),用于在同一主机上运行的容器之间通信的网络。 其他网络模式同理,不再举例。 |
--cap-add=NET_ADMIN | 授予容器网络管理权限,允许容器内的进程执行需要网络配置和管理的操作,例如修改网络接口(如启用/禁用接口),配置防火墙规则(如使用 iptables),设置路由表,调整网络相关的内核参数等。飞网容器启动TUN模式时该权限为必需,作用包括给Socket数据包添加SO_MARK标记,以便防火墙或路由规则能够识别和处理;监听 UDP 端口通信;使用NETLINK套接字(Linux 内核与用户空间通信的接口)调整路由表和 NAT 转发规则;访问/proc/net 和/proc/sys/net ,读取和修改网络配置。 |
--cap-add=NET_RAW | 授予容器创建和操作原始网络数据包的权限,例如:发送和接收自定义的网络数据包(不依赖标准协议栈),执行网络嗅探(如使用 tcpdump),实现某些低级网络协议(如 ICMP ping)。飞网容器启动TUN模式时该权限为必需,作用包括通过该权限访问/dev/tun 并进行原始网络包的读写与ioctl操作。 |
--cap-add=CAP_SYS_MODULE | 授予容器加载或卸载内核模块的权限。若飞网容器加载tun模块失败,可尝试添加此权限。` |
--env xxx | 配置容器启动的环境变量 |
-v /var/lib/gmzta:/var/lib/gmzta | 将主机上的/var/lib/gmzta 目录挂载到容器内的/var/lib/gmzta 目录,容器中该目录默认不包含飞网客户端程序的配置文件。同时配置环境变量GM_CONFIG_DIR=/var/lib/gmzta ,可防止容器重启导致设备数据丢失。该目录通常用于存储程序配置文件,日志文件,节点间共享的文件,证书文件等。 |
-v /dev/net/tun:/dev/net/tun | 将主机的/dev/net/tun设备挂载到容器内,使飞网能够以TUN模式创建虚拟网络接口。若容器环境不支持TUN设备挂载,则需切换至Gvisor模式。 |
关于飞网客户端程序权限的最佳实践
使用命令:getcap $(which gmztad)
查看程序当前权限
使用命令:sudo setcap cap_net_admin,cap_net_raw+ep $(which gmztad)
使用 Linux 的 capsh 或 setcap 对飞网客户端程序进行最小权限配置,减少潜在攻击面,提升安全性。
4.3 容器中执行飞网命令
docker exec [容器名] gmzta [子命令]
命令示例:docker exec gmzta-docker gmzta info
5. 使用docker compose启动飞网
下面内容以Nginx为例,介绍飞网容器的使用。通常Nginx既作为服务端对外提供服务,同时又作为客户端反向代理内部应用,因此选用Nginx来演示飞网容器的使用,其他程序可参照本文进行配置。
应用场景 | 网络模式 | 开启代理 | 容器是否暴露端口 | Nginx反向代理位置 | 验证方式(curl) |
---|---|---|---|---|---|
1.飞网节点A部署Nginx 2.Nginx反向代理内网业务系统 3.飞网节点B通过飞网节点A中的Nginx,远程访问该业务系统 点击查看该配置文件 | TUN | 否 | 不暴露端口 | 容器所在内网 | 设备B:curl http://100.x.y.A |
应用场景同上,配置文件不同 点击查看该配置文件 | GVISOR | 否 | 不暴露端口 | 容器所在内网 | 设备B:curl http://100.x.y.A |
1.飞网节点A部署业务系统 2.飞网节点A受ACL限制只能被飞网节点B访问 3.飞网节点B部署Nginx 4.飞网节点C通过飞网节点B访问飞网节点A中的业务系统 点击查看该配置文件 | TUN | 否 | 不暴露端口 | 飞网节点A | 设备C:curl http://100.x.y.B |
应用场景同上,配置文件不同 点击查看该配置文件 | GVISOR | 是 | 不暴露端口 | 飞网节点A | 设备C:curl http://100.x.y.B |
1.飞网节点A部署业务系统 2.飞网节点A受ACL限制只能被飞网节点B访问 3.飞网节点B部署Nginx 4.飞网节点B可以被外部网络访问(如:飞网节点B具有互联网IP地址) 5.外部网络或互联网用户通过飞网节点B访问飞网节点A的业务系统 点击查看该配置文件 | TUN | 否 | 外部网络,如:互联网 | 飞网节点A | 外部:curl http://1.2.3.4 |
应用场景同上,配置文件不同 点击查看该配置文件 | GVISOR | 是 | 外部网络,如:互联网 | 飞网节点A | 外部:curl http://1.2.3.4 |
6 制作集成飞网客户端程序的第三方容器镜像
通常,您不需要构建集成飞网客户端程序的容器镜像(例如构建Nginx+飞网的容器镜像),这会破坏容器进程的独立性,但在资源有限的场景中,您也可以集成飞网客户端程序构建自己的容器镜像。您可以参考以下链接进行配置。