Docker研学-Docker网络

学习自b站狂神说Docker: https://www.bilibili.com/video/BV1og4y1q7M4/?spm_id_from=333.337.search-card.all.click

Docker网络

原理

  1. 每启动一个容器,docker就会给容器分配一个地址,只要安装docker就会有一个默认网卡docker0(桥接模式),使用的技术是evth-pair技术
  2. 容器带来的网卡都是一对的,evth-pair就是一对虚拟设备接口,成对出现,一端连着协议,一端彼此相连(利用他充当桥梁,连接各种虚拟网络设备)
  3. 容器需要重复下载操作,可commit做一个自己的镜像(省去下载)

测试

# 获取ip地址 lo是本地回环地址 eth0是阿里云的内网地址 Docker0是Docker生成的地址(路由器)172.17.0.1
[root@localhost ~]# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN qlen 1
    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
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens32: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP qlen 1000
    link/ether 00:0c:29:83:43:d8 brd ff:ff:ff:ff:ff:ff
    inet 192.168.44.128/24 brd 192.168.44.255 scope global ens32
       valid_lft forever preferred_lft forever
    inet6 fe80::20c:29ff:fe83:43d8/64 scope link 
       valid_lft forever preferred_lft forever
3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> mtu 1500 qdisc noqueue state DOWN 
    link/ether 02:42:6a:af:7b:cc brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.1/16 brd 172.17.255.255 scope global docker0
       valid_lft forever preferred_lft forever
# 三种网络代表三种不同的环境

实现容器间的访问

# 查看容器内部的网络地址
[root@localhost ~]# docker run -d -P --name tomcat01 tomcat 

#tomcat容器可能没有ip addr命令 需进入容器手动安装
root@2e1f28f3c6d5:/usr/local/tomcat# apt update                    #更新apt依赖
root@2e1f28f3c6d5:/usr/local/tomcat# apt install -y iproute2       #安装ipaddr
root@2e1f28f3c6d5:/usr/local/tomcat# apt install -y net-tools      #安装ifconfig
root@2e1f28f3c6d5:/usr/local/tomcat# apt install -y iputils-ping   #安装ping

# 启动tomcat不进命令行看ip(精简命令) ip addr 容器启动会获得docker分配的ip地址 eth0@if9
[root@localhost ~]# docker exec -it tomcat1 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
8: eth0@if9: <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通容器内部 eth0@if9 172.17.0.2
[root@localhost ~]# ping 172.17.0.2
PING 172.17.0.2 (172.17.0.2) 56(84) bytes of data.
64 bytes from 172.17.0.2: icmp_seq=1 ttl=64 time=0.092 ms


# 启动容器后,再次执行ip addr会发现多出一个网卡 容器 8: eth0@if9 网卡 9: veth86be480@if8
[root@localhost ~]# ip addr
//......
9: veth86be480@if8: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 8e:44:40:04:e1:b3 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet6 fe80::8c44:40ff:fe04:e1b3/64 scope link 
       valid_lft forever preferred_lft forever

# 再启动一个容器测试,每启动一个容器,网卡就多一对 容器内也增加了 12: eth0@if13:
[root@localhost ~]# ip addr
//......
13: veth2a0e0b8@if12: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue master docker0 state UP 
    link/ether 0e:dd:58:44:0b:5e brd ff:ff:ff:ff:ff:ff link-netnsid 1
    inet6 fe80::cdd:58ff:fe44:b5e/64 scope link 
       valid_lft forever preferred_lft forever

# 在容器1可以ping通容器2
[root@localhost ~]# docker exec -it tomcat2 ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    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
12: eth0@if13: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    inet 172.17.0.3/16 brd 172.17.255.255 scope global eth0
       valid_lft forever preferred_lft forever
[root@localhost ~]# docker exec -it tomcat1 ping 172.17.0.3
PING 172.17.0.3 (172.17.0.3) 56(84) bytes of data.
64 bytes from 172.17.0.3: icmp_seq=1 ttl=64 time=35.1 ms

在这里插入图片描述
结论:容器1和2是公用的一个路由器(docker0),所有的容器不指定网络的情况下都是docker0,docker会给我们的容器分配一个默认的可用ip(有65535个)

