为容器编排、集群部署做铺垫

理解Docker0

Docker网络 - 图1
三个网卡
l0:本机回环地址
eth0:内网地址
docker0

docker是如何处理容器网络访问的?
尝试一下:

  1. 运行一个tomcat容器
  2. 使用ip addr查看容器内部网络,可以看到有一个331: eth0@if332
  3. 宿主机ping 172.17.0.3能够ping通。

Docker网络 - 图2

  1. docker run -d -P --name tomcat01 tomcat
  2. docker exec -it tomcat01 ip addr
  3. ping 172.17.0.3
  1. 我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0,桥接模式,使用的是evth-pair技术。
    此时再次在宿主机执行ip addr,发现多了一条这个。与刚刚启动的tomcat容器的信息是匹配的。

Docker网络 - 图3

  1. 如果再启动一个容器又会多一对

Docker网络 - 图4
veth-pair是成对的虚拟设备接口,一端连着协议,一端彼此相连
正是因为这个特性,veth-pair充当一个桥梁

  1. 在tomcat02中ping tomcat01的ip
    容器之间互相能够ping通

Docker网络 - 图5

老师画的图,但我觉得这个也不能叫做路由器吧…但可以辅助理解。
Docker网络 - 图6

Docker网络 - 图7

Docker中所有的网络都是虚拟的,转发效率高。
容器删除之后,对应网桥就没了。

—link

思考一个场景,我们编写了一个微服务,database url=ip:port,项目不重启,但是数据库ip变了(比如重启了容器所以ip变了),我们仍然希望连接到这个新的容器,如何用一个服务名来访问容器?

通过—link来实现

docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat03 tomcat
docker run -d -P --name tomcat03 --link tomcat01 tomcat
docker exec -it tomcat03 ping tomcat01
docker exec -it tomcat03 ping tomcat02
docker exec -it tomcat01 ping tomcat03

但是不是一个好的方法,反向不可以ping通,看下面截图:
Docker网络 - 图8

docker inspect tomcat03

“HostConfig”里面
Docker网络 - 图9

如果是tomcat01
Docker网络 - 图10

#直接查看hosts文件
docker exec -it tomcat03 cat /etc/hosts

Docker网络 - 图11
现在开发不建议使用—link

自定义网络

查看docker网络:

Docker网络 - 图12

bridge:桥接(docker默认)
host:和宿主机共享网络
none:不配置网络

#启动一个容器
#默认参数 --net bridge 使用docker0
#docker0的特点,默认是不能通过容器名访问

#自定义一个网络
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet

#查看一下
(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker network ls
NETWORK ID     NAME            DRIVER    SCOPE
c38149fd1d59   bridge          bridge    local
480762c35327   harbor_harbor   bridge    local
a6d1fd635ad8   host            host      local
a88653ee6e7a   mynet           bridge    local
580f8272eeba   none            null      local
(base) [root@izuf64eqyhnvmcv50ay73gz ~]#

#使用自定义网络发现能够ping通
docker run -d -P --name tomcat-net-01 --net mynet tomcat
docker run -d -P --name tomcat-net-02 --net mynet tomcat
docker exec -it tomcat-net-01 ping tomcat-net-02

Docker网络 - 图13

如果是我们自定义的网络,docker已经帮我们维护好了对应的关系。
不同的集群使用不同的网络,保证集群是安全和健康的。

网络连通

Docker网络 - 图14

如果想要tomcat-01能够访问mynet网络里的容器,应该用什么?
docker network connect [网络名] [容器名]

(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker network --help

Usage:  docker network COMMAND

Manage networks

Commands:
  connect     Connect a container to a network ######这条
  create      Create a network
  disconnect  Disconnect a container from a network
  inspect     Display detailed information on one or more networks
  ls          List networks
  prune       Remove all unused networks
  rm          Remove one or more networks

Run 'docker network COMMAND --help' for more information on a command.
(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker network connect --help

Usage:  docker network connect [OPTIONS] NETWORK CONTAINER

Connect a container to a network

Options:
      --alias strings           Add network-scoped alias for the container
      --driver-opt strings      driver options for the network
      --ip string               IPv4 address (e.g., 172.30.100.104)
      --ip6 string              IPv6 address (e.g., 2001:db8::33)
      --link list               Add link to another container
      --link-local-ip strings   Add a link-local address for the container
(base) [root@izuf64eqyhnvmcv50ay73gz ~]#

基本操作

(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker run -d -P --name tomcat05 tomcat
615e2e0e2643ffdef0b8cd4ff7fbc15de8e5337b3e540d2f181d330109ca7dcf
(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker network connect mynet tomcat05
(base) [root@izuf64eqyhnvmcv50ay73gz ~]# docker exec -it tomcat05 ping tomcat-net-01
PING tomcat-net-01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.052 ms
^C
--- tomcat-net-01 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 1000ms
rtt min/avg/max/mdev = 0.052/0.056/0.060/0.004 ms
(base) [root@izuf64eqyhnvmcv50ay73gz ~]#
#查看自定义网络信息
docker network inspect mynet

可以看到tomcat05被加到mynet中
Docker网络 - 图15

#查看tomcat05网络信息
docker exec -it tomcat05 ip addr

可以看到tomcat05多了一个ip
Docker网络 - 图16

Redis集群部署

分片+高可用+均衡负载
使用shell脚本

#创建自定义网络
docker network create redis --subnet 172.38.0.0/16

#通过脚本创建六个redis配置
for port in $(seq 1 6); \
do \
mkdir -p /home/my-test/redis/node-${port}/conf
touch /home/my-test/redis/node-${port}/conf/redis.conf
cat << EOF >/home/my-test/redis/node-${port}/conf/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.1${port} 
cluster-announce-port 6379
cluster-announce-bus-port 16379
appendonly yes
EOF
done

#启动这六个容器
for node in $(seq 1 6); \
do \
docker run -d -p 637${node}:6379 -p 1637${node}:16379 --name redis-${node} -v /home/my-test/redis/node-${node}/data:/data -v /home/my-test/redis/node-${node}/conf/redis.conf:/etc/redis/redis.conf --net redis --ip 172.38.0.1${node} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done


docker run -d -p 6371:6379 -p 16371:16379 --name redis-1 \
-v /home/my-test/redis/node-1/data:/data \
-v /home/my-test/redis/node-1/conf/redis.conf:/etc/redis/redis.conf \
--net redis --ip 172.38.0.11 \
redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#
docker exec -it redis-1 /bin/sh
#
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

Docker网络 - 图17

Docker网络 - 图18

可以看到redis-3是master节点,如果从外面把redis-3停掉
重新连接,get a,可以看到redis-4这个节点补了上来。

Docker网络 - 图19