Docker使用Link在容器之间建立连接
link方式:
通过link方式创建容器,然后我们可以使用被link容器的别名进行访问。
从而解除应用对IP的依赖。
不幸的是,link方式只能解决单机容器间的互联。多机情况下,容器的互联需要其他的方式。 
[root@dockerhost3 ~]# docker run -i -t mysql:latest /bin/bash
root@7942320d8886:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
242: eth0@if243: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:04 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.4/16 scope global eth0
       valid_lft forever preferred_lft forever[root@dockerhost3 ~]# docker ps
CONTAINER ID        IMAGE                 COMMAND                  CREATED              STATUS              PORTS                      NAMES
7942320d8886        mysql:latest          "docker-entrypoint..."   About a minute ago   Up About a minute   3306/tcp                   dreamy_hawking[root@dockerhost3 ~]# docker run -i -t --link=dreamy_hawking:myql mysql:latest /bin/bash
root@e4774fe79482:/# ip addr
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
244: eth0@if245: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default 
    link/ether 02:42:ac:11:00:05 brd ff:ff:ff:ff:ff:ff
    inet 172.17.0.5/16 scope global eth0
       valid_lft forever preferred_lft forever
需要特别注意一下“-link=dreamy_hawking:myql”,这个参数就是告诉Docker容器需要使用“dreamy_hawking”容器,并将其别名命名为db,这样在这两个容器里就可以使用“mysql”来作为提供mysql数据库服务的机器名。
root@e4774fe79482:/# 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.17.0.4      myql 7942320d8886 dreamy_hawking
172.17.0.5      e4774fe79482通过容器方式互联
如上面所说,link只适用于一台主机。
=========================================================================
=========================================================================
========================================================================= 
我们在使用Docker的时候,经常可能需要连接到其他的容器,比如:web服务需要连接数据库。按照往常的做法,需要先启动数据库的容器,映射出端口来,然后配置好客户端的容器,再去访问。其实针对这种场景,Docker提供了--link 参数来满足。
这里使用数据库服务器和客户端的例子来介绍下--link的用法。一、 创建容器
这里需要创建MySQL服务端和客户端的容器MySQL 服务端的Dockerfile:
FROM centos:centos6
MAINTAINER David "xx@xx.com"
RUN yum install -y mysql-server mysql
RUN /etc/init.d/mysqld start
RUN mysql -e "grant all privileges on *.* to 'root'@'%' identified by '1234';"
RUN mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by '1234';"
EXPOSE 3306
CMD ["/usr/bin/mysqld"]MySQL客户端的Dockerfile:
FROM centos:centos6
MAINTAINER David "xx@xx.com"
RUN yum install -y mysql根据Dockerfile来创建images
David@MacBook-Pro-3 ~$ docker build -t hzc/mysql_server  /path/mysql_server/Dockerfile
David@MacBook-Pro-3 ~$ docker build -t hzc/mysql_client  /path/mysql_client/Dockerfileimage构建执行结束之后,执行docker image|greo hzc,可以看到:
David@MacBook-Pro-3 ~$ docker image|grep hzc
hzc/mysql_client     latest       62cfe52e02bf    2 days ago     289 MB
hzc/mysql_server     latest       83c64aba0805    2 days ago     377.9 MB二、 启动容器
启动MySQL服务端的容器
David@MacBook-Pro-3 ~$ docker run -d -P --name=mysql_server hzc/mysql_server
David@MacBook-Pro-3 ~$ b5e097fe510d8f258dd82c48a2f6aa4c279e227c4472e42d3e9956ac419ae73c启动MySQL客户端容器
David@MacBook-Pro-3 ~$ docker run --name=mysql_client1:db -i -t hzc/mysql_client mysql -h db -uroot -p1234    #直接进入了mysql数据库

Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 1
Server version: 5.1.73 Source distribution
 
Copyright (c) 2000, 2013, Oracle and/or its affiliates. All rights reserved.
 
Oracle is a registered trademark of Oracle Corporation and/or its
affiliates. Other names may be trademarks of their respective
owners.
 
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
 
