https://yq.aliyun.com/articles/55912

摘要: 什么是docker的link机制 同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来通信,也可以通过宿主机的ip加上容器暴露出的端口号来通信,前者会导致ip地址的硬编码,不方便迁移,并且容器重启后ip地址会改变,除非使用固定的ip,后者的通信方式比较单一,只能依靠监听在暴露出的端口的进程来进行有限的通信。通过docker的link机制可以通过一个name来和另一

什么是docker的link机制

同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地址来通信,也可以通过宿主机的ip加上容器暴露出的端口号来通信,前者会导致ip地址的硬编码,不方便迁移,并且容器重启后ip地址会改变,除非使用固定的ip,后者的通信方式比较单一,只能依靠监听在暴露出的端口的进程来进行有限的通信。通过docker的link机制可以通过一个name来和另一个容器通信,link机制方便了容器去发现其它的容器并且可以安全的传递一些连接信息给其它的容器。其使用方式如下:

1.运行一个容器,通过–name指定一个便于记忆的名字,这个容器被称为source container,也就是要连接的容器

docker run --name db -e MYSQL_ROOT_PASSWORD=server -d mysql

上面通过传递环境变量MYSQL_ROOT_PASSWORD=server,来设置mysql服务的密码为server

2.运行另外一个容器,并link到上面启动的容器,这个容器被称为received container

sudo docker run -d --name web --link db:aliasdb nginx

上面通过--link连接名为db的容器,并为其设置了别名aliasdb
完成了上面的两个步骤后,在nginx的容器中就可以使用db或者aliasdb作为连接地址来连接mysql服务,即使容器重启了,地址发生了变化,不会影响两个容器之间的连接。

link机制的连接信息传递

虽然通过使用link机制nginx可以和mysql进行通信了,但是如何知道mysql的端口是多少呢,虽然说是固定的是
3306,但是也不排除更改端口号的问题,并且对应一些非固定端口的应用来说,只要要连接的容器的端口信息也是尤为重要的,link机制通过环境变量的方式提供了这些信息,除此之外像db的密码这些信息也会通过环境变量提供,docker将source container中定义的环境变量全部导入到received container中,在received container中可以通过环境变量来获取连接信息下面是db中提供的环境变量:

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/local/mysql/bin:/usr/local/mysql/scripts
HOSTNAME=c1a7c7f091eb
MYSQL_ROOT_PASSWORD=server
MYSQL_MAJOR=5.5
MYSQL_VERSION=5.5.48
HOME=/root

注: 使用docker exec db env命令来获得上面的结果
下面我们来看看在web这个容器中,这些变量是如何被导入的。

PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=6337c0044215
ALIASDB_PORT=tcp://172.17.0.8:3306
ALIASDB_PORT_3306_TCP=tcp://172.17.0.8:3306
ALIASDB_PORT_3306_TCP_ADDR=172.17.0.8
ALIASDB_PORT_3306_TCP_PORT=3306
ALIASDB_PORT_3306_TCP_PROTO=tcp
ALIASDB_NAME=/web/aliasdb
ALIASDB_ENV_MYSQL_ROOT_PASSWORD=server
ALIASDB_ENV_MYSQL_MAJOR=5.5
ALIASDB_ENV_MYSQL_VERSION=5.5.48
NGINX_VERSION=1.9.10-1~jessie
HOME=/root

上面的变量被分成了五个部分:

  • 第一个部分是web容器自身提供的一些环境变量,如NGINX_VERSION,HOSTNAME,HOME,PATH等.

  • 第二个部分则是ALIASDB_ENV开头的变量,这些都是从source container中导入的,变量来源于Dockerfile中使用ENV命令定义的变量,或者是docker run的时候通过-e 添加的环境变量。
  • 第三个部分是ALIASDB_NAME 这个变量,这变量记录了link的两个容器的组合,这里就是/web/db
  • 第四个部分就是ALIASDB_PORT开头的一系列变量,这些变量会有很组,每组变量的命名格式如下
<alias>_PORT_<port>_<protocol>
<alias>_PORT_<port>_<protocol>_PORT
<alias>_PORT_<port>_<protocol>_PROTO
<alias>_PORT_<port>_<protocol>_ADDR

