欢迎光临
我们一直在努力

通过一次思维碰撞看清docker 网桥模型

本站教程收集整理的这篇文章主要介绍了通过一次思维碰撞看清docker 网桥模型,本站教程本站觉得挺不错的,现在分享给大家,也给大家做个参考。

原文:通过一次思维碰撞看清docker 网桥模型

背景

这几天在研究Kubernetes, 遇到一个有意思的nodejs镜像:luksa/kubia

# 不带端口映射启动容器
docker run -it -d luksa/kubia
# 连接到默认的Bridge网桥,容器IP是 172.17.0.2

之后,在宿主机使用容器IP和8080 端口可访问该容器nodejs服务

对此我有几个疑问,这几个疑问在我看来有点与我之前对docker 网络的认知相冲突。

Q1. 不是说如果容器没有端口映射,容器内外隔离吗,怎么在宿主机内使用容器IP还可以访问容器

Q2. 容器IP:80 访问不到容器内nodejs服务,容器IP:8080可以访问,这个8080从哪里来

头脑风暴

首先排除一些同事说法:这个容器是以host网络模型连到宿主机,所以可以在宿主机通过容器IP访问

  • All containers without a –network specified, are attached to the default bridge network.
  • In terms of Docker, a bridge network uses a software bridge which allows containers connected to the same bridge network to communicate, while providing isolation from containers which are not connected to that bridge network.

对于问题1,我有个误区:没有端口映射,容器内外网络隔离,宿主机是无法访问容器的。

宿主机也在这个网桥上,我们在宿主机使用容器IP访问容器,实际上是走的网桥网络,能直接寻址容器 (不需要映射 端口一说)。

?

Q3.那端口映射到底起什么作用呢??

网桥模型确保了网桥内容器可相互访问,但除此之外的网络(127.0.0.1/宿主机物理IP 这些均其他网络)均不能访问容器, 这也正是bridge网络隔离的效果。

  1. 绑定宿主机的回环地址127.0.0.1
 docker run -it  -d  -p 127.0.0.1:8080:8080 luksa/kubia

那么在宿主机内只能使用127.0.0.1:8080可访问容器

vps云服务器

  1. 绑定宿主机的物理地址 10.201.80.126
docker run -it  -d  -p 10.201.80.126:8080:8080 luksa/kubia

那么在宿主机内可使用物理IP10.201.80.126:8080访问容器,这样局域网机器就能访问到容器了

@H_801_107@

3. 不写IP,这样会绑定到0.0.0.0,也就是宿主机所有的网卡。

docker run -it  -d  -p 8080:8080 luksa/kubia

很显然,宿主机内回环地址和物理地址均可以访问该容器了。

再回到上面的Q2问题,通过容器IP:8080访问容器,8080是哪里来的?

8080是容器内nodejs进程的监听端口,我们在构建镜像时本就无所谓使用expose指令

The EXPOSE instruction does not actually publish the port. It functions as a type of documentation between the person who builds the image and the person who runs the container, about which ports arE intended to be published.

所以在docekr ps时候,并不会在PORTS列显示任何内容,但是通过容器IP可直接连通容器内进程监听端口。

为啥访问容器IP:8080 就可以访问容器内nodejs提供的服务?

这是因为容器镜像在构建的时候,一般在0.0.0.0地址上监听请求,这意味着程序在所有地址的8080端口上监听请求。

这样就延伸出一个有趣的现象,让我们进入容器内部:

 docker exec -it 3cc9f428fc25 bash
curl 127.0.0.1:8080
curl 127.0.0.2:8080
curl 127.0.1:8080
curl 172.17.0.2:8080
curl 172.17.2:8080

几个看起来错误的IP竟然也可以访问nodejs服务, 这正是nodejs在http://0.0.0.0:8080地址监听请求的结果。

# 截取自该镜像构建源码: https://github.com/luksa/kubia-qps/blob/master/kubia-qps/app.js
var www = http.createServer(handler);
www.listen(8080);

# nodejs: server.listen([port[, host[, BACklog]]][, callBACk]) api
If host is omitted, the server will accept connections on the unspecified IPv6 address (::) when IPv6 is available, or the unspecified IPv4 address (0.0.0.0) otherwise.

猜想,验证,源码支持,解答了我一开始的几个疑问,对容器Bridge的网络认知进一步加深。

总结输出

  1. bridge网桥内容器通过容器IP相互访问,外部网络隔离
  2. docker run -p 参数通过端口映射,让容器内外部网络(宿主机)可以访问容器
  3. 一般情况下,对外提供web服务的docker镜像会在0.0.0.0 地址上监听请求
  • https://en.wikipedia.org/wiki/0.0.0.0
  • https://github.com/luksa/kubia-qps/blob/master/kubia-qps/app.js
  • https://linuxize.com/post/check-listening-ports-linux/

本站总结

以上是本站教程为你收集整理的通过一次思维碰撞看清docker 网桥模型全部内容,希望文章能够帮你解决通过一次思维碰撞看清docker 网桥模型所遇到的程序开发问题。

如果觉得本站教程网站内容还不错,欢迎将本站教程推荐给好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您有任何意见或建议可联系处理。

赞(0)
【声明】:本博客不参与任何交易,也非中介,仅记录个人感兴趣的主机测评结果和优惠活动,内容均不作直接、间接、法定、约定的保证。访问本博客请务必遵守有关互联网的相关法律、规定与规则。一旦您访问本博客,即表示您已经知晓并接受了此声明通告。