【Docker】Docker网络及容器间通信详解

目录

背景

默认网络

1、bridge 网络模式

2、host 网络模式

3、none 网络模式

4、container 网络模式

自定义网络

容器间网络通信

IP通信

Docker DNS server

Joined容器


前言

本实验通过docker DNS server和joined 容器两种方法实现Docker容器间的通信。Docker容器间通信可用于监控其他容器的网络流量、不同容器中程序如web server和app server的高效通信等场景。通过实验进一步熟悉Docker的架构和基本操作,了解Docker容器间通信的方式。

背景

当项目大规模使用 Docker 时,容器通信的问题也就产生了。要解决容器通信问题,必须先了解很多关于网络的知识。Docker 作为目前最火的轻量级容器技术,有很多令人称道的功能,也有着很多不完善的地方,网络方面就是 Docker 比较薄弱的部分。因此,我们有必要深入了解 Docker 的网络知识,以满足更高的网络需求。

默认网络

安装 Docker 以后,会默认创建三种网络,可以通过 docker network ls 查看。

image.png

我们有必要先来了解一下这几种网络模式都是什么意思。

网络模式参数说明
host模式-net=host容器和宿主机共享 Network namespace。
container模式–net=container:NAME_or_ID容器和另外一个容器共享 Network namespace。 kubernetes 中的pod就是多个容器共享一个 Network namespace。
none模式–net=none容器有独立的Network namespace,但并没有对其进行任何网络设置,如分配 veth pair 和网桥连接,配置IP等。
bridge模式–net=bridge默认为该模式,通过 -p 指定端口映射。

1、bridge 网络模式

在该模式中,Docker 守护进程创建了一个虚拟以太网桥 docker0,新建的容器会自动桥接到这个接口,附加在其上的任何网卡之间都能自动转发数据包。

默认情况下,守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名,从而将宿主机上的所有容器都连接到这个内部网络上。

比如运行一个基于 busybox 镜像构建的容器 bbox01,查看 ip addr:

busybox是一个软件工具箱,集成了linux中几百个常用的linux命令以及工具。

docker run -it --name bbox01 busybox

其中:

-i:以交互模式运行容器,通常与 -t 同时使用,表示开启了input功能

-t:为容器重新分配一个伪输入终端,通常与-i同时使用,表示开启了连接容器里的terminal(终端)

-d:指定容器在后台运行

image.png

然后宿主机通过 ip addr 可以发现:守护进程会创建一对对等虚拟设备接口 veth pair,将其中一个接口设置为容器的 eth0 接口(容器的网卡),另一个接口放置在宿主机的命名空间中,以类似 vethxxx 这样的名字命名。

image.png

同时,守护进程还会从网桥 docker0 的私有地址空间中分配一个 IP 地址和子网给该容器,并设置 docker0 的 IP 地址为容器的默认网关。也可以安装 yum install -y bridge-utils 以后,通过 brctl show 命令查看网桥信息。

yum install -y bridge-utils

image.png

对于每个容器的 IP 地址和 Gateway 信息,我们可以通过 docker inspect 容器名称|ID 进行查看,在 NetworkSettings 节点中可以看到详细信息。

image.png

我们可以通过 docker network inspect bridge 查看所有 bridge 网络模式下的容器,在 Containers 节点中可以看到容器名称。

docker network inspect bridge

image.png

关于 bridge 网络模式的使用,只需要在创建容器时通过参数 --net bridge 或者 --network bridge 指定即可,当然这也是创建容器默认使用的网络模式,也就是说这个参数是可以省略的。

image.png

Bridge 桥接模式的实现步骤主要如下:

  • Docker Daemon 利用 veth pair 技术,在宿主机上创建一对对等虚拟网络接口设备,假设为 veth0 和 veth1。而veth pair 技术的特性可以保证无论哪一个 veth 接收到网络报文,都会将报文传输给另一方。

  • Docker Daemon 将 veth0 附加到 Docker Daemon 创建的 docker0 网桥上。保证宿主机的网络报文可以发往 veth0;

  • Docker Daemon 将 veth1 添加到 Docker Container 所属的 namespace 下,并被改名为 eth0。如此一来,宿主机的网络报文若发往 veth0,则立即会被 Container 的 eth0 接收,实现宿主机到 Docker Container 网络的联通性;同时,也保证 Docker Container 单独使用 eth0,实现容器网络环境的隔离性。

