2019独角兽企业重金招聘Python工程师标准>>>

对于复杂的应用,不可避免需要多个服务部署在多个容器中,并且服务间存在相互间通信的情况。比如服务A需要连接mysql的容器。本文将介绍docker的容器网络,并通过实践解决在同一个docker Host主机下的容器间通信的问题。

在安装好docker后,docker将创建一个linux网桥docker0,它在内核层连通了其他的物理或虚拟网卡,也就是所有容器和本地主机都放到同一个物理网络。我们可以通过 brctl 命令查看网桥的信息,brctl是需要自行安装的。

[root@localhost ~]# brctl show
bridge name bridge id       STP enabled interfaces
br-1a83283cbf04     8000.0242123432ad   no
br-70590112bbda     8000.0242927ea6d9   no
docker0     8000.024232ccc082   no  

另外,docker还会给我们创建三个网络:bridge/host/none。我们可以通过network ls命令查看当前宿主机中所有的docker网络。

[root@localhost ~]# docker network lsNETWORK ID          NAME                DRIVER              SCOPE
5a9ac72df73f        bridge              bridge              local
7d9eb4bd321c        host                host                local
4b740dab2aab        none                null                local

其中,网桥bridge模式是在实际项目中常用的。接下来,以交互模式启动两个busybox容器。在没有指定相关网络的情况下,容器都会连接到默认的bridge网络。我们可以通过 --network 参数指定容器连接的网络。

[root@localhost ~]# docker run -itd --name=busybox1 busybox
2813aba53acd688fa69807158830bef27b4ea8dc2ecfe13e7e357ce98a204f0b[root@localhost ~]# docker run -itd --name=busybox2 busybox
83fbeeb4e0527ece0602729415a57383b474284143a381e0a27561a69d75b1f5

启动容器后,检查当前默认bridge网络情况。busybox1和busybox2容器已经连接到了bridge网络,除此之外,还可以获取到两个容器的IP地址。

[root@localhost ~]# docker network inspect bridge[{"Name": "bridge","Id": "5a9ac72df73f19beaade92a28d705509fd24c350497dd90ecae224fdb18214bc","Created": "2018-12-25T16:30:26.58008782+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": null,"Config": [{"Subnet": "172.17.0.0/16","Gateway": "172.17.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"2813aba53acd688fa69807158830bef27b4ea8dc2ecfe13e7e357ce98a204f0b": {"Name": "busybox1","EndpointID": "522f2b4b072098525939cc6b313f5673f82444d8ef6807bac0efcdce6a7c8418","MacAddress": "02:42:ac:11:00:02","IPv4Address": "172.17.0.2/16","IPv6Address": ""},"83fbeeb4e0527ece0602729415a57383b474284143a381e0a27561a69d75b1f5": {"Name": "busybox2","EndpointID": "e277940484662a341730766300149c2f63974d0b9e9cbd6c531bc7c8c37f31f9","MacAddress": "02:42:ac:11:00:03","IPv4Address": "172.17.0.3/16","IPv6Address": ""}},"Options": {"com.docker.network.bridge.default_bridge": "true","com.docker.network.bridge.enable_icc": "true","com.docker.network.bridge.enable_ip_masquerade": "true","com.docker.network.bridge.host_binding_ipv4": "0.0.0.0","com.docker.network.bridge.name": "docker0","com.docker.network.driver.mtu": "1500"},"Labels": {}}
]

接下来,我们测试下两个容器的互通情况。

进入busybox1容器,分别ping 容器busybox2的IP和容器名,可以发现可以通过IP地址ping通busybox2,但是不能通过容器ping通。其中,172.17.0.3是busybox2的IP地址。

[root@localhost ~]# docker attach  2813aba53acd/ # ping  172.17.0.3
PING 172.17.0.3 (172.17.0.3): 56 data bytes
64 bytes from 172.17.0.3: seq=0 ttl=64 time=0.090 ms
64 bytes from 172.17.0.3: seq=1 ttl=64 time=0.193 ms/ # ping busybox2

在容器中,可以查看容器的hosts文件,里面没有任何关于busybox2容器的信息。

/ # cat /etc/hosts127.0.0.1    localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.2  2813aba53acd

在计算机网络中,想通过域名ping通其它网站,有两种方法:一种是本地的hosts文件,里面配置的是路由规则;另一种是DNS服务,通过DNS服务器返回正确的IP地址。那么docker是否也可以通过容器名访问其它容器的方式呢?

(1)link连接

默认的桥接网络支持使用端口映射和 docker run --link 命令,实现容器间互相通信。该方法已经在官方文档中标识为不推荐使用

https://docs.docker.com/network/links/

下面,继续介绍通过 --link 参数时间容器间通信。我们将创建busybox3和busybox4两个容器,其中busybox4可以通过busybox3容器名与busybox3容器进行通信。

新建busybox3和busybox4,其中busybox4通过 --link 参数指定连接到 busybox3容器。

