在使用Docker部分,我們談到了通過網(wǎng)絡(luò)端口來連接運行服務(wù)的docker。這是與docker容器內(nèi)運行應(yīng)用程序交互的一種方法。在本節(jié)中,我們打算通過端口連接到一個docker容器,并向您介紹容器連接概念。
在使用docker部分,我們創(chuàng)建了一個python應(yīng)用的容器。
$ sudo docker run -d -P training/webapp python app.py
注:容器有一個內(nèi)部網(wǎng)絡(luò)和IP地址(在使用Docker部分我們使用
docker inspect命令顯示容器的IP地址)。Docker可以有各種網(wǎng)絡(luò)配置方式。你可以再這里學(xué)到更多docker網(wǎng)絡(luò)信息。
我們使用-P標記創(chuàng)建一個容器,將容器的內(nèi)部端口隨機映射到主機的高端口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
我們看這為什么不是一個好的主意呢?因為它限制了我們?nèi)萜鞯囊粋€端口。
我們還有很多設(shè)置-p標識的方法。默認-p標識會綁定本地主機上的指定端口。并且我們可以指定綁定的網(wǎng)絡(luò)地址。舉例設(shè)置localhost
$ sudo docker run -d -p 127.0.0.1:5001:5002 training/webapp python app.py
這將綁定容器內(nèi)部5002端口到主機的localhost或者127.0.0.1的5001端口。
如果要綁定容器端口5002到宿主機動態(tài)端口,并且讓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有一個連接系統(tǒng)允許將多個容器連接在一起,共享連接信息。docker連接會創(chuàng)建一個父子關(guān)系,其中父容器可以看到子容器的信息。
執(zhí)行此連接需要依靠你的docker的名字,這里我們可以看到當我們創(chuàng)建每一個容器的時候,它都會自動被命名。事實上我們已經(jīng)熟悉了老的nostalgic_morse指南。你也可以自己命名容器。這種命名提供了兩個有用的功能:
你可以使用--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
注:容器的名稱必須是唯一的。這意味著你只能調(diào)用一個web容器。如果你想使用重復(fù)的名稱來命名容器,你需要使用
docker rm命令刪除以前的容器。在容器停止后刪除。
連接允許容器之間可見并且安全地進行通信。使用--link創(chuàng)建連接。我們創(chuàng)建一個新容器,這個容器是數(shù)據(jù)庫。
$ sudo docker run -d --name db training/postgres
這里我們使用training/postgres容器創(chuàng)建一個新的容器。容器是PostgreSQL數(shù)據(jù)庫。
現(xiàn)在我們創(chuàng)建一個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容器是父/子關(guān)系。
我們連接容器做什么?我們發(fā)現(xiàn)連接的兩個容器是父子關(guān)系。這里的父容器是db可以訪問子容器web。為此docker在容器之間打開一個安全連接隧道不需要暴露任何端口在容器外部。你會注意到當你啟動db容器的時候我們沒有使用-P或者-p標識。我們連接容器的時候我們不需要通過網(wǎng)絡(luò)給PostgreSQL數(shù)據(jù)庫開放端口。
Docker在父容器中開放子容器連接信息有兩種方法:
/etc/hosts文件。讓我們先看看docker的環(huán)境變量。我們運行env命令來查看列表容器的環(huán)境變量。
$ 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
. . .
注:這些環(huán)境變量只設(shè)置頂一個進程的容器。同樣,一些守護進程(例如sshd)進行shell連接時就會去除。
我們可以看到docker為我們的數(shù)據(jù)庫容器創(chuàng)建了一系列環(huán)境變量。每個前綴變量是DB_填充我們指定的別名。如果我們的別名是db1,前綴別名就是DB1_。您可以使用這些環(huán)境變量來配置您的應(yīng)用程序連接到你的數(shù)據(jù)庫db容器。該連接時安全、私有的,只能在web容器和db容器之間通信。
docker除了環(huán)境變量,可以添加信息到父主機的/etc/hosts
root@aed84ee21bde:/opt/webapp# cat /etc/hosts
172.17.0.7 aed84ee21bde
. . .
172.17.0.5 db
這里我們可以看到兩個主機項。第一項是web容器用容器ID作為主機名字。第二項是使用別名引用IP地址連接數(shù)據(jù)庫容器。現(xiàn)在我們試試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,因為容器內(nèi)沒有它。
我們使用ping命令來pingdb容器,使用它解析到127.17.0.5主機。我們可以利用這個主機項配置應(yīng)用程序來使用我們的db容器。
注:你可以使用一個父容器連接多個子容器。例如,我們可以有多個web容器連接到我們的db數(shù)據(jù)庫容器。