《菜农升职记》之 Docker网络

2023-11-02 04:10
文章标签 docker 网络 升职 菜农

本文主要是介绍《菜农升职记》之 Docker网络,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

大家好呀,我是小菜~

本文主要介绍 docker 网络

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

刚结束完一个需求的小菜农刚想打开公众号《菜农曰》看看博客划划水,叮叮又响了!

“小菜农,这个测试环境的服务器连接信息,你登上去通过docker部署下你刚刚提交的分支测试下哈!”

导师程立给小菜农发来了消息

“docker是个啥玩意?之前不都是直接在服务器找个目录上传然后 nohup java -jar ... & 一套组合拳下来吗?”

小菜农顿时又自闭了,自从来到了职场真是处处碰壁!想想在学校还是三好学生真是唏嘘不已!

“等等!我记得公众号《菜农曰》写了一篇关于 docker 的,赶紧翻出来看看”

Docker上手,看完觉得自己又行了!

许久之后,小菜农方从文章中回过神来,“这下不得拿捏了!”。他打开服务器输入 docker ps 试了下指令

“有点意思啊!”他按照文章中的教程开始部署自己的应用项目。先是编写了自己应用的 dockerfile,然后通过 docker build 构建出自己的镜像,最后执行 docker run来运行自己的镜像,一整套下来一气呵成,行云流水!然后便在浏览器测试了下自己的功能内容,测试通过后。小菜农便陷入了思考,docker 是一个容器,可以内嵌一个操作系统,每个容器之间是相互隔离的,那为啥我可以从外界访问容器内的内容?容器之间是如何通信的?又怎么创建自定义网络?

几个问题想的小菜农头都大了!放弃是不可能放弃的,没准这以后可以成为自己升职加薪,走上人生巅峰的垫脚石之一呢!从这里可以看出小菜农还是很有斗志的嘛~

docker 容器在安装的时候会自动在 host 上创建三个网络,小菜农看到了这句话,那要怎么查看这三个网络了,通过help指令看看会不会有所发现?他快速地在终端敲入docker --help

“哦豁,果然有!network 不就是我想要的吗!”。机智的小菜农开始顺藤摸瓜,继而敲入docker network --help

ls 可以查看docker 的网络,那我来试试”

image-20220220191636020

终端上正如小菜农所料,出现了他想要看的内容。“bridge、host、none?” 小菜农还是有些网络基础的,前两个看名称都有点熟悉,但是 none 是个啥玩意?什么都没有的网络吗?。小菜农通过一番查询,没想到还真是,不由得佩服命名的开发者,这可真让人顾名思义~ 查询发现,挂在这个网络下的容器除了 lo,没有任何网卡

我们启动容器是通过 docker run来执行的,这个指令后面我们可以附加参数,通过 --network = none就可以指定该容器是使用 none 网络~

“那么这样一个封闭的网络有啥用,都上不了网”,小菜农嘀咕道

没错,就是要上不了网,有些特殊的应用场景需要将网络封闭起来,往往这种场景意味着安全性要求很高,因此需要进行隔离,这种情况就可以放到 none 网络防止被人侵入。

“既然是特殊场景才需要,那我目前应该还接触不到特殊场景,pass pass!让我康康 host 是什么网络”

小菜农知道了可以通过 --network指定网络类型,他试着启动了一个网络类型为host 的nginx来查看

小菜农看到这个网络配置不禁陷入了沉思,这怎么似曾相似?他将终端命令行往上滚了几页,终于发现为啥眼熟了!

原来他在上面的时候曾经输入 ip l 查看了宿主机的网络,你可以发现这两个配置是一模一样的!那就说明连接到 host 网络的容器共享 Docker host 的网络栈,容器的网络配置与宿主机的配置完全一样。那这样子的话直接使用 Docker host 网络的最大好处就是性能了。如果容器对网络传输效率有较高要求的时候,就可以使用 host 网络,也相当于是使用宿主机的网络,那么这样做的缺陷是什么?那就是端口会冲突,在宿主机上已经使用的网络,容器就不能再使用了!

