如何在任意端口Mock Docker容器的HTTP出站请求
我基于Docker开发了一个依赖其他服务的应用,测试阶段没法自动化验证容器的出站流量。这个服务接收请求完成计算后,需要把结果发送到另外两个外部服务。
测试时我会在本地启动Mock服务器,用来验证是否收到容器发送的结果。目前是通过docker-compose的extra_hosts配置做域名映射:
extra_hosts: - some-web-service.some-domain:127.0.0.1
因为用的是HTTP协议,现在只能把Mock服务部署在80端口?如果要启动多个Mock服务,或者80端口已经被占用,怎么把容器的出站流量重定向到比如1234端口?我想要实现类似下面的配置效果(但extra_hosts不支持这种写法):
extra_hosts: - some-web-service.some-domain:127.0.0.1:1234
方法1:用本地反向代理转发(推荐)
在本地搭个Nginx反向代理,把不同域名的请求转发到对应端口的Mock服务,extra_hosts保持原配置即可。
比如Nginx配置文件:
server { listen 80; server_name some-web-service.some-domain; location / { proxy_pass http://127.0.0.1:1234; proxy_set_header Host $host; # 保证Mock服务能拿到正确的请求域名 } } # 如果有第二个Mock服务,再加一个server块 server { listen 80; server_name another-service.some-domain; location / { proxy_pass http://127.0.0.1:5678; proxy_set_header Host $host; } }
启动Nginx后,容器请求some-web-service.some-domain时,流量会先到本地Nginx,再自动转发到1234端口的Mock服务,完全不用改容器里的代码或配置。
方法2:修改容器的iptables规则
通过iptables把容器发往目标IP的80端口流量,转发到本地的指定端口。注意容器内的127.0.0.1是容器自身,要改用Docker网关IP(通常是172.17.0.1,可以用docker inspect查看)。
docker-compose配置示例:
services: your-service: # 其他配置... extra_hosts: - some-web-service.some-domain:172.17.0.1 cap_add: - NET_ADMIN # 必须加这个权限才能修改iptables command: sh -c "iptables -t nat -A OUTPUT -d 172.17.0.1 -p tcp --dport 80 -j DNAT --to-destination 172.17.0.1:1234 && 你的服务启动命令"
这样容器里请求some-web-service.some-domain:80时,流量会被iptables重定向到本地1234端口的Mock服务。
方法3:用Docker host网络模式
直接让容器使用宿主机器的网络命名空间,这时容器内的127.0.0.1就是宿主的IP,你可以直接在服务配置里把目标地址改成http://some-web-service.some-domain:1234,不需要extra_hosts。
docker-compose配置:
services: your-service: # 其他配置... network_mode: host
缺点是容器会共享宿主的网络,隔离性差,只适合测试场景用。
内容的提问来源于stack exchange,提问作者waykiki

