Docker网络(5)
一、docker网络介绍
大量的互联网应用服务需要多个服务组件,这往往需要多个容器之间通过网络通信进行相互配合
docker 网络从覆盖范围可分为单个 host 上的容器网络和跨多个 host 的网络
docker 目前提供了映射容器端口到宿主主机和容器互联机制来为容器提供网络服务,在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的
docker 安装时会自动在host上创建三个网络,我们查看一下docker网络:
[root@ren8 ~]# docker network ls NETWORK ID NAME DRIVER SCOPE 5ada5821d5d1 bridge bridge local 011f63e62210 host host local 12362c774cf8 none null local
docker有四种网络模式:
(1)bridge模式
docker网络隔离基于网络命名空间,在物理机上创建docker容器时会为每一个docker容器分配网络命名空间,并且把容器IP桥接到物理机的虚拟网桥上。
(2)none模式
此模式下创建容器是不会为容器配置任何网络参数的,如:容器网卡、IP、通信路由等,全部需要自己去配置。
(3)host模式
此模式创建的容器没有自己独立的网络命名空间,是和物理机共享一个Network Namespace,并且共享物理机的所有端口与IP,并且这个模式认为是不安全的。
(4)container模式(用户自定义网络)
此模式和host模式很类似,只是此模式创建容器共享的是其他容器的IP和端口而不是物理机,此模式容器自身是不会配置网络和端口,创建此模式容器进去后,你会发现里边的IP是你所指定的那个容器IP并且端口也是共享的,而且其它还是互相隔离的,如进程等。
二、docker --- none 网络
none 网络就是什么都没有的网络。挂在这个网络下的容器除了 lo,没有其他任何网卡。容器创建时,可以通过 --network=none 指定使用 none 网络。
[root@ren8 ~]# docker run -it --network=none 192.168.11.7:5000/busybox:latest / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever / #
none 网络的应用
封闭的网络意味着隔离,一些对安全性要求高并且不需要联网的应用可以使用 none 网络。
比如某个容器的唯一用途是生成随机密码,就可以放到 none 网络中避免密码被窃取。
三、docker --- host 网络
连接到 host 网络的容器共享 docker host 的网络栈,容器的网络配置与 host 完全一样。可以通过 --network=host 指定使用 host 网络
[root@ren8 ~]# docker run --rm -it --network=host 192.168.11.7:5000/busybox:latest / # ip a 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever inet6 ::1/128 scope host valid_lft forever preferred_lft forever 2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast qlen 1000 link/ether 00:0c:29:14:ac:76 brd ff:ff:ff:ff:ff:ff inet 192.168.11.8/24 brd 192.168.11.255 scope global ens33 valid_lft forever preferred_lft forever inet6 fe80::20c:29ff:fe14:ac76/64 scope link valid_lft forever preferred_lft forever 3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue link/ether 02:42:cb:36:e1:bf brd ff:ff:ff:ff:ff:ff inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0 valid_lft forever preferred_lft forever
在容器中可以看到 host 的所有网卡,并且连 hostname 也是 host 的。host 网络的使用场景又是什么呢?
直接使用 Docker host 的网络最大的好处就是性能,如果容器对网络传输效率有较高要求,则可以选择 host 网络。当然不便之处就是牺牲一些灵活性,比如要考虑端口冲突问题,Docker host 上已经使用的端口就不能再用了。
Docker host 的另一个用途是让容器可以直接配置 host 网路。比如某些跨 host 的网络解决方案,其本身也是以容器方式运行的,这些方案需要对网络进行配置,比如管理 iptables
四、docker --- bridge 网络
docker 安装时会创建一个 命名为 docker0 的 linux bridge。如果不指定--network,创建的容器默认都会挂到 docker0 上:
[root@ren7 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242b89f778c no
当前 docker0 上没有任何其他网络设备,我们创建一个容器看看有什么变化:
[root@ren7 ~]# docker run -d mirrorgooglecontainers/pause-amd64:3.1 26e1529c8d5cb206ca6c6ec47adde1ef29e35f46159615225453246dab7eb30a [root@ren7 ~]# brctl show bridge name bridge id STP enabled interfaces docker0 8000.0242b89f778c no veth4506620
一个新的网络接口 veth4506620 被挂到了 docker0 上,veth4506620就是新创建容器的虚拟网卡。
进入刚才运行的容器查看网络,容器有一个网卡 eth0@if34
实际上 eth0@if34 和 veth4506620是一对 veth pair
veth pair 是一种成对出现的特殊网络设备,可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if34)在容器中,另一头(veth4506620)挂在网桥 docker0 上,其效果就是将 eth0@if34 也挂在了 docker0 上
eth0@if34 已经配置了 IP 172.17.0.2,为什么是这个网段呢?
看一下 bridge 网络的配置信息:
docker network inspect bridge
bridge 网络配置的 subnet 就是 172.17.0.0/16,并且网关是 172.17.0.1,在docker0上
容器创建时,docker 会自动从 172.17.0.0/16 中分配一个 IP,这里 16 位的掩码保证有足够多的 IP 可以供容器使用
五、创建 user --- defined 网络
我们可通过 bridge 驱动创建类似前面默认的 bridge 网络
(1)利用bridge驱动创建名为my-net2网桥(docker会自动分配网段):
docker network create --driver brigde my-net2
(2)查看一下当前 host 的网络结构变化:
docker network ls
(3)查看容器bridge网桥配置(bridge就是容器和网桥形成一对veth pair)
docker network inspect bridge
(4)利用bridge驱动创建名为my-net3网桥(user-defined网段及网关)
docker network create --driver brigde --subnet 172.22.1.0/24 --gateway 172.22.1.1 my-net3
(5)启动容器使用新建的my-net3网络
docker run -it --network=my-net3 httpd
(6)启动容器使用my-net3网络并指定ip(只有使用 --subnet 创建的网络才能指定静态 IP,如果是docker自动分配的网段不可以指定ip)
docker run -it --network=my-net3 --ip 172.22.1.10 httpd
(7)让已启动不同vlan的ningx容器连接到my-net2(其实在ningx中新建了my-net2的网卡)
docker run -it --network=my-net3 ningx
docker network connect my-net2 ningx
(8)使用--name指定启动容器名字,可以使用docker自带DNS通信,但只能工作在user-defined 网络,默认的 bridge 网络是无法使用 DNS 的
docker run -it --network=my_net2 --name=bbox1 busybox
docker run -it --network=my_net2 --name=bbox2 busybox
(9)容器之间的网络互联
a). 首先创建一个 db 容器
docker run -dti --name db centos:7.0
b). 创建一个 web 容器,并使其连接到 db
docker run -dti --name web --link db:dblink centos:7.0/bin/bash
--link db:dblink 实际是连接对端的名字和这个链接的名字,也就是和 db 容器建立一个叫做 dblink 的链接
c). 查看链接的情况
docker ps -a
d). 使用 ping 命令来测试网络链接的情况
(10)容器端口映射
在启动容器的时候,如果不指定参数,在容器外部是没有办法通过网络来访问容器内部的网络应用和服务的
当容器需要通信时,我们可以使用 -P (大) &&-p (小)来指定端口映射
-P : Docker 会随机映射一个 49000 ~ 49900 的端口到容器内部开放的网络端口
-p :则可以指定要映射的端口,并且在一个指定的端口上只可以绑定一个容器。
支持的格式有
IP : HostPort : ContainerPort
IP : : ContainerPort
IP : HostPort :
查看映射:
docker port
a)映射所有接口地址,此时绑定本地所有接口上的 5000 到容器的 5000 接口,访问任何一个本地接口的 5000 ,都会直接访问到容器内部
docker run -dti -p 5000:5000 centos:7.0 /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
(11)实验:通过端口映射实现访问本地的 IP:PORT 可以访问到容器内的 web
a)将容器80端口映射到主机8080端口
docker run -itd -p 8080:80 --name http-test httpd
b) 查看刚运行docker
docker ps
c) 进入容器
docker exec -it httpd-test
d) 容器内部编辑网页文件 index.html
********#echo “hhhhhhhhhhhh” > /var/www/html/index.html
e)到宿主机上打开浏览器输入 IP:PORT 访问验证
http://192.168.4.170:8080
网络排排查命令:
iptables -t nat -L
ip r
tcpdump -i docker0 -n icmp
tcpdump -i eth0 -n icmp