Docker进阶教程 - 4 Docker网络

news2025/2/23 13:26:44

更好的阅读体验:点这里 ( www.doubibiji.com

4 Docker网络

先说我们现在遇到的问题:

我们现在有一个 Redis 容器,一个 SpringBoot 项目容器,在 SpringBoot 项目的代码中如何访问 Redis 容器中的服务呢?

在 SpringBoot 项目中肯定不能使用 localhost,因为 localhost 表示当前的容器。之前都是将容器的端口映射到宿主机上的,所以我们访问容器中的服务器,都是通过 宿主机IP+端口 的方式来访问容器中的服务。所以在 SpringBoot 项目的容器中也可以通过 宿主机IP + redis:6379端口 来访问到 Redis 容器中的服务。

如果宿主机的IP不固定,会发生变化呢?那么容器之间该如何通信呢?

这就需要 Docker 网络了,Docker 网络主要解决的就是容器间的通信问题。


在启动了 Docker 之后,使用 ifconfig 命令查看网络信息,可以看到一个 docker0 的网络:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这个 docker0 就是 Docker 创建的虚拟网桥,用于容器与宿主机、容器与容器之间的网络通信。

上面的 enp0s5 是一个网络接口,是宿主机的物理或虚拟网络接口;

lo:是一个回环接口,通常用于允许计算机与其自身进行网络通信。

4.1 网络模式

我们在使用虚拟机的时候,虚拟机会有不同的网络模式,例如桥接、共享等;和虚拟机有些类似,安装 Docker 以后,也会默认创建三种网络模式,可以通过 docker network ls 查看。

# 命令
docker network ls

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

默认会有 bridgehostnone 三种模式。


网络操作有一些命令,这里先简单了解一下,可以通过帮助命令来查看有哪些命令:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看到 docker network 有 connect 、create、disconnect、inspect、ls、prune、rm 命令。

1 创建网络

我们可以创建自己的网络,命令如下:

# 命令
docker network create 网络名称

# 举个栗子:
docker network create doubi-network

创建未完成,可以查看到网络,默认也是 bridge 模式。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

2 删除网络

删除也非常简单,命令如下:

# 命令
docker network rm 网络ID/名称

# 举个栗子:
docker network rm doubi-network

运行如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

3 查看网络详细信息

可以通过如下命令查看网络的详细信息:

# 命令
docker network inspect 网络ID/名称

# 举个栗子:
docker network inspect bridge

查看名称为 bridge 的网络的详细信息:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

上图可以看到 bridge 网络的网桥名称就是 docker0


下面来介绍一下各种网络模式,以及如何使用来解决问题的。

4.2 bridge网络模式

bridge网络模式:为每一个容器分配、设置 IP 等,并将容器连接到一个 docker0 虚拟网桥,Docker 网络默认使用的就是该模式。

所以我们一开始通过 ifconfig 查看网络的时候,看到的 docker0 就是为 bridge 网络模式提供的虚拟网桥,该模式下,每一个容器都会有一个 IP 地址,每个容器的网络是独立的,一般情况下我们都是使用的这种模式。

docker run 命令中使用 --network bridge 指定使用该模式,一般不用写,默认就是用的这一个,使用 docker0 网桥。其实可以理解为 docker0 是一个路由器,各个容器都是连接到这个路由器上,通过这个路由器实现容器间的互连。


下面演示一下,首先使用 ubuntu 镜像启动两个容器:

# 如果本地没有ubuntu镜像,则首先拉取一个ubuntu镜像
docker pull ubuntu

# 启动容器ubuntu-1
docker run -it --name ubuntu-1 ubuntu /bin/bash

# 启动容器ubuntu-2
docker run -it --name ubuntu-2 ubuntu /bin/bash

此时查看两个 ubuntu 容器的详细信息,详细信息很长,使用 | tail -n 20 只查看最后的20行,会显示出容器的网络信息:

# 查看容器ubuntu-1的详细信息
docker inspect ubuntu-1 | tail -n 20

# 查看容器ubuntu-2的详细信息
docker inspect ubuntu-2 | tail -n 20

运行如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过上面可以看出,每个容器有自己的 IP。


此时在宿主机上,使用 ip addr 命令查看网络,会发现多了两个 veth 开头的虚拟网络接口,这两个虚拟网络接口用来和上面创建的两个容器进行通信,如下:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


此时我们进入 ubuntu-1 容器内,使用 ip addr 查看一下网络,可以看到容器内有名称为 eth0 的虚拟网卡,在 ubuntu-2 容器内也是一样的:

如果容器中没有 ip addr 命令,可以使用 apt 命令安装一下:apt update && apt-get install -y iproute2

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

可以看到容器中的 5: eth0@if6,这里表示 eth05 和 宿主机的 veth6 对应,可以再看一下上面宿主机的网络。

也就是说 docker0 网桥在宿主机上会给每个容器创建一个 veth 开头的虚拟网络接口,在容器内,会为每个容器会创建 eth0 的虚拟网络接口,使用 veth-pair 技术,每个 veth 会匹配容器内部的 eth0,两两配对,实现通信。如下图:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

所以容器间通信都需要经过 docker0docker0 相当于各个容器的网关。


默认情况下,容器在创建时会连接到这个默认桥接网络 docker0docker0 网络通常使用默认的网段(172.17.0.0/16),并且它的IP地址是 172.17.0.1。而使用这个默认网络模式的容器,IP 地址一般从 172.17.0.2 开始。

所以上面 ubuntu-1 容器的 IP 是 172.17.0.2 ,ubuntu-2 容器的 IP 是 172.17.0.3,此时进入到容器 ubuntu-1 可以通过 ping 172.17.0.3 ping 通 ubuntu-2 容器的,如果容器内没有 ping 命令,可以通过 apt update && apt install iputils-ping 命令安装。

但是这里有一个问题,如果我们停掉容器 ubuntu-2 ,启动另外一个容器 ubuntu-3,那么上面容器ubuntu-2的 IP 172.17.0.3 可能会被重新分配给新的容器 ubuntu-3,也就是说容器的 IP 会发生变化。所以在实际生产环境中,容器之间通常不能直接使用IP地址。

想想我们在一个容器中部署了服务器,通过 IP 连接到其他容器的 mysql 或 redis 服务,容器 IP 变化,会导致无法连接到服务。

怎么解决这个问题呢?使用默认的网络是不行的,需要使用后面的自定义网络。

4.3 host网络模式

host网络模式:容器将不会虚拟出自己的网卡,所以没有自己的 IP,而是使用宿主机的 IP 和端口。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


docker run 命令中使用 --network host 指定使用该模式。

举个栗子,启动一个 tomcat 容器:

之前部署tomcat容器的时候,官方镜像的tomcat,首页在webapp.dist目录下,导致访问首页是404,这里为了简单,直接使用一个可以直接访问到首页的镜像。

# x86架构,使用host模式启动tomcat镜像
docker search billygoo/tomcat8-jdk8
docker run -d --network host --name tomcat-1 billygoo/tomcat8-jdk8

# 我的宿主机是arm64架构,上面的用不了,我自己弄了一个,如果你主机是arm架构,你可以使用我的这个
docker search doubibiji/tomcat10
docker run -d --network host --name tomcat-1 doubibiji/tomcat10

上面的命令使用 host 模式启动 tomcat 容器,这里没有进行端口映射,因为 host 模式使用的就是宿主机的端口,所以 tomcat 就是使用宿主机的 8080 端口。

如果指定端口,不仅没有作用,还会有一个警告:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传


访问启动的 tomcat 直接使用 http://宿主机IP:8080

4.4 none网络模式

none网络模式:容器有独立的 Network namespace,但并没有对容器进行任何网络设置,如分配网卡、IP 等。这种模式下,容器禁用了网络功能,不能进行网络通信。如果需要,只能自己添加网络配置。

docker run 命令中使用 --network none 指定使用该模式。

举个栗子:

# 启动ubuntu容器,此时容器没有网络配置
docker run -it --network none --name ubuntu-1 ubuntu /bin/bash

none 网络模式一般很少用,这里不多解释。

4.5 container网络模式

container网络模式:容器不会创建自己的虚拟网卡和 IP ,而是和一个指定的容器共享 IP、端口,也就是用别的容器的IP和端口。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

docker run 命令中使用 --network container:别的容器ID或名称 指定使用该模式。

举个栗子:

这里如果用两个 tomcat 容器来演示,会有一个问题,因为容器2使用container模式,将使用容器1的IP和端口,而对于容器1而言,8080端口已经被容器1使用了,容器2就无法再使用容器1的8080端口了,所以会有问题。

使用ubuntu来演示:

# 如果本地没有ubuntu镜像,则首先拉取一个ubuntu镜像
docker pull ubuntu

# 启动容器ubuntu-1
docker run -it --name ubuntu-1 ubuntu /bin/bash

# 启动容器ubuntu-2,使用ubuntu-1的IP和端口
docker run -it --network container:ubuntu-1 --name ubuntu-2 ubuntu /bin/bash

进入到两个容器查看 IP,可以看到两个容器的 IP 是一样的。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意,此时如果停掉容器1,那么容器2的网络也没有了,容器2就无法通信了,因为容器2是依赖容器1的。

4.6 自定义网络模式

前面说了,因为容器的 IP 会发生变化,所以不能使用容器的 IP 来进行容器间的通信,需要使用自定义网络。

1 创建自定义网络

首先需要创建一个自定义网络,例如创建一个 doubi-network

# 创建doubi-network网络
docker network create doubi-network

创建完网络,可以通过 docker network ls 查看到存在的网络:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

查看宿主机的网络,发现多了一个网络接口:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

这里需要注意,我们创建了一个新的网络,也是桥接模式的,但是它是一个新的桥接网络,和docker0是独立开的,他们可以有不同的配置和属性,从上面也可以看到,他们是不同的网段的。

2 容器加入自定义网络

这里我们创建两个容器,ubuntu-1ubuntu-2 容器,然后在创建容器的时候加入自定义网络:

# 创建ubuntu-1容器,并加入到doubi-network网络
docker run -it --network doubi-network --name ubuntu-1 ubuntu /bin/bash

# 创建ubuntu-2容器,并加入到doubi-network网络
docker run -it --network doubi-network --name ubuntu-2 ubuntu /bin/bash

如果容器已经存在了,可以使用 docker network connect 命令加入到网络:

docker network connect 网络名 容器ID/名称

# 举个栗子
docker network connect doubi-network ubuntu-1

3 实现容器间通信

此时查看 ubuntu-1ubuntu-2 容器的网络,我这里 ubuntu-1 容器的 IP 是 172.19.0.2ubuntu-2 容器的 IP 是 172.19.0.3

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

此时进入到 ubuntu-1 ,肯定是可以通过命令 ping 172.19.0.3 来 ping 通 ubuntu-2 容器的。

但是这里我们不使通过 IP 来 ping,而是通过服务名称来 ping。

直接在容器 ubuntu-1 中执行命令 ping ubuntu-2 ,发现可以 ping 通 ubuntu-2 容器 。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

通过自定义网络,可以实现通过服务名(容器名称)来实现容器之间的通信。

如果我们的项目部署在一个容器中,另外有一个名称为 mysql 的容器服务,那么我们就可以在项目的容器中通过 jdbc:mysql//mysql:3306/数据库名?characterEncoding=utf-8&serverTimezone=Asiz?Shanghai 来连接到数据库服务,不用使用 IP 地址了。

4 还有一个问题

docker 容器默认使用的网络是 bridge,也是桥接模式,我们创建的网络也是桥接模式。

为什么默认的网络 bridge 只能通过 IP 来进行容器间的访问,自定义网络才能实现使用服务名来进行容器间的访问呢?

因为默认桥接网络不提供内置的服务发现机制,在默认桥接网络中,容器可以通过相互的IP地址进行通信,但无法通过服务名称进行DNS解析,因为 Docker 默认并没有提供 DNS 服务来支持容器名称解析。

创建的自定义网络,Docker 会启用内置的 DNS 服务,允许容器使用服务名称进行 DNS 解析,这意味着在用户定义网络上的容器可以通过其服务名称相互访问,而不仅仅是通过 IP 地址。


总结:

使用自定义网络可以实现容器之间的隔离,因为不在这个网络内的容器网段是不一样的,无法实现通信。而且自定义网络自带内置的DNS服务,使容器可以通过服务名称进行通信,而无需关心底层的IP地址。

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

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

相关文章

Harbor镜像仓库的安装和使用

1 Harbor安装 参考文章: 银河麒麟v10离线安装harbor 由于配置了本地私有yum源,因此,直接使用yum命令安装docker和docker-compose 1.1 安装docker yum install docker-ce1.2 安装docker-compose yum install docker-compose1.3 安装harbo…

服务器被挖矿后修改密码报错Authentication token manipulation error

服务器被挖矿,需要修改密码,结果执行的时候发现报错 passwd: Authentication token manipulation error 尝试执行下列命令后再进行密码修改,修改成功 chattr -i /etc/passwd /etc/shadowchattr的主要用法 参考文章: https://c.biancheng.ne…

GEE遥感云大数据林业应用典型案例及GPT模型应用

近年来遥感技术得到了突飞猛进的发展,航天、航空、临近空间等多遥感平台不断增加,数据的空间、时间、光谱分辨率不断提高,数据量猛增,遥感数据已经越来越具有大数据特征。遥感大数据的出现为相关研究提供了前所未有的机遇&#xf…

威纶通触摸屏在编辑画面时如何更改窗口画面大小?

威纶通触摸屏在编辑画面时如何更改窗口画面大小? 如下图所示,Windows11系统下,打开威纶通触摸屏编程软件easy builder pro,此时可以看到画面窗口非常小,不方便编辑和操作, 如下图所示,点击上方工…

swagger3快速使用

目录 &#x1f37f;1.导入依赖 &#x1f32d;2.添加配置文件 &#x1f9c2;3.添加注解 &#x1f96f;4.访问客户端 1.导入依赖 引入swagger3的依赖包 <dependency><groupId>io.springfox</groupId><artifactId>springfox-boot-starter</artif…

B3870 [GESP202309 四级] 变长编码(膜拜版)

本题包括&#xff1a; 1.进制的超强使用 2.进制的截位使用 本题参考洛谷题解&#xff1a;https://www.luogu.com.cn/article/daqzhu5m &#xff08;在线膜拜作者的代码中&#xff09; 难度&#xff1a;普及- 对于笔者而言&#xff1a; 这道题在洛谷上通过率很高&#xff0c;…

“JavaScript: void(0)的替代方案有哪些?”

学习目标&#xff1a; 理解javascript:void(0)的工作原理&#xff0c;以及它在前端开发中的作用和用途。掌握javascript:void(0)的正确用法&#xff0c;包括在HTML中使用和在事件处理程序中使用。能够识别javascript:void(0)可能引起的常见问题&#xff0c;并学会相应的解决方…

理财第一课:炒股词典

文章目录 基础代码规则委比委差量比换手率市盈率市净率 短线操作散户亏钱的原因庄家分析炒股战法波浪理论其它 钱者&#xff0c;人生之大事&#xff0c;死生存亡之地&#xff0c;不可不察也。耕田之利&#xff0c;十倍&#xff1b;珠玉之赢&#xff0c;百倍&#xff1b;闹革命&…

安科瑞消防产品监控系统解决方案【电气火灾 消防设备 】

一、电气火灾监控系统 系统概述 l针对低压用电环节各回路中的剩余电流、温度和故障电弧等进行实时监测&#xff1b; l侧重点为低压用电环节的安全性&#xff0c;当剩余电流越限时报警输出&#xff0c;以提醒维护人员进行安全检查&#xff0c;防止因漏电引起的火灾发生&#…

【GameFramework框架内置模块】9、有限状态机(FSM)

推荐阅读 CSDN主页GitHub开源地址Unity3D插件分享简书地址 大家好&#xff0c;我是佛系工程师☆恬静的小魔龙☆&#xff0c;不定时更新Unity开发技巧&#xff0c;觉得有用记得一键三连哦。 一、前言 【GameFramework框架】系列教程目录&#xff1a; https://blog.csdn.net/q7…

从零开始写 Docker(七)---实现 mydocker commit 打包容器成镜像

本文为从零开始写 Docker 系列第七篇&#xff0c;实现类似 docker commit 的功能&#xff0c;把运行状态的容器存储成镜像保存下来。 完整代码见&#xff1a;https://github.com/lixd/mydocker 欢迎 Star 推荐阅读以下文章对 docker 基本实现有一个大致认识&#xff1a; 核心原…

解决jenkins运行磁盘满的问题

参考&#xff1a;https://blog.csdn.net/ouyang_peng/article/details/79225993 分配磁盘空间相关操作&#xff1a; https://cloud.tencent.com/developer/article/2230624 登录jenkins相对应的服务或容器中查看磁盘情况&#xff1a; df -h在102挂载服务器上看到是这两个文件…

OSPF特殊区域(stub\nssa)

stub区域——只有1类、2类、3类&#xff1b;完全stub区域——只有1类、2类 NSSA区域&#xff1a;本区域将自己引入的外部路由发布给其他区域&#xff0c;但不需要接收其他区域的路由 在NSSA区域的路由器上&#xff0c;引入外部路由时&#xff0c;不会转换成5类LSA&#xff0c…

Ethsign银河活动开启,简单参与领6个NFT

简介&#xff1a;EthSign是一个基于区块链技术的去中心化电子签名平台&#xff0c;目的是解决传统中心化电子签名服务的各种问题。用户可以使用钱包或社交媒体帐户生成的私钥签署文件和协议&#xff0c;数字签名记录在链上&#xff0c;文件经过加密存储在去中心化存储网络中&am…

CSS学习(3)-浮动和定位

一、浮动 1. 元素浮动后的特点 脱离文档流。不管浮动前是什么元素&#xff0c;浮动后&#xff1a;默认宽与高都是被内容撑开&#xff08;尽可能小&#xff09;&#xff0c;而且可以设置宽 高。不会独占一行&#xff0c;可以与其他元素共用一行。不会 margin 合并&#xff0c;…

DETR算法简介

DETR方法是一种使用了Transformer的端到端的目标检测方法&#xff0c;也是经典目标检测算法之一&#xff0c;本文将用最少的话&#xff0c;介绍DETR算法的大致思想。之前的方法或多或少的都不要添加一下额外的步骤&#xff0c;进行人为干预&#xff0c;即使是号称端到端的YOLO系…

Linux卸载Zabbix6 Agent v1 v2 简易操作手册

一、Zabbix6 卸载Zabbix Agent v1 要在Linux系统上卸载Zabbix Agent v1(zabbix_agent)&#xff0c;您可以使用包管理器执行此操作。以下是针对不同Linux发行版的卸载命令&#xff1a; # 对于基于Debian的系统&#xff08;如Ubuntu&#xff09;: sudo apt-get remove zabbix-ag…

Java项目实战记录:雷达数据插值

Java项目实战记录&#xff1a;雷达数据插值 业务背景 之前已经实现了雷达数据的解析和雷达数据后端渲染功能&#xff0c;现在又有一个新的需求。之前是将雷达数据点使用GeoTools渲染成PNG的图片&#xff0c;但这个数据返给前端后不能无极缩放&#xff0c;因为它是个栅格图片&…

ArmSoM-Sige RK3588开发板使用手册

Sige7 使用手册&#xff0c;帮助用户了解Sige7的基本使用和需要的准备工作。 当您拿到产品的时候&#xff0c;您需要知道它的型号以及硬件版本&#xff0c;这些信息都可以在板子上的丝印找到。我们会尽可能详细地向您介绍产品的信息。 入门准备​ 在开始使用 ArmSoM-Sige7 之…

matlab空间曲线图形

说明&#xff1a;问题来自CSDN-问答板块&#xff0c;题主提问。 需求&#xff1a;如何用子图命令画出平面y2z&#xff0c;z2y与球面x^2y^2z^25相交的空间曲线图形。需要完整代码和结果的图片。 一、先看效果图 二、代码 % 创建figure figure% 创建二维网格&#xff0c;用于定…