• Docker0网络及原理探究


    个人观点:Docker网络通信在容器编排、集群部署中具有举足轻重的地位,(玩docker不懂docker0那就......玩不透哇👀)本篇分析Docker网络,并通过启动几个容器来探究Docker网络及容器通信,帮助读者理解一下😊。

    1、Docker0

    Docker 服务默认会创建一个 docker0 网桥(其上有一个 docker0 内部接口),它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和本地主机都放到同一个物理网络。

    Docker 默认指定了 docker0 接口 的 IP 地址和子网掩码,让主机和容器之间可以通过网桥相互通信,它还给出了 MTU(接口允许接收的最大传输单元),通常是 1500 Bytes,或宿主主机网络路由上支持的默认值。这些值都可以在服务启动的时候进行配置。

    2、清空所有镜像

    如果是初学者,还不是很了解docker0的情况下,建议清空所有镜像,创造一个比较干净的容器网络环境,更加清晰,有助于学习docker0😃

    # 1. 查看运行的容器
    docker ps
    
    # 2. 停掉所有正在运行的容器(否则删除不掉)
    docker stop [containerID]   # docker stop $(docker container ls -q)
    
    # 3. 执行删除
    docker rmi -f $(docker images -aq)
    
    # 4. 查看镜像
    docker images
    

    3、查看网卡信息

    1. 先了解一下ip addr命令
    ip addr
    
    lo        # 本机回环地址 127.0.0.1
    eth0      # 阿里云内网地址 172.31.81.32
    docker0   # docker生成的网卡 172.17.0.1
    
    1. 获取当前网卡ip地址和mac地址
    [root@--- ~]# ip addr
    1: lo:  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
    2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:16:3e:0a:00:34 brd ff:ff:ff:ff:ff:ff
        inet 172.31.81.32/20 brd 172.31.95.255 scope global dynamic eth0
           valid_lft 291944112sec preferred_lft 291944112sec
    3: docker0:  mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:a4:2f:c5:62 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@--- ~]# 
    
    

    下面通过docker启动几个容器来探究一下Docker网络👇

    4、运行容器之后,再次查看网卡信息

    安装Docker时,它会自动创建三个网络,默认bridge网桥(创建容器默认连接到此网络)、 nonehost

    4.1、运行mysql01, centos01, centos02容器

    • 启动时,docker默认的bridge网桥,docker0给容器服务自动分配ip
    docker run -it --name mysql01 -e MYSQL_ROOT_PASSWORD=123 mysql:5.7
    docker run -it --name centos01  centos /bin/bash
    docker run -it --name centos02  centos /bin/bash
    

    4.2、查看ip、mac地址信息

    • 可以看到上面启动的三个容器服务的mac信息
    $ ip addr
    1: lo:  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
    2: eth0:  mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
        link/ether 00:16:3e:0a:00:34 brd ff:ff:ff:ff:ff:ff
        inet 172.31.81.32/20 brd 172.31.95.255 scope global dynamic eth0
           valid_lft 291916543sec preferred_lft 291916543sec
    3: docker0:  mtu 1500 qdisc noqueue state UP group default 
        link/ether 02:42:a4:2f:c5:62 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
    140: br-799426d70aa2:  mtu 1500 qdisc noqueue state DOWN group default 
        link/ether 02:42:7f:01:1d:00 brd ff:ff:ff:ff:ff:ff
        inet 172.18.0.1/16 brd 172.18.255.255 scope global br-799426d70aa2
           valid_lft forever preferred_lft forever
    154: vethe3da564@if153:  mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether ea:84:fb:14:47:99 brd ff:ff:ff:ff:ff:ff link-netnsid 0
    156: veth6477da5@if155:  mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 86:35:30:8d:14:85 brd ff:ff:ff:ff:ff:ff link-netnsid 1
    158: veth17b2712@if157:  mtu 1500 qdisc noqueue master docker0 state UP group default 
        link/ether 72:76:f0:3c:17:e8 brd ff:ff:ff:ff:ff:ff link-netnsid 2
    

    4.3、查看docker网络

    [root@--- ~]# docker network ls
    NETWORK ID     NAME      DRIVER    SCOPE
    feafa30d4051   bridge    bridge    local
    e8bf4fced9e2   host      host      local
    6263db0933b9   none      null      local
    [root@--- ~]# 
    

    4.4、查看默认bridge网桥(docker0)

    [root@--- ~]# docker network inspect feafa30d4051
    [
        {
            "Name": "bridge",
            "Id": "feafa30d4051f24353508959bd420fd163ad0c98d6b30ec8ff13b59a59552bb1",
            "Created": "2021-09-26T15:10:27.167774553+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"
                    }
                ]
            },
            "Internal": false,
            "Attachable": false,
            "Ingress": false,
            "ConfigFrom": {
                "Network": ""
            },
            "ConfigOnly": false,
            "Containers": {
                "29298987c51b777b546bf6626560020ce235e390e1d7fcfe188c6db228ca4edf": {
                    "Name": "mysql01",
                    "EndpointID": "f6572c49234f74a6c0b652a379bb386f843ebd23b02abd59b1f6a9d1c9534b17",
                    "MacAddress": "02:42:ac:11:00:02",
                    "IPv4Address": "172.17.0.2/16",    # ✨容器的IP✨
                    "IPv6Address": ""
                },
                "cb1922b95b9316d129b54f3545fad9729092926e10a1d5517f8928db42706151": {
                    "Name": "centos01",
                    "EndpointID": "ef6cfa74f56bfa4f49143aa08cf323812002236bc63f75204dee7c3ec1162250",
                    "MacAddress": "02:42:ac:11:00:03",
                    "IPv4Address": "172.17.0.3/16",    # ✨容器的IP✨
                    "IPv6Address": ""
                },
                "cc6f510b9765ba018dbafd416c9774ddf5fd3ff55fa992827f55516e8dc70b6a": {
                    "Name": "centos02",
                    "EndpointID": "2f901aec8f8b455d1fb06112c9035a19f34cc597d8907f26f1b896f12d7eb7ba",
                    "MacAddress": "02:42:ac:11:00:04",
                    "IPv4Address": "172.17.0.4/16",    # ✨容器的IP✨
                    "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": {}
        }
    ]
    

    4.5、测试容器通信

    此时,进入centos01容器,ping mysql容器的ip可以ping通,但是ping不通容器名 ❗

    docker exec -it cb1922b95b93 /bin/bash
    ping 172.17.0.2
    
    # docker0不支持容器名连接访问
    ping mysql01
    ping: mysql01: Name or service not known
    
    
    docker run 启动镜像的时候docker都会分配一个网卡地址
    
    #查看运行容器的ip
    docker inspect 容器ID | grep IPAddress
    

    如下图👇

    5、容器通信原理

    • 只要我们安装了docker,就会有一个网卡docker0(相当于一个路由器),每启动一个docker容器,docker都会给docker容器分配一个ip(连接路由器的终端,同一网段下终端可以互相通信),

    • 通过evth-pair技术实现,evth-pair就是一对虚拟设备接口,他们都是成对出现的,一端连着协议,一端彼此相连,evth-pair充当一个桥梁,连接各种虚拟网络设备。

    • Docker网络使用的是Linux桥接,宿主机是docker容器的网桥,docker0,最多分配65535个

    • 删除容器之后,虚拟网卡就自动消失了。(虚拟网卡传递效率高!

    启动容器不设置网络,容器ip由docker0自动分配情况下,容器间的通信,要经过evth-pair技术实现,并不是直连的。(跟计算机网络通信类似,分层模型,TCP/IP协议数据报封装解封装)

    5.1、结论

    1. tomcat01,tomcat02是共用的一个路由器,docker0

    2. 所有的容器启动时,如果不指定网络的情况下,都是docker0路由的。65535

    最后

    上面docker0不支持容器名连接访问,容器通信只可以通过容器ip通信,docker也无法保证容器重启后的IP地址不变,所以更好的方式是通过别名进行互联,下篇继续讲解怎么通过别名进行容器通信,😊😊。


    🌹 持续更文,关注我,你会发现一个踏实努力的宝藏前端😊,让我们一起学习,共同成长吧。

    🎉 喜欢的小伙伴记得点赞关注收藏哟,回看不迷路 😉

    🎁 欢迎大家评论交流, 蟹蟹😊

  • 相关阅读:
    Redis系列23:性能优化指南
    使用Harbor搭建Docker仓库
    牛客周赛 Round 15 D 游游的树上边染红(树形dp)
    研究发现,每天冲洗鼻腔,可减少新冠症状和死亡风险
    【leetcode】2259. 移除指定数字得到的最大结果(js实现)
    编程语言发展史:高级语言的兴起
    ICLR‘23 UnderReview | LightGCL: 简单而有效的图对比学习推荐系统
    刷题##day4
    猿创征文|瑞吉外卖——移动端_邮箱验证码登录
    怎么将视频转换成mp4?
  • 原文地址:https://www.cnblogs.com/all-smile/p/16633820.html