docker使用的是linux桥接,在宿主机中虚拟一个docker容器网桥,默认是docker0网络,docker启动一个容器的时候,会根据docker网桥的网段给容器分配IP地址,折冲方式称为container-IP,同时docker网桥是每个容器的默认网关。因为在同一宿主机内的容器都默认接入同一个网桥内。容器与容器之间的对接也是通过网桥的veth对进行通信。
网桥是可以再次创建的,可以进行指定
docker网桥是宿主机虚拟出来的,并不是真实存在的网络设备,外部网络是无法寻址到的,这也就意味着外部网络无法通过container-IP访问到容器中。如果需要容器能被外部网络进行访问,可以通过将容器的端口映射到宿主机中,也就是在创建容器的时候,输入-p或者-P来选择暴露端口号,这样外部网络就可以通过宿主机来访问这个被映射出去的端口,进入到容器内部
docker网络模式 | 模式简介 |
---|---|
host | 容器和宿主机共享内核,即使用同一个网络 |
bridge | bridge模式是docker中默认使用的网络模式,就是上面介绍的网桥模式 |
none | 密封式的网络,没有进行任何的网络配置,容器与容器之间都是隔离开的 |
container | 一个容器的网络被多个容器所共享,也就是多个容器使用一个容器的网络 |
在此模式下,容器将不会虚拟出来自己的网卡、IP等信息,而是使用宿主机的IP和端口信息,如果在启动容器的时候,使用的是host模式,name这个容器将不会获得一个独立的networknamespace,而是和宿主机共用一个networknamespace。
此模式下,容器只有内核空间是共享的,但是文件系统、今晨等还是和宿主机之间隔离开的
使用host模式的容器是可以直接使用宿主机的IP地址外网通信的,容器内部的服务端口号也可以使用宿主机的端口,不需要自身再进行配置NAT
host模式最大的又是就是网络性能较好,但是dockerhost上面已经使用过的端口号,就不能再次使用,网络的隔离性不好
host模式的优点:解决了IP地址不固定的情况
bridge模式就是上面说的网桥模式,此模式是创建容器的时候默认使用的一种模式,docker中会默认创建有一个docker0的虚拟网桥,通过虚拟网桥以及IPtables net表进行配置与宿主机之间的关联
当docker进程启动的时候,会在主机上创建一个名为docker0的虚拟网桥,在此主机上启动的docker容器会默认连接到这个虚拟网桥上。
简单来说,网桥模式就是提供一个平台,在不更换这个平台的情况下,进行将多个容器连接在一起,通过这个平台进行实现与外网的交互以及容器与容器之间的交互。而且,如果有其他的网桥的话,也是可以借助宿主机网卡的转换,来实现跨网桥交互。
bridge优点:借助iptables net表规则,来实现给容器自动分配IP地址、网络连接等方面
这么模式没什么好说的,就是一个密封的容器模式,在创建之后,除非是通过宿主机,强行以挂载等方式访问,否则,该模式下,容器在创建之后,是一个完全的密封状态,虽然拥有自己的network namespace 但是并没有任何网络配置。也就是这个模式的容器没有网卡、IP、路由等信息。所以并不能与其他网络进行交互。需要我们人为的手动创建网络,才能实现与其他网络之间的通讯
none的优点:在一些应急场合下,这种模式的容器,可以作为一个个独立的小仓库,存储一些资源。在需要的时候,对容器进行打开一个小接口访问容器进行交互。一般都是作为本地的一种存储方式。
该模式,与host类似,但是不是与宿主机进行共享IP地址等信息。而是一个容器群中,只有一个容器提供IP信息,容器群中的其他容器都共享这个提供者的IP信息,使用这个容器的IP信息来实现与外网的通信交互。而且这种方式与host模式一样,只共享网络方面的信息。比如文件系统等这些其他信息,都还是正常隔离的。
两个容器的进程可以通过网卡设备通信
docker network ls NETWORK ID NAME DRIVER SCOPE 19863407e148 bridge bridge local 1aed4a7df0d1 host host local 9999064ae519 lnmp bridge local 上面可以看到我现在的网络模式信息,前两个都是默认创建的,第三个是我自己创建的一个网络,创建的也是一个网桥模式
docker network create test #创建一个名称为test的网络,默认是网桥模式 e1b000d5288db1b86c7c5b4c0c5d5dd590895e463cf14a385413be38d6b263ff #这是创建成功后的这个网络模式的ID docker network ls e1b000d5288d test bridge local
docker run -itd --name test --net test nginx:1.12 /bin/bash #955c2466a3ef06321b2b8a4c420dba6d928e679b0d355758b2deb9481baf9d87 #查看创建情况 docker ps -a #显示如下信息 955c2466a3ef nginx:1.12 "/bin/bash" 28 seconds ago Up 27 seconds 80/tcp test
docker inspect test | grep IPAddress #显示如下信息 "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "172.20.0.2",
bridge模式,默认是创建的172.17.0.0网段,每次自己创建的时候都会往后推,这是我创建的第三个网桥,以此类推,172.18.0.0与172.19.0.0我已经创建过了,这次则是顺延到了172.2.0.0。那么如果不想使用这种顺延的网桥的网址的话,可以自己进行指定网桥网段
docker network create --subnet=177.16.0.0/16 test1 #--subnet=****,可以指定想要的网段信息
创建完成之后,再创建一个容器查看一下信息
docker run -itd --name test1 --net test1 --ip 177.16.123.21 -p 8808:80 nginx:1.12 /bin/bash #指定IP地址为177.16.123.21 ,暴露的端口为8808
docker inspect test1 | grep IPAddress #内容如下 "SecondaryIPAddresses": null, "IPAddress": "", "IPAddress": "177.16.123.21", #可以看到,该网址就是我们之前配置的信息
暴露端口的方式,上面自定义网桥网段的时候已经展示过了,这里就说下使用的两个选项吧
-p:可以指定自己想要暴露的端口信息,格式: -p 8808:80
则是将8808这个端口信息暴露出去,将真实端口80隐藏起来
-P:是随机一个端口信息,不能自己进行配置,说只随机,其实也是从49153开始进行轮询,而不是真正的随机。下面就只展示一下结果
docker run -itd --name test1 --net test1 --ip 177.16.123.21 -p 8808:80 nginx:1.12 /bin/bash docker run -itd --name test2 --net test1 --ip 177.16.123.22 -P nginx:1.12 /bin/bash 这是两种创建方式,创建的结果如下: a47427ad180c nginx:1.12 "/bin/bash" 3 seconds ago Up 1 second 0.0.0.0:49153->80/tcp, :::49153->80/tcp test2 #这个是-P随机的,可以看到正如我上面所说的,是从49153开始进行的,并且需要注意,假如现在49153端口信息的容器删除之后,再次使用-P的方式创建,在轮询到65535之前,49153这个端口信息将不会再次被使用(除非是使用-p的方式进行指定) 500090d20e61 nginx:1.12 "/bin/bash" 6 minutes ago Up 6 minutes 0.0.0.0:8808->80/tcp, :::8808->80/tcp test1 #这是-p,进行指定一个端口信息
docker rm -f test2 #删除当前-P创建的49153这个端口的容器,再使用相同的方式进行创建 docker run -itd --name test2 --net test1 --ip 177.16.123.22 -P nginx:1.12 /bin/bash #可以看到,这次创建的与上次创建的一个字符都不差 docker ps -a d6826a9d3c95 nginx:1.12 "/bin/bash" 6 seconds ago Up 4 seconds 0.0.0.0:49154->80/tcp, :::49154->80/tcp test2 #但是结果是49154,证实了上面的说法
上面这些就是一些docker网络方面一些基础的小知识,后续的知识点我还待慢慢更新,先进行一点点梳理