Docker容器内部端口映射到外部宿主机端口

Docker允许通过外部访问容器或者容器之间互联的方式来提供网络服务
容器启动之后,容器中可以运行一些网络应用,通过-p或-P参数来指定端口映射。

注意:
宿主机的一个端口只能映射到容器内部的某一个端口上,比如:8080->80之后,就不能8080->81
容器内部的某个端口可以被宿主机的多个端口映射,比如:8080->80,8090->80,8099->80

1)启动容器时,选择一个端口映射到容器内部开放端口上
-p   小写p表示docker会选择一个具体的宿主机端口映射到容器内部开放的网络端口上。
-P   大写P表示docker会随机选择一个宿主机端口映射到容器内部开放的网络端口上。

比如:
[root@docker-test ~]# docker run -ti -d --name my-nginx -p 8088:80 docker.io/nginx
2218c7d88ccc917fd0aa0ec24e6d81667eb588f491d3730deb09289dcf6b8125
[root@docker-test ~]# docker run -ti -d --name my-nginx2 -P docker.io/nginx
589237ceec9d5d1de045a5395c0d4b519acf54e8c09afb07af49de1b06d71059
[root@docker-test ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED              STATUS              PORTS                   NAMES
589237ceec9d        docker.io/nginx     "nginx -g 'daemon ..."   6 seconds ago        Up 5 seconds        0.0.0.0:32770->80/tcp   my-nginx2
2218c7d88ccc        docker.io/nginx     "nginx -g 'daemon ..."   About a minute ago   Up About a minute   0.0.0.0:8088->80/tcp    my-nginx
 
由上面可知:
容器my-nginx启动时使用了-p,选择宿主机具体的8088端口映射到容器内部的80端口上了,访问http://localhost/8088即可
容器my-nginx2启动时使用了-P,选择宿主机的一个随机端口映射到容器内部的80端口上了,这里随机端口是32770,访问http://localhost/32770即可

2)启动创建时,绑定外部的ip和端口(宿主机ip是192.168.10.214)

[root@docker-test ~]# docker run -ti -d --name my-nginx3 -p 127.0.0.1:8888:80 docker.io/nginx 
debca5ec7dbb770ca307b06309b0e24b81b6bf689cb11474ec1ba187f4d7802c
[root@docker-test ~]# docker run -ti -d --name my-nginx4 -p 192.168.10.214:9999:80 docker.io/nginx              
ba72a93196f7e55020105b90a51d2203f9cc4d09882e7848ff72f9c43d81852a
[root@docker-test ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                         NAMES
ba72a93196f7        docker.io/nginx     "nginx -g 'daemon ..."   2 seconds ago       Up 1 second         192.168.10.214:9999->80/tcp   my-nginx4
debca5ec7dbb        docker.io/nginx     "nginx -g 'daemon ..."   3 minutes ago       Up 3 minutes        127.0.0.1:8888->80/tcp        my-nginx3
 
由上面可知:
容器my-nginx3绑定的宿主机外部ip是127.0.0.1,端口是8888,则访问http://127.0.0.1:8888或http://localhost:8888都可以,访问http://192.168.10.214:8888就会拒绝!
容器my-nginx4绑定的宿主机外部ip是192.168.10.214,端口是9999,则访问http://192.168.10.214:9999就可以,访问http://127.0.0.1:9999或http://localhost:9999就会拒绝!

3)容器启动时可以指定通信协议,比如tcp、udp

[root@docker-test ~]# docker run -ti -d --name my-nginx5 -p 8099:80/tcp docker.io/nginx
c08eb29e3c0a46386319b475cc95245ccfbf106ed80b1f75d104f8f05d0d0b3e
[root@docker-test ~]# docker run -ti -d --name my-nginx6 -p 192.168.10.214:8077:80/udp docker.io/nginx
992a48cbd3ef0e568b45c164c22a00389622c2b49e77f936bc0f980718590d5b
[root@docker-test ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                 NAMES
992a48cbd3ef        docker.io/nginx     "nginx -g 'daemon ..."   3 seconds ago       Up 2 seconds        80/tcp, 192.168.10.214:8077->80/udp   my-nginx6
c08eb29e3c0a        docker.io/nginx     "nginx -g 'daemon ..."   53 seconds ago      Up 51 seconds       0.0.0.0:8099->80/tcp                  my-nginx5

4)查看容器绑定和映射的端口及Ip地址

[root@docker-test ~]# docker port my-nginx5
80/tcp -> 0.0.0.0:8099
[root@docker-test ~]# docker inspect my-nginx5|grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.6",
                    "IPAddress": "172.17.0.6",

============问题:  Docker 端口映射到宿主机后, 外部无法访问对应宿主机端口==============

创建docker容器的时候,做了端口映射到宿主机, 防火墙已关闭, 但是外部始终无法访问宿主机端口?

这种情况基本就是因为宿主机没有开启ip转发功能,从而导致外部网络访问宿主机对应端口是没能转发到 Docker Container 所对应的端口上。

解决办法:

Linux 发行版默认情况下是不开启 ip 转发功能的。这是一个好的做法,因为大多数人是用不到 ip 转发的,但是如果架设一个 Linux 路由或者VPN服务我们就需要开启该服务了。

在 Linux 中开启 ip 转发的内核参数为:net.ipv4.ip_forward,查看是否开启 ip转发:

# cat /proc/sys/net/ipv4/ip_forward           // 0:未开启,1:已开启
 
==============================
打开ip转发功能, 下面两种方法都是临时打开ip转发功能!
# echo 1 > /proc/sys/net/ipv4/ip_forward
# sysctl -w net.ipv4.ip_forward=1
 
==============================
永久生效的ip转发
# vim /etc/sysctl.conf
net.ipv4.ip_forward = 1
 
# sysctl -p /etc/sysctl.conf      // 立即生效
 
Linux 系统中也可以通过重启网卡来立即生效 (修改sysctl.conf文件后的生效)
# service network restart                  //CentOS 6
# systemctl restart network              //CentOS 7

    原文作者:shirleyjj123
    原文地址: https://blog.csdn.net/shirleyjj123/article/details/120491501
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