1. 程式人生 > >Docker 網路-埠對映、容器連結、Networking

Docker 網路-埠對映、容器連結、Networking

在使用Docker容器時,我們需要訪問容器的內部網路,或需要在容器間相互訪問。Docker 容器預設不會開放任何埠,因此需要將容器與宿主機進行埠對映,使容器可外部訪問。而容器間互相訪問,除了可以基於埠對映進行訪問外,還可以通過容器連結(Link)的方式,也可以通過Docker 網路(Networking)實現。

1. 埠對映與外部訪問容器

Docker 容器執行後預設不會開啟任何網路埠,這樣就無法通過網路訪問容器。要使容器可以通過外部網路訪問Docker 容器的內部網路,就需要將容器埠與宿主機埠建立對映關係。

容器與宿主機間建立埠對映關係時,可以在執行容器時使用-P-p引數指定埠對映。兩者區別如下:

  • -P引數會隨機分配一個49000~49900之間的埠到容器內部開放的網路(通過EXPORT指定的)埠
  • -p則可以具體指定要對映的埠,並且在一個指定埠上只能繫結一個容器

1.1 -P繫結宿主機隨機埠

-P引數會隨機繫結一個49000~49900之間的埠所執行容器的匯出埠。

如,執行一個容器,並使用-P繫結宿主機埠:

在這個示例中,我們通過itbilu/express-app映象建立並運行了一個名為express-app的容器。執行容器時,我們通過-P引數進行了埠對映。這時,可以通過docker ps命令檢視所分配的埠號:

如上所示,宿主機的32771埠被繫結到了容器的3000埠。

1.2 -p
指定埠、IP地址繫結

如果不想使用隨機埠,則可以使用-p引數來指定要繫結的埠號。-p引數除了可以指定埠號外,還可以指定宿主機的IP,這一點在使用過程中非常有用。

-p支援以下幾種繫結格式:

繫結宿主機所有的IP

使用hostPort:containerPort格式進行宿主機及容器埠對映時,預設會將宿主機的所有IP繫結到容器。如:

在這個示例中,將宿主機的3000埠對映到了容器的3000埠。在這種情況下,會繫結本地所有介面上的所有IP地址。

對映到指定地址的指定埠

使用ip:hostPort:containerPort格式可以將宿主機指定的IP及埠,繫結到容器埠。

如,繫結127.0.0.1

IP到容器:

對映指定地址及隨機埠

ip::containerPort格式會繫結宿主機的指定IP地址及隨機埠到容器埠。如:

使用docker ps檢視所分配的埠:

1.3 其它

在前面示例中,我們通過docker ps檢視已建立的容器及容器所繫結的埠。除了docker ps命令外,還可以使用docker port檢視所繫結的埠及IP地址:

容器內部可能會使用多個網路埠,使用docker port命令時,可以指定埠引數,以檢視容器指定埠的繫結情況:

在建立/執行容器時,-p引數可以被多次使用,以繫結多個容器埠:

Docker進行埠繫結時,預設會繫結TCP埠。還可以使用udp標記來繫結udp埠:

容器的連線(link)系統是除了埠對映外,另一種跟容器中應用互動的方式。該系統會在源容器和接收容器之間建立一個隧道,接收容器可以看到源容器指定的資訊。Docker的連結是一個可以將具體的容器連線到一起來進行通訊的抽像層。

2.1 容器的命名

Docker的連線系統會依據容器的名稱來進行連線,因此,首先需要定義容器的名稱。在不指定容器命令的情況,系統會隨機分配一個名稱。但相對來說,自定義容器名稱更容易記。

自定義容器名稱,可以使用--name引數:

命令並執行容器後,可以通過docker ps命令來檢視相關資訊。也可以使用docker inspect命令來檢視容器的名稱:

使用--link引數可以讓容器間安全的進行互聯。

如,我們可以像下面這樣建立一個名為web的容器,並將它連線到db容器:

