《菜农升职记》之 Docker网络

简介: 本文主要介绍 docker 网络

刚结束完一个需求的小菜农刚想打开公众号《菜农曰》看看博客划划水,叮叮又响了!

“小菜农,这个测试环境的服务器连接信息,你登上去通过docker部署下你刚刚提交的分支测试下哈!”


导师程立给小菜农发来了消息


"docker是个啥玩意?之前不都是直接在服务器找个目录上传然后 nohup java -jar ... & 一套组合拳下来吗?"


小菜农顿时又自闭了,自从来到了职场真是处处碰壁!想想在学校还是三好学生真是唏嘘不已!


“等等!我记得公众号《菜农曰》写了一篇关于 docker 的,赶紧翻出来看看”


Docker上手,看完觉得自己又行了!


许久之后,小菜农方从文章中回过神来,“这下不得拿捏了!”。他打开服务器输入 docker ps 试了下指令


网络异常,图片无法展示
|


“有点意思啊!”他按照文章中的教程开始部署自己的应用项目。先是编写了自己应用的 dockerfile,然后通过 docker build 构建出自己的镜像,最后执行 docker run来运行自己的镜像,一整套下来一气呵成,行云流水!然后便在浏览器测试了下自己的功能内容,测试通过后。小菜农便陷入了思考,docker 是一个容器,可以内嵌一个操作系统,每个容器之间是相互隔离的,那为啥我可以从外界访问容器内的内容?容器之间是如何通信的?又怎么创建自定义网络?


几个问题想的小菜农头都大了!放弃是不可能放弃的,没准这以后可以成为自己升职加薪,走上人生巅峰的垫脚石之一呢!从这里可以看出小菜农还是很有斗志的嘛~


docker 容器在安装的时候会自动在 host 上创建三个网络,小菜农看到了这句话,那要怎么查看这三个网络了,通过help指令看看会不会有所发现?他快速地在终端敲入docker --help


网络异常,图片无法展示
|


“哦豁,果然有!network 不就是我想要的吗!”。机智的小菜农开始顺藤摸瓜,继而敲入docker network --help


网络异常,图片无法展示
|


“  ls 可以查看docker 的网络,那我来试试”


网络异常,图片无法展示
|


终端上正如小菜农所料,出现了他想要看的内容。“bridge、host、none?” 小菜农还是有些网络基础的,前两个看名称都有点熟悉,但是 none 是个啥玩意?什么都没有的网络吗?。小菜农通过一番查询,没想到还真是,不由得佩服命名的开发者,这可真让人顾名思义~ 查询发现,挂在这个网络下的容器除了 lo,没有任何网卡


网络异常,图片无法展示
|


我们启动容器是通过 docker run来执行的,这个指令后面我们可以附加参数,通过 --network = none就可以指定该容器是使用 none 网络~


“那么这样一个封闭的网络有啥用,都上不了网”,小菜农嘀咕道


没错,就是要上不了网,有些特殊的应用场景需要将网络封闭起来,往往这种场景意味着安全性要求很高,因此需要进行隔离,这种情况就可以放到 none 网络防止被人侵入。


“既然是特殊场景才需要,那我目前应该还接触不到特殊场景,pass pass!让我康康 host 是什么网络”


小菜农知道了可以通过 --network指定网络类型,他试着启动了一个网络类型为host 的nginx来查看


网络异常,图片无法展示
|


小菜农看到这个网络配置不禁陷入了沉思,这怎么似曾相似?他将终端命令行往上滚了几页,终于发现为啥眼熟了!


网络异常,图片无法展示
|


原来他在上面的时候曾经输入 ip l 查看了宿主机的网络,你可以发现这两个配置是一模一样的!那就说明连接到 host  网络的容器共享 Docker host 的网络栈,容器的网络配置与宿主机的配置完全一样。那这样子的话直接使用 Docker host 网络的最大好处就是性能了。如果容器对网络传输效率有较高要求的时候,就可以使用 host 网络,也相当于是使用宿主机的网络,那么这样做的缺陷是什么?那就是端口会冲突,在宿主机上已经使用的网络,容器就不能再使用了!


