大家好呀,我是小菜~
本文次要介绍
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 的网络,那我来试试”
终端上正如小菜农所料,呈现了他想要看的内容。“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@if67 和 veth9b75794 是一对 veth pair
,veth 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 的网络驱动,别离是 bridge
、overlay
和 macvlan
。overlay
和macvlan
用于创立跨主机的网络!
“跨主机?那就是集群咯!目前导师调配给我的服务器只有一台,看来没法验证了,只能等后续权限大点再验证了,嘿嘿!”,既然无奈验证其余两种,那就先将 bridge
搞明确~ 小菜农坏笑了起来!
下面曾经创立了一个 bridge
驱动类型的网络,那宿主机的网络配置应该产生了变动,小菜农输出了 brctl show
进行查看:
果然这个时候多了一个名为 br-76c202387b0c
的网桥,通过 ifconfig
能够发现网段也曾经调配了一个:
而这个应该就是新网络的网关了~ 小菜农真是越来越纯熟起来,看来学习真能使人自信!
所有都如小菜农所料,172.18.0.1
就是 Docker 主动调配的 IP 网段
“然而如果自定义的网络多了起来,调配的网段必定也是随之减少,那由 docker 调配的网段必定是随机,不不便记忆,能不能 本人指定 IP 网段”,小菜农突发奇想,输出 docker network create --help
会不会有所发现?
看到这后果,小菜农忍不住笑了起来,真有我的!这 subnet
和 gateway
不就是我想要的吗!~
这不就成了吗!而且宿主机上也有了新的网络,网段为 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-custom
和 nginx-ip
之间必定可能相互连通,小菜农验证一下猜测
后果是对的,那 nginx-default
是否能和其余两个容器相通呢?验证一下就晓得了!
由此可见同一网络中的容器、网关之间是相通的,而属于不同网桥之间的容器是不能相互通信的。难道这样子就完结了吗?两个不同网络之间的容器难道真的不能相通了?小菜农不甘心就这样放弃,盯着屏幕一阵发愣,“有了!加个路由的话,那么两个网络之间应该就能通信了吧!”如果 host 上对每个网络都只有一条路由,同时操作系统上开启了 ip forwarding,那么 host 就会造成一个路由器,挂接在不同网桥上的网络就可能通信!
小菜农通过ip r
查看宿主机上的路由表
能够看到 172.17.0.0/16
和 172.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.2
是 nginx-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 做架构
的程序猿吧~ 点个关注做个伴,让小菜不再孤独。咱们下文见!
明天的你多致力一点,今天的你就能少说一句求人的话!
我是小菜,一个和你一起变强的男人。
💋
微信公众号已开启,小菜良记,没关注的同学们记得关注哦!