天天看点

Docker - Docker初级网络配置 - 端口映射

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 - Docker初级网络配置 - 端口映射

通过​

​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 - Docker初级网络配置 - 端口映射

通过​

​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      

继续阅读