13、《每天5分钟玩转Docker容器技术》学习--Single-host网络
------------------------------------重要说明------------------------------------本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!
原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:
https://blog.运维网.com/cloudman
------------------------------------重要说明------------------------------------
首先学习 Docker 提供的几种原生网络,以及如何创建自定义网络。然后探讨容器之间如何通信,以及容器与外界如何交互。
Docker 安装时会自动在 host 上创建三个网络,我们可用 docker network ls 命令查看:
https://s1.运维网.com/images/20180405/1522926956304011.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
1. none 网络
https://s1.运维网.com/images/20180412/1523512888630761.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
故名思议,none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。
https://s1.运维网.com/images/20180405/1522926966344107.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
不禁会问,这样一个封闭的网络有什么用呢?
其实还真有应用场景。封闭意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。
比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
当然大部分容器是需要网络的。
2. host 网络
https://s1.运维网.com/images/20180412/1523512902416377.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络。
https://s1.运维网.com/images/20180405/1522926977509419.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables.
3. Bridge网络
https://s1.运维网.com/images/20180412/1523512914425872.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
Docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上。
https://s1.运维网.com/images/20180405/1522926987719835.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
当前 docker0 上没有任何其他网络设备,我们创建一个容器看看有什么变化。
https://s1.运维网.com/images/20180405/1522926995203732.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927001397592.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927007891817.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927017839709.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
一个新的网络接口 vethc32bb37、vethd0d7fc5 被挂到了 docker0 上,vethc32bb37、vethd0d7fc5就是新创建容器的虚拟网卡。
下面看一下容器的网络配置。
https://s1.运维网.com/images/20180405/1522927029185695.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
容器有一个网卡 eth0@if10。这里不禁会产生疑问,问什么不是host主机中的docker0对应的虚拟网卡呢?
实际上 container的虚拟网卡 和 host主机的docker0中的虚拟网卡 是一对 veth pair。veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头在容器中,另一头挂在网桥 docker0 上,其效果就是将 container的虚拟网卡 也挂在了 docker0 上。
如果有多个container虚拟网卡,如何查看container中的虚拟网卡和host主机中的docker0中虚拟网卡的对应关系呢?
https://s1.运维网.com/images/20180405/1522927038244262.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
通过docker network inspect bridge
https://s1.运维网.com/images/20180405/1522927089371461.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
其中我们还可以看到,为什么我们虚拟机的IP地址是172.17.0.0网段。
https://s1.运维网.com/images/20180405/1522927099390012.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
这里定义了虚拟机中使用的网段,和网关;网关就是host主机中docker0的IP。
https://s1.运维网.com/images/20180405/1522927107457270.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
容器创建时,docker 会自动从 172.17.0.0/16 中分配一个 IP,这里 16 位的掩码保证有足够多的 IP 可以供容器使用。
4. Joined container网络(总结)
5. 如何自定义容器网络?
除了 none, host, bridge 这三个自动创建的网络,用户也可以根据业务需要创建 user-defined 网络。
Docker 提供三种 user-defined 网络驱动:bridge, overlay 和 macvlan。
https://s1.运维网.com/images/20180405/1522927143557295.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
查看当前 host 的网络结构变化:
https://s1.运维网.com/images/20180405/1522927150356407.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
查看当前docker的网络结构变化:
https://s1.运维网.com/images/20180405/1522927157665591.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
查看my_net信息:docker network inspect my_net
https://s1.运维网.com/images/20180405/1522927171886224.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
这里 172.18.0.0/16 是 Docker 自动分配的 IP 网段。
我们可以自己指定 IP 网段吗?
答案是:可以。
只需在创建网段时指定 --subnet 和 --gateway 参数
docker network create --driver bridge --subnet 172.22.16.0/24 --gateway 172.22.16.1 my_net2
https://s1.运维网.com/images/20180405/1522927190732276.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927197861653.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927205397865.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927218395199.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
创建了新的 bridge 网络 my_net2,网段为 172.22.16.0/24,网关为 172.22.16.1。与前面一样,网关在 my_net2 对应的网桥 br-0881a55af507 上:
https://s1.运维网.com/images/20180405/1522927227258026.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
容器要使用新的网络,需要在启动时通过 --network 指定
https://s1.运维网.com/images/20180405/1522927236963847.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
容器分配到的 IP 为 172.22.16.2。
到目前为止,容器的 IP 都是 docker 自动从 subnet 中分配,我们能否指定一个静态 IP 呢?
答案是:可以,通过--ip指定。
https://s1.运维网.com/images/20180405/1522927246941113.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
注:只有使用 --subnet 创建的网络才能指定静态 IP。
my_net 创建时没有指定 --subnet,如果指定静态 IP 报错如下:
https://s1.运维网.com/images/20180405/1522927258811169.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
6. 容器如何访问外部世界?
1.容器访问外部世界
2.外部世界访问容器
在我们当前的实验环境下,docker host 是可以访问外网的。
https://s1.运维网.com/images/20180405/1522927266849649.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
我们看一下容器是否也能访问外网呢?
https://s1.运维网.com/images/20180405/1522927278870138.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
https://s1.运维网.com/images/20180405/1522927283789754.png?x-oss-process=image/watermark,size_16,text_QDUxQ1RP5Y2a5a6i,color_FFFFFF,t_100,g_se,x_10,y_10,shadow_90,type_ZmFuZ3poZW5naGVpdGk=
可见,容器默认就能访问外网。
请注意:这里外网指的是容器网络以外的网络环境,并非特指 internet。
现象很简单,但更重要的:我们应该理解现象下的本质。
------------------------------------重要说明------------------------------------
本文内容都是参考Cloudman系列进行学习,是个人学习过程记录,与原版不同!
原版请参考cloudman《每天5分钟玩转Docker容器技术》Cloudman博客如下:
https://blog.运维网.com/cloudman
------------------------------------重要说明------------------------------------
书籍:
1.《每天5分钟玩转Kubernetes》
https://item.jd.com/26225745440.html
2.《每天5分钟玩转Docker容器技术》
https://item.jd.com/16936307278.html
3.《每天5分钟玩转OpenStack》
https://item.jd.com/12086376.html
https://i.imgsafe.org/68/68da21ce15.png
感谢楼主的分享!
页:
[1]