前言

本讲是从Docker系列讲解课程,单独抽离出来的一个小节,单纯的介绍容器之间的通信,它和上一篇容器五种(3+2)网络模式中的自定义网络模式知识点互补。

本文带你的帮助, 让你在了解容器5种网络模式的基础上,对容器之间的通信有更清晰、深刻的了解,这也会后期学好K8s做好基本功铺垫。

概述

同一宿主机内A、B两个容器

单向通信:A需要知道B的存在,B不需要知道A的存在。

双向通信:A/B要相互知道对方的存在,并能正常的互通有无。

该模式,需要使用到上一讲,自定义网络模式的知识点,具体如下

一、容器之间默认桥接模式,基于IP的双向通信

1.容器间通过虚拟IP访问(效果差)

1)分别以桥接模式启动nginx和Tomcat两个容器,并分别赋予别名nginx、tomcat

docker ps -a #实验前,清空干扰容器
docker images #查看本机镜像列表
docker run --name nginx  -d nginx:alpine  #运行nginx容器
docker run --name tomcat -d -p 8080:8080 tomcat:8.5.46-jdk8-openjdk   #运行tomcat容器

2)docker inspect 获取两个容器的Ip地址

docker ps -a  #查看正在运行容器列表(主要是获取容器id)
docker inspect 7a  #根据容器ID首字母,查看nginx容器详细信息(主要是查看IP) 172.17.0.2
docker inspect 07  #根据容器ID首字母,查看tomcat容器详细信息(主要是查看IP)  172.17.0.3

可以获悉,nginx和tomcat的虚拟IP分别为 172.17.0.2、172.17.0.3

 

3)docker exec 进入nginx内部,访问tomcat的IP

docker ps
docker exec -it nginx /bin/sh  #使用nginx别名,进入nginx容器内部
ping -w 3 172.17.0.3:8080   #ping tomcat的Ip和端口
curl 172.17.0.3:8080

发现,通过IP是可以ping通同一宿主内的其他容器的(这是bridge网络模式的特性)

注:如果你对进入nginx容器内部为什么是/bin/sh不是/bin/bash感兴趣,点击进入。

4)docker exec 进入tomcat内部,访问nginx的IP

exit #退出nginx容器
docker ps
docker exec -it 07cde2b94cc8 /bin/sh  #进入tomcat容器内部
ping -w 3  172.17.0.2  #ping nginx的IP
curl  172.17.0.2  #访问nginx的IP

发现,在nginx容器内部,通过IP可以访问同一宿主机下的其他容器。

5)虚拟IP访问的弊端

虚拟IP不稳定,如果容器启动的先后顺序不同,容器的虚拟IP也会随之变化。尤其是在集群模式下,如果mysql的IP不固定,会造成不必要的麻烦。

注:桥接模式下的容器,默认在容器之间,只识别同一宿主机下其他容器的IP,不识别容器别名。

二、容器之间基于--link的单、双向通信(可以通过别名相互访问)

1.容器间通过别名单向通信

在上个操作步骤起始,docker run 两个容器的时候,都已经通过--name给容器分别指定了别名nginx、tomcat,下面试用容器的别名相互访问一下。

1)docker exec -it 进入Tomcat容器目录,ping nginx的别名(不通)

docker exec -it nginx /bin/sh #进入nginx容器内部
/ # ping tomcat
ping: bad address 'tomcat'

发现,桥接模式下,容器之间默认不识别彼此的别名,有没有办法让容器相互识别别名呢?

有,最常用的有两种办法:

1、使用link的方式,让容器之间彼此做link链接(该方式在容器数量极少情况面,还可行,容器多了,就不好使了 )

2、自定义网络模式(名字:mynet),并通过docker network create -d指定自定义的网络模式为bridge,让容器都链接到同一个自定义的网络模式上mynet上

预告:下面先介绍Link方式, 第二种方式上一篇,第六章:自定义网络模式,有详细介绍,稍后在双向通信中会再次介绍一下。

2)移除nginx容器,docker run 重新启动nginx,并--link关联tomcat容器,进入nginx容器后,用tomcat别名ping

docker stop nginx  #停掉没有使用--link链接的nginx
docker rm nginx
docker run --name nginx -d --link tomcat nginx:alpine  #重新启动nginx,并用--link链接到tomcat
docker exec -it nginx  /bin/sh  #进入nginx容器内部
ping tomcat  #尝试用tomcat别名ping通

发现,nginx容器在启动时,如果通过--link链接了tomcat容器的别名,那么进入nginx容器后,nginx容器内部,就可以识别tomcat的别名,当然也可以通过ping或curl来连通tomcat。

疑问:nginx启动时,用--link 主动链接tomcat了,从而在nginx容器内部可以识别tomcat的别名,反之呢?此时tomcat启动时,并没有通过--link主动链接nginx,在tomcat内部是否识别nginx的别名呢?下面就一起试验一下吧!

3)通过docker exec命令再次进入tomcat容器内部,ping nginx的别名

exit #退出nginx容器
docker ps
docker exec -it tomcat /bin/bash   #进入tomcat容器内部
ping nginx  #尝试用nginx的别名,发现不能ping通

发现,--link是单向的,nginx在run启动的时候,主动链接到tomcat,所以在nginx容器内部可以识别tomcat的别名。

反之,tomcat容器在run启动时,没有通过--link 链接nginx,所以在tomcat容器内部不能识别nginx的别名。

那有没有办法,在各自的容器内部,让双方相互相互识别各自的别名呢?

答案是有!那就是双方在run启动的时候,通过--link链接彼此的别名。

2.容器间通过别名访问双向通信

1)移除tomcat容器,重启启动tomcat容器时,用--link nginx,主动链接到nginx

exit #退出上面的tomcat容器
docker stop tomcat #停掉tomcat
docker rm tomcat  #移除掉没有--link的tomcat
docker run -d --name tomcat --link nginx -p 8080:8080  tomcat:8.5.46-jdk8-openjdk  #重新启动,并用--link链接到nginx

2)进入tomcat容器内部,尝试访问nginx的别名

docker exec -it tomcat /bin/bash  #进入到tomcat容器内部
ping -w 3 nginx  #发现,现在tomcat容器内部识别nginx了

3)小结

至此实现了--link模式下,通过容器的别名单双向通信。该方式的优点:相对于容器彼此间用IP访问要好很多,不用担心虚拟IP来回变化。

也就是说,在后台开发,配置文件中,不用配置mysql数据库的IP,直接写别名就可以了。使用该方式,要想实现双向通信,就要忍受,给每个容器link一下它要识别的容器的别名,其它容器反向也要这么操作,双方就可以自动双向通信。

从某种程度上说,这也是一件比较麻烦的事情,尤其的多数据源多容器的情况下。有没有更好的模式呢?有,就是下方的基于bridge自定义网络模式。

三、容器之间基于Bridge网桥的双向通信

1)准备工作,为保障实验效果,清理掉前面的所有实验容器

exit  #退出上一容器的内部
docker rm -f $(docker ps -qa)  #强制删除所有容器
docker ps -a   #检查一下,是否彻底清场

2)手动创建自定义网络mynet,并-d指定为bridge网桥模式

#--subnet 可以不指定,不指定的话,网段使用的就是docker0的网段
#自定义名字为mynet的网络,subnet指定子网网段(不能与其他网卡的网段重叠)
docker network create -d bridge --subnet 172.25.0.0/16 mynet  

注:-d是--driver的简写,对这个不是很了解的,建议熟悉一下或至少熟悉一下容器的五种网络模式中的第六章:自定义网络模式,当然,你也可以通过官网了解一下,点击进入官网。

3)启动两个容器时都赋予别名分别为nginx和tomcat,且通过--net绑定到mynet网卡

docker network ls   #可以看到自己定义的mynet网络
docker run -d --name nginx --net=mynet  nginx:alpine  #启动时起别名,并指定网络未mynet
docker run -d --name tomcat --net=mynet -p 8080:8080 tomcat:8.5.46-jdk8-openjdk  #启动时起别名,并指定网络未mynet

注:网络模式的指定,可以在docker run命令的时候同时指定。也可以在运行后,通过下面的命令单独指定:docker network connect mynet nginx ; docker network connect mynet tomcat

4)分别进入nginx和tomcat容器内部,查看是否可以相互访问对方的别名

docker exec -it nginx sh  #进入nginx容器内部
ping tomcat  #可以ping通tomcat的别名
exit docker exec -it tomat bash  #进入tomcat容器内部
ping nginx #可以ping通nginx的别名
exit

发现,可以互相ping通彼此的别名,是不是很Nice,只需要容器双方指向同一个自定义的桥接方式或者overlay方式的(mynet)网络就可以了。

5)关于 --subnet 172.25.0.0/16的引申

在docker run 启动容器,并--net=mynet(自定义网络)的时候,是可以不指定--subnet的,如果不指定,子网subnet默认使用的就是docker0的subnet,其子网网段就是172.17.0.1/16,可以通过docker network inspect bridge 得知。

docker network inspect bridge   #查看桥接模式的默认网卡信息

如果指定了--subnet 为 172.25.0.0/16,那么这个网段就不能和上面的docker0的subnet有重叠。同时,使用该自定义网络的容器,IP自然处在172.25这个网段之下,通过查看容器的详细信息,可以通过docker inspect nginx (该nginx绑定了mynet,而mynet在docker run时被指定的网段是172.25)得知。

docker inspect nginx #查看使用了自定义网络mynet的nginx的网络信息

发现,使用了mynet自定义网络模式的容器,容器的IP也会使用mynet指定的网段,172.25的网段IP。

6)自定义网络模式,互联互通的原理

自定义网络模式(需要用-d(或者--driver )指定为bridge或者overlay),它好比一个媒人,给两边的容器牵桥搭线,构建一个网段平台,只要是使用该自定义网络的容器,都在同一个网段内(通过--subnet指定,各自定义网络的subnet不能重复),就可以实现相互识别对方的别名。

相比于--link方式,简直是好太多了!!

注:对于--subnet选项创建子网而言,overlay网络可以支持多个子网,bridge网络只能指定一个子网。

总结

本文详细介绍了docker容器之间单双向通信,从最原始的桥接模式,容器之间只能通过IP访问互通,比较不方便。

后来演化出,使用--link 容器双/多方,相互给对方打标记,以便识别对方的别名,而不用去使用对方飘忽不定的IP来相互访问,这是一大进步。然而随着时代的发展,单机非集群模式下,该模式还有生存空间,随着大数据时代的深入,--link模式,也即将被官方淘汰(目前最新的20.*系列版本,暂时还在保留,被官网提示不建议使用,也仅仅是为kill it的前夕,缓冲一下)

最后,又再次了解了容器的五种网络模式,之一的自定义网络模式,该模式也更为灵活、简单,只需要将各容器在run时,指定为同一自定义网络即可实现各容器相互识别对方的别名。并且-d 指定为overlay时,功能更为强大,可以指定多个--subnet,这也意味着可以容纳更多的IP和容器。该模式,是不错的选择,随着编排工具的崛起,此种方式也在逐渐被取代!

尾言

吐血完成此文,一方面是为了加深自己对该知识点的理解,提升自己,另一方面也希望能够帮助后来人,在此汇总分享给大家,希望对大家有所帮助。

同时本讲也是从 Docker入门到进阶系列里面抽离出来的内容,因为它是一个庞大的知识体系,一篇文章难以讲述清楚,也为了让原文更加层次分明。

附注

猜测你可能对以下内容,较为感兴趣...

1、Docker容器 | Dockerfile优化

2、Docker容器的生命周期 | kill和stop | pause 和 unpause

3、 Docker容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解

4、Docker跨宿主机通信 | overlay和macvlay 图解

Docker学习:容器之间单/双向通信 |--link /自定义网络实现互认容器别名 (理论篇)相关推荐

  1. docker 获取宿主机ip_Docker基础修炼6——网络初探及单机容器间通信

    如果觉得文章有帮助,欢迎点击头像关注我获取更多原创文章,同时也欢迎转发. 同时也可以在我的历史文章中找到Linux操作系统相关的服务器运维管理入门系列文章,欢迎交流. 前文演示docker容器内部数据 ...

  2. Docker学习:容器间数据挂载与共享 | 远程共享挂载数据卷 | sshfs挂载远程volume | 容器内部通过sshfs访问远程主机 | -v |--volumes-from(实战篇)

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,主要介绍宿主.容器间数据共享,它的好处自然不言而喻,Tomcat集群就是这么玩儿的(多个tomcat服务,对应一套web应用). 核心原 ...

  3. Docker学习:外部浏览器访问容器 | 容器访问容器 | 访问容器的常用5种方式 | -p -P 详解

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,主要介绍容器间内部相互访问和外部访问容器的一些方法,它和前面两篇:容器五种(3+2)网络模式.容器之间单/双向通信 |--link /自 ...

  4. Docker学习:跨宿主机通信 | overlay和macvlay(理论+实战篇)

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,带你一起 深入了解在编排工具出现前,跨宿主机通信的两大得力干将overlay.macvlay,这也会后期学好K8s做好基本功铺垫,打下一 ...

  5. Docker学习(五):Docker网络

    Docker网络 1. docker network命令 #查看docker网络 docker network ls #帮助命令 docker network --help #创建网络 docker ...

  6. Docker学习:容器五种(3+2)网络模式 | bridge模式 | host模式 | none模式 | container 模式 | 自定义网络模式详解

    前言 本讲是从Docker系列讲解课程,单独抽离出来的一个小节,重点介绍容器网络模式, 属于了解范畴,充分了容器的网络模式,更有助于更好的理解Docker的容器之间的访问逻辑. 疑问:为什么要了解容器 ...

  7. Docker 容器互联 --link 和 自定义网络

    [Docker那些事]系列文章 Dockerfile 文件结构.docker镜像构建过程详细介绍 Dockerfile文件中CMD指令与ENTRYPOINT指令的区别 构建Docker镜像指南,含实战 ...

  8. docker 容器之间通信_还不清楚docker容器间是如何通信的?看这篇文章就够了

    如果觉得文章有帮助,欢迎点击头像关注我获取更多原创文章,同时也欢迎转发. 同时也可以在我的历史文章中找到Linux操作系统相关的服务器运维管理入门系列文章,欢迎交流. 前文演示docker容器内部数据 ...

  9. Docker学习(六):docker compose容器编排

    Docker-compose 实现对容器集群的快速编排 多服务部署的管理工具 定义docker-compose.yml文件,写好容器之间的调用关系,通过命令完成多个容器的同时启动关闭 解决了容器与容器 ...

  10. 容器技术-Docker 网络03-用户自定义网络-网络命令的使用

    基于 Docker18.09.0 Docker 系列文章目录 安装Docker和容器管理 Docker镜像管理 Dockerfile详解 Docker数据卷管理 Docker网络之默认网络 Docke ...

最新文章

  1. 测试人员如何赢得开发人员的尊重
  2. IJCV2021 人脸关键点检测器PIPNet
  3. python语言程序设计2019版第二章课后答案-python语言程序设计基础(嵩天)第二章课后习题...
  4. WPF多线程UI更新——两种方法
  5. linux下制作codeblocks绿色版,并集成devhelp
  6. 设计师学习HTML/CSS之路-09
  7. Android自动化测试之MonkeyRunner使用
  8. linux查看进程占用内存与ps命令
  9. 最全架构设计实践方法论(一)
  10. html5 电子白板 直播,HTML5 canvas教程 如何实现电子白板
  11. iOS逆向-微信自动添加好友
  12. 并发请求多 服务器响应慢 post,从服务端视角看高并发问题
  13. 中石油布局天然气商储 天然气国家储备有望
  14. Ubuntu18.04使用校园网上网的问题(以锐捷客户端为例)
  15. vue-生成二维码+下载二维码
  16. Java高级编程学习
  17. 一键装机linux_linux系统学习第十八天《搭建一键装机平台》终结篇
  18. Java调用存储过程(返回:简单类型VARCHAR、自定义对象STRUCT、列表数组VARRAY)
  19. Java中如何快速构建项目脚手架
  20. [BZOJ4668] 冷战

热门文章

  1. PyTorch搭建CNN-LSTM混合模型实现多变量多步长时间序列预测(负荷预测)
  2. python中反斜杠是什么意思_python中反斜杠是什么意思
  3. 计算机室英语单词怎么读,“计算机”英语单词怎么读?
  4. Activiti会签
  5. 酷派把用户手机当肉鸡,非一天两天
  6. React初尝试-仿写CNode社区
  7. 纯干货:Linux抓包命令集锦
  8. 【架构师实践课】单体和微服务怎么选?单体到微服务怎么转?
  9. 戴尔服务器引导盘装2008,DELL R720服务器安装Windows Server 2008 R2系统的图文详解
  10. 企业注销的债权债务如何处理