溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

怎么理解Docker網(wǎng)絡(luò)中的端口映射、容器鏈接、Networking

發(fā)布時間:2021-11-16 11:25:11 來源:億速云 閱讀:174 作者:iii 欄目:大數(shù)據(jù)

這篇文章主要講解了“怎么理解Docker網(wǎng)絡(luò)中的端口映射、容器鏈接、Networking”,文中的講解內(nèi)容簡單清晰,易于學(xué)習(xí)與理解,下面請大家跟著小編的思路慢慢深入,一起來研究和學(xué)習(xí)“怎么理解Docker網(wǎng)絡(luò)中的端口映射、容器鏈接、Networking”吧!

在使用Docker容器時,我們需要訪問容器的內(nèi)部網(wǎng)絡(luò),或需要在容器間相互訪問。Docker 容器默認(rèn)不會開放任何端口,因此需要將容器與宿主機進行端口映射,使容器可外部訪問。而容器間互相訪問,除了可以基于端口映射進行訪問外,還可以通過容器鏈接(Link)的方式,也可以通過Docker 網(wǎng)絡(luò)(Networking)實現(xiàn)。

  1. 端口映射與外部訪問容器

    • 1.1 -P綁定宿主機隨機端口

    • 1.2 -p指定端口、IP地址綁定

    • 1.3 其它

  2. 容器鏈接(Link)

    • 2.1 容器的命名

    • 2.2 容器的互聯(lián)

  3. Docker網(wǎng)絡(luò)(Networking)

    • 3.1 創(chuàng)建網(wǎng)絡(luò)

    • 3.2 創(chuàng)建容器并連接到網(wǎng)絡(luò)

    • 3.3 將已有容器連接到Docker網(wǎng)絡(luò)

    • 3.4 斷開網(wǎng)絡(luò)與網(wǎng)絡(luò)刪除

1. 端口映射與外部訪問容器

Docker 容器運行后默認(rèn)不會開啟任何網(wǎng)絡(luò)端口,這樣就無法通過網(wǎng)絡(luò)訪問容器。要使容器可以通過外部網(wǎng)絡(luò)訪問Docker 容器的內(nèi)部網(wǎng)絡(luò),就需要將容器端口與宿主機端口建立映射關(guān)系。

容器與宿主機間建立端口映射關(guān)系時,可以在運行容器時使用-P-p參數(shù)指定端口映射。兩者區(qū)別如下:

  • -P參數(shù)會隨機分配一個49000~49900之間的端口到容器內(nèi)部開放的網(wǎng)絡(luò)(通過EXPORT指定的)端口

  • -p則可以具體指定要映射的端口,并且在一個指定端口上只能綁定一個容器

1.1 -P綁定宿主機隨機端口

-P參數(shù)會隨機綁定一個49000~49900之間的端口所運行容器的導(dǎo)出端口。

如,運行一個容器,并使用-P綁定宿主機端口:

$ sudo docker run -d --name experss-app -P itbilu/express-app
28003e2dcdcd38075d1ad68d4791c77edaca47dc3d468b0333669ba483cd7b3d

在這個示例中,我們通過itbilu/express-app鏡像創(chuàng)建并運行了一個名為express-app的容器。運行容器時,我們通過-P參數(shù)進行了端口映射。這時,可以通過docker ps命令查看所分配的端口號:

$ sudo docker ps 
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                     NAMES
0781edb13563        itbilu/express-app   "npm start"         15 seconds ago      Up 14 seconds       0.0.0.0:32771->3000/tcp   experss-app

如上所示,宿主機的32771端口被綁定到了容器的3000端口。

1.2 -p指定端口、IP地址綁定

如果不想使用隨機端口,則可以使用-p參數(shù)來指定要綁定的端口號。-p參數(shù)除了可以指定端口號外,還可以指定宿主機的IP,這一點在使用過程中非常有用。

-p支持以下幾種綁定格式:

// 綁定宿主機IP及端口
ip:hostPort:containerPort
// 綁定宿主機IP
ip::containerPort
// 綁定宿主機端口
hostPort:containerPort

綁定宿主機所有的IP

使用hostPort:containerPort格式進行宿主機及容器端口映射時,默認(rèn)會將宿主機的所有IP綁定到容器。如:

