【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.rhkb.cn/news/164094.html

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

相关文章

hue实现对hiveserver2 的负载均衡

如果你使用的是CDH集群那就很是方便的 在Cloudera Manager中,进入HDFS Service 进入Instances标签页面,点击Add Role Instances按钮,如下图所示 点击Continue按钮,如下图所示 返回Instances页面,选择HttpFS角色…

新加坡服务器托管

新加坡是一个小而繁荣的国家,是东南亚唯一一个发达国家。它地理位置好,毗邻马来西亚和印度尼西亚,新加坡是一个拥有先进科技和强大经济的国家,主要以制造业、金融、旅游和航运为主,拥有先进的经济和现代化的基础设施&a…

Python入门指南

概述: Python是一种简单易学、功能强大的编程语言,广泛应用于数据分析、Web开发、人工智能等领域。本文将为初学者提供一个Python入门指南,从安装到基本语法,帮助您开始编写Python程序。 第一部分:安装Python 1、进入…

C++ 友元

采用类的机制后实现了数据的隐藏与封装,类的数据成员一般定义为私有成员,成员函数一般定义为公有的,依此提供类与外界间的通信接口。但是,有时需要定义一些函数,这些函数不是类的一部分,但又需要频繁地访问类的数据成员,这时可以将这些函数定义为该函数的友元函数。除了友元函数…

DC电源模块的模拟电源对比数字电源的优势有哪些?

BOSHIDA DC电源模块的模拟电源对比数字电源的优势有哪些? DC电源模块是一种电子元件,用于将交流电转换为直流电,以供电路板、集成电路等电子设备使用。在直流电源模块中,有模拟电源和数字电源两种类型。 模拟电源是一种传统的电源…

移动硬盘被格式化了如何恢复数据?四步教你如何恢复

在日常生活中,我们常常会使用各种存储设备来保存和备份我们的重要数据。移动硬盘作为一种便携式的存储设备,被广泛应用于数据的存储和传输。然而,有时候我们会不小心将移动硬盘格式化,从而丢失了里面的数据。本文将介绍移动硬盘格…

【SA8295P 源码分析 (三)】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析

【SA8295P 源码分析】97 - QNX AIS Camera 框架介绍 及 Camera 工作流程分析 一、QNX AIS Server 框架分析二、QNX Hypervisor / Android GVM 方案介绍三、Camera APP 调用流程分析四、QCarCam 状态转换过程介绍五、Camera 加串-解串 硬件链路分析六、摄像头初始化检测过程介绍…

基于MATLAB的图像条形码识别系统(matlab毕毕业设计2)

摘要 : 本论文旨在介绍一种基于MATLAB的图像条形码识别系统。该系统利用计算机视觉技术和图像处理算法,实现对不同类型的条形码进行准确识别。本文将详细介绍系统学习的流程,并提供详细教案,以帮助读者理解和实施该系统。 引言…

软件项目管理【UML-组件图】

目录 一、组件图概念 二、组件图包含的元素 1.组件(Component)->构件 2.接口(Interface) 3.外部接口——端口 4.连接器(Connector)——连接件 4.关系 5.组件图表示方法 三、例子 一、组件图概念…

LVS+Keepalived 实验

Keepalived 是什么 Keepalived 是一个基于VRRP协议来实现的LVS服务高可用方案,可以解决静态路由出现的单点故障问题的一款检查工具 在一个LVS服务集群中通常有主服务器(MASTER)和备份服务器(BACKUP)两种角色的服务器…

Vue笔记_插件组件_lucky-canvas抽奖转盘

文章目录 官网使用(vue2.x)[1] 下载[2] 引入[3] 使用配置项-width/height配置项-blocks配置项-prizes配置项-buttons优化案例 lucky-canvas 是一个基于 Js Canvas 的抽奖 web 前端组件,提供 大转盘和 九宫格两种抽奖界面,UI 精美,功能强大…

2020年12月 Python(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Python编程(1~6级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 要对二维列表所有的数据进行格式化输出,打印成表格形状,程序段如下: ls [[金京,89],[…

通达OA通用版V12的表单js定制开发,良好实践总结-持续更新

通达OA通用版V12的表单js定制开发的良好实践总结-持续更新 良好实践总结在表单中的js区域标准代码2023年10月19日获取地址栏:协议、域名/IP地址端口号获取地址栏的参数,比如run_id、flow_id等向表单中追加自定义css、js文件 良好实践总结 在webroot下的…

vue3学习(十)--- 依赖注入Provide 和 Inject

文章目录 Provide 和 Inject兄弟组件通信Event BusMitt库 Provide 和 Inject provide 可以在祖先组件中指定我们想要提供给后代组件----子、孙等组件的数据或方法,而在任何后代组件中,我们都可以使用 inject 来接收 provide 提供的数据或方法。 父组件…

如何通过沉浸式投影技术提升文旅夜游的互动体验?

伴随着国民经济的提升,文旅夜游市场也开始通过各类创新设计形式,来吸引更多的游客前来打卡游玩,使其逐渐成为了当下热度较高的一种游玩模式,其中在收集各类用户的体验反馈时,沉浸式投影依靠新颖的视觉体验以及沉浸式观…

SpringCloud-Sentinel

一、介绍 (1)提供界面配置配置服务限流、服务降级、服务熔断 (2)SentinelResource的blockHandler只处理后台配置的异常,运行时异常fallBack处理,且资源名为value时才生效,走兜底方法 二、安装…

android 指针动画转动

记录一种简单动画 效果图&#xff1a; 都是直接使用图片资源FrameLayout布局实现&#xff0c;布局如下&#xff1a; <LinearLayout xmlns:android"http://schemas.android.com/apk/res/android"xmlns:app"http://schemas.android.com/apk/res-auto"…

python小游戏:飞机射击游戏代码

创建一个完整的飞行游戏涉及到许多方面&#xff0c;包括图形设计、游戏物理引擎和用户输入处理等。在这里&#xff0c;我将提供一个简单的基础框架&#xff0c;你可以在其基础上进一步扩展和完善游戏。 在这个示例中&#xff0c;我们将使用Pygame库来创建一个基本的飞行游戏。…

1-k8s1.23.6-底座搭建-基于docker

这里写自定义目录标题 一、服务器准备二、安装docker三、安装k8s四、安装部署dashboard 一、服务器准备 服务器准备 服务器名称服务器IP角色CPU(最低要求)内存(最低要求)master192.168.248.10master2核2Gworker1192.168.248.11node2核2Gworker2192.168.248.12node2核2G 修改ip&…

SEM和SD的区别和联系,以及其计算方法

http://t.csdnimg.cn/aHe99http://t.csdnimg.cn/aHe99