小菜农觉得应该没那么简单,又查了下 host 网络的使用场景,不一会就有所发现了,使用 host 网络的另一个用途就是可以让容器直接配置 host 网络,比如某些需要跨 host 的网络解决方案,其本身也是以容器的方式运行的,这些方案需要对网络进行配置,比如管理 iptables 之类的场景。

“真是丈母娘看郎,越看越爱~ ”小菜农已经有点迷上了docker,越深入才发现越有意思。“还剩下 bridge 网络类型,让我康康!”

bridge 是一种桥接模式的网络,桥接顾名思义就是一端在这里另一端在那里。小菜农又大胆猜测了,那肯定就是一端在容器上,一端在宿主机上!接下来便进行了验证

小菜农想起了一个命令 brctl,该命令brctl 可用于设置、维护和检查linux内核中的以太网网桥配置。

无法使用 brctl 命令的童鞋可以使用以下命令安装

yum install -y bridge-utils

他通过brctl show查看宿主机的网桥配置,发现有个命为 docker0 的网桥,然后他通过启动一个容器继续观察网桥变化:

小菜农发现 interface 的内容发生了变化!有一个新的网络接口 veth9b75794 挂在了 docker 0 上,而 veth9b75794 就是刚刚创建容器的网卡,小菜农紧接着查看了下刚创建容器的网络配置

容器中有个一个 eth0@if67 网卡,小菜农会心一笑

“嘿嘿,被我发现了吧,要不是我会点网络,还真被这忽悠住了。刚刚上面查看到的网络接口是 veth9b75794,而这里是 eth0@if67,换成刚接粗网络的童鞋肯定一头雾水,这两个怎么不一样!实际上 eth0@if67veth9b75794 是一对 veth pairveth pair 是一种成对出现的特殊网络配置,而这就是我上面猜测的那样,网桥就是可以把它们想象成由一根虚拟网线连接起来的一对网卡,网卡的一头(eth0@if67)在容器中,另一头(veth9b75794)挂在网桥docker0上,其效果就是将eth0@if67也挂在了docker0上

172.17.0.2/16 这个 IP 也就是宿主机配置的,小菜农查看了下docker 的bridge配置

发现有个bridge网络配置的subnet就是172.17.0.0/16,并且网关是172.17.0.1。那么这个网关就是 docker 0!小菜农在宿主机输入 ifconfig' 进行验证

而这时,小菜农的脑子里浮现了一张图

到这里,小菜农已经熟悉了 docker 的三种网络类型的情况,便开始思考如何可以自定义网络,肯定存在很多场景用户需要根据业务来创建自定义网络来满足需求。在上面小菜农想要查询docker的网络配置时有输入过命令 docker network --help,输出结果的时候小菜农有点印象其中好像有个 create 的命令,赶紧又输入一遍进行确认:

果然,docker 已经支持用户创建自定义网络。很快呀!小菜农便在终端输入了创建网络的命令:

眼尖的小菜农一眼就发现了不对劲,创建网络的时候并没有指定 DRIVER 呀!而这个时候创建出来的网络驱动默认就是 bridge,那就说明是否还可以创建其他网络驱动的网络?小菜农再一次进行了尝试,但这次结果确认小菜农碰壁了

“难道只能创建 bridge 驱动类型的网络吗?” 小菜农嘀咕。依旧不死心便上了某搜索引擎进行结果查找。查找后发现原来Docker提供了三种 user-defined 的网络驱动,分别是 bridgeoverlaymacvlanoverlaymacvlan用于创建跨主机的网络!

“跨主机?那就是集群咯!目前导师分配给我的服务器只有一台,看来没法验证了,只能等后续权限大点再验证了,嘿嘿!”,既然无法验证其他两种,那就先将 bridge 搞明白~ 小菜农坏笑了起来!

上面已经创建了一个bridge驱动类型的网络,那宿主机的网络配置应该发生了变化,小菜农输入了 brctl show 进行查看:

果然这个时候多了一个名为 br-76c202387b0c 的网桥,通过ifconfig可以发现网段也已经分配了一个:

而这个应该就是新网络的网关了~ 小菜农真是越来越熟练起来,看来学习真能使人自信!