2、host 网络模式

  • host 网络模式需要在创建容器时通过参数 --net host 或者 --network host 指定;

  • 采用 host 网络模式的 Docker Container,可以直接使用宿主机的 IP 地址与外界进行通信,若宿主机的 eth0 是一个公有 IP,那么容器也拥有这个公有 IP。同时容器内服务的端口也可以使用宿主机的端口,无需额外进行 NAT 转换;

  • host 网络模式可以让容器共享宿主机网络栈,这样的好处是外部主机与容器直接通信,但是容器的网络缺少隔离性。

比如我基于 host 网络模式创建了一个基于 busybox 镜像构建的容器 bbox02,查看 ip addr:

docker run -it --name bbox02 --net host busybox

image.png

然后宿主机通过 ip addr 查看信息如下:

image.png

返回信息一模一样,我们可以通过 docker network inspect host 查看所有 host 网络模式下的容器,在 Containers 节点中可以看到容器名称。

docker network inspect host

3、none 网络模式

none 网络模式是指禁用网络功能,只有 lo 接口 local 的简写,代表 127.0.0.1,即 localhost 本地环回接口。在创建容器时通过参数 --net none 或者 --network none 指定;

none 网络模式即不为 Docker Container 创建任何的网络环境,容器内部就只能使用 loopback 网络设备,不会再有其他的网络资源。可以说 none 模式为 Docke Container 做了极少的网络设定,但是俗话说得好“少即是多”,在没有网络配置的情况下,作为 Docker 开发者,才能在这基础做其他无限多可能的网络定制开发。这也恰巧体现了 Docker 设计理念的开放。

比如基于 none 网络模式创建了一个基于 busybox 镜像构建的容器 bbox03,查看 ip addr:

docker run -it --name bbox03 --net none busybox

image.png

我们可以通过 docker network inspect none 查看所有 none 网络模式下的容器,在 Containers 节点中可以看到容器名称。

docker network inspect none

4、container 网络模式

Container 网络模式是 Docker 中一种较为特别的网络的模式。在创建容器时通过参数 --net container:已运行的容器名称|ID 或者 --network container:已运行的容器名称|ID 指定;

处于这个模式下的 Docker 容器会共享一个网络栈,这样两个容器之间可以使用 localhost 高效快速通信。

Container 网络模式即新创建的容器不会创建自己的网卡,配置自己的 IP,而是和一个指定的容器共享 IP、端口范围等。同样两个容器除了网络方面相同之外,其他的如文件系统、进程列表等还是隔离的。

基于容器 bbox01 创建了 container 网络模式的容器 bbox04,查看 ip addr:

docker run -it --name bbox04 --net container:bbox01 busybox

image.png

容器 bbox01 的 ip addr 信息如下:

image.png

宿主机的 ip addr 信息如下:

image.png

通过以上测试可以发现,Docker 守护进程只创建了一对对等虚拟设备接口用于连接 bbox01 容器和宿主机,而 bbox04 容器则直接使用了 bbox01 容器的网卡信息。

这个时候如果将 bbox01 容器停止,会发现 bbox04 容器就只剩下 lo 接口了。

image.png

然后 bbox01 容器重启以后,bbox04 容器也重启一下,就又可以获取到网卡信息了。

image.png

自定义网络

虽然 Docker 提供的默认网络使用比较简单,但是为了保证各容器中应用的安全性,在实际开发中更推荐使用自定义的网络进行容器管理,以及启用容器名称到 IP 地址的自动 DNS 解析。

从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 --name 为容器命名即可。

【说明】 Docker DNS 限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。

通过 docker network create 命令可以创建自定义网络模式

进一步查看 docker network create 命令使用详情,发现可以通过 --driver 指定网络模式且默认是 bridge 网络模式,提示如下:

image.png

创建一个基于 bridge 网络模式的自定义网络模式 custom_network,完整命令如下:

docker network create custom_network

image.png

通过 docker network ls 查看网络模式:

docker network ls

image.png

通过自定义网络模式 custom_network 创建容器:

docker run -di --name bbox08 --net custom_network busybox

image.png

通过 docker inspect 容器名称|ID 查看容器的网络信息,在 NetworkSettings 节点中可以看到详细信息。

docker inspect  bbox08

image.png

接下来通过 docker network connect 网络名称 容器名称 为容器连接新的网络模式。

docker network connect bridge bbox08

通过 docker inspect 容器名称|ID 再次查看容器的网络信息,多增加了默认的 bridge。

image.png

通过 docker network disconnect 网络名称 容器名称 命令断开网络。

docker network disconnect custom_network bbox08

image.png