mysql>查看进程
David@MacBook-Pro-3 ~$ docker ps
CONTAINER ID    IMAGE        COMMAND         CREATED       STATUS       PORTS           NAMES
213285ec2663    hzc/mysql_client  "mysql -h db -uroot -"  2 minutes ago    Up 2 minutes                 mysql_client1
b5e097fe510d    hzc/mysql_server  "/usr/bin/mysqld_safe"  4 minutes ago    Up 4 minutes    0.0.0.0:32768->3306/tcp  mysql_server可以看到多了一个参数配置--link=mysql_server:db , 是告诉当前容器需要使用mysql_server容器,并命名为db。这里db就是mysql_server容器的别名。在后面连接数据库的时候是可以直接使用mysql -h db -uroot  -p1234来连接mysql数据库。
三、 原理
在这里可以看到创建了两个容器,mysql_client1和mysql_server。容器mysql_client1连接到了mysql_server,建立了一种父子关系。查看父容器mysql_client1的环境变量
David@MacBook-Pro-3 ~$ docker exec -it 213285ec2663 bash
[root@213285ec2663 /]# env
HOSTNAME=213285ec2663
DB_NAME=/mysql_client1/db
TERM=xterm
DB_PORT=tcp://172.17.0.2:3306
DB_PORT_3306_TCP_PORT=3306
....
DB_PORT_3306_TCP_PROTO=tcp
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
PWD=/
DB_PORT_3306_TCP_ADDR=172.17.0.2
SHLVL=1
HOME=/root
DB_PORT_3306_TCP=tcp://172.17.0.2:3306
no_proxy=*.local, 169.254/16
DB_ENV_no_proxy=*.local, 169.254/16
LESSOPEN=||/usr/bin/lesspipe.sh %s
G_BROKEN_FILENAMES=1
_=/usr/bin/env可以看到已经得到了容器mysql_server的环境变量,给出的是3306的端口,而不是映射出来的端口。
查看hosts
[root@213285ec2663 /]# cat /etc/hosts
127.0.0.1  localhost
....
172.17.0.2  db b5e097fe510d mysql_server
172.17.0.3  213285ec2663可以看到两条hosts的配置,一个是数据库的ip对应的别名,容器ID,容器名称。另外一个是客户端对应的容器ID。所以这里可以使用别名连接到数据库服务端。
=========================================================================
=========================================================================
=========================================================================在使用Docker的时候我们会常常碰到这么一种应用,就是我需要两个或多个容器,其中某些容器需要使用另外一些容器提供的服务。比如这么一种情况:我们需要一个容器来提供mysql的数据库服务,而另外两个容器作为客户端来连接使用mysql数据库服务。下面我们就来看看Docker是怎样通过Link来实现这种功能的。
1. 创建两个容器image,一个用来模拟mysql数据库,另外一个使用mysql的client来模拟一些使用mysql服务的应用,这种应用可以是任何php,python,java等的应用。
1.1 先创建一个mysql_server目录并在其下创建一个Dockerfile文件,内容如下
FROM centos:centos6  
MAINTAINER Fanbin Kong "kongxx@hotmail.com"  

RUN yum install -y mysql-server mysql  

RUN /etc/init.d/mysqld start &&\  
    mysql -e "grant all privileges on *.* to 'root'@'%' identified by 'letmein';"&&\  
    mysql -e "grant all privileges on *.* to 'root'@'localhost' identified by 'letmein';"&&\  
    mysql -u root -pletmein -e "show databases;"  
EXPOSE 3306  
CMD ["/usr/bin/mysqld_safe"]然后根据Dockerfile来创建image
sudo docker build -t kongxx/mysql_server . 1.2 创建一个mysql_client目录并在其下创建一个Dockerfile文件,内容如下
FROM centos:centos6  
MAINTAINER Fanbin Kong "kongxx@hotmail.com"  
RUN yum install -y mysql 
然后根据Dockerfile来创建image
sudo docker build -t kongxx/mysql_client .  
1.3 创建完image之后,我们可以使用下面命令来查看结果
$ sudo docker images | grep kongxx  
kongxx/mysql_client   latest                aa31f22f6fc5        2 hours ago         303.7 MB  
kongxx/mysql_server   latest                3b9b08c8dda4        2 hours ago         353.3 MB 2. 第二步是根据image来创建我们的应用场景
2.1 首先创建提供mysql数据库服务的容器
sudo docker run --name=mysql_server -d -P kongxx/mysql_server  2.2 分别创建两个使用上一步创建出来mysql数据库服务的容器
第一个应用容器
sudo docker run --name=mysql_client1 --link=mysql_server:db -t -i kongxx/mysql_client /usr/bin/mysql -h db -u root -pletmein 第二个应用容器
sudo docker run --name=mysql_client2 --link=mysql_server:db -t -i kongxx/mysql_client /usr/bin/mysql -h db -u root -pletmein 这里需要特别注意一下“-link=mysql_server:db”,这个参数就是告诉Docker容器需要使用“mysql_server”容器,并将其别名命名为db,这样在这两个容器里就可以使用“db”来作为提供mysql数据库服务的机器名。所以在最后启动参数里我们使用的是“/usr/bin/mysql -h db -u root -pletmein”来连接mysql数据库的。
 
2.3 运行完上面两个命令,我们就会在创建了两个mysql的client的容器,此时我们可以使用下面命令来查看状态
sudo docker ps  
CONTAINER ID        IMAGE                        COMMAND                CREATED             STATUS              PORTS                     NAMES  
ac0c76c627c0        kongxx/mysql_client:latest   /usr/bin/mysql -h db   10 seconds ago      Up 9 seconds                                  mysql_client2  
763c4825722d        kongxx/mysql_client:latest   /usr/bin/mysql -h db   41 minutes ago      Up 40 minutes                                 mysql_client  
32f7839f7e9d        kongxx/mysql_server:latest   /usr/bin/mysqld_safe   About an hour ago   Up About an hour    0.0.0.0:49153->3306/tcp   mysql_client1/db,mysql_client2/db,mysql_server  这里注意一下最后一行,也就是mysql_server容器的“NAMES”列的内容“mysql_client1/db,mysql_client2/db,mysql_server”,这就说明mysql_client1和mysql_client2都和db建立的连接。