一切都如小菜农所料,172.18.0.1 就是 Docker 自动分配的 IP 网段

“但是如果自定义的网络多了起来,分配的网段肯定也是随之增加,那由 docker 分配的网段肯定是随机,不方便记忆,能不能自己指定 IP 网段”,小菜农突发奇想,输入 docker network create --help 会不会有所发现?

看到这结果,小菜农忍不住笑了起来,真有我的!这 subnetgateway 不就是我想要的吗!~

这不就成了吗!而且宿主机上也有了新的网络,网段为 172.10.0.0/16,网关为 172.10.0.1

既然创建了自己的网络,小菜农顿时成就感满满,这不得赶紧启动一个容器来试试自己的网络!

可以看到使用自己配置网络启动的容器,分配到的 IP 地址是 172.10.0.2/16,“既然容器的 IP 都是docker 自动从 subnet中分配的,那我能不能指定一个静态IP呢?”小菜农又提出了疑问,那么只能再祭出老套路 --help 进行解决了!小菜农手脚麻利的敲下 docker run --help | grep 'ip' 查看结果

小菜农笑容逐渐变态,没想到自己掌握了 help 神器!看来可以通过 --ip xxx来指定自己想要的IP,敲命令的手法逐渐娴熟起来,这不,一会功夫结果就出来了:

到目前为止,小菜农已经启动了三个容器

而网络之间的拓扑关系也忽然而出,小菜农连忙动手画了起来,以免忘记!

小菜农看着图发呆了一会,这图其实已经挺清晰了,nginx-customnginx-ip 之间肯定能够互相连通,小菜农验证一下猜想

结果是对的,那 nginx-default 是否能和其他两个容器相通呢?验证一下就知道了!

由此可见同一网络中的容器、网关之间是相通的,而属于不同网桥之间的容器是不能互相通信的。难道这样子就结束了吗?两个不同网络之间的容器难道真的不能相通了?小菜农不甘心就这样放弃,盯着屏幕一阵发呆,“有了!加个路由的话,那么两个网络之间应该就能通信了吧!” 如果 host 上对每个网络都只有一条路由,同时操作系统上开启了 ip forwarding,那么 host 就会形成一个路由器,挂接在不同网桥上的网络就能够通信!

小菜农通过ip r 查看宿主机上的路由表

可以看到 172.17.0.0/16172.10.0.0/16 两个路由都已经定义好了,下一步就需要看下 ip forwarding 是否已经开启,小菜农快速的敲下指令 sysctl net.ipv4.ip_forward

可以看到 ip forwarding 也已经开启了。那这个时候只需要为 nginx-default 容器添加一块 c-custom的网卡就可以通信了!万事俱备,只欠东风~

小菜农依旧通过熟悉的配方查看添加网卡的步骤

了解之后便开始动手操作

“nice,没有出错,这下应该可以通信了吧!” 小菜农嘀嘀咕咕,紧张的手颤抖的心继续敲下 ping 命令进行验证

瞪大了眼,第一次这么有成就感,没想到真的被自己折腾出来了!小菜农激动的差点站了起来,恨不得大声笑出来,但他知道,这只是自己成长的第一步,自己已经成功的跨出去了!平复下了激动的心,得出一个自己刚刚实验出的结论

两个容器要能通信,就必须要有属于同一个网络的网卡,当满足这一条件后,容器就可以通过 ip 进行交互了

结论来之不易,小菜农赶紧在自己的小本本上记录下来!尝到甜头的小菜农继续在网上进行搜索,看是否存在其他可以在容器间通信的方式,毕竟用 IP 进行通信还是属于比较基础的~ 很快,小菜农便找到了答案,有的! 容器间可以通过是那种方式进行通信

  • IP
  • Docker DNS Server
  • joined

IP 通信自己已经实验过了,接下来就要尝试其他两种方式。Docker DNS Server ?看解释是通过 容器名的方式,在上面创建的容器,小菜农都已经指定了容器名,接下来只要进行实验就行了

果然是可以的!可以通过容器名进行访问,那就意味这可以不用记忆那么长一串的 IP 了!

