docker - 网络

docker为什么需要网络管理

容器的网络默认与宿主机及其他容器都是相互隔离, 但同时我们也要考虑下面的一些 问题, 比如

• 多个容器之间是如何通信的

• 容器和宿主机是如何通信的

• 容器和外界主机是如何通信的

• 容器中要运行一些网络应用(如 nginx、web 应用、数据库等),如果要让外部也可 以访问这些容器内运行的网络应用应该如何实现

• 容器不想让它的网络与宿主机、与其他容器隔离应该如何实现

• 容器根本不需要网络的时候应该如何实现

• 容器需要更高的定制化网络(如定制特殊的集群网络、定制容器间的局域网)应 该如何实现

• ....

上述的这些问题都需要我们对容器的网络进行合理的管理才能解决,这就体现出了容 器网络管理的重要性

docker网络管理架构

Docker 容器网络是为应用程序所创造的虚拟环境的一部分,它能让应用从宿主机操作 系统的网络环境中独立出来,形成容器自有的网络设备、IP 协议栈、端口套接字、IP 路由表、防火墙等等与网络相关的模块。

Docker 为实现容器网络,主要采用的架构由三部分组成:CNM、Libnetwork 和驱动。

CNM

Docker 网络架构采用的设计规范是 CNM(Container Network Model)。CNM 中规定 了 Docker 网络的基础组成要素:Sandbox、Endpoint、Network。

• Sandbox:提供了容器的虚拟网络栈,也即端口、套接字、IP 路由表、防火墙、 DNS 配置等内容。主要用于隔离容器网络与宿主机网络,形成了完全独立的容器网络 环境。

• Network:Docker 内部的虚拟子网,使得网络内的参与者能够进行通讯。

• Endpoint:就是虚拟网络的接口,就像普通网络接口一样,Endpoint 的主要职责 是负责创建连接。Endpoint 类似于常见的网络适配器,那也就意味着一个 Endpoint 只 能接入某一个网络, 当容器需要接入到多个网络,就需要多个 Endpoint

如上图所示,容器 B 有两个 Endpoint 并且分别接入 Networkd A 和 Network B。那么容器 A 和容器 B 之间是可以实现通信的,因为都接入了 NetworkA。但是容器 A 和容 器 C 不可以通过容器 B 的两个 Endpoint 通信。

Libnetwork

Libnetwork 是 CNM 的一个标准实现。Libnetwork 是开源库,采用 Go 语言编写(跨 平台的),也是 Docker 所使用的库,Docker 网络架构的核心代码都在这个库中。 Libnetwork 实现了 CNM 中定义的全部三个组件,此外它还实现了本地服务发现、基 于 Ingress 的容器负载均衡,以及网络控制层和管理层等功能。

驱动

驱动主要负责实现数据层相关内容,例如网络的连通性和隔离性是由驱动来处理的。 驱动通过实现特定网络类型的方式扩展了 Docker 网络栈,例如桥接网络和覆盖网络。 Docker 内置了若干驱动,通常被称作原生驱动或者本地驱动。例如 Bridge Driver(宿主机和容器)Host Driver(容器之间)Overlay Driver(跨服务器)MacVLan Driver**、**IPVLan DriverNone Driver等 等。每个驱动负责创建其上所有网络资源的创建和管理。

常见网络类型

1、bridge 网络(默认网络)

bridge 驱动会在 Docker 管理的主机上创建一个 Linux 网桥。默认情况下,网桥上 的容器可以相互通信。也可以通过 bridge 驱动程序配置,实现对外部容器的访问。 Docker 容器的默认网络驱动.当我们需要多个容器在同一个 Docker 主机上通信时,桥 接网络是最佳选择。

2、host 网络

对于独立容器,移除容器和 Docker 主机之间的网络隔离,并直接使用主机的网络。 当网络堆栈不应该与 Docker 主机隔离,但是希望容器的其他资源被隔离时,主机网络 是最佳选择。

3、container 网络

这个模式指定新创建的容器和引进存在的一个容器共享一个网络 ,而不是和宿主 机共享。新创建的容器不会创建自己的网卡,配置自己的 ip,而是和一个指定的容器 共享 ip,端口等,两个容器除了网络方面,其他的如文件系统、进程列表等还是隔离 的。两个容器的进程可以通过 lo 网卡设备通信

4、none 网络

Docker 容器拥有自己的 Network Namespace,但是,并不为 Docker 容器进行任 何网络配置。也就是说,这个 Docker 容器没有网卡、IP、路由等信息。容器完全网络 隔离。

5、overlay 网络

