docker 网络和创建redis集群案例
Docker 网络
-
理解Docker0网络 docker0特点:默认域名不能访问,需要--link单向打通
我们可以在run 后面直接加cmd参数 查看容器的ip地址
docker exec -it tom01 ip addr
可以看到第一个lo是Loopback Address 回环地址
第二个172内网段的则是容器自己创建分配的ip地址.
默认情况下,
每启动一个docker容器,docker会给容器分配一个ip ,安装完docker 默认的网卡就是docker0,
而网卡使用bridge模式,用evth-pair技术进行容器之间或者容器和本机之间相互通信
可以看到docker的地址就是网关地址
-
evth-pair技术原理了解
默认情况下,linux和容器之间是不能访问的,是基于evth-pair技术,通过他们的协议,在彼此之间做了一个接口桥梁,得以相互分配到同一个ip内网段进行互访.
evth-pair都是一对对的
可以看到下图是创建了2个容器分别是tom01和tom02,而docker本体的ip地址里两个容器的ip对应关系分别是11-10和17-16.
从右边的两个容器里输出ip地址可以看到是10-11,16-17,这个就是evth-pair的技术,通过这个技术,让2个容器在同一网段,所以容器之间也是可以相互访问
大致的网络拓扑图就是这样
-
容器互联 --link
- 弊端:evth-pair是基于容器存在的,如果容器删除,那么容器和linux对应关系也会随之删除.而我们绑定容器服务常用的就是对应他的ip地址.
而容器万一蹦了,或者删除了对应的ip也会随之消失,新的容器对应的ip也发生变化,所以解决这个问题我们需要对应服务而不是ip地址,只要这个服务在,任何容器的删除增加都不需要重新制定IP,
举个例子,tom1:172.168.0.2,tom2 ip:172.168.0.3 我们可以ping 172.168.0.3,但是我们如果要实现绑定服务名,就需要ping tom2 也能ping通,所以就需要容器互联技术.
我们需要启动容器的时候使用--link参数
docker run -d -P --name tom03 --link tom02 tomcat:8.0.52
新建一个容器link到tom2,注意tom2此时必须是启动状态.
原理:我们可以进tom03下查看/etc/hosts文件,可以看到文件里就绑定了容器tom02,所以--link就是个Host映射
虽然tom03绑定了tom02,也可以Ping通,但是我们从tom02却无法ping tom03,所以这个--link只能单向绑定.
2.--link
虽然方便,但是单向绑定,操作不方便,有局限性,也不推荐使用
我们使用自定义网络模式进行容器互联
使用docker network 命令
使用docker network -l 可以查看网络模式
brige:桥接模式 docker默认 类似DNAT的模式(默认使用这种)docker run --name tom01 -d --net bridge tomcat:8.0.25
平时默认run的时候 --net bridge就是自动添加的
none:不配置网络只有回环地址 隔离性强
host: 和宿主机共享网络
container:容器网络相连(用的少,局限性大)--network container:NAME或者容器ID
如果启动容器的时候使用host模式,那么这个容器将不会获得一个独立的Network Namespace,而是和宿主机共用一个Network Namespace。容器将不会虚拟出自己的网卡,配置自己的IP等,而是使用宿主机的IP和端口。但是,容器的其他方面,如文件系统、进程列表等还是和宿主机隔离的。
使用host模式的容器可以直接使用宿主机的IP地址与外界通信,容器内部的服务端口也可以使用宿主机的端口,不需要进行NAT,host最大的优势就是网络性能比较好,但是docker host上已经使用的端口就不能再用了,网络的隔离性不好。
下面开始自定义个网络模式
主要还是用gateway,subnet 定义网关和子网
例:docker network create --gateway 192.168.0.1 --subnet 192.168.0.0/16 mynet
分别使用自定义的网络模式创建2个容器
docker run -d --name mynettom01 --network mynet tomcat:8.0.52
使用docker network inspect mynet
查看我们自定义的网络
接下来让我们试试自定义的网络中容器之间是否可以用域名访问,可以看到都是可以实现的.而且是双向的
实际企业应用中,我们可以为每个服务集群自定义一个网络 比如mysqlnet,redisnet.这样集群之间相互隔离,并且都可以用自定义的网络名字开启服务.
开启后,集群内的应用又相互访问,并且是双向的支持域名访问. - 弊端:evth-pair是基于容器存在的,如果容器删除,那么容器和linux对应关系也会随之删除.而我们绑定容器服务常用的就是对应他的ip地址.
-
集群之间的网络互通
从上面实现了集群之间隔离,但是如果集群之间需要数据交互,也是需要打通网络的.这里开始打通集群网络的操作. 主要使用docker network connect命令实现
之前已经创建了mynet,现在再创建另外集群的子网命名为secnet
- secnet下再开启2个tomcat容器
docker run -d --name tom03 --network secnet tomcat:8.0.52
- 我们的tomcat集群有2个位于192.168.0.0网段,而另外 2个位于192.167.0.0网段,可以看到2个网段不能直接ping通
- 把tom3加到192.168.0.0网段去
docker network connect mynet tom03
命令语法docker network connect [OPTIONS] NETWORK CONTAINER
我们可以看到docker直接把tom3放到了mynet网段中了,所以tom3可以直接ping mynettom01/02
下面ping通的截图,这就是一个容器2个网址,就是容器的公网和私网的概念.
- secnet下再开启2个tomcat容器
-
创建redis集群示例
redis未学,redis命令不懂,后续解决
-
创建redis的自定义网段 docker network create --subnet 172.38.0.0/16 --gateway 172.38.0.1 myredisnet
创建redis的容器集群
通过脚本创建redis配置
脚本命令
for port in $(seq 1 6);
do
mkdir -p /mydata/redis/node-${port}/conf
touch /mydata/redis/node-${port}/conf/redis.conf
cat EOF /mydata/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 -
创建6个redis的容器
docker run -p 6371:6379 -p 16371:16379 --name redis-1 -v /mydata/redis/node-1/data:/data -v /mydata/redis/node-1/conf/redis.conf:/etc/redis/redis.conf -d --network myredisnet --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
-
随便进入一个redis容器 redis用的是/bin/sh 要注意交互
-
后面就是redis创建集群的命令,没学redis,后面再研究
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就可以看到集群信息