小菜农觉得应该没那么简单,又查了下 host 网络的使用场景,不一会就有所发现了,使用 host 网络的另一个用途就是可以让容器直接配置 host 网络,比如某些需要跨 host 的网络解决方案,其本身也是以容器的方式运行的,这些方案需要对网络进行配置,比如管理 iptables 之类的场景。


“真是丈母娘看郎,越看越爱~ ”小菜农已经有点迷上了docker,越深入才发现越有意思。“还剩下 bridge 网络类型,让我康康!”


bridge 是一种桥接模式的网络,桥接顾名思义就是一端在这里另一端在那里。小菜农又大胆猜测了,那肯定就是一端在容器上,一端在宿主机上!接下来便进行了验证

小菜农想起了一个命令 brctl,该命令brctl 可用于设置、维护和检查linux内核中的以太网网桥配置。


无法使用 brctl 命令的童鞋可以使用以下命令安装


yum install -y bridge-utils


网络异常,图片无法展示
|


他通过brctl show查看宿主机的网桥配置,发现有个命为 docker0 的网桥,然后他通过启动一个容器继续观察网桥变化:


网络异常,图片无法展示
|


小菜农发现 interface 的内容发生了变化!有一个新的网络接口 veth9b75794 挂在了 docker 0 上,而 veth9b75794 就是刚刚创建容器的网卡,小菜农紧接着查看了下刚创建容器的网络配置


网络异常,图片无法展示
|


容器中有个一个 eth0@if67 网卡,小菜农会心一笑


“嘿嘿,被我发现了吧,要不是我会点网络,还真被这忽悠住了。刚刚上面查看到的网络接口是 veth9b75794,而这里是 eth0@if67,换成刚接粗网络的童鞋肯定一头雾水,这两个怎么不一样!实际上 eth0@if67veth9b75794 是一对 veth pairveth pair 是一种成对出现的特殊网络配置,而这就是我上面猜测的那样,网桥就是可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if67)在容器中,另一头(veth9b75794)挂在网桥docker0上,其效果就是将eth0@if67也挂在了docker0上


172.17.0.2/16 这个 IP 也就是宿主机配置的,小菜农查看了下docker 的bridge配置


网络异常,图片无法展示
|


发现有个bridge网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1。那么这个网关就是 docker 0!小菜农在宿主机输入 ifconfig' 进行验证


网络异常,图片无法展示
|


而这时,小菜农的脑子里浮现了一张图


网络异常,图片无法展示
|


到这里,小菜农已经熟悉了 docker 的三种网络类型的情况,便开始思考如何可以自定义网络,肯定存在很多场景用户需要根据业务来创建自定义网络来满足需求。在上面小菜农想要查询docker的网络配置时有输入过命令 docker network --help,输出结果的时候小菜农有点印象其中好像有个 create 的命令,赶紧又输入一遍进行确认:


网络异常,图片无法展示
|


果然,docker 已经支持用户创建自定义网络。很快呀!小菜农便在终端输入了创建网络的命令:


网络异常,图片无法展示
|


眼尖的小菜农一眼就发现了不对劲,创建网络的时候并没有指定 DRIVER 呀!而这个时候创建出来的网络驱动默认就是 bridge,那就说明是否还可以创建其他网络驱动的网络?小菜农再一次进行了尝试,但这次结果确认小菜农碰壁了


网络异常,图片无法展示
|


“难道只能创建 bridge 驱动类型的网络吗?” 小菜农嘀咕。依旧不死心便上了某搜索引擎进行结果查找。查找后发现原来Docker提供了三种 user-defined 的网络驱动,分别是 bridgeoverlaymacvlanoverlaymacvlan用于创建跨主机的网络!


