Docker 學(xué)習(xí)筆記(三):網(wǎng)絡(luò)基礎(chǔ)配置方法

在真正的容器生產(chǎn)環(huán)境中,若要對外提供服務(wù),至少存在兩種工作方式:

  1. 通過網(wǎng)絡(luò)訪問容器內(nèi)部的應(yīng)用和服務(wù);
  2. 應(yīng)用可能包含不止一個服務(wù)組件,這往往就需要多個容器通過網(wǎng)絡(luò)互聯(lián),協(xié)同工作。

這就需要掌握容器網(wǎng)絡(luò)的配置方法。這篇筆記記錄兩個最基本的知識點:

  1. 設(shè)置端口映射訪問容器應(yīng)用
  2. 設(shè)置容器互聯(lián)實現(xiàn)容器間通信

一、設(shè)置端口映射訪問容器應(yīng)用

啟動容器后,默認(rèn)情況下,在容器外部,是無法通過網(wǎng)絡(luò)訪問容器內(nèi)部的應(yīng)用和服務(wù)的。這時,需要通過指定 “-P” 或 “-p” 選項進行端口映射。

  • -P:由 Docker 隨機選定宿主機的端口映射到容器內(nèi)部
  • -p:指定宿主機的端口映射到容器內(nèi)部
隨機選定宿主機端口進行映射

在 “docker run” 指令中使用 “-P” 選項,創(chuàng)建并運行容器后,能夠看到本地的 “32679” 端口映射到該容器中的端口為 5000 的 “python” 服務(wù)上。

andy-zhang@localhost:~$ sudo docker run -d --name web-1 -P training/webapp python app.py
288bcfc7b84c1d5b0b16cb1ba9fbc5af6071377452f54b91675637e7bb975e9e

andy-zhang@localhost:~$ sudo docker ps -a
CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS         PORTS                    NAMES
288bcfc7b84c   training/webapp   "python app.py"   10 seconds ago   Up 8 seconds   0.0.0.0:32769->5000/tcp  web-1

“0.0.0.0” 代表在外部通過本機任意可達的 IP 地址都能進行訪問,宿主機的 IP 地址為 “192.168.198.129”,通過容器外部網(wǎng)絡(luò)測試結(jié)果如下圖所示:

隨機選定宿主機端口進行映射

利用同樣的方法,我們可以創(chuàng)建多個“宿主機-容器”的端口映射關(guān)系

andy-zhang@localhost:~$ sudo docker run -d --name web-2 -P training/webapp python app.py
adc2d9957013113b67ca6381d82b1a46e3a8f4af40ecbce3b460e127faa7f0d6

andy-zhang@localhost:~$ sudo docker run -d --name web-3 -P training/webapp python app.py
cf1b495166cc6b3965dc13d93f0b8d7226308c02e9070f9891cbd175df256855

andy-zhang@localhost:~$ sudo docker ps -a
CONTAINER ID   IMAGE             COMMAND           CREATED          STATUS         PORTS                     NAMES
cf1b495166cc   training/webapp   "python app.py"   6 seconds ago    Up 6 seconds   0.0.0.0:32771->5000/tcp   web-3
adc2d9957013   training/webapp   "python app.py"   11 seconds ago   Up 10 seconds  0.0.0.0:32770->5000/tcp   web-2
288bcfc7b84c   training/webapp   "python app.py"   14 minutes ago   Up 14 minutes  0.0.0.0:32769->5000/tcp   web-1

##############借助宿主機端口映射,訪問內(nèi)部每個容器################

andy-zhang@localhost:~$ sudo docker logs -f web-1
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.198.1 - - [05/Feb/2020 04:00:37] "GET / HTTP/1.1" 200 -
192.168.198.1 - - [05/Feb/2020 04:00:37] "GET /favicon.ico HTTP/1.1" 404 -

andy-zhang@localhost:~$ sudo docker logs -f web-2
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.198.1 - - [05/Feb/2020 04:09:23] "GET / HTTP/1.1" 200 -
192.168.198.1 - - [05/Feb/2020 04:09:23] "GET /favicon.ico HTTP/1.1" 404 -

andy-zhang@localhost:~$ sudo docker logs -f web-3
 * Running on http://0.0.0.0:5000/ (Press CTRL+C to quit)
192.168.198.1 - - [05/Feb/2020 04:09:27] "GET / HTTP/1.1" 200 -
192.168.198.1 - - [05/Feb/2020 04:09:27] "GET /favicon.ico HTTP/1.1" 404 -

通過宿主機端口映射配置訪問容器服務(wù)的網(wǎng)絡(luò)架構(gòu)如下圖所示:

通過端口映射訪問不同容器

容器網(wǎng)絡(luò)層提供的 IP 地址分配機制,會為每個容器分配自己的 IP 地址 (172.17 私有網(wǎng)絡(luò)),對使用者屏蔽。

指定宿主機端口進行映射

使用 “-P” 選項,宿主機映射端口由 Docker 平臺隨機分配,訪問前需要進行查詢,而采用 “-p” 選項,則可以通過人為設(shè)定而固化訪問端口。

注意:一個端口只允許綁定一個容器。

"-p" 選項支持的格式有:

  • host-port:container-port:映射宿主機所有地址的指定端口到容器的指定端口
  • host-ip:host-port:container-port:映射宿主機指定地址的指定端口到容器的指定端口
  • host-ip(localhost)::container-port:映射宿主機 localhost 地址(127.0.0.1)的任意端口到容器的指定端口

注意:宿主機的端口也不是隨意指定的,不開放或不存在的端口號是無法使用的

按照上述不同的映射配置方式創(chuàng)建容器,示例如下:

#########host-port:container-port#############
andy-zhang@localhost:~$ sudo docker run -d --name web4 -p 5000:5000 training/webapp python app.py

#########host-ip:host-port:container-port#############
andy-zhang@localhost:~$ sudo docker run -d --name web5 -p 192.168.198.129:5001:5000 training/webapp python app.py

#########host-ip(localhost)::container-port#############
andy-zhang@localhost:~$ sudo docker run -d --name web6 -p 127.0.0.1::5000 training/webapp python app.py

#########host-ip(localhost)::container-port#############
andy-zhang@localhost:~$ sudo docker run -d --name web7 -p 127.0.0.1::5000 training/webapp python app.py

######################查看采用不同映射方式創(chuàng)建的容器###########################

andy-zhang@localhost:~$ sudo docker ps -a
CONTAINER ID   IMAGE             COMMAND          CREATED           STATUS          PORTS                            NAMES
529d6b5d1209   training/webapp   "python app.py"  3 seconds ago     Up 1 second     127.0.0.1:32772->5000/tcp        web-7
70c8ba9db20b   training/webapp   "python app.py"  15 seconds ago    Up 13 seconds   127.0.0.1:32768->5000/tcp        web-6
accc1bc01f0a   training/webapp   "python app.py"  38 seconds ago    Up 36 seconds   192.168.198.129:5001->5000/tcp   web-5
738a70955c23   training/webapp   "python app.py"  2 minutes ago     Up 2 minutes    0.0.0.0:5000->5000/tcp           web-4

上述方式中,“web-4” 和 “web-5” 映射到了外部可達的地址,即 “192.168.198.129”,因此能夠在外部進行訪問:

可以成功訪問web-4的服務(wù)
可以成功訪問web-5的服務(wù)

而 “web-6” 和 “web-7” 只映射到本地地址,即 “127.0.0.1”,因此只能在本地進行訪問:

andy-zhang@localhost:~$ curl 127.0.0.1:32768
Hello world! 
無法訪問web-6的服務(wù)

最后,可以通過 docker port CONTAINER 指令查詢?nèi)萜饔成涞亩丝谇闆r

andy-zhang@localhost:~$ sudo docker port 738a70955c23
5000/tcp -> 0.0.0.0:5000
andy-zhang@localhost:~$ sudo docker port accc1bc01f0a
5000/tcp -> 192.168.198.129:5001

二、設(shè)置容器互聯(lián)實現(xiàn)容器間通信

使用 “--link” 選項,能夠?qū)崿F(xiàn)容器間的安全通信。命令格式為:docker run --link NAME:ALIAS,代表將一個容器 “鏈接” 到另外一個容器上??梢苑Q鏈接者為 “子容器”,被鏈接者為 “父容器”。

容器鏈接

下面通過一個 Web 應(yīng)用來舉例。一個典型的 Web 應(yīng)用可以由業(yè)務(wù)容器和數(shù)據(jù)庫容器組成,業(yè)務(wù)容器提供對外的業(yè)務(wù)服務(wù)訪問,內(nèi)部則和數(shù)據(jù)庫容器進行通訊,而數(shù)據(jù)庫容器則不需要對外暴露訪問地址和端口。架構(gòu)如下:

