1、Docker网络

Docker有多种网络模式可以选择,可以根据应用场景和需求选择合适的网络模式。

  1. 桥接模式(Bridge Mode):默认情况下,Docker使用桥接模式创建一个虚拟网络,所有容器会连接到这个虚拟网络中。每个容器分配一个IP地址并且可以通过主机的IP地址进行访问。可以使用--network bridge参数指定桥接模式。
  2. 主机模式(Host Mode):容器直接使用宿主机的网络,不会创建虚拟网络。容器和宿主机共享网络接口和IP地址,因此容器可以通过宿主机的IP地址进行访问。可以使用--network host参数指定主机模式。
  3. 容器模式(Container Mode):可以将多个容器连接在同一个网络中,这些容器可以直接通过容器的名称进行通信,而不需要指定IP地址。可以使用--network container:<container_name>参数将容器添加到指定的网络中。
  4. 无网络模式(None Mode):容器没有网络接口,与外界隔离,只能通过进程间通信(IPC)或者共享卷(Volumes)进行通信。可以使用--network none参数指定无网络模式。

除了以上四种基本模式,Docker还支持自定义网络模式,并提供了网络插件机制,可以根据实际需求创建自己的网络模式。

使用方法:

  1. 创建一个网络:docker network create <network_name>
  2. 启动一个容器并连接到指定网络:docker run --network <network_name> <container_name>
  3. 查看网络信息:docker network inspect <network_name>
  4. 删除网络:docker network rm <network_name>

可以通过docker network --help命令查看更多关于网络的使用方法和选项。

1)理解Docker0

清空所有环境

查看docker 服务之间的 网络通讯 查看dockerip_redis

查看docker 服务之间的 网络通讯 查看dockerip_redis_02

测试

三个网络

查看docker 服务之间的 网络通讯 查看dockerip_网络_03

问题: docker 是如何处理容器网络访问的?

创建3个容器,查看3个容器分别和linux主机的网桥绑定

查看docker 服务之间的 网络通讯 查看dockerip_docker_04

查看docker 服务之间的 网络通讯 查看dockerip_学习_05


查看docker 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_06

原理

查看docker 服务之间的 网络通讯 查看dockerip_docker_07

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,是可以成功的

查看docker 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_08

结论 :

  1. tomcat01 和 tomcat02 是公用一个路由器,docker0。
  2. 所有的容器不指定网络的情况下,都是通过docker0路由的,docker会给我们的容器分配一个默认的可用IP

小结

Docker使用的是Linux的桥接,宿主机是一个Docker容器的网桥 docker0

查看docker 服务之间的 网络通讯 查看dockerip_redis_09

与外面网络的连接:直连的方式

查看docker 服务之间的 网络通讯 查看dockerip_网络_10

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不通

查看docker 服务之间的 网络通讯 查看dockerip_redis_11

添加–link后

查看docker 服务之间的 网络通讯 查看dockerip_学习_12

inspect网络:查看配置的信息

查看docker 服务之间的 网络通讯 查看dockerip_学习_13


查看docker 服务之间的 网络通讯 查看dockerip_docker_14

查看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

查看docker 服务之间的 网络通讯 查看dockerip_网络_15

查看docker 服务之间的 网络通讯 查看dockerip_网络_16

镜像中有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 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_17

查看docker 服务之间的 网络通讯 查看dockerip_redis_18

我们自定义的网络docker当我们维护好了对应的关系,推荐我们平时这样使用网络!

好处:

redis - 不同的集群使用不同的网络,保证集群是健康和安全的

mysql - 不同的集群使用不同的网络,保证集群是健康安全的

查看docker 服务之间的 网络通讯 查看dockerip_网络_19

4)网络连通

查看docker 服务之间的 网络通讯 查看dockerip_学习_20

将tomcat01和tomcat-net-01相连

查看docker 服务之间的 网络通讯 查看dockerip_docker_21

如果直接将两个网络相连,网关就变了,不行,所以只需要把容器和网络相连就好了

查看docker 服务之间的 网络通讯 查看dockerip_学习_22

# 测试打通 tomcat - mynet
[root@xxx ~]# docker network connect mynet tomcat01

# 连通之后就是将 tomcat01 放到了 mynet 网络下

# 一个容器两个ip地址
# 阿里云服务:公网ip  私网ip

查看docker 服务之间的 网络通讯 查看dockerip_docker_23

结果:

查看docker 服务之间的 网络通讯 查看dockerip_学习_24

查看docker 服务之间的 网络通讯 查看dockerip_redis_25

# 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 服务之间的 网络通讯 查看dockerip_学习_26

# 创建网卡
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镜像服务

查看docker 服务之间的 网络通讯 查看dockerip_redis_27

2.配置集群的所有的IP

查看docker 服务之间的 网络通讯 查看dockerip_学习_28

查看docker 服务之间的 网络通讯 查看dockerip_学习_29

3.启动集群

查看docker 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_30

①测试高可用

查看docker 服务之间的 网络通讯 查看dockerip_学习_31

14是13的从机,13宕掉后,14选举成为master,保证服务的运行,保证了集群的高可用

查看docker 服务之间的 网络通讯 查看dockerip_网络_32

docker搭建redis集群完成!
我们使用了Docker之后,所有的技术都会变得简单起来!

2、SpringBoot微服务打包Docker镜像

  1. 架构springboot项目
  2. 打包应用
  3. 编写dockerfile
  4. 构建镜像
  5. 发布运行
  6. 以后我们使用了Docker之后,给别人交付的就是一个镜像即可!

查看docker 服务之间的 网络通讯 查看dockerip_网络_33

查看docker 服务之间的 网络通讯 查看dockerip_网络_34

查看docker 服务之间的 网络通讯 查看dockerip_网络_35

查看docker 服务之间的 网络通讯 查看dockerip_docker_36

查看docker 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_37

查看docker 服务之间的 网络通讯 查看dockerip_查看docker 服务之间的 网络通讯_38