一、docker网络介绍
大量的互联网应用服务需要多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合
docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络
docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务,在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的
docker 安装时会自动在host上创建三个网络,我们查看一下docker网络:
[root@localhost ~]# docker network ls
二、docker--none网络
none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。
none 网络的应用
封闭的网络意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。
比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
当然大部分容器是需要网络的,我们接着看 host 网络。
三、 docker--host网络
host 网络
连接到 host 网络的容器,共享 docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,就可以选择 host 网络。
当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables
四、docker--bridge网络
docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上
当前 docker0 上没有任何其他网络设备,我们创建一个容器看看有什么变化
[root@localhost ~]# docker run -itd amd64/busybox:latest
934e02cbfc674e51d53fdda3c660e68cbf1ff292976983e357a9ab029c141930
一个新的网络接口vethfc6f32b 被挂到了 docker0 上,vethfc6f32b就是新创建容器的虚拟网卡。
进入刚才运行的容器查看网络,容器有一个网卡 eth0@if9
实际上 vethfc6f32b 和 eth0@if9是一对 veth pair
veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if9)在容器中,另一头(vethfc6f32b)挂在网桥 docker0 上,其效果就是将 eth0@if9 也挂在了 docker0 上
eth0@if9 已经配置了 IP 172.17.0.2,为什么是这个网段呢?
看一下 bridge 网络的配置信息:
docker network inspect bridge
bridge 网络配置的 subnet 就是 172.17.0.0/16
容器创建时,docker 会自动从 172.17.0.0/16 中分配一个 IP,这里 16 位的掩码保证有足够多的 IP 可以供容器使用
五、创建 user-defined 网络
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络
(1)利用bridge驱动创建名为my-net2网桥(docker会自动分配网段):
[root@localhost ~]# docker network create --driver bridge my-net2
(2)查看一下当前 host 的网络结构变化:
[root@localhost ~]# docker network list
(3)查看容器bridge网桥配置(bridge就是容器和网桥形成一对veth pair)
[root@localhost ~]# docker network inspect my-net2
(4)利用bridge驱动创建名为my-net3网桥(user-defined网段及网关)
[root@localhost ~]# docker network create --driver bridge my-net3 --subnet 10.10.0.0/24 --gateway 10.10.0.1
6116641cc722e24f4ad753c1bfca036956fd1c4a940c031a5d15c927623f6bbc
(5)启动容器使用新建的my-net3网络
[root@localhost ~]# docker run -itd --network=my-net3 --name box1 centos:latest
[root@localhost ~]# docker exec -it box1 /bin/sh
(6)启动容器使用my-net3网络并指定ip(只有使用 --subnet 创建的网络才能指定静态 IP,如果是docker自动分配的网段不可以指定ip)
[root@localhost ~]# docker run -itd --network=my-net3 --ip 10.10.0.100 --name box3 httpd:latest
(7)让已启动不同vlan的ningx容器,可以连接到my-net2(其实在nigx中新建了my-net2的网卡)
[root@localhost ~]# docker network connect my-net2 box3
(8)使用--name指定启动容器名字,可以使用docker自带DNS通信,但只能工作在user-defined 网络,默认的 bridge 网络是无法使用 DNS 的
[root@localhost ~]# docker run -itd --network=my-net2 --name=bbox1 httpd:latest
[root@localhost ~]# docker run -itd --network=my-net2 --name=bbox2 httpd:latest
(9)容器之间的网络互联
a). 首先创建一个 db 容器
[root@localhost ~]# docker run -dti --name db centos:latest
b). 创建一个 web 容器,并使其连接到 db
[root@localhost ~]# docker run -dti --name web --link db:dblink centos:latest
--link db:dblink 实际是连接对端的名字和这个链接的名字,也就是和 db 容器建立一个叫做 dblink 的链接
c). 查看链接的情况
[root@localhost ~]# docker ps -a
d). 使用 ping 命令来测试网络链接的情况
[root@localhost ~]# docker exec -it web /bin/bash
[root@localhost ~]# docker exec -it db /bin/bash
单向通
(10)容器端口映射
在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的
当容器需要通信时,我们可以使用 -P (大) &&-p (小)来指定端口映射
-P : Docker 会随机映射一个 49000 ~ 49900 的端口到容器内部开放的网络端口
-p :则可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。
支持的格式有(宿主机:HostPort 容器: ContainerPort)
IP : HostPort : ContainerPort
IP : : ContainerPort
IP : HostPort :
a)映射所有接口地址,此时绑定本地所有接口上的 8081到容器的 80 接口,访问任何一个本地接口的 5000 ,都会直接访问到容器内部
[root@localhost ~]# docker run -itd -p 250:80 --name http httpd:latest
浏览器测试
[root@localhost ~]# docker exec -it 1a372e287ef0 /bin/bash
b)多次使用可以实现多个接口的映射
docker run -dti -p 5000:5000 -p 5022:22 centos:7.0 /bin/bash
c)映射到指定地址的指定接口
此时会绑定本地 192.168.4.169 接口上的 5000 到容器的 5000 接口
docker run -dti -p 192.168.4.169:5000:5000 centos:7.0 /bin/bash
d) 映射到指定地址的任意接口
此时会绑定本地 192.168.4.169 接口上的任意一个接口到容器的 5000 接口
docker run -dti -p 192.168.4.169::5000 centos:7.0 /bin/bash
e) 使用接口标记来指定接口的类型
docker run -dti -p 192.168.4.169::5000/UDP centos:7.0 /bin/bash