前两种方式都已经实验过了,看到 joined 小菜农又有点懵了,加入 ? 小菜农继续往下看了解释

joined 容器是另一种实现容器间通信的方式

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

“还真神奇,docker中处处充满了惊喜呀!”,小菜农随后便进行了尝试

这边值得注意的是,两个容器共享同一个网络栈,那么端口就不能冲突,因此启动的时候需要分离端口

到这里,小菜农不由得心满意足了,刚要退出服务器开始继续工作,却被自己的网页吸引过去了,网页上开着正是小菜农刚刚启动的docker项目。“咦,外界是怎么与容器进行连接的?” 小菜农再次提出了疑问,容器如何访问外界?外界又如何访问容器? 看来还是得继续学习(划水)呀!

小菜农再次切换到服务器页面,尝试从容器内进行访问外界

其实不用尝试,小菜农也清楚,容器肯定能访问到外界,不然外部接口如何调用~ 但是为什么能访问到呢?小菜农查看了宿主机的 iptables 规则

可以看到有这么两条规则,一条是 docker 0,一条是小菜农刚刚自定义的,那它是什么意思呢?小菜农又犯迷糊了,看了旁边的肖老大,这不有现成的大佬可以问吗!肖老大有些好奇,小菜农这是接到啥需求了,怎么会问到这个问题,不过也没多想,新人总要照顾好的不是!便开始巴拉巴拉解释起来,小菜农也听得云里雾里,“这样说明白了吗?”。“啊?哦!差不多知道这个意思了,嘿嘿,谢谢肖老大”,“不客气不客气,下次遇到不会记得还来找我哈”,肖老大略微粗犷的嗓门,让小菜农倍感温馨!总结了下肖老大的解释:如果网桥 docker 0 接收到来自 172.17.0.0/16 网段的外出包,就会把它交给 MASQUERADE 处理,而 MASQUERADE 的处理方式就是将包的源地址替换成 host 的地址发送出去,即做了一次网络地址转换 NAT。

既然如此,那么通过抓包应该就可以看清楚网络地址转化的过程,小菜农打算使用 tcpdump 来做一次简易抓包查看下结果,首先他起了两个终端,一个终端通过 ping www.baidu.com 来发送网络包,一个包通过 tcpdump -i docker0 -n icmp 抓取网络信息

172.17.0.2nginx-default 容器的 IP,通过转包可以发现该 IP 地址是往 180.101.49.11 发送数据包,到这里小菜农完成了第一步,接受继续通过 tcpdump -i eth0 -n icmp 查看宿主机的网络流出信息

“啊哈!果然变了,这个时候ping包的原地址,变成了 ehp0 的 IP 172.26.19.234

弄清楚了 容器内部访问外界 后,那么接下来就是搞清楚 外界如果访问容器

小菜农记得刚刚自己启动容器后,在 PORTS 那里有显示端口,便在浏览器试了下就可以顺利访问了!小菜农又起了一个容器进行实验

启动容器后,便可以利用 32771 这个端口号进行访问,而32771这个端口是宿主机自动分配的,小菜农又试了下自己指定端口访问

指定端口后,通过自己指定的端口也是可以访问的,而这其中的缘由,小菜农也通过查询发现是通过 docker-proxy 实现的

每一个映射的端口,host 都会启动一个 docker-proxy 进程来处理访问容器的流量。

到这里,小菜农就搞懂了 Docker 中的网络使用,但是小菜农眉头一皱,今天玩的都是单机,那么在集群中网络又是如何访问呢?

不要空谈,不要贪懒,和小菜一起做个吹着牛X做架构的程序猿吧~点个关注做个伴,让小菜不再孤单。咱们下文见!

今天的你多努力一点,明天的你就能少说一句求人的话!

我是小菜,一个和你一起变强的男人。 💋

微信公众号已开启,小菜良记,没关注的同学们记得关注哦!

这篇关于《菜农升职记》之 Docker网络的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/328014

相关文章

如何用Docker运行Django项目

本章教程,介绍如何用Docker创建一个Django,并运行能够访问。 一、拉取镜像 这里我们使用python3.11版本的docker镜像 docker pull python:3.11 二、运行容器 这里我们将容器内部的8080端口,映射到宿主机的80端口上。 docker run -itd --name python311 -p

