写在前面
大家在本地环境进行联调或者运行一些服务的时候,是不是经常通过 ip:port
进行测试。有时候服务一多,经常性的需要记住很多 ip:port
信息。
本文将介绍如何通过自定义域名的方式去替换 ip:port
,减去我们的记忆负担,提升我们的开发体验。
方案一:修改本地 Hosts
文件 + Nginx Proxy
这里推荐一款工具,SwitchHosts(记忆中,之前的版本叫做 SwitchHosts!
),页面简洁,操作一目了然。
配置 Hosts 文件,只需要将域名的地址跟 IP 做映射即可。

测试
1 2 3 4 5 6 7 8 9
| ➜ ~ ping a.dev.io PING a.dev.io (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.098 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.086 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.093 ms ^C --- a.dev.io ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.086/0.101/0.118/0.012 ms
|
修改 Hosts 文件这种方式,如果我们在本机又部署了一个 b 服务,此时需要加一个 b.dev.io
,则需要额外新增一条记录,并不能做到泛域名解析(*.dev.io
)。如果要在本地支持泛域名解析,那么就只能通过方案二来实现了。
方案二:dnsmasq
原生的 dnsmasq 是不具备界面的,这里推荐一款带有 web 界面的 dnsmasq
,同时还支持「Hot Reload」机制。
我们通过 docker 快速启动一个 dnsmasq 服务,首先新建一个配置文件 dnsmasq.conf
,并将配置文件存放在 config 目录下。
1 2 3 4 5 6 7
| log-queries no-resolv server=8.8.8.8 server=114.114.114.114 strict-order
address=/dev.io/127.0.0.1
|
这里我们使用 jpillora/dnsmasq:latest
这个镜像,下面是编排文件:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| version: "3.8"
services: dns-server: image: jpillora/dnsmasq:latest ports: - "53:53/udp" - 8080:8080 environment: - HTTP_USER=root - HTTP_PASS=root volumes: - ./config/dnsmasq.conf:/etc/dnsmasq.conf restart: unless-stopped logging: driver: "json-file" options: max-size: "1m"
|
运行 docker-compose up
启动服务,访问管理界面 http://localhost:8080

测试(记得把方案一的 Hosts 记录重置一下😉)
1 2
| ➜ ~ ping a.dev.io ping: cannot resolve a.dev.io: Unknown host
|
哦豁,失败了,需要修改本机 DNS 配置,如图所示:

再次测试
1 2 3 4 5 6 7 8 9
| ➜ ~ ping a.dev.io PING a.dev.io (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.043 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.044 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.133 ms ^C --- a.dev.io ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.043/0.099/0.144/0.045 ms
|
此时,如果测试一下 b.dev.io
呢?
1 2 3 4 5 6 7 8 9
| ➜ ~ ping b.dev.io PING b.dev.io (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.052 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.143 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.142 ms ^C --- b.dev.io ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.052/0.112/0.143/0.043 ms
|
没错,天然支持泛域名解析,还记得我们上面的配置么?
1
| address=/dev.io/127.0.0.1
|
这里配置就意味着 *.dev.io
都会指向到 127.0.0.1
。
方案三:go-dnsmasq(2021.09.16 更新)
运行了一段时间方案二之后,发现我的 MBP 越来越卡,通过 docker stats 发现可能存在内存泄漏的问题。经过折腾群群主(苏洋)的建议,更换了另外一个 dns 镜像,可解决内存泄漏的问题,同时苏大还对该镜像进行了精简(镜像大小约2.7M)。
新增配置文件 config/hosts.conf
创建编排文件
1 2 3 4 5 6 7 8 9 10 11 12
| version: "3.8"
services: dns-server: image: soulteary/go-dnsmasq:test command: dnsmasq -l 0.0.0.0:53 -f /hosts.conf -p 1s -n 114.114.114.114:53 -n 8.8.8.8:53 ports: - "53:53/udp" - "53:53/tcp" volumes: - ./config/hosts.conf:/hosts.conf:rw restart: unless-stopped
|
运行 docker-compose up
启动服务,同时别忘了参考方案二,需要修改本机 DNS 配置。
测试一下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| ➜ ~ ping a.dev.io PING a.dev.io (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.049 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.084 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.162 ms ^C --- a.dev.io ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.049/0.098/0.162/0.047 ms ➜ ~ ping b.dev.io PING b.dev.io (127.0.0.1): 56 data bytes 64 bytes from 127.0.0.1: icmp_seq=0 ttl=64 time=0.061 ms 64 bytes from 127.0.0.1: icmp_seq=1 ttl=64 time=0.186 ms 64 bytes from 127.0.0.1: icmp_seq=2 ttl=64 time=0.125 ms ^C --- b.dev.io ping statistics --- 3 packets transmitted, 3 packets received, 0.0% packet loss round-trip min/avg/max/stddev = 0.061/0.124/0.186/0.051 ms
|
泛域名解析已经可以支持了。最重要的是,这个方案至少不会让我的电脑越用越卡。😁
如果想要知道 DNS 的解析日志,可以通过 docker-compose logs -f
查看,如果你不想通过命令行的方式查看,也可以通过配置 Dozzle
来查看容器的日志,具体使用方式可以参考苏大的博文:https://soulteary.com/2020/11/15/view-container-logs-in-realtime.html
小插曲
苏大当时未编译 arm 架构的镜像,因此我这边 clone 了源码,在本地的 m1 芯片的电脑上重新编译了一个本地镜像,所以小伙伴们可以看到上述编排文件的镜像 TAG 为 soulteary/go-dnsmasq:test
。
如果也有小伙伴是 m1 芯片想要体验该镜像的话,可以参考我的方案进行本地编译。
- 首先 clone 仓库地址,
git clone https://github.com/soulteary/go-dnsmasq.git
- 修改 Dockfile 内容,将 npx 注释一下,代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| FROM golang:1.16-alpine AS Builder WORKDIR /app COPY . . RUN go env -w GO111MODULE=on && \ go env -w GOPROXY=https://mirrors.aliyun.com/goproxy/,direct && \ go mod download ARG VERSION=1.1.0
RUN go build -o dnsmasq -ldflags "-w -s -X main.Version=${VERSION}" -tags="netgo" -trimpath cmd/dnsmasq/main.go
FROM scratch
COPY --from=Builder /app/dnsmasq /bin/dnsmasq ENV DNSMASQ_LISTEN=0.0.0.0:53 EXPOSE 53 53/udp CMD ["/bin/dnsmasq"]
|
- 打包本地镜像
docker build . -t soulteary/go-dnsmasq:test
另外,群主已经答应后面会更新 arm 架构的镜像啦,小伙伴们后面应该可以直接从官方的镜像仓库 soulteary/go-dnsmasq 拉取。
下一篇,我们来聊聊如果通过 Traefik 代理本地容器服务来提升本地的开发体验。
参考
- https://little-star.love/posts/f114e298/
- https://soulteary.com/2021/08/19/dns-for-local-development.html