其中<port>是在Dockerfile中使用EXPOSE导出的端口,还有docker run 的时候使用-p导出的端口。<protocol>则是这些端口对应的协议。

  • 第五个部分就是ALIASDB_PORT这个变量,这个变量是EXPOSE导出端口中的第一个端口对应的连接url,
    如果有EXPOSE导出的端口,还有docker run -p指定导出的端口,那么通过-p指定的端口是第一个被导出的端口

link机制和/etc/hosts

使用了link机制后,可以通过指定的名字来和目标容器通信,这其实是通过给/etc/hosts中加入名称和IP的解析关系来实现的,下面是名为web的容器中的/etc/hosts信息.

172.17.0.10 6337c0044215
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.17.0.8 aliasdb c1a7c7f091eb db

通过上面的信息可以看出,link机制给received container(这里是名为web的容器)添加了一条关于db容器的名称解析。有了这个名称解析后就可以不使用ip来和目标容器通信了,除此之外当目标容器重启,docker会负责更新/etc/hosts文件,因此可以不用担心容器重启后IP地址发生了改变,解析无法生效的问题。但是很不幸的是,环境变量无法更新,上文中提到了link机制会通过环境变量将一些db容器的信息导入到web容器中,这种导入是一次性的,此后这个容器更新了环境变量的信息是无法在web容器中更新的。

link机制和网络新特性

通过上文中对link机制的介绍,可以发现link机制提供了如下几个功能

  • 名称解析

  • 对link的容器可以使用别名
  • 安全的容器间连接通信
  • 环境变量的注入

安全的容器间连接通信,这个需要结合docker daemon的-icc=false 这个选项,默认同一个宿主机上的所有容器可以互相通信,当使用-icc=false 的时候所有容器之间是无法进行互相通信的(具体原因会单独出篇文章分析),但是使用link机制后,即使使用了-icc=false 两个容器之间也可以进行基于端口的通信。很不幸的是当docker引入网络新特性后,link机制变的有些多余,但是为了兼容早期版本,–link机制在默认网络上的功能依旧没有发生变化,docker引入网络新特性后,内置了一个DNS Server,但是只有用户创建了自定义网络后,这个DNS Server才会起作用。在网络新特性为未引入之前,有三种网络,第一种就是docker0这种桥接网络,用的也是最多的,第二个则是复用主机网络,称为HOST网络,第三种就是none网络,只创建了一个空的网络命名空间,没有网络接口,无法和外界通信,可以让使用者自己去构建网络。当网络新特性引入后,有了overlay网络,有了用户自定义网络。用户自定义网络下,用户可以通过docker的network子命令创建一个自定义的桥接网络,这个自定义桥接的网络和默认的docker0桥接网络基本功能都是一致的,只是在这个自定义桥接网络中拥有一些特性,可以替代link机制。这些特性包括如下几个方面:

  • 基于DNS的名称自动解析

  • 安全的隔离环境
  • 动态的附加或者脱离一个网络
  • 支持使用–link设置别名

在用户自定义网络下,不使用link机制就可以实现名称解析功能了,不再是通过link机制追加名称解析关系到/etc/hosts文件中了。并且在默认的docker0桥接网络和自定义网络下使用link机制的效果是不一样的,在自定义网络中link机制只是负责设置别名的,不再提供环境变量注入的功能了。自定义网络中同时也提供了--net-alias功能和link机制提供别名功能是一样的。保留link机制目的是为了兼容。

参考文献

Legacy container links
Linking containers in user-defined networks