Linux 网络编程 --- 应用层

一、自定义协议和序列化反序列化 代码: 序列化反序列化实现网络版本计算器 二、HTTP协议 1、谈两个简单的预备知识 https://www.baidu.com/ --- 域名 --- 域名解析 --- IP地址 http的端口号为80端口,https的端口号为443 url为统一资源定位符。CSDNhttps://mp.csdn.net/mp_blog/creation/editor

ASIO网络调试助手之一:简介

多年前,写过几篇《Boost.Asio C++网络编程》的学习文章,一直没机会实践。最近项目中用到了Asio,于是抽空写了个网络调试助手。 开发环境: Win10 Qt5.12.6 + Asio(standalone) + spdlog 支持协议: UDP + TCP Client + TCP Server 独立的Asio(http://www.think-async.com)只包含了头文件,不依

poj 3181 网络流,建图。

题意: 农夫约翰为他的牛准备了F种食物和D种饮料。 每头牛都有各自喜欢的食物和饮料,而每种食物和饮料都只能分配给一头牛。 问最多能有多少头牛可以同时得到喜欢的食物和饮料。 解析: 由于要同时得到喜欢的食物和饮料,所以网络流建图的时候要把牛拆点了。 如下建图: s -> 食物 -> 牛1 -> 牛2 -> 饮料 -> t 所以分配一下点: s  =  0, 牛1= 1~

poj 3068 有流量限制的最小费用网络流

题意: m条有向边连接了n个仓库,每条边都有一定费用。 将两种危险品从0运到n-1,除了起点和终点外,危险品不能放在一起,也不能走相同的路径。 求最小的费用是多少。 解析: 抽象出一个源点s一个汇点t,源点与0相连,费用为0,容量为2。 汇点与n - 1相连,费用为0,容量为2。 每条边之间也相连,费用为每条边的费用,容量为1。 建图完毕之后,求一条流量为2的最小费用流就行了

poj 2112 网络流+二分

题意: k台挤奶机,c头牛,每台挤奶机可以挤m头牛。 现在给出每只牛到挤奶机的距离矩阵,求最小化牛的最大路程。 解析: 最大值最小化,最小值最大化,用二分来做。 先求出两点之间的最短距离。 然后二分匹配牛到挤奶机的最大路程,匹配中的判断是在这个最大路程下,是否牛的数量达到c只。 如何求牛的数量呢,用网络流来做。 从源点到牛引一条容量为1的边,然后挤奶机到汇点引一条容量为m的边

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络

配置InfiniBand (IB) 和 RDMA over Converged Ethernet (RoCE) 网络 服务器端配置 在服务器端,你需要确保安装了必要的驱动程序和软件包,并且正确配置了网络接口。 安装 OFED 首先,安装 Open Fabrics Enterprise Distribution (OFED),它包含了 InfiniBand 所需的驱动程序和库。 sudo

【机器学习】高斯网络的基本概念和应用领域

引言 高斯网络(Gaussian Network)通常指的是一个概率图模型,其中所有的随机变量(或节点)都遵循高斯分布 文章目录 引言一、高斯网络(Gaussian Network)1.1 高斯过程(Gaussian Process)1.2 高斯混合模型(Gaussian Mixture Model)1.3 应用1.4 总结 二、高斯网络的应用2.1 机器学习2.2 统计学2.3

网络学习-eNSP配置NAT

NAT实现内网和外网互通 #给路由器接口设置IP地址模拟实验环境<Huawei>system-viewEnter system view, return user view with Ctrl+Z.[Huawei]undo info-center enableInfo: Information center is disabled.[Huawei]interface gigabit

禅道Docker安装包发布

禅道Docker安装包发布 大家好, 禅道Docker安装包发布。 一、下载地址 禅道开源版:   /dl/zentao/docker/docker_zentao.zip  备用下载地址:https://download.csdn.net/download/u013490585/16271485 数据库用户名: root,默认密码: 123456。运行时,可以设置 MYSQL_ROOT_P