“跨主机?那就是集群咯!目前导师分配给我的服务器只有一台,看来没法验证了,只能等后续权限大点再验证了,嘿嘿!”,既然无法验证其他两种,那就先将 bridge 搞明白~ 小菜农坏笑了起来!


上面已经创建了一个bridge驱动类型的网络,那宿主机的网络配置应该发生了变化,小菜农输入了 brctl show 进行查看:


网络异常,图片无法展示
|


果然这个时候多了一个名为 br-76c202387b0c 的网桥,通过ifconfig可以发现网段也已经分配了一个:


网络异常,图片无法展示
|


而这个应该就是新网络的网关了~ 小菜农真是越来越熟练起来,看来学习真能使人自信!


网络异常,图片无法展示
|


一切都如小菜农所料,172.18.0.1 就是 Docker 自动分配的 IP 网段


“但是如果自定义的网络多了起来,分配的网段肯定也是随之增加,那由 docker 分配的网段肯定是随机,不方便记忆,能不能自己指定 IP 网段”,小菜农突发奇想,输入 docker network create --help 会不会有所发现?


网络异常,图片无法展示
|


看到这结果,小菜农忍不住笑了起来,真有我的!这 subnetgateway 不就是我想要的吗!~


网络异常,图片无法展示
|


这不就成了吗!而且宿主机上也有了新的网络,网段为 172.10.0.0/16,网关为 172.10.0.1


网络异常,图片无法展示
|


既然创建了自己的网络,小菜农顿时成就感满满,这不得赶紧启动一个容器来试试自己的网络!


网络异常,图片无法展示
|


可以看到使用自己配置网络启动的容器,分配到的 IP 地址是 172.10.0.2/16,“既然容器的 IP 都是docker 自动从 subnet中分配的,那我能不能指定一个静态IP呢?”小菜农又提出了疑问,那么只能再祭出老套路 --help 进行解决了!小菜农手脚麻利的敲下 docker run --help | grep 'ip' 查看结果


网络异常,图片无法展示
|


小菜农笑容逐渐变态,没想到自己掌握了 help 神器!看来可以通过 --ip xxx来指定自己想要的IP,敲命令的手法逐渐娴熟起来,这不,一会功夫结果就出来了:


网络异常,图片无法展示
|


到目前为止,小菜农已经启动了三个容器


网络异常,图片无法展示
|


而网络之间的拓扑关系也忽然而出,小菜农连忙动手画了起来,以免忘记!


网络异常,图片无法展示
|


小菜农看着图发呆了一会,这图其实已经挺清晰了,nginx-customnginx-ip 之间肯定能够互相连通,小菜农验证一下猜想


网络异常,图片无法展示
|


结果是对的,那 nginx-default 是否能和其他两个容器相通呢?验证一下就知道了!


网络异常,图片无法展示
|


由此可见同一网络中的容器、网关之间是相通的,而属于不同网桥之间的容器是不能互相通信的。难道这样子就结束了吗?两个不同网络之间的容器难道真的不能相通了?小菜农不甘心就这样放弃,盯着屏幕一阵发呆,“有了!加个路由的话,那么两个网络之间应该就能通信了吧!” 如果 host 上对每个网络都只有一条路由,同时操作系统上开启了 ip forwarding,那么 host 就会形成一个路由器,挂接在不同网桥上的网络就能够通信!


小菜农通过ip r 查看宿主机上的路由表


网络异常,图片无法展示
|


可以看到 172.17.0.0/16172.10.0.0/16 两个路由都已经定义好了,下一步就需要看下 ip forwarding 是否已经开启,小菜农快速的敲下指令 sysctl

net.ipv4.ip_forward


网络异常,图片无法展示
|


可以看到 ip forwarding 也已经开启了。那这个时候只需要为 nginx-default 容器添加一块 c-custom的网卡就可以通信了!万事俱备,只欠东风~


小菜农依旧通过熟悉的配方查看添加网卡的步骤


网络异常,图片无法展示
|


了解之后便开始动手操作


网络异常,图片无法展示
|

“nice,没有出错,这下应该可以通信了吧!” 小菜农嘀嘀咕咕,紧张的手颤抖的心继续敲下 ping 命令进行验证


网络异常,图片无法展示
|


瞪大了眼,第一次这么有成就感,没想到真的被自己折腾出来了!小菜农激动的差点站了起来,恨不得大声笑出来,但他知道,这只是自己成长的第一步,自己已经成功的跨出去了!平复下了激动的心,得出一个自己刚刚实验出的结论


两个容器要能通信,就必须要有属于同一个网络的网卡,当满足这一条件后,容器就可以通过 ip 进行交互了


结论来之不易,小菜农赶紧在自己的小本本上记录下来!尝到甜头的小菜农继续在网上进行搜索,看是否存在其他可以在容器间通信的方式,毕竟用 IP 进行通信还是属于比较基础的~ 很快,小菜农便找到了答案,有的! 容器间可以通过是那种方式进行通信


  • IP


  • Docker DNS Server


  • joined


IP 通信自己已经实验过了,接下来就要尝试其他两种方式。Docker DNS Server ?看解释是通过 容器名的方式,在上面创建的容器,小菜农都已经指定了容器名,接下来只要进行实验就行了


网络异常,图片无法展示
|


果然是可以的!可以通过容器名进行访问,那就意味这可以不用记忆那么长一串的 IP 了!


前两种方式都已经实验过了,看到 joined 小菜农又有点懵了,加入 ? 小菜农继续往下看了解释


joined 容器是另一种实现容器间通信的方式


joined 容器非常特别,它可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined 容器之间可以通过 127.0.0.1 直接通信


“还真神奇,docker中处处充满了惊喜呀!”,小菜农随后便进行了尝试


网络异常,图片无法展示
|


这边值得注意的是,两个容器共享同一个网络栈,那么端口就不能冲突,因此启动的时候需要分离端口


到这里,小菜农不由得心满意足了,刚要退出服务器开始继续工作,却被自己的网页吸引过去了,网页上开着正是小菜农刚刚启动的docker项目。“咦,外界是怎么与容器进行连接的?” 小菜农再次提出了疑问,容器如何访问外界?外界又如何访问容器? 看来还是得继续学习(划水)呀!


小菜农再次切换到服务器页面,尝试从容器内进行访问外界


网络异常,图片无法展示
|


其实不用尝试,小菜农也清楚,容器肯定能访问到外界,不然外部接口如何调用~ 但是为什么能访问到呢?小菜农查看了宿主机的 iptables 规则


网络异常,图片无法展示
|


可以看到有这么两条规则,一条是 docker 0,一条是小菜农刚刚自定义的,那它是什么意思呢?小菜农又犯迷糊了,看了旁边的肖老大,这不有现成的大佬可以问吗!肖老大有些好奇,小菜农这是接到啥需求了,怎么会问到这个问题,不过也没多想,新人总要照顾好的不是!便开始巴拉巴拉解释起来,小菜农也听得云里雾里,“这样说明白了吗?”。“啊?哦!差不多知道这个意思了,嘿嘿,谢谢肖老大”,“不客气不客气,下次遇到不会记得还来找我哈”,肖老大略微粗犷的嗓门,让小菜农倍感温馨!总结了下肖老大的解释:如果网桥 docker 0 接收到来自 172.17.0.0/16 网段的外出包,就会把它交给 MASQUERADE 处理,而 MASQUERADE 的处理方式就是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换 NAT。


既然如此,那么通过抓包应该就可以看清楚网络地址转化的过程,小菜农打算使用 tcpdump 来做一次简易抓包查看下结果,首先他起了两个终端,一个终端通过 ping www.baidu.com 来发送网络包,一个包通过 tcpdump -i docker0 -n icmp 抓取网络信息