這樣就在webdb之間建立了互聯關係。

--link引數格式

--link引數的格式為--link name:alias,其中:name表示要連線的容器的名稱,而alias表示連線後的別名。

通過--link參靈敏,Docker 會在兩個互聯的容器之間建立了一個安全的隧道,且不用對映它們的埠到宿主主機上。在前面我們啟動db容器的時,並沒有使用-p-P引數,從而避免了暴露資料庫埠到外部網路上,增加了容器的安全性。

3. Docker網路(Networking)

在Docker 1.9及之後,增加了Docker Networkingdocker network命令。容器之間的連線通過網路來建立,這被稱為Docker Networking

通過埠對映的方式開放容器的內部網路,這種方式並不夠靈活、強大,且會暴露埠到外部網路。容器連結和Dcoker Networking是更好的處理方式,Docker 1.9之前的版本推薦使用容器連結(Link)的方式,在Docker 1.9及之後則更推薦使用Dcoker Networking。相對連結來說,Networking具有以下優點:

  • Dcoker Networking可以將容器連線到不同宿主機上的容器
  • 通過Dcoker Networking連線的容器,可以在不更新連線的情況下對容器進行停止、啟動或重啟。而連結則需要通過更新配置,重啟對應的容器來更新容器之間的網路
  • 使用Dcoker Networking可以不用關心容器是否已執行,也不用關心容器的執行順序,而可以在網路內部獲取容器名的解析和發現

Docker 安裝會,有三個網路會被自動建立。可以通過docker network ls命令檢視:

在Docker歷史上,這三個網路是Docker執行的一部分。在執行容器時,可以使用--network指定要執行容器的網路,面這三個網路都可選。

3.1 建立網路

Docker Networking允許使用者建立自己的網路,容器間可以通過這個網路互相通訊。Docker Networking允許容器跨越不同的宿主機通訊,且網路配置方式更靈活。

Docker Engine 會在引擎安裝時自動建立一個名為bridge(橋接)網路,這個網路會與docker0(Docker內部網路)相對應。

除此之外,使用者還可以自行建立bridgeoverlay型別的網路。bridge網路適用於單臺宿主機執行的單Docker引擎環境,而overlay網路允許我們跨多臺宿主機進行通訊。

要實現Docker Networking互聯,首先要使用docker network create命令建立一個網路:

如上,我們建立了一個名為my_network的網路,現在可以通過docker network inspect檢視這個新建的網路:

在不新增額外引數的情況下,建立的是一個本地橋接網路。而建立overlay網路,需要預先存在一些條件,詳細官方文件:Create networks

使用docker network ls命令也可以看到這個新建的網路:

3.2 建立容器並連線到網路

建立網路後,可以在建立容器時通過--network引數指定容器要使用的網路:

使用docker network inspect檢視的網路情況:

可以看到my_network網路的Containers引數中,包含了網建立的容器的資訊,表中容器已連線到我們所建立的網路,而該容器的IP地址為172.18.0.2

接下來,建立一個互動式容器,並檢視該容器內部的網路情況:

然後使用ping測試是否可以連線到db容器:

由此可見在同一網路中的容器是可以互相訪問的。

3.3 將已有容器連線到Docker網路

當需要將已在執行的容器新增到已有的網路時,可以使用docker network connect命令。

刪除剛建立的web容器,並使用以下命令重新建立:

將這個容器連線到已建立的名為my_network的網路:

使用docker network inspect檢視的網路情況,Containers節點內容如下:

一個容器可以連線入多個網路,從而構建出非常複雜的網路模型。

3.4 斷開網路與網路刪除

還可以使用docker network disconnect命令將容器與網路斷開連線:

這樣就將容器web與網路my_network斷開的了連線。

網路不在需要後,可以使用docker network rm命令將網路刪除:

注意:刪除網路時,需要已斷開所容器的連線,否則會刪除失敗。