Web應(yīng)用典型架構(gòu)
第一步,創(chuàng)建數(shù)據(jù)庫容器

簡化起見,采用 Docker Hub 的一個 PostgreSQL 數(shù)據(jù)庫的鏡像:training/postgres

#獲取PostgreSQL鏡像
andy-zhang@localhost:~$ sudo docker pull training/postgres

#創(chuàng)建并啟動PostgreSQL容器
andy-zhang@localhost:~$ sudo docker run -d --name postgre-db training/postgres

#進入PostgreSQL容器,啟動bash
andy-zhang@localhost:~$ sudo docker exec -i -t 838b8725282e bash

#查看PostgreSQL服務(wù)是否正常運行
root@838b8725282e:/# ps -ax | grep postgre
     1 ?        Ss     0:00 su postgres -c /usr/lib/postgresql/$PG_VERSION/bin/postgres -D 
     ……
     ……

#查詢PostgreSQL容器IP地址,172.17.0.9
root@838b8725282e:/# ifconfig
eth0      Link encap:Ethernet  HWaddr 02:42:ac:11:00:09  
          inet addr:172.17.0.9  Bcast:172.17.255.255  Mask:255.255.0.0
          ……
          ……
第二步,創(chuàng)建業(yè)務(wù)容器,并鏈接到該數(shù)據(jù)庫容器中

仍然采用上文的 “training/webapp” 作為業(yè)務(wù)容器鏡像模板。使用 “--link” 選項鏈接到第一步創(chuàng)建的 “postgre-db” 容器

sudo docker run -d --name web1 --link postgre-db:db -p 192.168.198.129:5001:5000 training/webapp python app.py
sudo docker run -d --name web2 --link postgre-db:db -p 192.168.198.129:5002:5000 training/webapp python app.py
sudo docker run -d --name web3 --link postgre-db:db -p 192.168.198.129:5003:5000 training/webapp python app.py

為了效果對比,創(chuàng)建一個不使用 “--link” 選項的普通業(yè)務(wù)容器

sudo docker run -d --name web-temp -P training/webapp python app.py

使用 docker exec -i -t 指令登錄到 web-1(web-2/web-3 和 web-1 一樣,不重復(fù)操作)和 web-temp 業(yè)務(wù)容器中,做如下四件事:

  • 查詢?nèi)萜?IP 地址
  • 執(zhí)行 env | grep DB 命令
  • ping 數(shù)據(jù)庫容器 IP 地址,即 172.17.0.9
  • ping 數(shù)據(jù)庫容器名,即 postgre-db

最后的結(jié)果是:

  • web-1、web-2、web-3、web-temp 和 postgre-db 均由容器平臺自動分配了內(nèi)部 IP,地址段為 172.17.0.*
  • 執(zhí)行 env | grep DB 命令后,web-1、web-2、web-3 均能查詢到 postgre-db 容器的信息,而 web-temp 則查詢不到,這正是 “--link” 選項的結(jié)果
DB_NAME=/web1/db
DB_PORT_5432_TCP_ADDR=172.17.0.9
DB_PORT=tcp://172.17.0.9:5432
DB_PORT_5432_TCP=tcp://172.17.0.9:5432
DB_PORT_5432_TCP_PORT=5432
DB_PORT_5432_TCP_PROTO=tcp
DB_ENV_PG_VERSION=9.3
  • web-1、web-2、web-3、web-temp 都能 ping 通 postgre-db 容器 IP
  • web-1、web-2、web-3 能夠 ping 通 postgre-db 容器名,web-temp 則不行

對于未創(chuàng)建關(guān)聯(lián),卻能夠通過內(nèi)部 IP 成功互聯(lián)的問題,在實際應(yīng)用場景下,問題不大。內(nèi)部 IP 屬于基礎(chǔ)設(shè)施層面的管理,而容器則處于租戶層面,基于用戶角色管控,租戶只能獲取自己容器的相關(guān)信息。當(dāng)然,如果對于管理員“作惡”,那是另外一個范疇的問題了。后續(xù)專門會針對容器安全進行學(xué)習(xí)和整理,此處不再展開了。


Look,Docker!
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時請結(jié)合常識與多方信息審慎甄別。
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容