解读docker容器网络

本文涉及的产品
容器镜像服务 ACR,镜像仓库100个 不限时长
简介: 解读docker容器网络

docker的网络模型如下图:

[root@test-a-docker01 ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:dbff:feb7:ad6e  prefixlen 64  scopeid 0x20<link>
        ether 02:42:db:b7:ad:6e  txqueuelen 0  (Ethernet)
        RX packets 170  bytes 19218 (18.7 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 222  bytes 36474 (35.6 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.23  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fd15:4ba5:5a2b:1008:192:168:11:23  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::f906:733a:ec14:9a9a  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::b57c:b4f:30d1:d6e2  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::b7ae:6dc9:eb0b:6f0d  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:29:ce:cc  txqueuelen 1000  (Ethernet)
        RX packets 6636  bytes 1370980 (1.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3443  bytes 452340 (441.7 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 32  bytes 2592 (2.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 32  bytes 2592 (2.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
vethc1173e2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::e8db:16ff:fe96:ef87  prefixlen 64  scopeid 0x20<link>
        ether ea:db:16:96:ef:87  txqueuelen 0  (Ethernet)
        RX packets 55  bytes 4354 (4.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 75  bytes 8788 (8.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@test-a-docker01 ~]#
  • 「veth」xxxxxxx:它主要用于解决网络名称空间之间的隔离,当启动一个容器,会跟着自动创建一个veth虚拟接口,好比是容器接了一条网线到这个veth虚拟接口,并且通过veth虚拟接口和docker0进行通信,veth会随着的容器的启动而自动增加,也会随着容器的销毁而自动销毁,每个容器都会有各自的veth。
  • docker0:是一个虚拟网卡,类似网桥,也可以看成是一个二层网络设备,通过它可以将linux支持的不同的端口连接起来,实现多对多的通信。docker0这个虚拟网卡有个IP地址(172.17.0.1),进去容器里面看网络地址消息,会发现它就是容器的网关

接下来剖析一下细节

不管是运行的还是没有运行的,那么当前都只有一个web01容器在运行

[root@test-a-docker01 ~]# docker ps -a
CONTAINER ID   IMAGE     COMMAND                  CREATED       STATUS       PORTS                                   NAMES
a809b11833c6   nginx     "/docker-entrypoint.…"   4 hours ago   Up 4 hours   0.0.0.0:8080->80/tcp, :::8080->80/tcp   web01
[root@test-a-docker01 ~]#

查看web01容器的详情,它的输出是json,为了方便查看,可复制出来对json串进行解析

[root@test-a-docker01 ~]# docker inspect web01

丢到https://www.json.cn/进行解析

可通过--format选项直接获取容器web01的ip地址

[root@test-a-docker01 ~]# docker inspect web01 --format='{{.NetworkSettings.IPAddress}}'
172.17.0.2

接下来再拉起一个容器web02

[root@test-a-docker01 ~]# docker run -d -p 8081:80 --name web02 -h web02 -v /data/webdata:/usr/share/nginx/html nginx
092f185073eb5834097fe0d1c4ada3a65b6016e5ad717f1471927ed6c351afec
[root@test-a-docker01 ~]# 
[root@test-a-docker01 ~]# docker ps
CONTAINER ID   IMAGE     COMMAND                  CREATED         STATUS         PORTS                                   NAMES
092f185073eb   nginx     "/docker-entrypoint.…"   5 seconds ago   Up 4 seconds   0.0.0.0:8081->80/tcp, :::8081->80/tcp   web02
a809b11833c6   nginx     "/docker-entrypoint.…"   5 hours ago     Up 5 hours     0.0.0.0:8080->80/tcp, :::8080->80/tcp   web01
[root@test-a-docker01 ~]#

现在有了两个容器,继续看下网络接口的情况

[root@test-a-docker01 ~]# ifconfig
docker0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 172.17.0.1  netmask 255.255.0.0  broadcast 172.17.255.255
        inet6 fe80::42:dbff:feb7:ad6e  prefixlen 64  scopeid 0x20<link>
        ether 02:42:db:b7:ad:6e  txqueuelen 0  (Ethernet)
        RX packets 205  bytes 23535 (22.9 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 271  bytes 46325 (45.2 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
ens32: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet 192.168.11.23  netmask 255.255.255.0  broadcast 192.168.11.255
        inet6 fd15:4ba5:5a2b:1008:192:168:11:23  prefixlen 64  scopeid 0x0<global>
        inet6 fe80::f906:733a:ec14:9a9a  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::b57c:b4f:30d1:d6e2  prefixlen 64  scopeid 0x20<link>
        inet6 fe80::b7ae:6dc9:eb0b:6f0d  prefixlen 64  scopeid 0x20<link>
        ether 00:50:56:29:ce:cc  txqueuelen 1000  (Ethernet)
        RX packets 6935  bytes 1400532 (1.3 MiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 3598  bytes 473025 (461.9 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
lo: flags=73<UP,LOOPBACK,RUNNING>  mtu 65536
        inet 127.0.0.1  netmask 255.0.0.0
        inet6 ::1  prefixlen 128  scopeid 0x10<host>
        loop  txqueuelen 1000  (Local Loopback)
        RX packets 32  bytes 2592 (2.5 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 32  bytes 2592 (2.5 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
veth3a0e879: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::5c99:aaff:fe4e:9cfb  prefixlen 64  scopeid 0x20<link>
        ether 5e:99:aa:4e:9c:fb  txqueuelen 0  (Ethernet)
        RX packets 26  bytes 4357 (4.2 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 48  bytes 10080 (9.8 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
vethc1173e2: flags=4163<UP,BROADCAST,RUNNING,MULTICAST>  mtu 1500
        inet6 fe80::e8db:16ff:fe96:ef87  prefixlen 64  scopeid 0x20<link>
        ether ea:db:16:96:ef:87  txqueuelen 0  (Ethernet)
        RX packets 64  bytes 4804 (4.6 KiB)
        RX errors 0  dropped 0  overruns 0  frame 0
        TX packets 87  bytes 9389 (9.1 KiB)
        TX errors 0  dropped 0 overruns 0  carrier 0  collisions 0
[root@test-a-docker01 ~]#

docker0网桥还是1个,「veth」xxxxxxx多了1个,也就是说veth会随着的容器的增加而增加,也会随着容器的销毁而销毁,每个容器都会有各自的veth。

接下来探讨一下,外部是如何访问到容器里提供的服务

创建容器web01

docker run -d -p 8080:80 --name web01 -h web01 -v /data/webdata:/usr/share/nginx/html nginx

-p 选项中,当宿主机接收到一个来自8080端口的请求就会转发给容器的80端口进行处理

这个转发的动作是由iptables的PREROUTING实现,PREROUTING是目的地址转换(DNAT),再结合路由表就可以得知发往172.17.0.0/16网络的数据包由docker0接收,再到veth,最终到达容器。

# 查看dant规则
[root@test-a-docker01 ~]# iptables -t nat -vnL DOCKER
Chain DOCKER (2 references)
 pkts bytes target     prot opt in     out     source               destination         
    0     0 RETURN     all  --  docker0 *       0.0.0.0/0            0.0.0.0/0           
    7   364 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8080 to:172.17.0.2:80
    2   104 DNAT       tcp  --  !docker0 *       0.0.0.0/0            0.0.0.0/0            tcp dpt:8081 to:172.17.0.3:80
# 查看路由
[root@test-a-docker01 ~]# ip route
default via 192.168.11.2 dev ens32 proto static metric 100 
172.17.0.0/16 dev docker0 proto kernel scope link src 172.17.0.1 
192.168.11.0/24 dev ens32 proto kernel scope link src 192.168.11.23 metric 100

那么,容器又是如何访问到外部的呢?主要是由iptables的POSTROUTING进行实现,POSTROUTING是源地址转换(SNAT)。

# 查看SNAT规则
[root@test-a-docker01 ~]# iptables -t nat -vnL POSTROUTING
Chain POSTROUTING (policy ACCEPT 18 packets, 1296 bytes)
 pkts bytes target     prot opt in     out     source               destination         
   13   759 MASQUERADE  all  --  *      !docker0  172.17.0.0/16        0.0.0.0/0           
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.2           172.17.0.2           tcp dpt:80
    0     0 MASQUERADE  tcp  --  *      *       172.17.0.3           172.17.0.3           tcp dpt:80
[root@test-a-docker01 ~]# 
# 查看路由表
[root@test-a-docker01 ~]# route -n
Kernel IP routing table
Destination     Gateway         Genmask         Flags Metric Ref    Use Iface
0.0.0.0         192.168.11.2    0.0.0.0         UG    100    0        0 ens32
172.17.0.0      0.0.0.0         255.255.0.0     U     0      0        0 docker0
192.168.11.0    0.0.0.0         255.255.255.0   U     100    0        0 ens32
[root@test-a-docker01 ~]#
相关实践学习
每个IT人都想学的“Web应用上云经典架构”实战
本实验从Web应用上云这个最基本的、最普遍的需求出发,帮助IT从业者们通过“阿里云Web应用上云解决方案”,了解一个企业级Web应用上云的常见架构,了解如何构建一个高可用、可扩展的企业级应用架构。
相关文章
|
26天前
|
人工智能 弹性计算 运维
ACK Edge与IDC:高效容器网络通信新突破
本文介绍如何基于ACK Edge以及高效的容器网络插件管理IDC进行容器化。
|
21天前
|
NoSQL 关系型数据库 MySQL
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
136 56
《docker高级篇(大厂进阶):4.Docker网络》包括:是什么、常用基本命令、能干嘛、网络模式、docker平台架构图解
|
28天前
|
监控 NoSQL 时序数据库
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
《docker高级篇(大厂进阶):7.Docker容器监控之CAdvisor+InfluxDB+Granfana》包括:原生命令、是什么、compose容器编排,一套带走
200 77
|
10天前
|
搜索推荐 安全 数据安全/隐私保护
7 个最能提高生产力的 Docker 容器
7 个最能提高生产力的 Docker 容器
81 35
|
1月前
|
监控 Docker 容器
在Docker容器中运行打包好的应用程序
在Docker容器中运行打包好的应用程序
|
9天前
|
Ubuntu Linux 开发工具
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
Docker 是一个开源的容器化平台,允许开发者将应用程序及其依赖项打包成标准化单元(容器),确保在任何支持 Docker 的操作系统上一致运行。容器共享主机内核,提供轻量级、高效的执行环境。本文介绍如何在 Ubuntu 上安装 Docker,并通过简单步骤验证安装成功。后续文章将探讨使用 Docker 部署开源项目。优雅草央千澈 源、安装 Docker 包、验证安装 - 适用场景:开发、测试、生产环境 通过以上步骤,您可以在 Ubuntu 系统上成功安装并运行 Docker,为后续的应用部署打下基础。
docker 是什么?docker初认识之如何部署docker-优雅草后续将会把产品发布部署至docker容器中-因此会出相关系列文章-优雅草央千澈
|
15天前
|
存储 Kubernetes 开发者
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
Docker 是一种开源的应用容器引擎,允许开发者将应用程序及其依赖打包成可移植的镜像,并在任何支持 Docker 的平台上运行。其核心概念包括镜像、容器和仓库。镜像是只读的文件系统,容器是镜像的运行实例,仓库用于存储和分发镜像。Kubernetes(k8s)则是容器集群管理系统,提供自动化部署、扩展和维护等功能,支持服务发现、负载均衡、自动伸缩等特性。两者结合使用,可以实现高效的容器化应用管理和运维。Docker 主要用于单主机上的容器管理,而 Kubernetes 则专注于跨多主机的容器编排与调度。尽管 k8s 逐渐减少了对 Docker 作为容器运行时的支持,但 Doc
84 5
容器化时代的领航者:Docker 和 Kubernetes 云原生时代的黄金搭档
|
21天前
|
关系型数据库 应用服务中间件 PHP
实战~如何组织一个多容器项目docker-compose
本文介绍了如何使用Docker搭建Nginx、PHP和MySQL的环境。首先启动Nginx容器并查看IP地址,接着启动Alpine容器并安装curl测试连通性。通过`--link`方式或`docker-compose`配置文件实现服务间的通信。最后展示了Nginx配置文件和PHP代码示例,验证了各服务的正常运行。
45 3
实战~如何组织一个多容器项目docker-compose
|
15天前
|
Unix Linux Docker
CentOS停更沉寂,RHEL巨变限制源代:Docker容器化技术的兴起助力操作系统新格局
操作系统是计算机系统的核心软件,管理和控制硬件与软件资源,为用户和应用程序提供高效、安全的运行环境。Linux作为开源、跨平台的操作系统,具有高度可定制性、稳定性和安全性,广泛应用于服务器、云计算、物联网等领域。其发展得益于庞大的社区支持,多种发行版如Ubuntu、Debian、Fedora等满足不同需求。
41 4
|
30天前
|
数据建模 应用服务中间件 nginx
docker替换宿主与容器的映射端口和文件路径
通过正确配置 Docker 的端口和文件路径映射,可以有效地管理容器化应用程序,确保其高效运行和数据持久性。在生产环境中,动态替换映射配置有助于灵活应对各种需求变化。以上方法和步骤提供了一种可靠且易于操作的方案,帮助您轻松管理 Docker 容器的端口和路径映射。
98 3