小结

Docker使用的是Linux的桥接,宿主机中是一个Docker容器的网桥docker0,核心是使用了Linux的虚拟化网络技术,在容器内和docker0分别创建了虚拟网卡,通过evth-pair进行连接,Docker中所有的网络接口都是虚拟的(虚拟的网络效率高,类似内网传递)
在这里插入图片描述

若删除一个容器

# 删除容器的同时对应的一对网卡也会被删除
[root@localhost ~]# docker rm -f tomcat1
[root@localhost ~]# ip addr

docker每次启动会重新分配ip,ip会崩但服务名不变,服务名不变,项目就不需要重启,(数据库会宕机重启后IP就换掉了)需要做到通过名字访问容器,完成高可用。

–link

# 两个容器之间直接通过服务名ping不通(可解决)
[root@localhost ~]# docker exec -it tomcat1 ping tomcat2
ping: tomcat2: Name or service not known

# --link可实现 以服务名完成网络通信
[root@localhost ~]# docker run -d -P --name tomcat3 --link tomcat2 tomcat

# 3可ping通2,但2不能ping3(反向不通)
[root@localhost ~]# docker exec -it tomcat3 ping tomcat2
PING tomcat2 (172.17.0.3) 56(84) bytes of data.
64 bytes from tomcat2 (172.17.0.3): icmp_seq=1 ttl=64 time=0.054 ms
[root@localhost ~]# docker exec -it tomcat2 ping tomcat3
ping: tomcat3: Name or service not known

# 查看当前网络配置(bridge是docker0)
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
503e09d0e453   bridge    bridge    local
22f671f332f6   host      host      local
5f4d28c03a21   none      null      local

