1、Docker网络
Docker有多种网络模式可以选择,可以根据应用场景和需求选择合适的网络模式。
- 桥接模式(Bridge Mode):默认情况下,Docker使用桥接模式创建一个虚拟网络,所有容器会连接到这个虚拟网络中。每个容器分配一个IP地址并且可以通过主机的IP地址进行访问。可以使用
--network bridge
参数指定桥接模式。 - 主机模式(Host Mode):容器直接使用宿主机的网络,不会创建虚拟网络。容器和宿主机共享网络接口和IP地址,因此容器可以通过宿主机的IP地址进行访问。可以使用
--network host
参数指定主机模式。 - 容器模式(Container Mode):可以将多个容器连接在同一个网络中,这些容器可以直接通过容器的名称进行通信,而不需要指定IP地址。可以使用
--network container:<container_name>
参数将容器添加到指定的网络中。 - 无网络模式(None Mode):容器没有网络接口,与外界隔离,只能通过进程间通信(IPC)或者共享卷(Volumes)进行通信。可以使用
--network none
参数指定无网络模式。
除了以上四种基本模式,Docker还支持自定义网络模式,并提供了网络插件机制,可以根据实际需求创建自己的网络模式。
使用方法:
- 创建一个网络:
docker network create <network_name>
- 启动一个容器并连接到指定网络:
docker run --network <network_name> <container_name>
- 查看网络信息:
docker network inspect <network_name>
- 删除网络:
docker network rm <network_name>
可以通过docker network --help
命令查看更多关于网络的使用方法和选项。
1)理解Docker0
清空所有环境
测试
三个网络
问题: docker 是如何处理容器网络访问的?
创建3个容器,查看3个容器分别和linux主机的网桥绑定
原理
1.我们每启动一个docker容器,docker就会给docker容器分配一个ip,我们只要按照了docker,就会有一个docker0桥接模式,使用的技术是veth-pair技术!
再次测试ip add
# 我们发现这个容器带来网卡,都是一对对的
# veth-pair 就是一对的虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连
# 正因为有这个特性 veth-pair 充当一个桥梁,连接各种虚拟网络设备的
# OpenStac,Docker容器之间的连接,OVS的连接,都是使用evth-pair技术
2.我们来测试一下 tomcat1 和 tomcat2 是否可以ping 通
tomcat01和tomcat02使用主机和容器的相互绑定网卡,去互相ping,是可以成功的
结论 :
- tomcat01 和 tomcat02 是公用一个路由器,docker0。
- 所有的容器不指定网络的情况下,都是通过docker0路由的,docker会给我们的容器分配一个默认的可用IP
小结
Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0
与外面网络的连接:直连的方式
Docker中所有网络接口都是虚拟的,虚拟的转发效率高(内网传递文件)。
只要容器删除,对应的网桥一对就没了!
思考一个场景:我们编写了一个微服务,database url=ip: 项目不重启,数据ip换了,我们希望可以处理这个问题,可以通过名字来进行访问容器?
2)–link
[root@AlibabaECS ~]# docker exec -it tomcat02 ping tomcat01
ping: tomcat01: Name or service not known
# ping不通
# 如何解决呢?
# 通过 --link 就可以解决了
[root@AlibabaECS ~]# 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.171 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=2 ttl=64 time=0.092 ms
64 bytes from tomcat02 (172.17.0.3): icmp_seq=3 ttl=64 time=0.104 ms
# 用tomcat02 ping tomcat03 ping不通
添加–link后
inspect网络:查看配置的信息
查看tomcat03就是在在本地配置了tomcat02的配置
# 查看hosts 配置,在这里原理发现
[root@AlibabaECS ~]# docker exec -it tomcat03 cat /etc/hosts
127.0.0.1 localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.3 tomcat02 c2e5a8a29151
172.17.0.4 50b163f99e32
镜像中有IP映射后,才能互相ping通
–link 本质就是在hosts配置中添加映射
现在使用Docker已经不建议使用–link了!
自定义网络,不适用docker0!
docker0问题:不支持容器名连接访问!
3)自定义网络
查看所有的docker网络
docker network inspect
网络模式
bridge :桥接 docker(默认,自己创建也是用bridge模式)
none :不配置网络,一般不用
host :和宿主机共享网络
container :容器网络连通(用得少!局限很大)
①测试
# 我们直接启动的命令
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 网关
[root@xxx ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
dd7c8522864cb87c332d355ccd837d94433f8f10d58695ecf278f8bcfc88c1fc
[root@xxx ~]# docker network ls
NETWORK ID NAME DRIVER SCOPE
04038c2f1d64 bridge bridge local
81476375c43d host host local
dd7c8522864c mynet bridge local
64ba38c2cb2b none null local
自己的网络就创建好了
②使用自定义的网络
[root@xxx ~]# docker run -d -P --name tomcat-net-01 --net mynet tomcat
1de6f5994a480160d932de239b104b366ebd5b954e740a5ab8c0d5aeea8f5ba5
[root@xxx ~]# docker run -d -P --name tomcat-net-02 --net mynet tomcat
f26916a49e5ee239aee23584020e0d23d53d2e644d5cb5155d831edc0803d957
[root@xxx ~]# docker network inspect mynet
[
{
"Name": "mynet",
"Id": "dd7c8522864cb87c332d355ccd837d94433f8f10d58695ecf278f8bcfc88c1fc",
"Created": "2020-09-05T12:43:54.847233062+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": {
"1de6f5994a480160d932de239b104b366ebd5b954e740a5ab8c0d5aeea8f5ba5": {
"Name": "tomcat-net-01",
"EndpointID": "c308999d4e51ed9e5975f3b4f3c1d468bfb08d93de7561d55062db055f44ef18",
"MacAddress": "02:42:c0:a8:00:02",
"IPv4Address": "192.168.0.2/16",
"IPv6Address": ""
},
"f26916a49e5ee239aee23584020e0d23d53d2e644d5cb5155d831edc0803d957": {
"Name": "tomcat-net-02",
"EndpointID": "8d9dbdd6ca119559ef4f1dd82a36e0d279c0b8284fe19f36c6d992047937a764",
"MacAddress": "02:42:c0:a8:00:03",
"IPv4Address": "192.168.0.3/16",
"IPv6Address": ""
}
},
"Options": {},
"Labels": {}
}
]
# 再次测试ping连接 , 现在不适用 --link 也可以ping名字了
[root@xxx ~]# 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.094 ms
64 bytes from tomcat-net-02.mynet (192.168.0.3): icmp_seq=2 ttl=64 time=0.067 ms
我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!
好处:
redis - 不同的集群使用不同的网络,保证集群是健康和安全的
mysql - 不同的集群使用不同的网络,保证集群是健康安全的
4)网络连通
将tomcat01和tomcat-net-01相连
如果直接将两个网络相连,网关就变了,不行,所以只需要把容器和网络相连就好了
# 测试打通 tomcat - mynet
[root@xxx ~]# docker network connect mynet tomcat01
# 连通之后就是将 tomcat01 放到了 mynet 网络下
# 一个容器两个ip地址
# 阿里云服务:公网ip 私网ip
结果:
# 01连通ok
[root@AlibabaECS ~]# 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.098 ms
64 bytes from tomcat-net-01.mynet (192.168.0.2): icmp_seq=2 ttl=64 time=0.091 ms
# 02依旧是打不通的
[root@AlibabaECS ~]# docker exec -it tomcat02 ping tomcat-net-01
Error: No such container: tomcat02
结论:需要进行跨网络操作,就需要使用docker network connect 连通!
5)实战:部署Redis集群
# 创建网卡
docker network create redis --subnet 172.38.0.0/16
# 通过脚本创建六个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
# 创建结点1
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 --net redis --ip 172.38.0.11 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点2
docker run -p 6372:6379 -p 16372:16379 --name redis-2 \
-v /mydata/redis/node-2/data:/data \
-v /mydata/redis/node-2/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.12 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点3
docker run -p 6373:6379 -p 16373:16379 --name redis-3 \
-v /mydata/redis/node-3/data:/data \
-v /mydata/redis/node-3/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.13 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点4
docker run -p 6374:6379 -p 16374:16379 --name redis-4 \
-v /mydata/redis/node-4/data:/data \
-v /mydata/redis/node-4/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.14 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点5
docker run -p 6375:6379 -p 16375:16379 --name redis-5 \
-v /mydata/redis/node-5/data:/data \
-v /mydata/redis/node-5/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.15 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
#创建结点6
docker run -p 6376:6379 -p 16376:16379 --name redis-6 \
-v /mydata/redis/node-6/data:/data \
-v /mydata/redis/node-6/conf/redis.conf:/etc/redis/redis.conf \
-d --net redis --ip 172.38.0.16 redis:5.0.9-alpine3.11 redis-server /etc/redis/redis.conf
# 创建集群
[root@iZ2zeg4ytp0whqtmxbsqiiZ ~]# docker exec -it redis-1 /bin/sh
/data # ls
appendonly.aof nodes.conf
/data # 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
>>> Performing hash slots allocation on 6 nodes...
Master[0] -> Slots 0 - 5460
Master[1] -> Slots 5461 - 10922
Master[2] -> Slots 10923 - 16383
Adding replica 172.38.0.15:6379 to 172.38.0.11:6379
Adding replica 172.38.0.16:6379 to 172.38.0.12:6379
Adding replica 172.38.0.14:6379 to 172.38.0.13:6379
M: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
replicates 259e804d6df74e67a72e4206d7db691a300c775e
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
Can I set the above configuration? (type 'yes' to accept): yes
>>> Nodes configuration updated
>>> Assign a different config epoch to each node
>>> Sending CLUSTER MEET messages to join the cluster
Waiting for the cluster to join
...
>>> Performing Cluster Check (using node 172.38.0.11:6379)
M: 541b7d237b641ac2ffc94d17c6ab96b18b26a638 172.38.0.11:6379
slots:[0-5460] (5461 slots) master
1 additional replica(s)
M: a89c1f1245b264e4a402a3cf99766bcb6138dbca 172.38.0.12:6379
slots:[5461-10922] (5462 slots) master
1 additional replica(s)
S: 7a16b9bbb0615ec95fc978fa62fc054df60536f0 172.38.0.16:6379
slots: (0 slots) slave
replicates a89c1f1245b264e4a402a3cf99766bcb6138dbca
S: 061a9d38f22910aaf0ba1dbd21bf1d8f57bcb7d5 172.38.0.15:6379
slots: (0 slots) slave
replicates 541b7d237b641ac2ffc94d17c6ab96b18b26a638
M: 259e804d6df74e67a72e4206d7db691a300c775e 172.38.0.13:6379
slots:[10923-16383] (5461 slots) master
1 additional replica(s)
S: 9b19170eea3ea1b92c58ad18c0b5522633a9e271 172.38.0.14:6379
slots: (0 slots) slave
replicates 259e804d6df74e67a72e4206d7db691a300c775e
[OK] All nodes agree about slots configuration.
>>> Check for open slots...
>>> Check slots coverage...
[OK] All 16384 slots covered.
1.开启6个redis镜像服务
2.配置集群的所有的IP
3.启动集群
①测试高可用
14是13的从机,13宕掉后,14选举成为master,保证服务的运行,保证了集群的高可用
docker搭建redis集群完成!
我们使用了Docker之后,所有的技术都会变得简单起来!
2、SpringBoot微服务打包Docker镜像
- 架构springboot项目
- 打包应用
- 编写dockerfile
- 构建镜像
- 发布运行
- 以后我们使用了Docker之后,给别人交付的就是一个镜像即可!