通过 docker inspect 容器名称|ID 再次查看容器的网络信息,发现只剩下默认的 bridge。

image.png

可以通过 docker network rm 网络名称 命令移除自定义网络模式,网络模式移除成功会返回网络模式名称。

docker network rm custom_network

image.png

容器间网络通信



通常,容器间的通信方式有以下三种:

  • IP通信

  • Docker DNS server

  • Joined容器


IP通信

当docker容器启动的时候,docker会默认给当前容器被分配一个随机的ip。需要分别进入两个容器,通过容器的本地host文件,查看两个容器自身的ip,再经过指定后进行互通。采用IP通信的前提是两个容器必须要属于同一个网络的网卡,但是因为部署过后再指定应用的ip很麻烦,所以ip通信方式就不再过多赘述。


Docker DNS server

Docker DNS Server 是 Docker 容器运行时环境中的一种内置 DNS 服务器。它提供容器间的域名解析服务,使得容器可以通过域名进行网络通信,而无需关注底层的 IP 地址和网络配置。

Docker DNS Server 的主要特点和工作原理如下:

(1)内置 DNS 服务器:Docker 在创建容器时会在每个容器上运行一个内置的 DNS 服务器,该服务器负责处理容器内部的域名解析请求。DNS 服务器默认监听在容器的 loopback 网络接口上。

(2)自动解析容器名:Docker DNS Server 使用容器名作为域名的一部分,因此容器可以通过使用其他容器的名称来访问对应的服务。例如,一个名为 web 的容器可以通过将其他容器的域名设置为 http://XXXXX.com 来访问该服务。

(3)容器间通信:当一个容器需要与另一个容器进行通信时,它可以使用目标容器的名称作为域名进行解析。Docker DNS Server 会将容器名解析为容器的 IP 地址,并将通信请求转发给目标容器。

(4)自动更新记录:当容器创建、销毁或重新调度时,Docker DNS Server 会自动更新容器名与 IP 地址之间的映射关系。这样可以确保容器名始终能够正确解析到对应的 IP 地址。

(5)自定义网络:Docker 允许创建自定义网络,容器可以加入特定的网络中。在自定义网络中,Docker DNS Server 会为该网络中的所有容器提供域名解析服务,使得容器可以相互之间通过容器名进行通信。


Joined容器

joined 容器可以使两个或多个容器共享一个网络栈,共享网卡和配置信息, joined 容器之间可以通过 127.0.0.1直接通信。当一个容器加入到另一个容器的命名空间中时,它可以访问和共享该容器的网络、文件系统和其他资源。这种容器间的连接方式称为容器的链接(Container Linking)。

下面是 Joined 容器的主要特点和使用方式如下:

(1)共享命名空间:Joined 容器会与目标容器共享相同的网络命名空间,这意味着它们可以直接通过本地的 localhost 地址进行通信。同时,Joined 容器还可以共享其他命名空间,如文件系统、进程等,使得它们能够访问和操作彼此的资源。

(2)便捷的通信机制:通过容器的链接,Joined 容器之间可以通过容器名称进行网络通信。这样可以简化容器间的通信配置,并且无需暴露端口给外部网络。

(3)灵活的应用部署:将容器加入到另一个容器中,可以方便地将多个容器组合成一个应用程序的部署单元。这种方式允许开发者以模块化的方式构建和管理复杂的应用程序。

看完这些介绍,接下来我们首先明确一点,容器之间要互相通信,必须要有属于同一个网络的网卡。

我们先创建两个基于默认的 bridge 网络模式的容器。

docker run -di --name default_bbox01 busybox
docker run -di --name default_bbox02 busybox

image.png

通过 docker network inspect bridge 查看两容器的具体 IP 信息。

docker network inspect bridge

image.png

然后测试两容器间是否可以进行网络通信。

docker exec -it default_bbox01 ping 172.17.0.3

image.png

经过测试,从结果得知两个属于同一个网络的容器是可以进行网络通信的,但是 IP 地址可能是不固定的,有被更改的情况发生,这时就需要用到DNS server了。

从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过容器名称通信。方法很简单,只要在创建容器时使用 --name 为容器命名即可。

但是使用 Docker DNS 有个限制:只能在 user-defined 网络中使用。也就是说,默认的 bridge 网络是无法使用 DNS 的,所以我们就需要自定义网络。

先创建自定义网络。

docker network create custom_network

然后创建两个基于自定义网络模式的容器。

docker run -di --name custom_bbox02 --net custom_network busybox
docker run -di --name custom_bbox03 --net custom_network busybox

