在使用[?Docker 部分](https://github.com/widuu/chinese_docker/blob/master/userguide/usingdocker.md), 我們談到了如何通過網絡端口來訪問運行在 Docker 容器內的服務。這是與docker容器內運行應用程序交互的一種方法。在本節中,我們打算通過端口連接到一個docker容器,并向您介紹容器連接概念。
## 網絡端口映射
在[使用docker](https://github.com/widuu/chinese_docker/blob/master/userguide/usingdocker.md)部分,我們創建了一個python應用的容器。
~~~
$ sudo docker run -d -P training/webapp python app.py
~~~
> 注:容器有一個內部網絡和IP地址(在使用Docker部分我們使用`docker inspect`命令顯示容器的IP地址)。Docker可以有各種網絡配置方式。你可以再這里學到更多docker網絡信息。
我們使用`-P`標記創建一個容器,將容器的內部端口隨機映射到主機的高端口49000到49900。這時我們可以使用`docker ps`來看到端口5000綁定主機端口49155。
~~~
$ sudo docker ps nostalgic_morse
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
bc533791f3f5 training/webapp:latest python app.py 5 seconds ago Up 2 seconds 0.0.0.0:49155->5000/tcp nostalgic_morse
~~~
我們也可以使用`-p`標識來指定容器端口綁定到主機端口
~~~
$ sudo docker run -d -p 5000:5000 training/webapp python app.py
~~~
我們看這為什么不是一個好的主意呢?因為它限制了我們容器的一個端口。
我們還有很多設置`-p`標識的方法。默認`-p`標識會綁定本地主機上的指定端口。并且我們可以指定綁定的網絡地址。舉例設置`localhost`
~~~
$ sudo docker run -d -p 127.0.0.1:5001:5002 training/webapp python app.py
~~~
這將綁定容器內部5002端口到主機的`localhost`或者`127.0.0.1`的5001端口。
如果要綁定容器端口5002到宿主機動態端口,并且讓`localhost`訪問,我們可以這樣做:
~~~
$ sudo docker run -d -p 127.0.0.1::5002 training/webapp python app.py
~~~
我們也可以綁定UDP端口,我們可以在后面添加`/udp`,舉例:
~~~
$ sudo docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py
~~~
我們可以使用`docker port`快捷方式來綁定我們的端口,這有助于向我們展示特定的端口。例如我們綁定`localhost`,如下是`docker port`輸出:
~~~
$ docker port nostalgic_morse 5000
127.0.0.1:49155
~~~
> 注:`-p`可以使用多次配置多個端口。
## Docker容器連接
端口映射并不是唯一把docker連接到另一個容器的方法。docker有一個連接系統允許將多個容器連接在一起,共享連接信息。docker連接會創建一個父子關系,其中父容器可以看到子容器的信息。
### 容器命名
執行此連接需要依靠你的docker的名字,這里我們可以看到當我們創建每一個容器的時候,它都會自動被命名。事實上我們已經熟悉了老的`nostalgic_morse`指南。你也可以自己命名容器。這種命名提供了兩個有用的功能:
* 1.給容器特定的名字使你更容易記住他們,例如:命名web應用程序為web容器。
* 2.它為docker提供一個參考,允許其他容器引用,舉例連接web容器到db容器。
你可以使用`--name`標識來命名容器,舉例:
~~~
$ sudo docker run -d -P --name web training/webapp python app.py
~~~
我們可以看到我們啟動了的容器,就是我們使用`--name`標識命名為`web`的容器。我們可以使用`docker ps`命令來查看容器名稱。
~~~
$ sudo docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
aed84ee21bde training/webapp:latest python app.py 12 hours ago Up 2 seconds 0.0.0.0:49154->5000/tcp web
~~~
我們也可以使用`docker inspect`來返回容器名字。
~~~
$ sudo docker inspect -f "{{ .Name }}" aed84ee21bde
/web
~~~
> 注:容器的名稱必須是唯一的。這意味著你只能調用一個web容器。如果你想使用重復的名稱來命名容器,你需要使用`docker rm`命令刪除以前的容器。在容器停止后刪除。
## 容器連接
連接允許容器之間可見并且安全地進行通信。使用`--link`創建連接。我們創建一個新容器,這個容器是數據庫。
~~~
$ sudo docker run -d --name db training/postgres
~~~
這里我們使用`training/postgres`容器創建一個新的容器。容器是PostgreSQL數據庫。
現在我們創建一個`web`容器來連接`db`容器。
~~~
$ sudo docker run -d -P --name web --link db:db training/webapp python app.py
~~~
這將使我們的web容器和db容器連接起來。`--link`的形式
~~~
--link name:alias
~~~
`name`是我們連接容器的名字,`alias`是link的別名。讓我們看如何使用alias。
讓我們使用`docker ps`來查看容器連接.
~~~
$ docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
349169744e49 training/postgres:latest su postgres -c '/usr About a minute ago Up About a minute 5432/tcp db
aed84ee21bde training/webapp:latest python app.py 16 hours ago Up 2 minutes 0.0.0.0:49154->5000/tcp db/web,web
~~~
我們可以看到我們命名的容器,`db`和`web`,我們還在名字列中可以看到web容器也顯示`db/web`。這告訴我們web容器和db容器是父/子關系。
我們連接容器做什么?我們發現連接的兩個容器是父子關系。這里的父容器是`db`可以訪問子容器`web`。為此docker在容器之間打開一個安全連接隧道不需要暴露任何端口在容器外部。你會注意到當你啟動db容器的時候我們沒有使用`-P`或者`-p`標識。我們連接容器的時候我們不需要通過網絡給PostgreSQL數據庫開放端口。
Docker在父容器中開放子容器連接信息有兩種方法:
* 環境變量
* 更新`/etc/hosts`文件。
讓我們先看看docker的環境變量。我們運行`env`命令來查看列表容器的環境變量。
~~~
$ sudo docker run --rm --name web2 --link db:db training/webapp env
. . .
DB_NAME=/web2/db
DB_PORT=tcp://172.17.0.5:5432
DB_PORT_5000_TCP=tcp://172.17.0.5:5432
DB_PORT_5000_TCP_PROTO=tcp
DB_PORT_5000_TCP_PORT=5432
DB_PORT_5000_TCP_ADDR=172.17.0.5
. . .
~~~
> 注:這些環境變量只設置頂一個進程的容器。同樣,一些守護進程(例如sshd)進行shell連接時就會去除。
我們可以看到docker為我們的數據庫容器創建了一系列環境變量。每個前綴變量是`DB_`填充我們指定的別名。如果我們的別名是`db1`,前綴別名就是`DB1_`。您可以使用這些環境變量來配置您的應用程序連接到你的數據庫db容器。該連接時安全、私有的,只能在web容器和db容器之間通信。
docker除了環境變量,可以添加信息到父主機的`/etc/hosts`
~~~
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7 aed84ee21bde
. . .
172.17.0.5 db
~~~
這里我們可以看到兩個主機項。第一項是web容器用容器ID作為主機名字。第二項是使用別名引用IP地址連接數據庫容器。現在我們試試ping這個主機:
~~~
root@aed84ee21bde:/opt/webapp# apt-get install -yqq inetutils-ping
root@aed84ee21bde:/opt/webapp# ping db
PING db (172.17.0.5): 48 data bytes
56 bytes from 172.17.0.5: icmp_seq=0 ttl=64 time=0.267 ms
56 bytes from 172.17.0.5: icmp_seq=1 ttl=64 time=0.250 ms
56 bytes from 172.17.0.5: icmp_seq=2 ttl=64 time=0.256 ms
~~~
> 注:我們不得不安裝`ping`,因為容器內沒有它。
我們使用`ping`命令來ping`db`容器,使用它解析到`127.17.0.5`主機。我們可以利用這個主機項配置應用程序來使用我們的`db`容器。
> 注:你可以使用一個父容器連接多個子容器。例如,我們可以有多個web容器連接到我們的db數據庫容器。
- 關于Docker
- 鏡像簡介
- 安裝篇
- Mac OS X
- Ubuntu
- Red Hat Enterprise Linux
- CentOS
- Debain
- Gentoo
- Google Cloud Platform
- Rackspace Cloud
- Amazon EC2
- IBM Softlayer
- Arch Linux
- FrugalWare
- Fedora
- openSUSE
- CRUX Linux
- Microsoft Windows
- Binaries
- 用戶指南
- 使用Docker Hub
- 在Docker中運行應用
- 使用容器
- 使用docker鏡像
- 連接容器
- 管理容器數據
- 使用Docker Hub
- Docker Hub
- 賬戶
- 存儲庫
- 自動構建
- 官方案例
- Docker中運行MongoDB
- Docker中運行Redis服務
- Docker中運行PostgreSQL
- Docker中運行Riak服務
- Docker中運行SSH進程服務
- Docker中運行CouchDB服務
- Docker中運行Apt-Cacher-ng服務