$ sudo docker run -d --name experss-app -p 3000:3000 itbilu/express-app

在這個示例中,將宿主機的3000端口映射到了容器的3000端口。在這種情況下,會綁定本地所有接口上的所有IP地址。

映射到指定地址的指定端口

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

如,綁定127.0.0.1IP到容器:

$ sudo docker run -d --name experss-app -p 127.0.0.1:3000:3000 itbilu/express-app

映射指定地址及隨機端口

ip::containerPort格式會綁定宿主機的指定IP地址及隨機端口到容器端口。如:

$ sudo docker run -d --name experss-app -p 127.0.0.1::3000 itbilu/express-app

使用docker ps查看所分配的端口:

$ sudo docker ps
CONTAINER ID        IMAGE                COMMAND             CREATED             STATUS              PORTS                       NAMES
6289a4714594        itbilu/express-app   "npm start"         4 seconds ago       Up 4 seconds        127.0.0.1:32768->3000/tcp   experss-app

1.3 其它

在前面示例中,我們通過docker ps查看已創(chuàng)建的容器及容器所綁定的端口。除了docker ps命令外,還可以使用docker port查看所綁定的端口及IP地址:

$ sudo docker port experss-app
3000/tcp -> 127.0.0.1:32768

容器內(nèi)部可能會使用多個網(wǎng)絡(luò)端口,使用docker port命令時,可以指定端口參數(shù),以查看容器指定端口的綁定情況:

$ sudo docker port experss-app 3000
127.0.0.1:32768

在創(chuàng)建/運行容器時,-p參數(shù)可以被多次使用,以綁定多個容器端口:

$ sudo docker run -d --name experss-app -p 3000:3000 -p 5000:80 itbilu/express-app

Docker進行端口綁定時,默認(rèn)會綁定TCP端口。還可以使用udp標(biāo)記來綁定udp端口:

$ sudo docker run -d --name experss-app -p 3000:3000/udp itbilu/express-app

2. 容器鏈接(Link)

容器的連接(link)系統(tǒng)是除了端口映射外,另一種跟容器中應(yīng)用交互的方式。該系統(tǒng)會在源容器和接收容器之間創(chuàng)建一個隧道,接收容器可以看到源容器指定的信息。Docker的鏈接是一個可以將具體的容器連接到一起來進行通信的抽像層。

2.1 容器的命名

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

自定義容器名稱,可以使用--name參數(shù):

$ sudo docker run -d --name db training/postgres

命令并運行容器后,可以通過docker ps命令來查看相關(guān)信息。也可以使用docker inspect命令來查看容器的名稱:

$ sudo docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS               NAMES
db2093b13127        training/postgres   "su postgres -c '/..."   4 seconds ago       Up 2 seconds        5432/tcp            db
$ sudo docker inspect -f "{{ .Name }}" db2093b13127
/db

2.2 容器的互聯(lián)

使用--link參數(shù)可以讓容器間安全的進行互聯(lián)。

如,我們可以像下面這樣創(chuàng)建一個名為web的容器,并將它連接到db容器:

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

這樣就在webdb之間建立了互聯(lián)關(guān)系。

--link參數(shù)格式

--link參數(shù)的格式為--link name:alias,其中:name表示要連接的容器的名稱,而alias表示連接后的別名。

通過--link參靈敏,Docker 會在兩個互聯(lián)的容器之間創(chuàng)建了一個安全的隧道,且不用映射它們的端口到宿主主機上。在前面我們啟動db容器的時,并沒有使用-p-P參數(shù),從而避免了暴露數(shù)據(jù)庫端口到外部網(wǎng)絡(luò)上,增加了容器的安全性。

3. Docker網(wǎng)絡(luò)(Networking)

在Docker 1.9及之后,增加了Docker Networkingdocker network命令。容器之間的連接通過網(wǎng)絡(luò)來創(chuàng)建,這被稱為Docker Networking。

