Docker - Docker初級網絡配置 - 端口映射
端口映射
Docker容器啟動之前,如果不進行端口映射,在容器外部是無法通過網絡來通路容器内的網絡應用和服務。因為容器中常常會運作一些網絡應用和服務,如果想在容器外部通過網絡來通路容器内的網絡應用和服務,就需要對該容器進行端口映射,可以通過
docker run
指令中的
-P
或
-p
選項來進行端口映射。
随機端口映射
當通過
docker run
指令中的
-P
選項來進行端口映射時,Docker會随機映射一個端口到容器開放的網絡端口。
以
nginx
為例,先拉取
nginx
的鏡像。
[root@izoq008ryseuupz ~]# docker image pull nginx
Using default tag: latest
latest: Pulling from library/nginx
852e50cd189d: Already exists
571d7e852307: Pull complete
addb10abd9cb: Pull complete
d20aa7ccdb77: Pull complete
8b03f1e11359: Pull complete
Digest: sha256:6b1daa9462046581ac15be20277a7c75476283f969cb3a61c8725ec38d3b01c3
Status: Downloaded newer image for nginx:latest
docker.io/library/nginx:latest
[root@izoq008ryseuupz ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nginx latest bc9a0695f571 2 days ago 133MB
再以
nginx
鏡像建立容器
nginx.1
,使用
-P
選項來進行随機的端口映射。
[root@izoq008ryseuupz ~]# docker run -itd -P --name nginx.1 nginx
91e3c7ed957f8196fd631eb7bce21acaa96bc253551303ecba2bf193201284ba
通過
docker ps -l
指令,可以看到本地主機的
32775
端口被映射到了容器的
80
端口。此時通路本地主機的
32775
端口即可通路容器内
nginx
應用提供的界面。
[root@izoq008ryseuupz ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
91e3c7ed957f nginx "/docker-entrypoint.…" 17 minutes ago Up 5 seconds 0.0.0.0:32775->80/tcp nginx.1

通過
docker logs nginx.1
指令,可以看到剛剛用浏覽器通路容器中
nginx
應用提供的界面的記錄。
[root@izoq008ryseuupz ~]# docker logs nginx.1
...
111.8.49.168 - - [27/Nov/2020:09:03:53 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" "-"
2020/11/27 09:03:53 [error] 21#21: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 111.8.49.168, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "ip:32775", referrer: "http://ip:32775/"
111.8.49.168 - - [27/Nov/2020:09:03:53 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://ip:32775/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" "-"
指定端口映射
通過
docker run
指令中的
-p
選項來進行指定的端口映射。将本地主機的
8083
端口映射到容器的
80
端口。
[root@izoq008ryseuupz ~]# docker run -itd -p 8083:80 --name nginx.2 nginx
0e62792a194559bf33c2b39f70b64133cb89a48846278ccee651fda68aa6dad1
[root@izoq008ryseuupz ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e62792a1945 nginx "/docker-entrypoint.…" 6 seconds ago Up 5 seconds 0.0.0.0:8083->80/tcp nginx.2
此時通路本地主機的
8083
端口即可通路容器内
nginx
應用提供的界面。
通過
docker logs nginx.2
指令,同樣可以看到剛剛用浏覽器通路容器中
nginx
應用提供的界面的記錄。
[root@izoq008ryseuupz ~]# docker logs nginx.2
...
111.8.49.168 - - [27/Nov/2020:09:28:32 +0000] "GET / HTTP/1.1" 200 612 "-" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" "-"
2020/11/27 09:28:32 [error] 28#28: *1 open() "/usr/share/nginx/html/favicon.ico" failed (2: No such file or directory), client: 111.8.49.168, server: localhost, request: "GET /favicon.ico HTTP/1.1", host: "ip:8083", referrer: "http://ip:8083/"
111.8.49.168 - - [27/Nov/2020:09:28:32 +0000] "GET /favicon.ico HTTP/1.1" 404 555 "http://ip:8083/" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/87.0.4280.66 Safari/537.36" "-"
通過
docker ps
指令,可以看到之前建立的兩個容器的端口映射都是在本地主機的
0.0.0.0
上。
[root@izoq008ryseuupz ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
0e62792a1945 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 0.0.0.0:8083->80/tcp nginx.2
91e3c7ed957f nginx "/docker-entrypoint.…" 53 minutes ago Up 36 minutes 0.0.0.0:32775->80/tcp nginx.1
網上對于
0.0.0.0
的解釋
首先,
0.0.0.0
是不能被
ping
通的。在伺服器中,
0.0.0.0
并不是一個真實的的IP位址,它表示本機中所有的IPV4位址。監聽
0.0.0.0
的端口,就是監聽本機中所有IP的端口。
C:\Users\Kaven>ping 0.0.0.0
正在 Ping 0.0.0.0 具有 32 位元組的資料:
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。
PING:傳輸失敗。常見故障。
0.0.0.0 的 Ping 統計資訊:
資料包: 已發送 = 4,已接收 = 0,丢失 = 4 (100% 丢失),
指定位址的指定端口映射
可以通過
ip:hostPort:containerPort
這種格式來進行指定位址的指定端口映射,比如
127.0.0.1:8083
。
[root@izoq008ryseuupz ~]# docker stop nginx.2
nginx.2
[root@izoq008ryseuupz ~]# docker run -itd -p 127.0.0.1:8083:80 --name nginx.3 nginx
a20b18b97fa4bf7576f6a0d769394a390cfb64ad5fc895453b548bf3f75105ca
[root@izoq008ryseuupz ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
a20b18b97fa4 nginx "/docker-entrypoint.…" 4 seconds ago Up 4 seconds 127.0.0.1:8083->80/tcp nginx.3
通過
docker inspect nginx.3
指令,也可以看到端口映射資訊。
"Ports": {
"80/tcp": [
{
"HostIp": "127.0.0.1",
"HostPort": "8083"
}
]
}
下面這條指令啟動不了容器,因為它會預設使用
0.0.0.0
,報錯的原因也正是如此 - 位址已在使用中
address already in use
。
docker run -itd -p 8083:80 --name nginx.4 nginx
[root@izoq008ryseuupz ~]# docker run -itd -p 8083:80 --name nginx.4 nginx
a5211ec678440044945e4d6f16fe59f3ac10367192262768096e7b748ebd027c
docker: Error response from daemon: driver failed programming external connectivity on endpoint nginx.4 (809bed1de2bb89f5d54b5b200503701279a153e60dac08b93e13af8c40a02e36): Error starting userland proxy: listen tcp 0.0.0.0:8083: bind: address already in use.
而下面這條指令卻可以啟動容器。
docker run -itd -p 127.0.0.2:8083:80 --name nginx.5 nginx
[root@izoq008ryseuupz ~]# docker run -itd -p 127.0.0.2:8083:80 --name nginx.5 nginx
f60dcb586968471e7a8127ccef4cb4e89c4198df748da404f78afaff4afa42de
通過
docker ps -a
指令,可以看到所有容器的一些資訊。
[root@izoq008ryseuupz ~]# docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f60dcb586968 nginx "/docker-entrypoint.…" 19 seconds ago Up 18 seconds 127.0.0.2:8083->80/tcp nginx.5
a5211ec67844 nginx "/docker-entrypoint.…" 2 minutes ago Created nginx.4
a20b18b97fa4 nginx "/docker-entrypoint.…" 7 minutes ago Up 7 minutes 127.0.0.1:8083->80/tcp nginx.3
0e62792a1945 nginx "/docker-entrypoint.…" 29 minutes ago Exited (0) 7 minutes ago nginx.2
91e3c7ed957f nginx "/docker-entrypoint.…" About an hour ago Up 58 minutes 0.0.0.0:32775->80/tcp nginx.1
指定位址的随機端口映射
可以通過
ip::containerPort
這種格式來進行指定位址的随機端口映射,比如
127.0.0.1
的随機端口。
[root@izoq008ryseuupz ~]# docker run -itd -p 127.0.0.1::80 --name nginx.6 nginx
396b7d9e64c047187c0391485ba1d275587d86409573e882bc68a9357dfcb6f2
[root@izoq008ryseuupz ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
396b7d9e64c0 nginx "/docker-entrypoint.…" 9 seconds ago Up 9 seconds 127.0.0.1:32768->80/tcp nginx.6
可以看到Docker将
127.0.0.1
的
32768
端口映射到了容器的
80
端口,而這個
32768
端口是由Docker随機指定的。
多個端口映射
使用多個
-p
選項即可進行多個端口映射。
[root@izoq008ryseuupz ~]# docker run -itd -p 9091:9091 -p 9092:8080 -p 9093:8083 --name nginx.8 nginx
5ac6438dcc2a2d1b7f668eb10d8285085c396a44f896aae0b3dc09935e4e95eb
[root@izoq008ryseuupz ~]# docker ps -l
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5ac6438dcc2a nginx "/docker-entrypoint.…" 6 seconds ago Up 4 seconds 80/tcp, 0.0.0.0:9091->9091/tcp, 0.0.0.0:9092->8080/tcp, 0.0.0.0:9093->8083/tcp nginx.8
檢視端口映射配置
docker port
指令可以檢視容器的端口映射配置。
[root@izoq008ryseuupz ~]# docker port nginx.6 80
127.0.0.1:32768
[root@izoq008ryseuupz ~]# docker port nginx.5 80
127.0.0.2:8083
[root@izoq008ryseuupz ~]# docker port nginx.3
80/tcp -> 127.0.0.1:8083
[root@izoq008ryseuupz ~]# docker port nginx.8
8080/tcp -> 0.0.0.0:9092
8083/tcp -> 0.0.0.0:9093
9091/tcp -> 0.0.0.0:9091