大多数人映像中的回环地址是 127.0.0.1
,其实可以去 lookip 127.0.0.11 查询当前地址的类型,发现这个 ip 也是属于回环地址,那究竟什么是回环地址。
我们要参考协议 rfc3330 定义,发现 127.0.0.0/8
整个网段都属于回环网段,在 windows 操作系统上可以起动一个 nginx listen 80 端口,发现通过 127.0.0.1 ~ 127.255.255.254 都可以访问到此网页。mac 系统不能监听除 127.0.0.1 之外的回环地址。
那么 docker 内部的 dns 服务为什么是 127.0.0.11
,可以是 127.0.0.1 吗。
进入容器内
$ dig @127.0.0.11 mysql
; <<>> DiG 9.16.33-Debian <<>> @127.0.0.11 mysql
; (1 server found)
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 9050
;; flags: qr rd ra; QUERY: 1, ANSWER: 1, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;mysql. IN A
;; ANSWER SECTION:
mysql. 600 IN A 172.26.0.4
;; Query time: 0 msec
;; SERVER: 127.0.0.11#53(127.0.0.11)
;; WHEN: Mon Dec 05 09:38:49 UTC 2022
;; MSG SIZE rcvd: 46
这里是有返回实际的 mysql 这个域的地址,如果尝试 127.0.0.1 ?
$ dig @127.0.0.1 mysql
; <<>> DiG 9.16.33-Debian <<>> @127.0.0.1 mysql
; (1 server found)
;; global options: +cmd
;; connection timed out; no servers could be reached
可以看到是无法访问此地址的,所有说一个服务是可以绑定在除 127.0.0.1 之外的回环地址上的。(mac 不支持)
func main(){
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run("127.0.0.11:8080")
}
这里可以看到我试图将当前的一个 http 服务绑定在 127.0.0.11 这个 ip 上,运行此程序,如果此时如下实验
$ curl 127.0.0.11:8080/ping
{"message":"pong"}
$ curl 127.0.0.1:8080/ping
curl: (7) Failed to connect to 127.0.0.1 port 8080: Connection refused
可以看除一旦绑定到对应的 ip 上,只能通过当前的回环 ip 访问,不能通过其他 ip 访问。
稍微调整一下程序
func main(){
r := gin.Default()
r.GET("/ping", func(c *gin.Context) {
c.JSON(200, gin.H{
"message": "pong",
})
})
r.Run(":8080")
}
应该可以猜测 127.0.0.1 和 127.0.0.11 都可以访问到此服务。
$ curl 127.0.0.11:8080/ping
{"message":"pong"}
$ curl 127.0.0.1:8080/ping
{"message":"pong"}
因为如果 listen 的时候不填写对应的 ip,那么默认监听的是 0.0.0.0 也就是当前的 host,那么通过任务回环地址都是可以访问到此服务。
小结
- 回环地址指的是一类地址
- docker 内部提供一个 127.0.0.11 的 dns 查询服务
- linux 可以绑定到任何一个回环地址上
- 通过任何回环地址都可以访问到主机上的服务
网友评论