网络异常,图片无法展示
|


网络异常,图片无法展示
|


172.17.0.2nginx-default 容器的 IP,通过转包可以发现该 IP 地址是往 180.101.49.11 发送数据包,到这里小菜农完成了第一步,接受继续通过 tcpdump -i eth0 -n icmp 查看宿主机的网络流出信息


网络异常,图片无法展示
|


“啊哈!果然变了,这个时候ping包的原地址,变成了 ehp0 的 IP 172.26.19.234


网络异常,图片无法展示
|


弄清楚了 容器内部访问外界 后,那么接下来就是搞清楚 外界如果访问容器


小菜农记得刚刚自己启动容器后,在 PORTS 那里有显示端口,便在浏览器试了下就可以顺利访问了!小菜农又起了一个容器进行实验


网络异常,图片无法展示
|


启动容器后,便可以利用 32771 这个端口号进行访问,而32771这个端口是宿主机自动分配的,小菜农又试了下自己指定端口访问


网络异常,图片无法展示
|


指定端口后,通过自己指定的端口也是可以访问的,而这其中的缘由,小菜农也通过查询发现是通过 docker-proxy 实现的


网络异常,图片无法展示
|


每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量。


到这里,小菜农就搞懂了 Docker 中的网络使用,但是小菜农眉头一皱,今天玩的都是单机,那么在集群中网络又是如何访问呢?


目录
相关文章
|
30天前
|
Docker 容器
docker swarm启动服务并连接到网络
【10月更文挑战第16天】
27 5
|
30天前
|
调度 Docker 容器
docker swarm创建覆盖网络
【10月更文挑战第16天】
19 5
|
1月前
|
负载均衡 网络协议 关系型数据库
docker swarm 使用网络启动服务
【10月更文挑战第15天】
27 4
|
1月前
|
应用服务中间件 nginx Docker
docker swarm创建覆盖网络
【10月更文挑战第14天】
19 3
|
1月前
|
数据安全/隐私保护 Docker 容器
docker swarm创建网络
【10月更文挑战第15天】
20 1
|
1月前
|
Docker 容器
docker swarm 在服务中使用网络
【10月更文挑战第14天】
22 2
|
15天前
|
Docker 容器
【赵渝强老师】Docker的None网络模式
Docker容器在网络方面实现了逻辑隔离,提供了四种网络模式:bridge、container、host和none。其中,none模式下容器具有独立的网络命名空间,但不包含任何网络配置,仅能通过Local Loopback网卡(localhost或127.0.0.1)进行通信。适用于不希望容器接收任何网络流量或运行无需网络连接的特殊服务。
|
15天前
|
Docker 容器
【赵渝强老师】Docker的Host网络模式
Docker容器在网络环境中是隔离的,可通过配置不同网络模式(如bridge、container、host和none)实现容器间或与宿主机的网络通信。其中,host模式使容器与宿主机共享同一网络命名空间,提高性能但牺牲了网络隔离性。
|
15天前
|
Kubernetes Docker 容器
【赵渝强老师】Docker的Container网络模式
Docker容器在网络环境中彼此隔离,但可通过配置不同网络模式实现容器间通信。其中,container模式使容器共享同一网络命名空间,通过localhost或127.0.0.1互相访问,提高传输效率。本文介绍了container模式的特点及具体示例。
|
15天前
|
Linux Docker 容器
【赵渝强老师】Docker的Bridge网络模式
本文介绍了Docker容器的网络隔离机制及其四种网络模式:bridge、container、host和none。重点讲解了默认的bridge模式,通过示例演示了如何创建自定义bridge网络并配置容器的网络信息。文中还附有相关图片和视频讲解,帮助读者更好地理解Docker网络的配置和使用方法。
下一篇
无影云桌面