借助 Docker 集群模块 Docker Swarm 搭建的跨 Docker Daemon 网络。将多个 Docker 守护进程连接在一起,使集群服务能够相互通信。当我们需要运行在不同 Docker 主机上的容器进行通信时,或者当多个应用程序使用集群服务协同工作时,覆 盖网络是最佳选择。

另外,在 Docker 安装时,会自动安装一块 Docker 网卡称为 docker0,它是一个网 桥设备,主要用于 Docker 各容器及宿主机的网络通信。

docker网络管理命令

|---------------------------|-----------------------|--------------|
| 命令 | 别名 | 功能 |
| docker network create | | 创建网络 |
| docker network connect | | 连接网络 |
| docker network disconnect | | 断开网络 |
| docker network ls | docker network list | 列出网络 |
| docker network prune | | 删除不使用的网络 |
| docker network inspect | | 查看网络详情 |
| docker network rm | docker network remove | 删除 1 个或者多个网络 |

docker network create命令

功能

创建自定义网络

语法

docker network create [OPTIONS] NETWORK

关键参数

-d, --driver**:**网络驱动

--gateway**:**网关地址

--subnet**:**表示网段的 CIDR 格式的子网

--ipv6**:**启用 ipv6

docker network inspect命令

功能

查看网络详情

语法

docker network inspect [OPTIONS] NETWORK [NETWORK...]

关键参数

**-f,--format:**指定格式

也能查看哪些容器属于这个网络

docker network connect命令

功能

于将容器连接到网络。可以按名称或 ID 连接容器。 一旦连接,容器可以与同 一网络中的其他容器通信。

语法

docker network connect [OPTIONS] NETWORK CONTAINER

关键参数

--ip**:**指定 IP 地址

--ip6**:**指定 IPv6 地址

启动一个容器,执行命令 docker run -dit --name busybox1 busybox:1.37.0

进入容器,查看网络配置

退出容器,然后给容器添加一个新的网络进来

执行命令 docker network connect mynet1 busybox1

再次进入容器,查看网络配置

就可以看到新添加的网络了。

也可以查看网络mynet1关联的容器。查看网络详情

其中的Containers就能看到和该网络关联的容器了。

docker network disconnect命令

功能

断开网络

语法

docker network disconnect [OPTIONS] NETWORK CONTAINER

关键参数

**-f:**强制退出

将上个命令加入mynet1网络的容器 busybox1断开连接

执行命令 docker network disconnect mynet1 busybox1

进入busybox1容器查看网络配置

就能看到容器的网络还原了

docker network prune命令

功能

删除不使用的网络

语法

docker network prune [OPTIONS]

关键参数

-f, --force**:**不提示

先建2个网络

然后再删除不使用的网络

docker network rm命令

功能

删除 1 个或者多个网络

语法

docker network rm NETWORK [NETWORK...]

先建几个网络

指定删除mynet1网络

批量删除网络

新建一个网络,然后将网络连接至一个容器

然后删除网络

也就是说 和容器关联的网络是删除不了的

docker network ls命令

功能

列出网络

语法

docker network ls [OPTIONS]

别名 docker network list

关键参数

**-f, --filter:**指定过滤条件

**--format:**指定格式

**--no-trunc:**不截断

**-q, --quiet :**仅仅显示 id

网络基本操作

1、创建网络并指定 ip 地址段

2、分别用两种方式创建两种容器,各自加入这个网络

方式一 执行命令 docker run -dit --network=net1 --name busybox1 busybox:1.37.0

查看容器详情,观察网络字段,执行命令 docker container inspect busybox1

方式二 执行命令 docker run -dit --name busybox2 busybox:1.37.0

然后查看容器详情,执行命令, docker container inspect busybox2

观察网络字段

输入ifconfig

可以看到创建容器时没有指定网络的时候,默认网关是docker0桥的ip

通过命令 docker network connect net1 busybox2 将容器加入net1网络

再次查看容器详情的网络字段

可以看到busybox2就有两个网络,一个是docker0桥的,一个是新加进来的net1网络

可以看到,两种方式加入网络效果是不一样的,不加参数指定网络的容器会比加参数指定网络的容器多一个网络,就是docker网桥。

也就说 运行容器的时候不通过参数 --network指定网络,会默认关联docker网桥的。也就是说,创建容器时不指定网络的容器,在创建完之后,容器之间都连接了docker网桥的,是能通信的。

3、将容器和网络断开

分别执行命令 docker network disconnect net1 busybox1

docker network disconnect net1 busybox2

4、删除网络

执行命令 docker network rm net1

网络就被清理了。

网络详解

docker Bridge网络

网络介绍

