个人观点: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: <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 forever
2: 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 291944112sec
3: 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.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: <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 forever
2: 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 291916543sec
3: 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 forever
140: 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 forever
154: 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 0
156: 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 1
158: 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网络

[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地址不变,所以更好的方式是通过别名进行互联,下篇继续讲解怎么通过别名进行容器通信,。


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

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

欢迎大家评论交流, 蟹蟹

Docker0网络及原理探究的更多相关文章

  1. [原] KVM 虚拟化原理探究(5)— 网络IO虚拟化

    KVM 虚拟化原理探究(5)- 网络IO虚拟化 标签(空格分隔): KVM IO 虚拟化简介 前面的文章介绍了KVM的启动过程,CPU虚拟化,内存虚拟化原理.作为一个完整的风诺依曼计算机系统,必然有输 ...

  2. Docker容器间网络互联原理,讲不明白算我输....

    @ 目录 一.今天我们要搞明白的实验 二.前置网络知识 2.1.docker默认为我们创建的网络 2.2.怎么理解docker0网桥 2.3.什么是veth-pair技术? 三.同一个局域网中不同主机 ...

  3. [原] KVM 虚拟化原理探究(1)— overview

    KVM 虚拟化原理探究- overview 标签(空格分隔): KVM 写在前面的话 本文不介绍kvm和qemu的基本安装操作,希望读者具有一定的KVM实践经验.同时希望借此系列博客,能够对KVM底层 ...

  4. [原] KVM 虚拟化原理探究 —— 目录

    KVM 虚拟化原理探究 -- 目录 标签(空格分隔): KVM KVM 虚拟化原理探究(1)- overview KVM 虚拟化原理探究(2)- QEMU启动过程 KVM 虚拟化原理探究(3)- CP ...

  5. [原] KVM 虚拟化原理探究(6)— 块设备IO虚拟化

    KVM 虚拟化原理探究(6)- 块设备IO虚拟化 标签(空格分隔): KVM [toc] 块设备IO虚拟化简介 上一篇文章讲到了网络IO虚拟化,作为另外一个重要的虚拟化资源,块设备IO的虚拟化也是同样 ...

  6. ThreadPoolExcutor 原理探究

    概论 线程池(英语:thread pool):一种线程使用模式.线程过多会带来调度开销,进而影响缓存局部性和整体性能.而线程池维护着多个线程,等待着监督管理者分配可并发执行的任务.这避免了在处理短时间 ...

  7. [原] KVM 虚拟化原理探究(4)— 内存虚拟化

    KVM 虚拟化原理探究(4)- 内存虚拟化 标签(空格分隔): KVM 内存虚拟化简介 前一章介绍了CPU虚拟化的内容,这一章介绍一下KVM的内存虚拟化原理.可以说内存是除了CPU外最重要的组件,Gu ...

  8. [原] KVM 虚拟化原理探究(3)— CPU 虚拟化

    KVM 虚拟化原理探究(3)- CPU 虚拟化 标签(空格分隔): KVM [TOC] CPU 虚拟化简介 上一篇文章笼统的介绍了一个虚拟机的诞生过程,从demo中也可以看到,运行一个虚拟机再也不需要 ...

  9. [原] KVM 虚拟化原理探究(2)— QEMU启动过程

    KVM 虚拟化原理探究- QEMU启动过程 标签(空格分隔): KVM [TOC] 虚拟机启动过程 第一步,获取到kvm句柄 kvmfd = open("/dev/kvm", O_ ...

随机推荐

  1. Python参数传递中的 args, kwargs

    概念 真正的Python参数传递语法是*和**,其被称为 被称为打包和解包参数.*args和**kwargs只是大家默认的一种形式.也可以写成*keys和**kkeys等其他形式.二者都是为了在不知道 ...

  2. RPA-UiPath视频教程1

    UiPath下载.安装.激活.第一个案例Helloworld!.参数类型.变量的介绍和使用 https://www.bilibili.com/video/av92816532 RPA直播公开课2020 ...

  3. Linux yum的实现和配置

    使用yum或dnf解决rpm包的依赖关系. YUM:Yellowdog Update Modifier.是rpm的前端程序 作用:解决软件包之间的依赖关系 yum工作原理: yum 服务器存放rpm包 ...

  4. static关键字续、继承、重写、多态

    static关键字 1.对于实例变量,每个java对象都拥有自己的一份,存储在堆内存当中,在构造方法执行的时候初始化. 2.所有对象都拥有同一个属性时,并且值相同,建议声明为static变量. 3.静 ...

  5. 扩展新的WCV到标准的WC后,不能在业务角色里面看见视图解决方法

    by zyi 感谢群主红枣的分享 1.把你的WCVIEW扩展进WC中 2.使用UI Designer打开你的WCVIEW 3.更改你的WCVIEW名字

  6. Min-max 容斥与 kth 容斥

    期望的线性性: \[E(x+y)=E(x)+E(y) \] 证明: \[E(x+y)=\sum_i \sum_j(i+j)*P(i=x,j=y) \] \[=\sum_i\sum_ji*P(i=x,j ...

  7. gnet: 一个轻量级且高性能的 Go 网络框架 使用笔记

    一个偶然的机会接触到了golang,被它的高并发传说所吸引,就开始学这门语言,越学感觉越有意思^_^ 注册了博客园这么多年,第一次写东西,年纪大了,脑子不好使了,就得写下来,记下来,为了自己以后查阅, ...

  8. 密码学系列之:在线证书状态协议OCSP详解

    目录 简介 PKI中的CRL CRL的缺点 CRL的状态 OCSP的工作流程 OCSP的优点 OCSP协议的细节 OCSP请求 OCSP响应 OCSP stapling 总结 简介 我们在进行网页访问 ...

  9. github package的使用教程

    一.写在前面 上一次,笔者向大家介绍了把gitlab仓库作为npm私包的使用方法,具体的详见我的博文地址https://www.cnblogs.com/cnroadbridge/p/16406476. ...

  10. springboot 中如何正确在异步线程中使用request

    起因: 有后端同事反馈在异步线程中获取了request中的参数,然后下一个请求是get请求的话,发现会偶尔出现参数丢失的问题. 示例代码: @GetMapping("/getParams&q ...