理解docker0
1.lo 本机回环地址
2.ens33 服务器内网地址
3.docker0 地址
三个网络
问题,docker 是如何处理容器网络访问的?
docker run -d -P --name tomcat01 tomcat
# 查看容器的内部网络地址 ip addr
docker exec -it tomcat01 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default 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
30: eth0@if31: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default
link/ether 02:42:ac:11:00:02 brd ff:ff:ff:ff:ff:ff link-netnsid 0
inet 172.17.0.2/16 brd 172.17.255.255 scope global eth0
valid_lft forever preferred_lft forever
# 思考,Linux 能不能ping通容器内部
# 容器与容器之间能不能互ping?
原理
1.我们每安装启动一个docker容器,docker就会给docker容器分配一个ip,我们只要安装了docker,就会有一个网卡docker0
桥接模式,使用的技术是 evth-pair技术
再次测试ip addr
2.在启动一个容器测试,发现又多一对网卡
我们发现这个容器带来网卡,都是一对一对的
evth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
正因为有这个特性,evth-pair 充当一个桥梁,连接各种虚拟网络设备的
openstac,Docker容器之间的连接,ovs的连接,都是使用,evth-pair 技术
3.测试一下容器之间是否能ping通
docker exec -it tomcat01 ping 172.17.0.3
# 结论容器与容器之间是可以相互ping通的
结论:tomcat01和tomcat02是公用的一个路由器,docker0
所有的容器不指定网络的情况下,都是docker0路由的,docker会给我们的容器分配一个默认的可用IP
255.255.0.1/16 域 局域网
00000000.00000000.00000000.00000000
255.255.0.0 255 * 255 - 65000
小结
Docker使用的是Linux的桥接,宿主机中是一个docker容器的网桥 docker0
Docker中的所有的网络接口都是虚拟的,虚拟的转发效率高!
只要容器删除,对应的网桥一对就没了!
容器互联 --link
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
eabb6bc29294 tomcat "catalina.sh run" 5 seconds ago Up 5 seconds 0.0.0.0:32771->8080/tcp tomcat02
962f961aa9ff tomcat "catalina.sh run" 33 seconds ago Up 33 seconds 0.0.0.0:32770->8080/tcp tomcat01
docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
# 如何可以解决名字相互能ping通
docker run -d -P --name tomcat03 --link tomcat02 tomcat
1e7d9cb504518d2232a019d46b6b8903e523a3afea00cff9015999c589b95de3
# 通过--link 即可解决网络通连问题
docker exec -it tomcat03 ping tomcat02
PING tomcat02 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat02 (172.17.0.3): icmp_seq=1 ttl=64 time=0.060 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.079 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.039 ms
# 反向可以ping通吗?
# 说白了就是hosts映射
本质探究:–link 就是我们在hosts配置中增加了 一个主机名
我们现在玩docker已经不建议使用–link 了
docker0问题:它不支持容器名连接访问!
自定义网络
查看所有的docker网络
网络模式
bridge : 桥接 docker (默认,自己创建也使用bridge 模式)
none : 不配置网络
host : 和宿主机共享网络
container : 容器内网络连通
测试
# 我们直接启动的命令 --net bridge tomcat ,而这个就是我们的docker0
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge tomcat
# docker0 特点: 默认,域名不能访问, --link可以打通连接!
# 我们可以自定义一个网络
--driver bridge
--subnet 192.168.0.0/16
--gateway 192.168.0.1 mynet
docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
我们自己的网络就创建好了
docker network inspect mynet
[
{
"Name": "mynet",
"Id": "da26f6e9e4b1e933e3fff1a4b15a237a84d2bb0b10ac90373fcf924ca00a831b",
"Created": "2020-11-22T21:54:57.105303537+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "192.168.0.0/16",
"Gateway": "192.168.0.1"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {
"1bfb6fde84692e8dcda970d7d33b50a134cce0eb6a6249b8f9347f8220b60405": {
"Name": "tomcat-net-02",
"EndpointID": "9878c14469536135c2b99eef2e04b289f92a6c0fdf4aa6e057e0d719f9051c5b",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
},
"d4254187aad62f77f5b0173e9f5e865072520885d46da15d28825334c25776ab": {
"Name": "tomcat-net-01",
"EndpointID": "e50724082235d4436330ad1f26a051f5e03389f62950b717eea7db88f46f48f3",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 再次测试ping连接
docker exec -it tomcat-net-01 ping 192.168.0.3
PING 192.168.0.3 (192.168.0.3) 56(84) bytes of data.
64 bytes from 192.168.0.3: icmp_seq=1 ttl=64 time=0.101 ms
64 bytes from 192.168.0.3: icmp_seq=2 ttl=64 time=0.058 ms
64 bytes from 192.168.0.3: icmp_seq=3 ttl=64 time=0.039 ms
# 现在不使用 --link也可以相互ping通了
docker exec -it tomcat-net-01 ping tomcat-net-02
PING tomcat-net-02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.048 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.040 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=3 ttl=64 time=0.041 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=4 ttl=64 time=0.041 ms
我们自定义的网络docker都已经帮我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
不同的集群使用不同的网络,保证集群是安全和健康的
网络连通
# 测试打通 tomcat01 - mynet
docker network connect mynet tomcat01
docker network inspect mynet
# 连通之后就是将 tomcat01 放到了 mynet 网络下
# 官方解释就是一个容器两个ip
# 阿里云服务器, 公网ip 私网ip
# 测试 01 连接ok
docker exec -it tomcat01 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.075 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.042 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=3 ttl=64 time=0.042 ms
# 02 是依旧打不通的
docker exec -it tomcat02 ping tomcat-net-01
ping: tomcat-net-01: Name or service not known
结论:假设要跨网操作,就需要需要docker network connect 连通 !
实战:部署Redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
docker network create redis --subnet 172.38.0.0/16
04ddb12d919d0b032a25fe3d1532b2faacba48f9cabaf1a9f4fa0a44ff1d0a38
[root@localhost ~]# docker network inspect redis
[
{
"Name": "redis",
"Id": "04ddb12d919d0b032a25fe3d1532b2faacba48f9cabaf1a9f4fa0a44ff1d0a38",
"Created": "2020-11-22T22:37:40.864981122+08:00",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": {},
"Config": [
{
"Subnet": "172.38.0.0/16"
}
]
},
"Internal": false,
"Attachable": false,
"Ingress": false,
"ConfigFrom": {
"Network": ""
},
"ConfigOnly": false,
"Containers": {},
"Options": {},
"Labels": {}
}
]
(redis配置文件挂载目录+运行脚本)
vim redis.sh
#!/bin/bash
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
docker run -p 637${port}:6379 -p1637${port}:16379 --name redis-${port} \
-v /mydata/redis/node-${port}/data:/data \
-v /mydata/redis/node-${port}/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.1${port} redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
done
创建集群
docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof nodes.conf
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 nodes
测试停掉172.38.0.13
docker stop redis-3
如果高可用替代成功了,从机就会自动替代主机
redis-cli -c
get a
docker搭建redis集群完成