深入理解docker的link机制的更多相关文章

  1. Docker使用Link与newwork在容器之间建立连接

    一,使用 --link容器互联 docker 默认使允许container 互通的(通过-icc=false 关闭互通)同一个宿主机上的多个docker容器之间如果想进行通信,可以通过使用容器的ip地 ...

  2. 【Docker官方文档】理解Docker

    本文来自Docker的官方文档,详细介绍了Docker的体系结构.重要概念.内部工作机理等内容,推荐不了解Docker内部原理的同学阅读. 什么是Docker? Docker是一个用于开发.交付和运行 ...

  3. [Docker 官方文档] 理解 Docker

    http://segmentfault.com/a/1190000002609286 什么是 Docker? Docker 是一个用于开发.交付和执行应用的开放平台,Docker 设计用来更快的交付你 ...

  4. 【转】理解Docker容器网络之Linux Network Namespace

    原文:理解Docker容器网络之Linux Network Namespace 由于2016年年中调换工作的原因,对容器网络的研究中断过一段时间.随着当前项目对Kubernetes应用的深入,我感觉之 ...

  5. 【Docker】Docker概述、理解docker的集装箱、标准化、隔离的思想、 docker出现解决了什么问题

    整理一下 慕课网 第一个docker化的java应用 Docker环境下的前后端分离项目部署与运维 课程时所做的笔记 Docker概述 docker - https://www.docker.com/ ...

  6. 【转】深入理解 Java 垃圾回收机制

    深入理解 Java 垃圾回收机制   一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  7. 深入理解java垃圾回收机制

    深入理解java垃圾回收机制---- 一.垃圾回收机制的意义 Java语言中一个显著的特点就是引入了垃圾回收机制,使c++程序员最头疼的内存管理的问题迎刃而解,它使得Java程序员在编写程序的时候不再 ...

  8. 我理解的Hanlder--android消息传递机制

    每一个学习Android的同学都会觉得Handler是一个神奇的东西,我也一样,开始我以为我懂了Handler的机制,后来发现自己是一知半解,昨天想想,我能否自己实现一个Handler,让子线程与Ac ...

  9. 理解Docker单机容器网络

    在” 理解Docker单机容器网络 “一文中,还有一个Docker容器网络的功能尚未提及,那就是Docker容器的端口映射.即将容器的服务端口P’ 绑定到宿主机的端口P上,最终达到一种效果:外部程序通 ...

随机推荐

  1. GIF/PNG/JPG和WEBP/base64/apng图片优点和缺点整理

    GIF/PNG/JPG/WEBP/APNG都是属于位图(位图 ,务必区别于矢量图): GIF/PNG和JPG这三种格式的图片被广泛应用在现今的互联网中,gif曾在过去互联网初期慢速的情况下几乎是做到了 ...

  2. SSD固态硬盘的闪存芯片颗粒介绍

    固态硬盘凭借其存取速率超快等自身优势,被越来越多的电脑爱好者所青睐,并迅速普及到了广大用户的电脑中,因为固态硬盘与传统机械硬盘相比,确实在运行效率等方面有了质的提升,这里先了解一些评判固态硬盘优劣的知 ...

  3. C#-WinForm-客户端程序-Form基本属性

    WinForm - 客服端程序(C/S) WindowsForm 的简称 客户端应用程序:是需要安装在用户电脑上才可以使用的程序,代码部分在用户电脑上执行 特点:不需要联网也可以打开使用部分功能,但现 ...

  4. shell替换一个或多个空格为逗号

    (1)把文本中的一个或者多个空格替换为逗号 文本内容如下: # cat text 1 2 4 2 2 3 4 3 3 4 4 4 4 2 4 (2)shell程序代码为: # cat text | s ...

  5. ajax请求web服务返回json格式

    由于.net frameword3.5以上添加了对contenttype的检查,当ajax发送请求时,如果设置了contenttype为json,那么请求webservice时,会自动将返回的内容转为 ...

  6. Leetcode 300 Longest Increasing Subsequence

    Given an unsorted array of integers, find the length of longest increasing subsequence. For example, ...

  7. 【BZOJ-2502】清理雪道 有上下界的网络流(有下界的最小流)

    2502: 清理雪道 Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 594  Solved: 318[Submit][Status][Discuss] ...

  8. Linux Nginx(master-slave)、Apache(woker、prefork) Working Mode Research

    catalog . Apache工作模式 . Nginx工作模式 1. Apache工作模式 Apache服务器支持三种工作模式(Apache称之为MPM,简写为Multi-Processing Mo ...

  9. web开发 虚拟目录映射

    A 当服务器和 web应用不在一个目录下 $CATALINA_BASE/conf/catalina/localhost/ 文件夹下创建一个xml文件,任意文件名都可以,但是此文件名是web应用发布后的 ...

  10. soapUI测试webservice(参数为xml格式的处理方式)

    如果传递的是xml,要用<![CDATA[   ]]>将xml注释为字符串 示例 <?xml version="1.0" encoding="UTF-8 ...