通过 docker network inspect custom_network 查看两容器的具体 IP 信息。

image.png

然后测试两容器间是否可以进行网络通信,分别使用具体 IP 和容器名称进行网络通信。

docker exec -it custom_bbox02 ping 172.19.0.3

image.png

docker exec -it custom_bbox02 ping custom_bbox03

image.png

经过测试,从结果得知两个属于同一个自定义网络的容器是可以进行网络通信的,并且可以使用容器名称进行网络通信。

那如果此时希望 bridge 网络下的容器可以和 custom_network 网络下的容器进行网络又该如何操作?那就让 bridge 网络下的容器连接至新的 custom_network 网络即可。

docker network connect custom_network default_bbox01

至于最后提到的通过joined 容器通信就是一种基于容器网络(Container Network)实现的方式。通过加入容器的方式,我们可以轻松地实现容器间的通信,而无需依赖外部的网络设备或服务。这种方式适用于需要实现容器间紧密耦合的应用场景,例如一个容器用作数据库服务,另一个容器用作应用程序服务,它们之间需要进行数据交互和通信。

joined 容器可以使两个或多个容器共享一个网络栈,共享网卡和配置信息,joined容器之间可以通过 127.0.0.1直接通信。

创建一个 httpd 容器,名字为 web1

docker run -d -it --name=web1  httpd

image.png

创建一个busybox 容器并通过--network=container:web1指定joined 容器为web1。

docker run -it  --network=container:web1 busybox

image.png

在busybox容器中用 ip a命令查看网络配置信息,然后用命令exit退出。

image.png

进入web1容器:

docker exec -it web1 /bin/bash

image.png

查看web1的网络配置信息,可以看到这里web1容器 和busybox容器的网卡 mac 地址、IP 完全一样,它们共享了相同的网络栈。

image.png

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/107223.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

SQL利用Case When Then多条件判断

CASE WHEN 条件1 THEN 结果1 WHEN 条件2 THEN 结果2 WHEN 条件3 THEN 结果3 WHEN 条件4 THEN 结果4 ......... WHEN 条件N THEN 结果N ELSE 结果X END Case具有两种格式。简单Case函数和Case搜索函数。 --简单Case函数 CASE sex WHEN 1 THEN…

wordpress遇到的问题

一) 403 Forbidden 我是lnmpwordpress,所以在 /etc/nginx/conf.d/default.conf中 修改location 加上 index.php刷新即可; 二)wordpress插件更新,需要输入服务器的FTP登录凭证的问题 在 wp-config.php的文件中进行修改…

一键搞定!黑群晖虚拟机+内网穿透实现校园公网访问攻略!

文章目录 前言本教程解决的问题是:按照本教程方法操作后,达到的效果是前排提醒: 1. 搭建群晖虚拟机1.1 下载黑群晖文件vmvare虚拟机安装包1.2 安装VMware虚拟机:1.3 解压黑群晖虚拟机文件1.4 虚拟机初始化1.5 没有搜索到黑群晖的解…

1.算法-Python遗传算法实例

题记 以下是一个python遗传算法实例,包括全过程和解析。 编辑main.py文件 main.py文件如下: #导入生成伪随机数的模块 import random# 随机生成初始种群 # 1.初始化种群,在搜索空间内随机生成一组个体,称为种群 # 定义函数&#…

功能集成,不占空间,同为科技TOWE嵌入式桌面PDU超级插座

随着现代社会人们生活水平的不断提高,消费者对生活质量有着越来越高的期望。生活中,各式各样的电气设备为我们的生活带来了便利,在安装使用这些用电器时,需要考虑电源插排插座的选择。传统的插排插座设计多暴露于空间之中&#xf…

LeetCode讲解篇之138. 随机链表的复制

LeetCode讲解篇之138. 随机链表的复制 文章目录 LeetCode讲解篇之138. 随机链表的复制题目描述题解思路题解代码 题目描述 题解思路 先遍历一遍链表,用哈希表保存原始节点和克隆节点的映射关系,先只克隆节点的Val,然后再次遍历链表&#xff…

逐字稿 | 视频理解论文串讲(上)【论文精读】

大家好,前两期我们讲了视频理解领域里的两篇经典的论文,一个是双流网络,第一个是 I3D 网络,所以说对视频理解这个问题有了个基本的了解。 那今天我们就从 2014 年开始,一直到最近 2021 年的工作,我们一起来…