Docker Bridge 网络采用内置的 bridge 驱动,bridge 驱动底层采用的是 Linux 内核中 Linux bridge 技术。就网络而言,bridge 网络是在网络段之间转发流量的链路层设备, 而网桥可以是在主机内核中运行的硬件设备或软件设备;就 Docker 而言,桥接网络使 用软件网桥 docker0,它允许连接到同一网桥网络的容器进行通信,同时提供与未连 接到该网桥网络容器的隔离。

Docker Container 的 bridge 桥接模式可以参考下图:

默认情况下,创建的容器在没有使用--network 参数指定要加入的 docker 网络时, 默认都是加入 Docker 默认的单机桥接网络,即下面的 name 为 bridge 的网络。

默认的 bridge 网络会被映射到内核中为 docker0 的网桥上。

Docker 默认的 bridge 网络和 Linux 内核中的 docker0 网桥是一一对应的关系。

bridge 是 Docker 对网络的命名,而 docker0 是内核中网桥的名字。

容器间的网络通信

1、启动两个容器

执行命令 docker run -dit --name busybox1 busybox:1.37.0

docker run -dit --name busybox2 busybox:1.37.0

2、分别进入两个容器查看自己的ip,然后ping对方ip

进入busybox1容器,ping busybox2容器

进入busybox2容器,ping busybox1容器

查看默认网络bridge关联的容器字段

可以看到busybox1和busybox2,都和bridge网络进行了关联。

其中的Options字段可以看到bridge网络的名字

3、停掉busybox1容器

执行命令 docker stop busybox1

再次查看bridge网络关联的容器

就只剩下了busybox2容器了。

创建自定义bridge

1、创建自定义的桥接网络

执行命令 docker network create mynet(不指定网络驱动,默认就是网桥。不指定子网,就自动分配子网)

查看新建桥接网络的详情,执行命令 docker network inspect mynet

然后在查看宿主机上的网卡信息,多了一个网桥

2、启动两个容器,并加入到这个桥接网络

分别执行命令 docker run -dit --name b1 --network mynet busybox:1.37.0

docker run -dit --name b2 --network mynet busybox:1.37.0

查看创建网络的container字段

两个容器成功加入了这个网络了

3、两个容器相互ping,看能否ping通

两个容器依然能相互ping通

DNS解析

Docker 自定义桥接网络是支持通过 Docker DNS 服务进行域名解析的, 也就是说我们 可以直接使用容器名进行通信,因为 DNS 服务可以解析容器名到 IP 地址的映射, 但 是默认的 bridge****网络是不支持 DNS

1、创建两个容器使用默认的桥接网络

创建两个容器并指定为自定的桥接网络 ,执行命令 docker run -dit --name b3 busybox:1.37.0 docker run -dit --name b4 busybox:1.37.0

2、然后互相ping容器名

再去另一个容器ping

ip能ping通,但是ping容器名ping不通。默认的 bridge****网络是不支持 DNS

1、创建两个容器使用自定义的桥接网络

创建自定义桥接网络,执行命令 docker network create mynet

创建两个容器并指定为自定的桥接网络 ,执行命令 docker run -dit --name b1 --network mynet busybox:1.37.0 docker run -dit --name b1 --network mynet busybox:1.37.0

2、然后互相ping容器名

再去另一个容器ping

Docker 自定义桥接网络是支持通过 Docker DNS 服务进行域名解析的。

端口暴露和转发

暴露方式

端口暴露有 2 种方式,在启动容器的时候添加端口参数,一种-P 暴露所有端口,一种 是-p,暴露指定端口

-P将指定的容器端口映射至主机所有地址的一个动态端口,·"动态端口"指随机端口,具 体的映射结果可使用 docker port 命令查看

**-p <hostPort>:<containerPort>**将容器端口<containerPort>映射至指定的主机端口<hostPort>

端口转发

连接 bridge 网络的容器只能与连接在当前网络中的容器进行通信。如果一个容器 想要对外提供一些网络服务的话,需要进行端口转发才可以实现。

端口转发将 Docker 容器的端口映射到宿主机的端口上,那么任何发送到宿主机该端口 的流量,都会被转发到容器的端口中。

如下图所示,两个容器内部均开放 80 端口,它 们分别映射到宿主机的 8088 和 8089 端口, 即表示任何发送到 8088 端口的流量都会转发到 Container 1 容器的 80 端口, 发送到 8089 端口的流程都会转发到 Container 2 容器的 80 端口。

启动nginx容器,暴露端口80给宿主机的8081端口。

执行命令 docker run -d --name nginx1 -p 8081:80 nginx:1.23.4

通过8081端口在web端访问nginx首页

docker Host网络

网络介绍

Docker 容器运行默认都会分配独立的 Network Namespace 隔离子系统, 但是如果基 于 host 网络模式,容器将不会获得一个独立的 Network Namespace,而是和宿主机 共用同一个 Network Namespace,容器将不会虚拟出自己的网卡,IP 等,而是直接使 用宿主机的 IP 和端口。

连接到 host 网络的容器共享宿主机的网络栈,容器的网络配置与宿主机完全一样。我 们可以通过 --network=host 指定使用 host 网络。

操作

1、创建两个容器,一个使用桥接网络,一个使用宿主机网络

创建容器,使用默认桥接网络,执行命令 docker run -dit --name b1 busybox:1.37.0

创建容器,使用宿主机网络,执行命令 docker run -dit --name b2 --network host busybox:1.37.0

使用宿主机网络,只用将--network参数指定为host即可

2、查看两个容器的网络差异

查看使用桥接网络容器b1的网络ip信息

查看使用宿主机网络容器b2的网络ip信息

查看宿主机的网络配置

可以看到使用宿主机网络的容器p2的网络信息和宿主机网络完全相同。

使用场景

• 之前我们提到 bridge 网络在通信的时候需要进行端口转发以及 NAT 地址转换, 这势必会消耗掉一些资源以及性能。

• 那么直接使用 host 网络最大的好处就是性能好,如果容器对网络传输效率有较高 的要求,建议选择 host 网络。当然也会牺牲一些东西,比如要考虑端口冲突问题,其 他服务已经被占用的端口就不能再使用了

docker Container网络

网络介绍

Docker Container 的 other container 网络模式是 Docker 中一种较为特别的网络的模 式。之所以称为"other container 模式",是因为这个模式下的 Docker Container,会使 用其他容器的网络环境。之所以称为"特别",是因为这个模式下容器的网络隔离性会处 于 bridge 桥接模式与 host 模式之间。Docker Container 共享其他容器的网络环境,则 至少这两个容器之间不存在网络隔离,而这两个容器又与宿主机以及除此之外其他的 容器存在网络隔离。

Docker Container 的 other container 网络模式可以参考下图:

操作

1、创建两个容器,第二个容器通过容器网络,加入到第一个容器网络里面

创建第一个容器,执行命令 docker run -itd --name b3 busybox:1.37.0

创建第二个容器,执行命令 docker run -itd --name b4 --network container:b3 busybox:1.37.0

使用容器网络,只用将--network参数指定为container:目标容器名或者id即可

查看b4的容器详情,其中网络配置是空的

2、分别进入容器,查看两个容器的ip信息

b3的ip信息

b4的ip信息

二者ip信息都是一样的

3、停掉第一个容器停掉,观察第二个容器还有ip变化

关掉b3容器,执行命令 docker stop b3

然后查看b4容器的ip信息。

可以看到b4的ip就没有了。

4、重启两个容器,观察ip会不会恢复

重启第一个容器b3,执行命令 docker restart b3

重启第一个容器b3,执行命令 docker restart b4

两个容器的ip又恢复一样了

使用场景

在这种模式下的 Docker Container 可以通过 localhost 来访问 namespace 下的其他容 器,传输效率较高。

但是两个容器之间存在依赖,如果依赖容器重启了,会导致另外 一个服务的网络不可用。

docker None网络

网络介绍

none 网络就是指没有网络。挂在这个网络下的容器除了 lo(本地回环),没有其他任何 网卡。

操作

1、启动一个容器,指定为none网络

执行命令 docker run -itd --name b5 --network none busybox:1.37.0

在运行容器的时候,可以通过--network=none 参数来指定容器使用 none 网络

2、进入容器查看网络信息

应用场景

针对一些对安全性要求比较高并且不需要联网的应用, 可以使用 none 网络, 比 如生成随机密码, 避免生成密码被第三方获取。

一些第三方的应用可能需要 docker 帮忙创建一个没有网络的容器, 网络由第三 方自己来配置。

相关推荐
代码游侠2 小时前
应用——MPlayer 媒体播放器系统代码详解
linux·运维·笔记·学习·算法
优选资源分享2 小时前
Qflow v1.6.2 | 开源高效桌面自动化工具
运维·自动化
老兵发新帖3 小时前
ubuntu添加用户完整命令
linux·运维·ubuntu
snpgroupcn3 小时前
大规模 SAP 转型综合方案:S/4HANA 迁移、数据迁移与系统集成
运维·制造
❀͜͡傀儡师3 小时前
运维问题排查笔记:磁盘、Java进程与SQL执行流程
java·运维·笔记
m0_488777654 小时前
Docker容器技术场景化操作实战及网络模式部署
运维·docker·容器·网络模式
2501_939909054 小时前
Docker
运维·docker·容器
嘻哈baby4 小时前
Linux进程排查实战:strace和lsof救命指南
运维
vortex54 小时前
Linux 处理以 Null 字节分隔内容的文件
linux·运维·服务器