Docker6-端口映射與容器互聯

有時候我們會碰到需要多個服務組件容器共同協作的情況, 這往往需要多個容器之間有能夠相互訪問到對方的服務.

除了通過網絡訪問外, Docker 還提供了兩個很方便的功能來滿足服務訪問的基本需求: 一個是允許映射容器內應用的服務端口到本地宿主主機; 另一個是互聯機制實現多個容器間通過容器名來快速訪問.

端口映射實現訪問容器

1.從外部訪問容器應用
在啟動容器的時候, 如果不指定對應的參數, 在容器外部是無法通過網絡來訪問容器內的網絡應用和服務的.

當容器中運行一些網絡應用, 要讓外部訪問這些應用時, 可以通過 -P-p 參數來指定端口映射. 當使用 -P (大寫的) 標記時, Docker 會將容器所有暴露的端口隨機映射到宿主主機的 49000~49900 之間的一個端口:

docker run -d -P training/webapp python app.py

此時, 可以使用 docker ps 看到, 本地主機的

docker ps -l
//輸出信息
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS              PORTS                     NAMES
6f3bce18f77c        training/webapp     "python app.py"     14 seconds ago      Up 14 seconds       0.0.0.0:32768->5000/tcp   blissful_goldberg

-p(小寫的) 可以指定要映射的端口, 并且, 在一個指定端口上只可以綁定一個容器. 支持的格式有 IP:HostPort:ContainerPort | IP::ContainerPort | HostPort:ContainerPort

2.映射所有接口地址
使用 HostPort:ContainerPort 格式將本地的 5000 端口映射到容器的 5000端口, 可以執行:

docker run -d -p 5000:5000 training/webapp python app.py

多次使用 -p 標記可以綁定多個端口:

docker run -d -p 5000:5000 -p 3000:80 training/webapp python app.py

3.映射到指定地址的指定端口
可以使用 IP:HostPort:ContainerPort 格式指定映射使用一個特定地址, 比如 localhost 地址 127.0.0.1:

docker run -d -p 127.0.0.1:5000:5000 training/webapp python app.py

4.映射到指定地址的任意端口
使用 IP::ContainerPort 綁定 localhost 的任意端口到容器的 5000 端口, 本地主機會自動分配一個端口:

docker run -d -p 127.0.0.1::5000 training/webapp python app.py

還可以使用 udp 標記來指定 udp 端口:

docker run -d -p 127.0.0.1:5000:5000/udp training/webapp python app.py

5.查看映射端口配置
使用 docker port 命令來查看當前映射的端口配置, 也可以查看綁定的地址:

docker port 6f3bce18f77c
//輸出信息
5000/tcp -> 0.0.0.0:32768

也可以查看容器中的服務端口, 被映射到了宿主主機的哪個端口:

docker port 6f3bce18f77c 5000
//輸出信息
0.0.0.0:32768

容器有自己的內部網絡和 IP 地址, 使用 docker inspect +容器 ID 可以獲取容器的具體信息.


互聯機制實現便捷互訪

容器的互聯是一種讓多個容器中應用進行快速交互的方式. 它會在源和接收容器之間創建連接關系, 接收容器可以通過容器名快速訪問到源容器, 而不用指定具體的 ip 地址.

使用 --link 參數可以讓容器之間安全進行交互.
首先創建一個新的容器:

docker run -d --name db training/postgres

然后創建一個新的 web 容器, 并將它連接到 db 容器:

docker run -d -P --name web --link db:aliasDb training/webapp python app.py

此時, db 容器和 web 容器建立互聯關系.

注意:建立互聯關系的時候, 名字為 db 的容器必須在運行.

--link 參數的格式 --link name:alias, 其中 name 是要連接的容器名稱, alias 是這個連接的別名.

使用 docker ps 來查看容器的連接, 如下所示:

docker ps --no-trunc
//輸出信息
CONTAINER ID                                                       IMAGE               COMMAND                                                                                                                                                                    CREATED             STATUS              PORTS                     NAMES
10f712c0adf2887d964fe1eb12fd8b602a78f948817c4d54b7fa3b4f7fef821e   training/webapp     "python app.py"                                                                                                                                                            47 seconds ago      Up 46 seconds       0.0.0.0:32772->5000/tcp   web
2c3a75c29c989a66c9c8179a39112328b13eced089af9525edc68a198367ba18   training/postgres   "su postgres -c '/usr/lib/postgresql/$PG_VERSION/bin/postgres -D /var/lib/postgresql/$PG_VERSION/main/ -c config_file=/etc/postgresql/$PG_VERSION/main/postgresql.conf'"   54 seconds ago      Up 53 seconds       5432/tcp                  db,web/aliasDb

可以看到自定義命名的容器, db 和 web, db 容器的 names 列有 db 也有 web/aliasDb. 這表示 web 容器連接到 db 容器, 這允許 web 容器訪問 db 容器的信息.

Docker 相當于在兩個互聯的容器之間創建了一個虛擬通道, 而且不用映射它們的端口到宿主主機上. 在啟動 db 容器的時候并沒有私用 -p-P 標記, 從而避免了暴露數據庫服務端口到外部網絡上.

Docker 通過兩種方式為容器公開連接信息:
1.更新環境變量.
2.更新 /etc/hosts 文件.
使用 env 命令來查看 web 容器的環境變量:

docker run --rm --name web5 --link db:aliasDb training/webapp env
//輸出信息
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
HOSTNAME=cf7de1d9281c
ALIASDB_PORT=tcp://172.17.0.2:5432
ALIASDB_PORT_5432_TCP=tcp://172.17.0.2:5432
ALIASDB_PORT_5432_TCP_ADDR=172.17.0.2
ALIASDB_PORT_5432_TCP_PORT=5432
ALIASDB_PORT_5432_TCP_PROTO=tcp
ALIASDB_NAME=/web5/aliasDb
ALIASDB_ENV_PG_VERSION=9.3
HOME=/root

其中 ALIASDB_開頭的環境變量是通過 web 容器連接 db 容器使用的, 前綴采用大寫的連接別名.

除了環境變量之外, Docker 還添加 host 信息到父容器的 /etc/hosts 文件. 下面是父容器 web 的 hosts 文件:

root@d28f99ea8427:/opt/webapp# 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.2  aliasDb 2c3a75c29c98 db
172.17.0.5  d28f99ea8427

這里有兩個 hosts 信息, 第一個是 web 容器, web 容器用自己的 id 作為默認主機名(172.17.0.5 d28f99ea8427), 第二個是 db 容器的 ip 別名 容器 id 和 主機名(172.17.0.2 aliasDb 2c3a75c29c98 db).

用 ping 來測試 db 容器, 它會解析成 172.17.0.2. 用戶可以連接多個子容器到父容器, 比如可以連接多個 web 到同一個 db 容器上.

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
平臺聲明:文章內容(如有圖片或視頻亦包括在內)由作者上傳并發布,文章內容僅代表作者本人觀點,簡書系信息發布平臺,僅提供信息存儲服務。

推薦閱讀更多精彩內容

  • 轉載自 http://blog.opskumu.com/docker.html 一、Docker 簡介 Docke...
    極客圈閱讀 10,543評論 0 120
  • 五、Docker 端口映射 無論如何,這些 ip 是基于本地系統的并且容器的端口非本地主機是訪問不到的。此外,除了...
    R_X閱讀 1,797評論 0 7
  • Spring Cloud為開發人員提供了快速構建分布式系統中一些常見模式的工具(例如配置管理,服務發現,斷路器,智...
    卡卡羅2017閱讀 134,948評論 18 139
  • 0x01 核心概念 Docker鏡像類似于虛擬機鏡像,可以理解為一個面向Docker引擎的只讀模板,包含了文件系統...
    閑云逸心閱讀 4,767評論 0 9
  • 我沒想過上岸 我不厭倦漂泊 有人遮陽擋雨 有人隨時離去 可能你也一樣 寧愿衣衫襤褸 逆風而居
    我們都是鹿閱讀 266評論 0 0