解决 vscode使用Prettier格式化js文件报错:Cannot find module ‘./parser-babylon‘

报错如下: ["ERROR" - 11:48:58] Error formatting document. ["ERROR" - 11:48:58] Cannot find module ./parser-babylon Require stack: - d:\VueCode\VueProject\myqqmusic\node_modules\prettier\index.js - c:\Users\Administrator.SKY-2…

微信小程序开发之框架篇

目录 一,框架 1.页面管理 2.基础组件 3.丰富的API 二、小程序视图层 1.响应的数据绑定 2.列表渲染 3.条件渲染 4.模板 三、逻辑层 App Service 1.注册小程序 2.注册页面 2.1.使用 Page 构造器注册页面 2.2.在页面中使用 behaviors 3.页面路由 4.小…

Linux文件系统 struct file 结构体解析

文章目录 一、open系统调用1.1 简介1.2 files_struct1.2.1 简介1.2.2 init_files1.2.2 CLONE_FILES 1.3 源码分析1.3.1 get_unused_fd_flags1.3.2 do_filp_open1.3.3 fd_install 二、struct file简介三、其他参考资料 一、open系统调用 1.1 简介 NAMEopen, creat - open and …

旧手机热点机改造成服务器方案

如果你也跟我一样有这种想法, 那真的太酷了!!! ok,前提是得有root,不然体验大打折扣 目录 目录 1.做一个能爬墙能走百度直连的热点机(做热点机用) 2.做emby视频服务器 3.做文件服务, 存取文件 4.装青龙面板,跑一些定时任务 5.做远程摄像头监控 6.做web服务器 7.内网穿…

51单片机点阵

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 前言一、点阵是什么?1.点阵的原理2. 3*3 点阵显示原理3. 8*8点阵实物图4. 8*8点阵内部原理图5. 16*16点阵实物图,显示原理 二、使用步骤1.先…

数据结构与算法--其他算法

数据结构与算法--其他算法 1 汉诺塔问题 2 字符串的全部子序列 3 字符串的全排列 4 纸牌问题 5 逆序栈问题 6 数字和字符串转换问题 7 背包问题 8 N皇后问题 暴力递归就是尝试 1,把问题转化为规模缩小了的同类问题的子问题 2,有明确的不需要继续…

设计模式之是简单工厂模式

分类 设计模式一般分为三大类:创建型模式、结构型模式、行为型模式。 创建型模式:用于创建对象,共五种,包括单例模式、简单工厂模式、工厂方法模式、抽象工厂模式、建造者模式、原型模式。结构型模式:用于处理类或对…

超火爆的6 个必学持续集成工具,测试人的福音

开发人员喜欢把写的代码当成自己的孩子,他们会被当成艺术品一样呵护。作为家长,总是会认为自己的孩子是最好的,也会尽全力给自己的孩子最好的,就算有时候会超出自己的能力范围。 最终,孩子会走出去,和其他…

android studio检测不到真机

我的情况是: 以前能检测到,有一天我使用无线调试,发现调试有问题,想改为USB调试,但是半天没反应,我就点了手机上的撤销USB调试授权,然后就G了。 解决办法: 我这个情况比较简单&…

Leetcode刷题笔记--Hot61-70

1--课程表(207) 主要思路: 用 in 记录每一门课程剩余的先修课程个数,当剩余先修课程个数为0时,将该课程加入到队列q中。 每修队列q中的课程,以该课程作为先修课程的所有课程,其剩余先修课程个数…

vue elementui的select组件实现滑到底部分页请求后端接口

vue elementui的select组件实现滑到底部分页请求后端接口 1.实现效果2.实现原理 1.实现效果 老规矩&#xff0c;直接上最后的实现效果 2.实现原理 直接上代码 <el-form-item class"diagmosisItem" label"诊断" v-scroll"handleScroll">…

✔ ★【备战实习(面经+项目+算法)】 10.15学习时间表

✔ ★【备战实习&#xff08;面经项目算法&#xff09;】 坚持完成每天必做如何找到好工作1. 科学的学习方法&#xff08;专注&#xff01;效率&#xff01;记忆&#xff01;心流&#xff01;&#xff09;2. 每天认真完成必做项&#xff0c;踏实学习技术 认真完成每天必做&…

【微信小程序开发】基础语法篇

&#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 接下来看看由辉辉所写的关于小程序的相关操作吧 目录 &#x1f973;&#x1f973;Welcome Huihuis Code World ! !&#x1f973;&#x1f973; 一.视图层 1.数据绑定 wxml js 2 .列…