写点什么

Docker 网络及原理探究

作者:甜点cc
  • 2022-10-22
    河南
  • 本文字数:4159 字

    阅读完需:约 14 分钟

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

1、Docker0

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


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

2、清空所有镜像

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


  1. 查看运行的容器

docker ps

  1. 停掉所有正在运行的容器(否则删除不掉)

docker stop [containerID] # docker stop $(docker container ls -q)

  1. 执行删除

docker rmi -f $(docker images -aq)

  1. 查看镜像

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 addr1: 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 forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 291944112sec3: docker0: <NO-CARRIER,BROADCAST,MULTICAST,UP> 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.7docker run -it --name centos01  centos /bin/bashdocker run -it --name centos02  centos /bin/bash
复制代码

4.2、查看 ip、mac 地址信息

  • 可以看到上面启动的三个容器服务的mac信息

ip addr


$ ip addr1: 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 forever2: eth0: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 291916543sec3: docker0: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 forever140: br-799426d70aa2: <NO-CARRIER,BROADCAST,MULTICAST,UP> 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 forever154: vethe3da564@if153: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 0156: veth6477da5@if155: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 1158: veth17b2712@if157: <BROADCAST,MULTICAST,UP,LOWER_UP> 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 网络

docker network ls

[root@--- ~]# docker network lsNETWORK ID     NAME      DRIVER    SCOPEfeafa30d4051   bridge    bridge    locale8bf4fced9e2   host      host      local6263db0933b9   none      null      local[root@--- ~]# 
复制代码

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

ocker network inspect

[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/bashping 172.17.0.2
# docker0不支持容器名连接访问ping mysql01ping: mysql01: Name or service not known

docker run 启动镜像的时候docker都会分配一个网卡地址
#查看运行容器的ipdocker 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 地址不变,所以更好的方式是通过别名进行互联,下篇继续讲解怎么通过别名进行容器通信,😊😊。




我是 甜点cc


热爱前端,也喜欢专研各种跟本职工作关系不大的技术,技术、产品兴趣广泛且浓厚,等待着一个创业机会。本号主要致力于分享个人经验总结,希望可以给一小部分人一些微小帮助。


希望能和大家一起努力营造一个良好的学习氛围,为了个人和家庭、为了我国的互联网物联网技术、数字化转型、数字经济发展做一点点贡献。数风流人物还看中国、看今朝、看你我。


发布于: 刚刚阅读数: 6
用户头像

甜点cc

关注

看见另一种可能 2020-04-30 加入

欢喜勇猛

评论

发布
暂无评论
Docker网络及原理探究_Docker_甜点cc_InfoQ写作社区