1.docker 网络
当你开始大规模使用Docker时,你会发现需要了解很多关于网络的知识。
Docker作为目前最火的轻量级容器技术,有很多令人称道的功能,如Docker的镜像管理。
然而,Docker同样有着很多不完善的地方,网络方面就是Docker比较薄弱的部分。
因此,我们有必要深入了解Docker的网络知识,以满足更高的网络需求。
这里我们先讨论docker的单主机网络模式,它包括以下4类:
host
bridge
none
joined-container
查看网卡模式命令:
docker network ls
1.1 host
类似于VMware的桥接模式,但没有独立ip;
docker不会为容器创建独有的network namespace;
使用宿主机的默认网络命名空间,共享一个网络栈;
表现为容器内和宿主机的IP一致;
这种模式用于网络性能较高的场景,但安全隔离性相对差一些。
命令:创建网络为host的容器
1.2 bridge
桥接模式,有点类型VM-NAT,dockerd进程启动时会创建一个docker0网桥,容器内的数据通过这个网卡设备与宿主机进行数据传输。
docker会为容器创建独有的network namespace,也会为这个命名空间配置好虚拟网卡,路由,DNS,IP地址与iptables规则。
1.3 none
none模式可以说是桥接模式的一种特例,docker会为容器创建独有的network namespace ,但不会为这个命名空间准备虚拟网卡,IP地址,路由等,需要用户自己配置。
1.4 joined-container
容器共享模式,这种模式是host模式的一种延伸,一组容器共享一个network namespace;
对外表现为他们有共同的IP地址,共享一个网络栈;
kubernetes的pod就是使用的这一模式。
关于跨主机的docker网络通信,包含overlay、macvaln,又包含calico、flannel、weave等方案,不过跨主机的docker网络管理更多的是交给kubernetes或swarm等编排工具去实现了。
=======================================
2、容器互联(自定义局域网络****)
我们为什么需要自定义网络?
将容器放在自定义的网络(数据局域网)中,容器之间是可以相互通信的,这样的话,我们就不需要使用 --link(旧技术,已淘汰) 来实现通信了。
如何自定义网络?
查看容器网络docker network ls,容器启动时默认的网络是bridge(桥接)模式(即,容器启动时默认是存在--net bridge)
2.1 我们可以通过 docker network create 自定义一个网络
自定义网络:
(1)自定义网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 tigerNet
(2)查看容器网络
docker network ls NETWORK ID NAME DRIVER SCOPE fd8851346218 bridge bridge local ea9e3751f590 host host local 8e3e1706738d none null local 8fe9146fa417 tigerNet bridge local # 这个是我们自定义的网络
接下来,我们启动两个容器,并将其放入我们自定义的网络中
// 1、启动centos01 --net tigerNet 将容器发布到我们自定义的网络中去 docker run --name centos01 -itd --net tigerNet centos:7 // 2、启动centos02 docker run --name centos02 -itd --net tigerNet centos:7 // 3、查看 tigerNet 网络中的变化 docker network inspect tigerNet [ { ... // 我们可以发现多了两个容器 "Containers": { "0cfb02b5bfb96d705bd4216a3c50f4b71614631f418694301896e4d75a9d38a2": { "Name": "centos01", "EndpointID": "ff76dfdb768869596e11948fad96afad9220d0b8d9c6bf1949222844b3c2aa11", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "31f982e351c9fb748ebbca247b0978d40586282f1cc95e95f2bb6b82390f9918": { "Name": "centos02", "EndpointID": "7621ff14626877ca68d9599f9489826f30992c2fa9cf9b3f320d7b560690d243", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, ... } ] #ping一下两个容器 // 1、centos02 ping centos01 可ping通 [root@localhost /]# docker exec -it centos01 ping centos02 PING centos02 (192.168.0.3) 56(84) bytes of data. 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=1 ttl=64 time=0.122 ms 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=2 ttl=64 time=0.125 ms 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=3 ttl=64 time=0.089 ms // 2、centos01 ping centos02 可ping通 [root@localhost /]# docker exec -it centos02 ping centos01 PING centos01 (192.168.0.2) 56(84) bytes of data. 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=1 ttl=64 time=0.119 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=2 ttl=64 time=0.114 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=3 ttl=64 time=0.114 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=4 ttl=64 time=0.070 ms
2.2、容器互联(局域网络之间的联通****)
有这么一个需求,我们希望一个局域网中的容器可以与另一个局域网中的容器进行通信,如下:
现在构建两个局域网
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 tigerNet
docker network create --driver bridge --subnet 192.167.0.0/16 --gateway 192.167.0.1 studiousNet
在 tigerNet 中启动 centos01 和 centos02(2.1中已实现)
在 studiousNet中启动centos03 和 centos04
docker run --name centos03 -itd --net studiousNet centos:7
docker run --name centos04 -itd --net studiousNet centos:7
现在我们来打通局域网与容器之间的通信
docer给我提供了docker network connect命令,可以实现打通局域网与容器之间的通信
将 centos04 添加到 tigerNet 中,我们可以发现原来 docker 是给 centos04 设置了双IP
// 1、启动centos01 --net tigerNet 将容器发布到我们自定义的网络中去 docker run --name centos01 -itd --net tigerNet centos:7 // 2、启动centos02 docker run --name centos02 -itd --net tigerNet centos:7 // 3、查看 tigerNet 网络中的变化 docker network inspect tigerNet [ { ... // 我们可以发现多了两个容器 "Containers": { "0cfb02b5bfb96d705bd4216a3c50f4b71614631f418694301896e4d75a9d38a2": { "Name": "centos01", "EndpointID": "ff76dfdb768869596e11948fad96afad9220d0b8d9c6bf1949222844b3c2aa11", "MacAddress": "02:42:c0:a8:00:02", "IPv4Address": "192.168.0.2/16", "IPv6Address": "" }, "31f982e351c9fb748ebbca247b0978d40586282f1cc95e95f2bb6b82390f9918": { "Name": "centos02", "EndpointID": "7621ff14626877ca68d9599f9489826f30992c2fa9cf9b3f320d7b560690d243", "MacAddress": "02:42:c0:a8:00:03", "IPv4Address": "192.168.0.3/16", "IPv6Address": "" } }, ... } ] #ping一下两个容器 // 1、centos02 ping centos01 可ping通 [root@localhost /]# docker exec -it centos01 ping centos02 PING centos02 (192.168.0.3) 56(84) bytes of data. 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=1 ttl=64 time=0.122 ms 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=2 ttl=64 time=0.125 ms 64 bytes from centos02.tigerNet (192.168.0.3): icmp_seq=3 ttl=64 time=0.089 ms // 2、centos01 ping centos02 可ping通 [root@localhost /]# docker exec -it centos02 ping centos01 PING centos01 (192.168.0.2) 56(84) bytes of data. 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=1 ttl=64 time=0.119 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=2 ttl=64 time=0.114 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=3 ttl=64 time=0.114 ms 64 bytes from centos01.tigerNet (192.168.0.2): icmp_seq=4 ttl=64 time=0.070 ms
3.3、容器互联(Redis集群实战****)
1、集群介绍
2、集群搭建
① 创建一个redis网络
docker network create redis --subnet 172.38.0.0/16
② 编写 redis.conf 文件
我们打算,使用数据卷挂载 redis 中的redis.conf,所以我们需要宿主机上提前配置到redis集群的配置文件
mkdir -p /home/redis/node0{1..6}/data vim /home/redis/node01/redis.conf port 6379 bind 0.0.0.0 cluster-enabled yes cluster-config-file nodes.conf cluster-node-timeout 5000 cluster-announce-ip 172.38.0.11 cluster-announce-bus-port 16379 appendonly yes cd /home/redis/node01/ cp redis.conf ../node02/ cp redis.conf ../node03/ cp redis.conf ../node04/ cp redis.conf ../node05/ cp redis.conf ../node06/ vim ../node02/redis.conf cluster-announce-ip 172.38.0.12 vim ../node03/redis.conf cluster-announce-ip 172.38.0.13 vim ../node04/redis.conf cluster-announce-ip 172.38.0.14 vim ../node05/redis.conf cluster-announce-ip 172.38.0.15 vim ../node06/redis.conf cluster-announce-ip 172.38.0.16
③ 启动6个redis容器
docker run --name redis01 -p 6371:6379 -p 16371:16379 \ -v /home/redis/node01/data:/data \ -v /home/redis/node01/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.11 redis redis-server /etc/redis/redis.conf docker run --name redis02 -p 6372:6379 -p 16372:16379 \ -v /home/redis/node02/data:/data \ -v /home/redis/node02/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.12 redis redis-server /etc/redis/redis.conf docker run --name redis03 -p 6373:6379 -p 16373:16379 \ -v /home/redis/node03/data:/data \ -v /home/redis/node03/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.13 redis redis-server /etc/redis/redis.conf docker run --name redis04 -p 6374:6379 -p 16374:16379 \ -v /home/redis/node04/data:/data \ -v /home/redis/node04/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.14 redis redis-server /etc/redis/redis.conf docker run --name redis05 -p 6375:6379 -p 16375:16379 \ -v /home/redis/node05/data:/data \ -v /home/redis/node05/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.15 redis redis-server /etc/redis/redis.conf docker run --name redis06 -p 6376:6379 -p 16376:16379 \ -v /home/redis/node06/data:/data \ -v /home/redis/node06/redis.conf:/etc/redis/redis.conf \ -d --net redis --ip 172.38.0.16 redis redis-server /etc/redis/redis.conf
④ 随便进入一个容器,并创建一个redis集群
docker exec -it redis01 /bin/bash
redis-cli --cluster create 172.38.0.11:6379 172.38.0.12:6379 172.38.0.13:6379 172.38.0.14:6379 172.38.0.15:6379 172.38.0.16:6379 --cluster-replicas 1
⑤ 进入集群,并查看集群信息
redis-cli -c cluster info cluster nodes
⑥ 集群高可用测试
存入一个name值到redis集群中,查看 set k1 1 bgsave 将对应的容器停掉 docker stop redis02 查看name值(集群搭建成功) get k1