[root@localhost ~]# docker run -itd --name=busybox3 busybox
a539a74a9ecad6782f88944604bbdd045f4a1fd6965a3484e04d1dbbec1e511d[root@localhost ~]# docker run -itd --link busybox3  --name=busybox4 busybox
f6c470354b55300106a3a8960c4c935dcdd0cb0f7ad6c941c8f040fdb0cd0a04

重新进入容器busybox4,查看hosts文件,可以看到host文件中已经出现busybox3容器,并配置了路由规则。

/ # cat /etc/hosts127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.17.0.4  busybox3 a539a74a9eca
172.17.0.5  f6c470354b55

测试busybox4连接容器busybox3

/ # ping busybox3
PING busybox3 (172.17.0.4): 56 data bytes
64 bytes from 172.17.0.4: seq=0 ttl=64 time=0.077 ms
64 bytes from 172.17.0.4: seq=1 ttl=64 time=0.125 ms
^C
--- busybox3 ping statistics ---
2 packets transmitted, 2 packets received, 0% packet loss

(2)自定义bridge网络,实现容器间通信

从 Docker 1.10 版本开始,docker daemon 实现了一个内嵌的 DNS server,使容器可以直接通过“容器名”通信。使用默认的bridge网络,不能通过DNS server实现通过容器名通信,但是使用自定义bridge网络可以做到通过容器名互相通信。

通过 docker network create 命令创建一个自定义的bridge网络

[root@localhost ~]# docker network create --driver bridge busybox_bridge
1a83283cbf047fea14231daef7edb67e8a11383f61c176e5c4983e961e757a1e[root@localhost ~]# docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
53c7e86fc3ec        bridge              bridge              local
1a83283cbf04        busybox_bridge      bridge              local
7d9eb4bd321c        host                host                local
4b740dab2aab        none                null                local

分别创建busybox5/busybox6容器,在run命令里加入--network参数使两个容器绑定到前面自定义的网络中。

[root@localhost ~]# docker run -itd --network busybox_bridge --name busybox5 busybox
ccd81a357cf48af2c01c64cd1ef7a4c463b415bd477d965f19a3b47be3760208[root@localhost ~]# docker run -itd --network busybox_bridge --name busybox6 busybox
d3e5af0eeb86a480fe868bb9ea7cea2cb29b7f12b7f680cbd5b48288c15b10e9

查看busybox_bridge网络情况,可以看到,busybox5/busybox6容器已经绑定到该网络中。

[root@localhost ~]# docker network inspect busybox_bridge[{"Name": "busybox_bridge","Id": "1a83283cbf047fea14231daef7edb67e8a11383f61c176e5c4983e961e757a1e","Created": "2018-12-25T22:17:10.981291803+08:00","Scope": "local","Driver": "bridge","EnableIPv6": false,"IPAM": {"Driver": "default","Options": {},"Config": [{"Subnet": "172.18.0.0/16","Gateway": "172.18.0.1"}]},"Internal": false,"Attachable": false,"Ingress": false,"ConfigFrom": {"Network": ""},"ConfigOnly": false,"Containers": {"ccd81a357cf48af2c01c64cd1ef7a4c463b415bd477d965f19a3b47be3760208": {"Name": "busybox5","EndpointID": "4da57d779c14bdee415eee69a92dd802250bf6e89cd744f8543c4498e32aebdc","MacAddress": "02:42:ac:12:00:02","IPv4Address": "172.18.0.2/16","IPv6Address": ""},"d3e5af0eeb86a480fe868bb9ea7cea2cb29b7f12b7f680cbd5b48288c15b10e9": {"Name": "busybox6","EndpointID": "6f130cc2055399c051cd556e20835793332605f9ee636885c602f2b257f9db80","MacAddress": "02:42:ac:12:00:03","IPv4Address": "172.18.0.3/16","IPv6Address": ""}},"Options": {},"Labels": {}}
]

接下来进入busybox5容器,测试是否可以通过容器名ping通busybox6

[root@localhost ~]# docker attach busybox5/ # ping busybox6
PING busybox6 (172.18.0.3): 56 data bytes
64 bytes from 172.18.0.3: seq=0 ttl=64 time=0.107 ms
64 bytes from 172.18.0.3: seq=1 ttl=64 time=0.149 ms

看下容器的hosts文件,文件里是没有busybox6的映射配置的。那么它是怎么通过容器名访问到另一个容器的呢?答案就是内嵌的dns服务器。

/ # cat /etc/hosts
127.0.0.1   localhost
::1 localhost ip6-localhost ip6-loopback
fe00::0 ip6-localnet
ff00::0 ip6-mcastprefix
ff02::1 ip6-allnodes
ff02::2 ip6-allrouters
172.18.0.2  ccd81a357cf4

查看DNS服务,可以看到指定了DNS解析服务地址:nameserver 127.0.0.11 。如果是连接到默认bridge网络的容器,在resolv.conf文件是没有127.0.0.11这个DNS服务器配置的

/ # cat /etc/resolv.conf
nameserver 127.0.0.11
options ndots:0

容器中的DNS名称解析优先级顺序为:

  • ​ 内置DNS服务器127.0.0.11。
  • ​ 通过--dns等参数为容器配置的DNS服务器。
  • ​ docker守护进程的--dns服务配置(默认为8.8.8.8和8.8.4.4)
  • ​ 宿主机上的DNS设置。

文章收录于:

容器技术系列汇总

转载于:https://my.oschina.net/thinwonton/blog/2993309

docker容器网络 - 同一个host下的容器间通信相关推荐

  1. 『中级篇』容器网络之host和none(29)

    原创文章,欢迎转载.转载请注明:转载自IT人故事会,谢谢! 原文链接地址:『中级篇』容器网络之host和none(29) 前几节主要说的bridge network,在实际中bridge确实运用比较广 ...

  2. Docker 配置网络 - 使用 host 网络

    原文地址 如果你为容器使用 host 网络驱动程序,则该容器的网络堆栈不与 Docker 主机隔离.例如,如果运行绑定到端口 80 的容器并使用 host 网络,则可以直接通过宿主机 IP 地址的端口 ...

  3. Docker 配置网络教程 - host 网络

    https://blog.csdn.net/kikajack/article/details/79460255 这部分教程中,独立容器直接连接到 Docker 主机的网络,没有网络隔离. 1. 目标 ...

  4. Docker源码分析(八):Docker Container网络(下)

    http://www.infoq.com/cn/articles/docker-source-code-analysis-part8 1.Docker Client配置容器网络模式 Docker目前支 ...

  5. Mac系统下docker容器无法使用--net host共享宿主机端口的解决方案

    文章目录 背景 解决过程一 分析 Mac系统下docker容器无法使用--net host共享宿主机端口的原因 docker的网络配置 host模式 overlay模式 macvlan模式 bridg ...

  6. Docker原生网络、自定义网络、Docker容器通信、跨主机容器网络

    Docker原生网络.自定义网络.Docker容器通信.跨主机容器网络 Docker原生网络 bridge Host none Docker自定义网络 自定义bridge overlay macvia ...

  7. Docker容器-------网络模式,数据卷和数据卷容器

    目录 Docker网络实现原理 Docker的网络模式 Host模式 Container模式 none模式 bridge模式 自定义网络 查看网络模式列表 查看容器信息(包含配置.环境.网关.挂载.c ...

  8. Docker网络体系结构:设计可扩展、可移植的Docker容器网络

    原文地址 译者:本人翻译水平有限,目的仅是为了学好Docker,如有错误请见谅. 翻译版本:v1.01(将不断优化翻译质量) 本文包含以下内容 Docker容器就是将应用及其所依赖运行环境的完整文件系 ...

  9. 【无标题】自己动手写Docker系列 -- 6.3 手动配置容器网络(上)

    简介 网络部分较为复杂,本篇先利用之前写好的基础容器和网桥部分,加上手工给容器配置网络,让其容器与宿主机网络部分功能正常,为后面程序编写打下基础 源码说明 同时放到了Gitee和Github上,都可进 ...

最新文章

  1. AWR baseline template的管理
  2. Edit Distance编辑距离(NM tag)- sam/bam格式解读进阶
  3. 蚂蚁金服张洁:基于深度学习的支付宝人脸识别技术解秘-1
  4. 2018 Multi-University Training Contest 9 杭电多校第九场 (有坑待补)
  5. 两年Java工作经验应该会些什么技术
  6. anaconda 安装在c盘_Tensorflow 2.1安装
  7. libevent evbuffer缓冲源码分析
  8. 【DP + 卖股票】LeetCode 188. Best Time to Buy and Sell Stock IV
  9. 聚类分析在SPSS上的实现及分析
  10. 目的地址和ARP地址应答中的源地址
  11. Ubuntu20.04 解决双显卡黑屏、花屏、HDMI失效、亮度调节失效
  12. 2_PY基本数据类型
  13. 扎实的PHP编程基础,PHP的一些基础编程题
  14. MATLAB中同一路径下同文件的末尾继续写入数据
  15. 3. MySQL笔记
  16. 求知若饥,虚心若愚——Stay Hungry, Stay Foolish
  17. C++常用数据结构总结
  18. nginx(三十二)rewrite模块
  19. 数据挖掘基础:度量数据的相似性和相异性
  20. python pptx table_Python-pptx Table

热门文章

  1. vijos 1476 旅游规划题解
  2. java 16 -12 静态导入
  3. IIS7 配置PHP服务器
  4. jQuery UI 之 LigerUI 快速入门
  5. Android定位方式和测试方法
  6. VS2010 发布web项目 问题
  7. 4月《程序员》上我讲HTML5的文章---激动人心的HTML5之美
  8. 【C++】重载运算符(一)
  9. 【C++】【六】约瑟夫问题
  10. CDMA模块上网设置的过程