Veil:让容器流量自动走代理
之前在服务器上跑容器,有些容器需要走代理才能联网。一开始我每个容器里都装代理客户端,配环境变量、映射端口,几台机器下来就烦了。后来一想,与其每个容器单独折腾,不如直接建一个共享的代理网络,容器加进来就自动走代理,不用改任何配置。项目开源在 github.com/therainisme/veil
怎么做到的
两个容器:veil-net 跑 Mihomo(开了 TUN 模式),veil-box 是干活的环境。关键就一行配置:
network_mode: "service:veil-net"
这让 veil-box 共享 veil-net 的网络栈,所有流量都经过 Mihomo 的 TUN 虚拟网卡,DNS 也被 Mihomo 劫持到 127.0.0.1:53 处理。容器里的程序完全不知道代理的存在,该联网联网,该解析域名解析域名。
选 TUN 主要是图省事。HTTP/SOCKS 代理得每个应用手动配,很多命令行工具还不支持;Redir 模式只能代理 TCP,DNS 查询这种 UDP 流量管不了。TUN 在内核层面截获所有流量,TCP、UDP、ICMP 全都拿下,真正意义上透明。
用法
cp veil.yml.example veil.yml
# 编辑 veil.yml,填上你的代理服务器信息
vim veil.yml
docker compose up -d
docker exec -it -u veil veil-box bash
进容器后直接 curl google.com 试试,不需要设 http_proxy,也不需要改任何应用配置。
veil.yml.example 模板已经在仓库里了,DNS 配置和分流规则都写好了,开箱即用。
两个版本
- veil-box:日常开发环境,装了 git、vim、python3、build-essential 这些常用工具
- veil-actions-runner:在 veil-box 基础上加了 Docker CE,用来跑需要代理的 CI/CD 流水线
对应的 compose 文件分别是 docker-compose.yml 和 docker-compose.yml.actions-runner。
让自己的容器也走代理
不限于 veil-box,任何容器都能接入这个代理网络:
services:
veil-net:
# ... 不变
my-app:
image: my-app:latest
network_mode: "service:veil-net"
depends_on:
- veil-net
几个注意点
veil-net 需要 /dev/net/tun 和 NET_ADMIN/NET_RAW 权限。 TUN 模式要在内核创建虚拟网卡,没有这些权限跑不起来。docker-compose.yml 里已经写好了:
cap_add:
- NET_ADMIN
- NET_RAW
devices:
- /dev/net/tun:/dev/net/tun
veil-box 跑了 systemd,所以开了 privileged。 如果你觉得没必要,可以只跑 veil-net,然后把自己的容器用 network_mode: "service:veil-net" 接进来就行,veil-box 本身不是必须的。
该直连的流量走了代理? 检查 veil.yml 的 rules 部分,确保有这两条直连规则:GEOSITE,CN,DIRECT 和 GEOIP,CN,DIRECT,no-resolve。同时 geodata-mode 和 geo-auto-update 都要是 true。
更新代理配置后只需要重启代理容器:
docker compose restart veil-net
更新镜像:
docker compose pull
docker compose up -d