Docker container中services/applications与主机或者其它containers之间通讯的两种方式python
port mapping(端口映射)git
container linking(容器链接)web
使用端口映射来链接docker
经常使用的命令(以training/webapp
为例):shell
docker run -d -P traning/webapp ... docker run -d -p traning/webapp ...
-P
flag当container被建立而且运行时,-P标记马上生效数据库
它container内部的任意端口映射到docker host的port编程
Docker host的port是随机的ubuntu
它的生命力是短暂的(容器中止后端口映射就会失效)后端
e.g.安全
adolph@geek:~$ docker run -d -P training/webapp python app.py 3f30e81a01cdf9895a70828beebea32910f848ac00f92303e6af77faeee1db0a adolph@geek:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 3f30e81a01cd training/webapp:latest "python app.py" 8 seconds ago Up 8 seconds 0.0.0.0:32769->5000/tcp agitated_hawking
内部的5000端口映射到外部的主机的32769
端口
-p
flag能够指定container内外的端口
内外的5000端口映射
docker run -d -p 5000:5000 training/webapp python app.py adolph@geek:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES cf6bd021034d training/webapp:latest "python app.py" 4 seconds ago Up 2 seconds 0.0.0.0:5000->5000/tcp compassionate_lalande
这样作的很差的地方在于你只把congtainer内外的5000端口映射在一块儿,container内的其它端口被抛弃了
映射到主机的××端口
docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py
映射到主机的某个随机端口
docker run -d -p 127.0.0.1::5000 training/webapp python app.py
注意127.0.0.1:
有个冒号
-p参数使用的次数不少,主要用来配置多个端口
Docker有自带的
linking system
用来链接多个container,而且容许从一个container发送信息到另外一个。发送信息的称为source container
,接收信息的称为recipient container
,recipient container智能看到一些通过筛选的关于source container的某些信息
Docker依赖于容器的名字来创建链接,Docker启动容器时会自动给它起个名字,固然你也能够本身命名
命名有两个很是棒的好处:
告知container的做用或者属于哪一种类型,如traning/webapp
能够看出是webapp的container
方便Docker经过name指定container
在运行container时经过--name
标记来命名新的container
adolph@geek:~$ docker run -d -P --name web training/webapp python app.py 1be7fc1ca8f9b683a8c309a1f6315c65819db15e8105ddd1b198e50c4082842f adolph@geek:~$ docker ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES 1be7fc1ca8f9 training/webapp:latest "python app.py" 4 seconds ago Up 3 seconds 0.0.0.0:32770->5000/tcp web adolph@geek:~$ docker inspect -f "{{.Name}}" 1be7f /web
<span style="color:red;">注意:</span>container的name必须是惟一的,好比说刚才的web
,若是你想给另外一个容器起名为web
,那只能把原来的web
container删除(docker rm [-f])。另外,docker run --rm --name..
会在容器中止运行后当即删除
经过链接通讯
links容许容器发现对方而且创建安全的信息传输通道,link建立好后容器间通讯的通道就创建好了。
注意事项:
须要运行的两个容器不能重名
不能和其它已经存在的(无论有没有运行)容器重名
docker ps -a
查看全部容器的信息
docker rm [container name]
删除容器
link代码
--link <name or id>:alias
name or id
指咱们要链接的container的名字
shell1的代码(我在一个shell中运行这些命令总会有1个容器在启动后就EXIT(0)
)
adolph@geek:~$ docker run -i -t --name db adolph/ubuntu:14.04 root@a1bb409128b9:/#
shell2
adolph@geek:~$ docker run -d -P --name web --link db:db training/webapp python app.py 09fed08b63e709e61d17f698ccec55a6d04ddb6e33c1aea3879f78d1970451ce adolph@geek:~$ docker inspect -f "{{.HostConfig.Links}}" web [/db:/web/db]
we can see that the
web
container is now linked to thedb
containerweb/db
. Which allows it to access information about the db container.
recipient container | source container |
---|---|
web | db |
为了作到容器间的通讯,Docker没有使用端口,而是本身创建了tunnel
(隧道),使用link
链接容器的好处是咱们不须要将source container
的端口暴露给网络,Docker的tunnel使用两种方式实现链接:
Environment variables(环境变量)
Updating the /etc/hosts file(更新/etc/hosts
文件)
当咱们链接容器是Docker会建立不少环境变量,而且它会在目标容器自动基于
--link
后面的参数建立环境变量。Docker会公开来自source container
的全部环境变量,这些变量包括:
the ENV commands in the source container's Dockerfile(源容器Dockerfile中的ENV
命令)
the -e
, --env
and --env-file
options on the docker run command when the source container is started(容器运行时run
后面的-e
, --env
和 --env-file
参数)
这些环境变量容许咱们经过编程从目标容器发现来自源容器的信息
警告:理解docker link链接容器的机制很重要,link容许全部目标容器得到源容器的指定数据和信息,因此从安全性的角度,不建议在源容器中存储敏感的数据
<alias>_NAME
docker run -d -P --name web --link db:db training/webapp python app.py
这个变量是为目标容器创建的,如上,--link db:db
后web
容器被连接到db
容器,这是Docker会在web
容器中建立DB_NAME=/web/db
<name>_PORT_<port>_<protocol>
Docker为每个源容器暴露的每个端口。
<name>指--link中指定的目标容器的别名
<port>源容器暴露的端口号
<protocol> TCP或UDP
Docker使用不一样的前缀格式来规定3种不一样的环境变量:
prefix_ADDR
来自URL的ip地址。例如:WEBDB_PORT_8080_TCP_ADDR=172.17.0.82.
prefix_PORT
来自URL的端口。例如:WEBDB_PORT_8080_TCP_PORT=8080.
prefix_PROTO
来自URL的协议。例如:WEBDB_PORT_8080_TCP_PROTO=tcp.
每一组环境变量对应一个端口,若是容器公开多个端口(好比3个),Docker就会建立9个环境变量,每一个端口3个。
此外,Docker还会为源容器
第一个公开的端口建立<alias>_PORT
,这里的第一个
指的是具备lowest port
的端口。例如:WEBDB_PORT=tcp://172.17.0.82:8080
,若是它吗知足tcp和udp,那指的是tcp
最后,Docker还会建立这样一个变量:<alias>_ENV_<name>
,用来链接源容器和目标容器的桥梁。Docker使用这个值来启动源容器。
e.g:
adolph@geek:~$ sudo docker run --rm --name web2 --link db:db training/webapp env [sudo] password for adolph: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin HOSTNAME=20fb0166d9c6 DB_NAME=/web2/db HOME=/
个人电脑上并无看到环境变量!可能由于个人db容器和官网例子上的容器不一直吧,并且个人db容器中并无安装数据库。
Docker建立的这些变量有助于咱们用来链接和配置源容器里的工具,好比链接数据库...
更新
/etc/hosts
文件
这部分本身有不懂的地方,之后慢慢看吧。
-p
,-P
标记容器的命名是惟一的,不能重复。能够更改容器的名字
docker rename oldname newname
--link <name or id>:alias,name指要链接的容器,alais指目标容器/简称
可以清除代码中那个是目标容器,哪一个是源容器,资源开放共享的方向
docker run -d -P --name web --link db:webdb training/webapp python app.py
这条命令中db
是要链接的容器,是源容器,web是目标容器,webdb是web的别称
adolph@geek:~$ docker inspect -f "{{.HostConfig.Links}}" web [/db:/web/webdb]
都是我的理解,可能有错误,还请指正。