# 查看对应网卡的具体信息,启动服务,不指定ip,就会随机分配一个ip
[root@localhost ~]# docker network inspect 503e09d0e453
[
    {
        "Name": "bridge",
        "Id": "503e09d0e4539a7a786e67516e80c5de902b1ce90bdec51002f008304de6891c",
        "Created": "2023-10-24T09:03:06.242436289+08:00",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": null,
            "Config": [
                {
                    "Subnet": "172.17.0.0/16",
                    "Gateway": "172.17.0.1"             Docker0
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {                               启动的容器
            "19a1a4b71bc42464865e6d67274527d5ae8fcaa0ad7fa293e146c88ec4e9fe68": {
                "Name": "tomcat3",           
                "EndpointID": "5fd50887709fec04a7e5501c19b8d6bb6898c4ff4c8faf03e7b6b125fd3a6f82",
                "MacAddress": "02:42:ac:11:00:04",
                "IPv4Address": "172.17.0.4/16",
                "IPv6Address": ""
            },
            "4200b69eb015a7503699eede4f4dd8c564b49136a73804da5cd516862f04e29d": {
                "Name": "tomcat2",
                "EndpointID": "6b29c3d57349dffcaed1c9bec1671d8923991b7e35a085840b29052011ac68f9",
                "MacAddress": "02:42:ac:11:00:03",
                "IPv4Address": "172.17.0.3/16",
                "IPv6Address": ""
            },
            "76342dafbaa1702a9d8b8ee5ab9444ccdf59f0328f2e33e1deca97451f2dc4b5": {
                "Name": "tomcat1",
                "EndpointID": "d70da230988aa9e961d835cd7e397a8a7feaa872aac499aec0c413dbe5a94fc3",
                "MacAddress": "02:42:ac:11:00:02",
                "IPv4Address": "172.17.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {
            "com.docker.network.bridge.default_bridge": "true",
            "com.docker.network.bridge.enable_icc": "true",
            "com.docker.network.bridge.enable_ip_masquerade": "true",
            "com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
            "com.docker.network.bridge.name": "docker0",
            "com.docker.network.driver.mtu": "1500"
        },
        "Labels": {}
    }
]

# 查看tomcat2的详细信息
[root@localhost ~]# docker inspect 4200b69eb015
//......
"NetworkSettings": {                                网络设置
            "Bridge": "",
            "SandboxID": "f089fd4fff3bd78be835064252c0743204387eb4c62ac2bb6ebba9c36f2aa265",
"HairpinMode": false,
            "LinkLocalIPv6Address": "",
            "LinkLocalIPv6PrefixLen": 0,
            "Ports": {
                "8080/tcp": [
                    {
                        "HostIp": "0.0.0.0",
                        "HostPort": "32768"
                    },
                    {
                        "HostIp": "::",
                        "HostPort": "32768"
                    }
                ]
            },
//......
"Networks": {
                "bridge": {
                    "IPAMConfig": null,
                    "Links": null,
                    "Aliases": null,
                    "NetworkID": "503e09d0e4539a7a786e67516e80c5de902b1ce90bdec51002f008304de6891c",
                    "EndpointID": "6b29c3d57349dffcaed1c9bec1671d8923991b7e35a085840b29052011ac68f9",
                    "Gateway": "172.17.0.1",             网关
                    "IPAddress": "172.17.0.3",           ip地址
                    "IPPrefixLen": 16,
                    "IPv6Gateway": "",
                    "GlobalIPv6Address": "",
                    "GlobalIPv6PrefixLen": 0,
                    "MacAddress": "02:42:ac:11:00:03",
                    "DriverOpts": null
}

# 原理其实是容器3在本地配置了容器2的配置,进入容器查看,linux下/etc/hosts文件是配置本地绑定的(破解软件,若配置了 127.0.0.1 www.baidu.com则请求百度会走到127)
[root@localhost ~]# docker exec -it tomcat3 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	tomcat2 4200b69eb015      #容器内写死,访问容器2,走到172.17.0.3
172.17.0.4	19a1a4b71bc4

–link在hosts配置中增加了一个映射172.17.0.3 tomcat2 4200b69eb015(单向的,需两边都配置),目前不建议使用了,有局限性

docker0不支持容器名连接访问,域名不能访问,–link可以打通连接(网络默认就是他)

自定义网络-容器互联

# 移除网卡
[root@localhost ~]# docker network rm mynet

# 查看所有的docker网络
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
503e09d0e453   bridge    bridge    local
22f671f332f6   host      host      local
5f4d28c03a21   none      null      local

# 网络模式
bridge:桥接模式(默认,自己创建也用这个)(1,2不能直接访问,但1可以通过3访问2)
none:不配置网络
host:和宿主机共享网络
container:容器网络连通(用得少)(直接互联但局限性很大)

测试

# 通过docker network --help命令查看帮助文档

#直接启动的命令有默认的隐藏项--net bridge,这个就是docker0(bridge是他的名字)
docker run -d -P --name tomcat01 tomcat
docker run -d -P --name tomcat01 --net bridge  tomcat

# 通过create创建自定义网络,桥接模式,子网掩码,网关(从哪里出去),名字
# --driver bridge           默认,不写也是他
# --subnet 192.168.0.0/16   是192.168.0.2到192.168.255.255
# --gateway 192.168.0.1     网关 从这出去
[root@localhost ~]# docker network create --driver bridge --subnet 192.168.0.0/16 --gateway 192.168.0.1 mynet
41fd8e2a01d879385326e021f32a0aadfe3bb4ca5afb15b534895d4257e7ab9d

# 查看创建的网络
[root@localhost ~]# docker network ls
NETWORK ID     NAME      DRIVER    SCOPE
503e09d0e453   bridge    bridge    local
22f671f332f6   host      host      local
41fd8e2a01d8   mynet     bridge    local
5f4d28c03a21   none      null      local

# 查看网络详细信息
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "41fd8e2a01d879385326e021f32a0aadfe3bb4ca5afb15b534895d4257e7ab9d",
        "Created": "2023-10-24T10:40:57.415257632+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": {},
        "Options": {},
        "Labels": {}
    }
]

# 创建容器走自定义网络
[root@localhost ~]# docker run -d -P --name tomcat-net01 --net mynet tomcat2:1.0
ae072824e82d4718c678cdf65d4500b9e0c5e5ca01a986f46d05d31744898aa1
[root@localhost ~]# docker run -d -P --name tomcat-net02 --net mynet tomcat2:1.0
ee998de82b55e24497d4c531a2788e3ca0c268acf7a3582ea941970e35d7bd10

# 网络内创建容器后的具体信息,是我们预先分配的ip
[root@localhost ~]# docker network inspect mynet
[
    {
        "Name": "mynet",
        "Id": "41fd8e2a01d879385326e021f32a0aadfe3bb4ca5afb15b534895d4257e7ab9d",
        "Created": "2023-10-24T10:40:57.415257632+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": {                     出现了我们创建的容器
            "ae072824e82d4718c678cdf65d4500b9e0c5e5ca01a986f46d05d31744898aa1": {
                "Name": "tomcat-net01",
                "EndpointID": "64c71d020f0d40b0229d71eeec8054e73652073d0418d045545e8f7c8bb85642",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "ee998de82b55e24497d4c531a2788e3ca0c268acf7a3582ea941970e35d7bd10": {
                "Name": "tomcat-net02",
                "EndpointID": "e452021914e0c10e0243aa1a7bf4289791be6a89b46f0a7eec5bc42857e2fd49",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

# 自定义网络容器不配置--link也可以ping通(ip和服务名),docker0的缺点被修复
[root@localhost ~]# docker exec -it tomcat-net01 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=6.87 ms
[root@localhost ~]# docker exec -it tomcat-net01 ping tomcat-net02
PING tomcat-net02 (192.168.0.3) 56(84) bytes of data.
64 bytes from tomcat-net02.mynet (192.168.0.3): icmp_seq=1 ttl=64 time=0.097 ms

自定义网络docker已经维护好对应的关系,推荐使用。

好处:不同的网络间是隔离的(有自己的子网),互不影响(可以打通)

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

网络连通-跨网络操作

# 不同网络的容器间不能够直接ping通(192.168.0.3与172.17.0.3)
[root@localhost ~]# docker run -d -P --name tomcat05 tomcat2:1.0
476d764c4f0429482c10aa353aa01ecd05ecccac8f16d9bd48c76092dc6427d5
[root@localhost ~]# docker exec -it tomcat05 ping tomcat-net01
ping: tomcat-net01: Name or service not known

# docker network connect 打通tomcat05-mynet
# 连通就是将tomcat05放到了mynet网络下(一个容器2个ip)
[root@localhost ~]# docker network connect mynet tomcat05
[root@localhost ~]# docker network inspect mynet
//......
        "Containers": {
            "476d764c4f0429482c10aa353aa01ecd05ecccac8f16d9bd48c76092dc6427d5": {
                "Name": "tomcat05",        容器05放到了mynet网络中
                "EndpointID": "6bfb6ba5241b0a1c23cbc80352f178c87241eb8610cb15868acc0d87bca89cef",
                "MacAddress": "02:42:c0:a8:00:04",
                "IPv4Address": "192.168.0.4/16",
                "IPv6Address": ""
            },
            "ae072824e82d4718c678cdf65d4500b9e0c5e5ca01a986f46d05d31744898aa1": {
                "Name": "tomcat-net01",
                "EndpointID": "64c71d020f0d40b0229d71eeec8054e73652073d0418d045545e8f7c8bb85642",
                "MacAddress": "02:42:c0:a8:00:02",
                "IPv4Address": "192.168.0.2/16",
                "IPv6Address": ""
            },
            "ee998de82b55e24497d4c531a2788e3ca0c268acf7a3582ea941970e35d7bd10": {
                "Name": "tomcat-net02",
                "EndpointID": "e452021914e0c10e0243aa1a7bf4289791be6a89b46f0a7eec5bc42857e2fd49",
                "MacAddress": "02:42:c0:a8:00:03",
                "IPv4Address": "192.168.0.3/16",
                "IPv6Address": ""
//......
]

# 再次尝试ping操作,可以ping通,但05同网络下的其他容器是不通的
[root@localhost ~]# docker exec -it tomcat05 ping tomcat-net01
PING tomcat-net01 (192.168.0.2) 56(84) bytes of data.
64 bytes from tomcat-net01.mynet (192.168.0.2): icmp_seq=1 ttl=64 time=0.116 ms

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

泰勒疯狂展开

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值