通過端口映射的方式開放容器的內(nèi)部網(wǎng)絡(luò),這種方式并不夠靈活、強大,且會暴露端口到外部網(wǎng)絡(luò)。容器鏈接和Dcoker Networking是更好的處理方式,Docker 1.9之前的版本推薦使用容器鏈接(Link)的方式,在Docker 1.9及之后則更推薦使用Dcoker Networking。相對鏈接來說,Networking具有以下優(yōu)點:

  • Dcoker Networking可以將容器連接到不同宿主機上的容器

  • 通過Dcoker Networking連接的容器,可以在不更新連接的情況下對容器進行停止、啟動或重啟。而鏈接則需要通過更新配置,重啟對應(yīng)的容器來更新容器之間的網(wǎng)絡(luò)

  • 使用Dcoker Networking可以不用關(guān)心容器是否已運行,也不用關(guān)心容器的運行順序,而可以在網(wǎng)絡(luò)內(nèi)部獲取容器名的解析和發(fā)現(xiàn)

Docker 安裝會,有三個網(wǎng)絡(luò)會被自動創(chuàng)建??梢酝ㄟ^docker network ls命令查看:

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
32dfd86b7900        bridge              bridge              local
18814c612f64        host                host                local
7914b1c3168c        none                null                local

在Docker歷史上,這三個網(wǎng)絡(luò)是Docker執(zhí)行的一部分。在運行容器時,可以使用--network指定要運行容器的網(wǎng)絡(luò),面這三個網(wǎng)絡(luò)都可選。

3.1 創(chuàng)建網(wǎng)絡(luò)

Docker Networking允許用戶創(chuàng)建自己的網(wǎng)絡(luò),容器間可以通過這個網(wǎng)絡(luò)互相通訊。Docker Networking允許容器跨越不同的宿主機通訊,且網(wǎng)絡(luò)配置方式更靈活。

Docker Engine 會在引擎安裝時自動創(chuàng)建一個名為bridge(橋接)網(wǎng)絡(luò),這個網(wǎng)絡(luò)會與docker0(Docker內(nèi)部網(wǎng)絡(luò))相對應(yīng)。

除此之外,用戶還可以自行創(chuàng)建bridgeoverlay類型的網(wǎng)絡(luò)。bridge網(wǎng)絡(luò)適用于單臺宿主機運行的單Docker引擎環(huán)境,而overlay網(wǎng)絡(luò)允許我們跨多臺宿主機進行通訊。

要實現(xiàn)Docker Networking互聯(lián),首先要使用docker network create命令創(chuàng)建一個網(wǎng)絡(luò):

$ sudo docker network create my_network
32ddd24fd698665888ffa542215ae79a140b31ab3a10c96422ce2aee67b904a9

如上,我們創(chuàng)建了一個名為my_network的網(wǎng)絡(luò),現(xiàn)在可以通過docker network inspect查看這個新建的網(wǎng)絡(luò):

$ sudo docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "32ddd24fd698665888ffa542215ae79a140b31ab3a10c96422ce2aee67b904a9",
        "Created": "2017-04-04T04:05:13.230681143Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {},
        "Options": {},
        "Labels": {}
    }
]

在不添加額外參數(shù)的情況下,創(chuàng)建的是一個本地橋接網(wǎng)絡(luò)。而創(chuàng)建overlay網(wǎng)絡(luò),需要預(yù)先存在一些條件,詳細(xì)官方文檔:Create networks

使用docker network ls命令也可以看到這個新建的網(wǎng)絡(luò):

$ docker network ls
NETWORK ID          NAME                DRIVER              SCOPE
32ddd24fd698        my_network          bridge              local
ae4ab5ad7602        bridge              bridge              local
18814c612f64        host                host                local
7914b1c3168c        none                null                local

3.2 創(chuàng)建容器并連接到網(wǎng)絡(luò)

創(chuàng)建網(wǎng)絡(luò)后,可以在創(chuàng)建容器時通過--network參數(shù)指定容器要使用的網(wǎng)絡(luò):

$ sudo docker run -d --name db --network=my_network training/postgres

使用docker network inspect查看的網(wǎng)絡(luò)情況:

$ docker network inspect my_network
[
    {
        "Name": "my_network",
        "Id": "32ddd24fd698665888ffa542215ae79a140b31ab3a10c96422ce2aee67b904a9",
        "Created": "2017-04-04T04:05:13.230681143Z",
        "Scope": "local",
        "Driver": "bridge",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "172.18.0.0/16",
                    "Gateway": "172.18.0.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Containers": {
            "dccb4267650d8659e65aa3876ec6a427224111a91b4b253bb105af2295ad7a4a": {
                "Name": "db",
                "EndpointID": "6b1610e37eafbd044beb33f91f1d5d8e337da1b7376690f05b6fdeb0916edb9f",
                "MacAddress": "02:42:ac:12:00:02",
                "IPv4Address": "172.18.0.2/16",
                "IPv6Address": ""
            }
        },
        "Options": {},
        "Labels": {}
    }
]

可以看到my_network網(wǎng)絡(luò)的Containers參數(shù)中,包含了網(wǎng)創(chuàng)建的容器的信息,表中容器已連接到我們所創(chuàng)建的網(wǎng)絡(luò),而該容器的IP地址為172.18.0.2

接下來,創(chuàng)建一個交互式容器,并查看該容器內(nèi)部的網(wǎng)絡(luò)情況:

$ sudo docker run -t -i --name web --network=my_network training/webapp /bin/bash
root@acb03a7adec2:/opt/webapp#

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

# ping db
PING db (172.18.0.2) 56(84) bytes of data.
64 bytes from db.my_network (172.18.0.2): icmp_seq=1 ttl=64 time=0.136 ms
64 bytes from db.my_network (172.18.0.2): icmp_seq=2 ttl=64 time=0.092 ms
...

由此可見在同一網(wǎng)絡(luò)中的容器是可以互相訪問的。

3.3 將已有容器連接到Docker網(wǎng)絡(luò)

當(dāng)需要將已在運行的容器添加到已有的網(wǎng)絡(luò)時,可以使用docker network connect命令。

刪除剛創(chuàng)建的web容器,并使用以下命令重新創(chuàng)建:

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

將這個容器連接到已創(chuàng)建的名為my_network的網(wǎng)絡(luò):

$ sudo docker network connect my_network web

使用docker network inspect查看的網(wǎng)絡(luò)情況,Containers節(jié)點內(nèi)容如下:

...
"Containers": {
    "7258828bc9ab9153f060aa38c24daa63e22478632270172f5a1485e0e9a4797b": {
        "Name": "web",
        "EndpointID": "457fbf4ecebaabbe6cce2e95d7b1f47e35450897de3e6a00cde835cd3305eee9",
        "MacAddress": "02:42:ac:12:00:03",
        "IPv4Address": "172.18.0.3/16",
        "IPv6Address": ""
    },
    "dccb4267650d8659e65aa3876ec6a427224111a91b4b253bb105af2295ad7a4a": {
        "Name": "db",
        "EndpointID": "6b1610e37eafbd044beb33f91f1d5d8e337da1b7376690f05b6fdeb0916edb9f",
        "MacAddress": "02:42:ac:12:00:02",
        "IPv4Address": "172.18.0.2/16",
        "IPv6Address": ""
    }
}
...

一個容器可以連接入多個網(wǎng)絡(luò),從而構(gòu)建出非常復(fù)雜的網(wǎng)絡(luò)模型。

3.4 斷開網(wǎng)絡(luò)與網(wǎng)絡(luò)刪除

還可以使用docker network disconnect命令將容器與網(wǎng)絡(luò)斷開連接:

$ sudo docker network disconnect my_network web

這樣就將容器web與網(wǎng)絡(luò)my_network斷開的了連接。

網(wǎng)絡(luò)不在需要后,可以使用docker network rm命令將網(wǎng)絡(luò)刪除:

$ sudo docker network rm my_network

注意:刪除網(wǎng)絡(luò)時,需要已斷開所容器的連接,否則會刪除失敗。

感謝各位的閱讀,以上就是“怎么理解Docker網(wǎng)絡(luò)中的端口映射、容器鏈接、Networking”的內(nèi)容了,經(jīng)過本文的學(xué)習(xí)后,相信大家對怎么理解Docker網(wǎng)絡(luò)中的端口映射、容器鏈接、Networking這一問題有了更深刻的體會,具體使用情況還需要大家實踐驗證。這里是億速云,小編將為大家推送更多相關(guān)知識點的文章,歡迎關(guān)注!

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI