一、 遗留的容器连接方式  --link

--link是docker 的一个遗留的特征,最终可能被删除。除非绝对需要使用,不然,建议使用 user-defined network 建立容器间的连接。不同的是,使用--link,容器间可共享变量,而使用 user-defined 网络不行,但是也通过一种更可控方式实现容器间变量共享,例如数据卷。

本文章主要默认桥接网络下 容器间采用遗留连接特征(--link)通讯细节,并且讨论容器间的安全交互问题。随着docker 网络特征(network features)的引入,仍然可以使用 创建连接方式促进容器间交互,但是它与 默认桥接网络和自定义的桥接网络又存在不同。

本文章首先讨论容器间端口连接问题,然后深入 讨论容器在 默认桥接网络下的连接问题。

1.1 使用网络端口映射方式连接

首先,运行一个简单的python flask 程序

[root@localhost docker]# docker run -P -d  training/webapp python app.py

容器创建后,由于采用 -P(大写)参数,docker自动将容器内部需要开放的端口自动映射到主机上一个随机较高的短暂端口范围内的端口。我们可使用docker ps  或 docker container ls 查看

[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
a9e336610a0a        training/webapp     "python app.py"     7 seconds ago       Up 6 seconds        0.0.0.0:32768->5000/tcp   elated_hugle

可发现,将容器的5000 tcp端口映射到主机端口32768.

也可以通过指定具体端口映射关系,例如将主机端口80映射到容器端口5000  标记  -p(小写)

[root@localhost docker]# docker run -p 80:5000 -d  training/webapp python app.py
b9401a847804210e665e540ff8bc3e9b80863731eeb96f4aa5e0b82465834095
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                  NAMES
b9401a847804        training/webapp     "python app.py"     4 seconds ago       Up 2 seconds        0.0.0.0:80->5000/tcp   affectionate_mahavira
[root@localhost docker]# 

如此方式,智能一个容器的5000端口映射到主机,但是如此存在多个容器间该端口需要通讯,则不适用。解决方式,采用主机的一个较高临时端口范围来绑定不同容器的临时端口。

[root@localhost docker]# docker run -d -p 8000-9000:5000 --name node1 --hostname test1  training/webapp python app.py
c92a9244159a569031882bc9429dbdad9b5993d99cac61128eb529103f1ff543
[root@localhost docker]# docker run -d -p 8000-9000:5000 --name node2 --hostname test2  training/webapp python app.py
a7387aae557b039e26a13b7c0bad41b2f366283f778654efa60fdcc67697b672
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
a7387aae557b        training/webapp     "python app.py"     2 seconds ago       Up 1 second         0.0.0.0:8001->5000/tcp   node2
c92a9244159a        training/webapp     "python app.py"     13 seconds ago      Up 12 seconds       0.0.0.0:8000->5000/tcp   node1
[root@localhost docker]# 

如此,每个容器的5000端口,将自动映射到主机的端口范围内。

默认情况下,使用 -p标记,是将指定端口绑定到主机所有接口(0.0.0.0)上,使用 -p另一种方式可把端口映射到本地 local host上,或者指定某个网卡上。

[root@localhost docker]# docker run -d -p 127.0.0.1:80:5000 training/webapp python app.py
37ebfc97fbf60d7cdc2b939e34fb555847395499fe00aa183a16810a118d450e
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                    NAMES
37ebfc97fbf6        training/webapp     "python app.py"     10 seconds ago      Up 8 seconds        127.0.0.1:80->5000/tcp   brave_albattani

如此方式将主机 localhost 的端口80 绑定到容器端口 5000。但是和上述说的确定一样,只能存在一个容器能够绑定,可以使用动态绑定方式

[root@localhost docker]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py
d654f947c0f7ab2bfb2a70e20e9266dc598276641cc544986b4e71c899bd8753
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                       NAMES
d654f947c0f7        training/webapp     "python app.py"     5 seconds ago       Up 3 seconds        127.0.0.1:32768->5000/tcp   trusting_noether

此时,动态端口为32768.再动态启动一个, 32769

[root@localhost docker]# docker run -d -p 127.0.0.1::5000 training/webapp python app.py
c5e7b5dfc039652d3d5545c622b38bc01637a056d8bad4fbf47e3578c3a9d612
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED              STATUS              PORTS                       NAMES
c5e7b5dfc039        training/webapp     "python app.py"     4 seconds ago        Up 3 seconds        127.0.0.1:32769->5000/tcp   sharp_easley
d654f947c0f7        training/webapp     "python app.py"     About a minute ago   Up About a minute   127.0.0.1:32768->5000/tcp   trusting_noether

默认情绪下,绑定端口一般都为tcp协议,可在 -p的参数下带 /udp /tcp /sctp等方式,指定协议类型

[root@localhost docker]# docker run -d -p 127.0.0.1:82:5000/udp training/webapp python app.py
1304cc996745431dea2460a1d9c87b4549c5f29521b8aec4d9a7e001a9d0e3eb
[root@localhost docker]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                              NAMES
1304cc996745        training/webapp     "python app.py"     2 seconds ago       Up 1 second         5000/tcp, 127.0.0.1:82->5000/udp   clever_murdock

同样,可使用 docker port 指令,查看容器具体端口的映射情况 可通过容器ID 或者容器名

[root@localhost docker]# docker port node1 5000
0.0.0.0:8000

注意:  -p 标记可重复使用,用于指定不同端口映射关系。

1.2 连接容器到链接系统

这一章节,主要介绍,默认桥接网络模式下容器连接。网络端口映射不是容器间通讯的唯一方式,docker 还拥有一个链接系统,允许容器相互连接,并共享连接信息,当一个容器被连接,则源容器的信息将可被发送给被连接的容器。因此,被连接的容器可查看源容器的被选定数据源的各方面信息,例如变量等。

1.2.1 命名的重要性

为建立链接系统,docker依赖容器的命名,容器在创建时,如果未指定命名,则自动给一个名字,使用 --name 标记,在启动容器时,可自定义指定容器名字。使用名字具有如下两个好处:

(1) 便于记忆,例如一个web程序的容器,可命名为 web

(2)    为docker 提供了一个方便的引用点,例如将容器 web 连接到 容器db

例如启动一个名为web的容器,然后调用 docker ps , 或者docker container inspect web 查看容器具体信息

[root@localhost hadoop]# docker run -d -P --name web training/webapp python app.py
93e7d4982c5436783ad2f57270aeb73feaaa57e7273e932c5524542c0aeb967f
[root@localhost hadoop]# docker ps
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
93e7d4982c54        training/webapp     "python app.py"     6 seconds ago       Up 5 seconds        0.0.0.0:32769->5000/tcp   web

注意 :容器名称必须唯一,意味着一台主机的daemon 下,只能存在一个名为web的容器,如果需要重新建立一个名为web的容器,需要先删除旧的容器,这里有个建议,在启动容器时 docker  create / run  带上标记 --rm  ,  一旦容器停止,则自动删除该容器。

1.2.2 容器间沟通  --link

链接 允许容器发现各自对方,同时构建安全的信息交互链路,当创建一个链接时,则在源容器和接收容器间创建了一条沟通渠道,接收容器可浏览源容器的部分数据信息。我们使用标记 --link ,这次我们创建一个包含数据库的容器,。

[root@localhost hadoop]# docker run -d --name db training/postgres
8ebe0029de23186cfd729b48c4e227be6392ad6d56f1cb53b96e9e789883ee7a
[root@localhost hadoop]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                     NAMES
8ebe0029de23        training/postgres   "su postgres -c '/us…"   49 seconds ago      Up 47 seconds       5432/tcp                  db
93e7d4982c54        training/webapp     "python app.py"          13 minutes ago      Up 13 minutes       0.0.0.0:32769->5000/tcp   web

我们在再把之前的容器web 删除, 然会在新建一个容器 连接db

[root@localhost hadoop]# docker container rm -f web
web
[root@localhost hadoop]# docker run -d -P --link db:db --name web training/webapp python app.py
ae71a962f945a14a1f879258e326318d374d91fe99628120d3f69d369f4ba4d5
[root@localhost hadoop]# 

使用 --link 标记的个数   --link  <name or id>:alias     冒号左边为容器的名称或者ID  右边为  源容器的别名。

然后我们可调用 docker inspect -f  格式查看web 容器的链接信息

[root@localhost hadoop]# docker inspect -f {{.HostConfig.Links}} web
[/db:/web/db]
[root@localhost hadoop]# 

可发现,web容器已经链接到 db容器,/web/db, 允许web容器访问db容器的部分信息,进入容器 web  打开 /etc/hosts 就可以看到db容器的信息,同时可直接ping db

[root@localhost hadoop]# docker exec -ti web /bin/bash
root@ae71a962f945:/opt/webapp# pwd
/opt/webapp
root@ae71a962f945:/opt/webapp# 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
192.168.0.3     db 8ebe0029de23
192.168.0.2     ae71a962f945
root@ae71a962f945:/opt/webapp# ping db
PING db (192.168.0.3) 56(84) bytes of data.
64 bytes from db (192.168.0.3): icmp_seq=1 ttl=64 time=0.130 ms
64 bytes from db (192.168.0.3): icmp_seq=2 ttl=64 time=0.038 ms

那么当我们使用 --link 建立容器间的链接时,实际进行什么操作? 我们知道,一个链接运行 源容器将自身部分信息传递给接收容器,这里接收容器是 web, 源容器是db, web可方式db的某些信息, 实际上,docker 在web容器和db容器新建一个安全通道,该通道并不需要容器对外开放任何端口。而且也不用在启动容器时,采用参数 -p  或者 -P指定容器开发端口,这就是 link的最大好处之一,不需要向容器公开通道,这里就是 PostgreSQL数据库不需要向 web公开端口。

docker传递源容器的信息给接收容器,一般采用如下两种方式:

(1)    环境变量

(2) 更新/etc/hosts  文件  。  前面通过查看该文件可观察到  添加了db容器的IP地址和容器ID

1.3 环境变量

在创建容器间的链接时,docker会创建根据 --link 的参数,创建一些环境变量,同时docker可能暴露源 容器的环境变量,那些可能被暴露源容器的环境变量来自于如下:

(1)源容器的Dockerfile 中使用ENV 指定的环境变量

(2)源容器在启动时,-e  或  --env 或者  --env-file  指定的环境变量

那些带有源容器信息的环境变量,被允许在接收容器程序化发现(特定规则,下文讲到)。因此,注意,环境变量中避免存储一些敏感信息,避免被那些连接容器发现。

docker在创建链接时,根据--link参数 为接收端容器生成一个 <alias>_NAME 的环境变量,这里指web容器,我们可进入容器内部查询。

[root@localhost hadoop]# docker exec -ti web /bin/bash
root@0af1176d2df9:/opt/webapp# echo $BACKDB_NAME
/web/backdb
root@0af1176d2df9:/opt/webapp# 

我们使用 --link   db:backdb 将web容器链接到db容器,则在web容器新建一个环境变量 BACKDB_NAME=/web/backdb

同样 docker 还为源容器的公开的端口新建了一些列的环境变量。以如下的规则;

<name>_PORT_<port>_<protocol>

每个段部分的命名与介绍:

<name>   即为  --link 指定的别名,  例如     这里的backdb

<port>   开放的端口

<protocol>  TCP  或者UDP

docker 使用这些前缀定义,定义了三个不同的环境变量:

固定前缀 ADDR 返回源容器地址信息  例如   BACKDB_PORT_5432_TCP_ADDR =192.168.0.2

固定前缀PORT返回源容器的开放端口信息 例如: BACKDB_PORT_5432_TCP_PORT = 5432

固定前缀PROTO 返回源容器开放端口通讯协议: 例如: BACKDB_PORT_5432_TCP_PROTO=tcp

当有多个开放端口时,针对每个端口定义该三个变量,如果有4个开放端口,则存在12个如此规则的环境变量。

[root@localhost hadoop]# docker exec -ti web /bin/bash
root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_ADDR
192.168.0.2
root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_PORT
5432
root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT_5432_TCP_PROTO
tcp
root@0af1176d2df9:/opt/webapp# 

另外,docker 还创建一个环境变量 <alias>_PORT 返回第一个开放端口的具体信息 (包含了ip、port 、protocol)

root@0af1176d2df9:/opt/webapp# echo $BACKDB_PORT
tcp://192.168.0.2:5432
root@0af1176d2df9:/opt/webapp# 

最后,针对源容器的环境变量,在接收容器,将每个变量采用<alias>_ENV_<name>方式保存,并在接收容器启动时创建该些变量,例如前面,如果我们启动db容器时 带入参数 -e DBNAME="testName".   则我们在接收容器web内可查看该变量,注意alias别名前缀使用大写。

root@0af1176d2df9:/opt/webapp# echo $BACKDB_ENV_DBNAME
testName

注意:与/etc/hosts文件中的主机条目不同,如果源容器重新启动,存储在环境变量中的IP地址不会自动更新。因此,一般使用/etc/hosts 解析源容器的IP地址信息。

那些变量,仅为容器第一个进程设置,当一些守护经常构建时,例如sshd, 那些变量将被清除。

1.4 更新 /etc/hosts文件

容器间创建链接后,docker自动更新接收容器的/etc/hosts文件,添加源容器的ip地址等相关信息到条目中,源容器的/etc/hosts未保存接收容器的信息。

root@0af1176d2df9:/opt/webapp# 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
192.168.0.2     backdb 92aca4dce8fc db
192.168.0.3     0af1176d2df9
root@0af1176d2df9:/opt/webapp# exit
[root@localhost hadoop]#
[root@localhost hadoop]# docker exec -ti db /bin/bash
root@92aca4dce8fc:/# 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
192.168.0.2     92aca4dce8fc
root@92aca4dce8fc:/# 

如web容器内保存 db容器的 名称,ID和别名,web容器分别利用名称  ID和别名 均可访问到db容器

root@0af1176d2df9:/opt/webapp# 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
192.168.0.2     backdb 92aca4dce8fc db
192.168.0.3     0af1176d2df9
root@0af1176d2df9:/opt/webapp# ping db
PING backdb (192.168.0.2) 56(84) bytes of data.
64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.145 ms
64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.038 ms
64 bytes from backdb (192.168.0.2): icmp_seq=3 ttl=64 time=0.044 ms
^C
--- backdb ping statistics ---
3 packets transmitted, 3 received, 0% packet loss, time 2000ms
rtt min/avg/max/mdev = 0.038/0.075/0.145/0.050 ms
root@0af1176d2df9:/opt/webapp# ping backdb
PING backdb (192.168.0.2) 56(84) bytes of data.
64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.112 ms
64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.037 ms
^C
--- backdb ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.037/0.074/0.112/0.038 ms
root@0af1176d2df9:/opt/webapp# ping 92aca4dce8fc
PING backdb (192.168.0.2) 56(84) bytes of data.
64 bytes from backdb (192.168.0.2): icmp_seq=1 ttl=64 time=0.053 ms
64 bytes from backdb (192.168.0.2): icmp_seq=2 ttl=64 time=0.045 ms
^C
--- backdb ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.045/0.049/0.053/0.004 ms
root@0af1176d2df9:/opt/webapp# ping 192.168.0.2
PING 192.168.0.2 (192.168.0.2) 56(84) bytes of data.
64 bytes from 192.168.0.2: icmp_seq=1 ttl=64 time=0.098 ms
64 bytes from 192.168.0.2: icmp_seq=2 ttl=64 time=0.041 ms
^C
--- 192.168.0.2 ping statistics ---
2 packets transmitted, 2 received, 0% packet loss, time 999ms
rtt min/avg/max/mdev = 0.041/0.069/0.098/0.029 ms
root@0af1176d2df9:/opt/webapp# 

一个容器可允许被多个容器同时连接,但是注意不能启动相同容器名

docker容器网络配置之容器间的链接(默认桥接网络下的links)相关推荐

  1. Docker之 默认桥接网络与自定义桥接网卡

    docker引擎会默认创建一个docker0网桥,它在内核层连通了其他的物理或虚拟网卡,这就将所有容器和宿主机都放到同一个二层网络. 1. docker如何使用网桥 1.1 Linux虚拟网桥的特点 ...

  2. linux如何启动网络配置文件,linux系统的网络配置教程 Ubuntu系统网络设置方法网络配置linux及Ubuntu通过修改配置文件进行网络配置...

    Windows系统网络配置方法 一.设置网络 1)Windows打开cmdcmd 输入ipconfig  /all 可以看到 修改为静态IP Ubuntu修改网络为静态IP 设置虚拟机: 查看IPif ...

  3. docker容器的网络配置,允许docker可以被宿主机以外的其它主机访问以及局域网内可以直接访问docker容器ip

    自从Docker容器出现以来,容器的网络通信就一直是被关注的焦点,也是生产环境的迫切需求.容器的网络通信又可以分为两大方面:单主机容器上的相互通信,和跨主机的容器相互通信. 一.端口映射(局域网,外网 ...

  4. 自己动手写Docker系列 -- 5.5实现容器停止

    简介 在上篇中我们实现了通过exec命令,重新进入了后台运行中的容器,本篇将实现stop命令,将运行中的容器停止 源码说明 同时放到了Gitee和Github上,都可进行获取 Gitee: https ...

  5. 云容器云引擎:容器化微服务,Istio占C位出道

    在精彩的软件容器世界中,当新项目涌现并解决你认为早已解决的问题时,这感觉就像地面在你的脚下不断地移动.在许多情况下,这些问题很久以前被解决,但现在的云原生架构正在推动着更大规模的应用程序部署,这就需要 ...

  6. 容器云技术:容器化微服务,Istio占C位出道

    在精彩的软件容器世界中,当新项目涌现并解决你认为早已解决的问题时,这感觉就像地面在你的脚下不断地移动.在许多情况下,这些问题很久以前被解决,但现在的云原生架构正在推动着更大规模的应用程序部署,这就需要 ...

  7. Docker 之 桥接网络 (二)

    参考:https://docs.docker.com/network/network-tutorial-standalone/ 一.与独立容器联网 本系列教程讨论独立Docker容器的连网.要使用群集 ...

  8. 【CentOS Linux 7】【Linux网络配置基础】

    Linux系统及应用---调研报告 [CentOS Linux 7]实验1[VMware安装.新建虚拟机:63个基础命令运行结果图] [CentOS Linux 7]实验2[Shell编程及应用] [ ...

  9. virtualbox 创建桥接网络_VirtualBox桥接网络的简单配置,让虚拟机直接访问网络

    VirtualBox桥接网络的简单配置,让虚拟机直接访问网络 分类: Linux 2009-08-20 08:59 5071人阅读 评论(0) 收藏 举报 (1)最新的 VirtualBox 可以简单 ...

最新文章

  1. weblogic学习笔记(1)
  2. 奥数国家队最强6人集结,深圳中学独占2席,人大附中连续三年入围
  3. 深入了解gradle和maven的区别
  4. 关系数据库——mysql常用函数总结
  5. 基于类的软件复用技术
  6. 服务器常规维修与判断方法,服务器常规维修与判断方法88119.doc
  7. Linux守护进程的启动方法
  8. STM32移植FATFS+USB+FLASH+PDFLIB库总结
  9. SCC(三):HEVC IBC
  10. 计算机网络期中考试总结反思,关于期中反思的说说
  11. C语言编程 犯二的程度,犯二的程度 - osc_jhl7rojx的个人空间 - OSCHINA - 中文开源技术交流社区...
  12. 【JAVA】List常用移除、过滤、去重、flatMap、peek等操作
  13. 98年阿里P6架构师晒出工资单,看完扎心了。。。
  14. 天池竞赛——服务器故障预测
  15. 台式电脑打不开计算机c盘,电脑打不开显示C盘损坏怎么办
  16. Walkthrough: Word 2007 XML 格式
  17. 航空Ethernet嵌入式测试平台ETest
  18. 0x00a1bdb3 指令引用的 0x00000001 内存。该内存不能为 read。
  19. 某系统采用基于优先权的非抢占式进程调度策略,完成一次进程调度和进程切换的系统时间开销为 1μs。
  20. 做题记(4)P1080 国王游戏

热门文章

  1. first season twenty-third episode,Ben was born!!!,Hi Ben???
  2. 苹果手机越狱软件_俄罗斯要求 iPhone 预装本国软件,苹果称等同于越狱无法接受...
  3. Linux系统chmod命令读、写、执行
  4. 大数据与云计算技术周报(第148期)
  5. Linux:dd命令详解(df du命令参数)
  6. python/appium实现华为应用商城app界面上下滑动打开关闭通知栏等功能
  7. 寒假每日一题题解(1.29)摘花生(DP水题)
  8. r7 6700g核显相当于什么显卡 锐龙r76700g性能怎么样
  9. Android如何查看手机网卡信息和ip信息
  10. MICCAI-iseg2017挑战赛小结与婴儿脑组织分割总结