Docker容器端口映射方法汇总

Docker容器内部端口映射到外部宿主机端口的方法汇总。

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

注意:

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

容器内部的某个端口可以被宿主机的多个端口映射,比如:8080->80,8090->80,8099->80

一、启动容器时,选择一个端口映射到容器内部开放端口上

-p 小写p表示docker会选择一个具体的宿主机端口映射到容器内部开放的网络端口上。

-P 大写P表示docker会随机选择一个宿主机端口映射到容器内部开放的网络端口上。

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

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

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

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

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

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

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

五、容器启动绑定多IP和端口(跟多个-p)

  1. [root@docker- test ~] # docker run -ti -d --name my-nginx8 -p 192.168.10.214:7777:80 -p 127.0.0.1:7788:80 docker.io/nginx 
  2. 0e86be91026d1601b77b52c346c44a31512138cedc7f21451e996dd2e75d014d
  3. [root@docker- test ~] # docker ps
  4. CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS                                                 NAMES
  5. 0e86be91026d        docker.io /nginx     "nginx -g 'daemon ..."   17 seconds ago      Up 15 seconds       127.0.0.1:7788->80 /tcp , 192.168.10.214:7777->80 /tcp   my-nginx8

六、容器除了在启动时添加端口映射关系,还可以 通过宿主机的iptables进行nat转发,将宿主机的端口映射到容器的内部端口上, 这种方式适用于容器启动时没有指定端口映射的情况!

  1. [root@docker- test ~] # docker run -ti -d --name my-nginx9 docker.io/nginx
  2. 990752e39d75b977cbff5a944247366662211ce43d16843a452a5697ddded12f
  3. [root@docker- test ~] # docker ps
  4. CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS            NAMES
  5. 990752e39d75        docker.io /nginx     "nginx -g 'daemon ..."   2 seconds ago       Up 1 second         80 /tcp           my-nginx9
  6. 这个时候,由于容器my-nginx9在启动时没有指定其内部的80端口映射到宿主机的端口上,所以默认是没法访问的!
  7. 现在通过宿主机的iptables进行net转发
  8. 首先获得容器的ip地址
  9. [root@docker- test ~] # docker inspect my-nginx9|grep IPAddress
  10.              "SecondaryIPAddresses" : null,
  11.              "IPAddress" : "172.17.0.9" ,
  12.                      "IPAddress" : "172.17.0.9" ,
  13. [root@docker- test ~] # ping 172.17.0.9
  14. PING 172.17.0.9 (172.17.0.9) 56(84) bytes of data.
  15. 64 bytes from 172.17.0.9: icmp_seq=1 ttl=64 time =0.105 ms
  16. 64 bytes from 172.17.0.9: icmp_seq=2 ttl=64 time =0.061 ms
  17. .....
  18. [root@docker- test ~] # telnet 172.17.0.9 80 
  19. Trying 172.17.0.9...
  20. Connected to 172.17.0.9.
  21. Escape character is '^]'
  22. centos7下部署iptables环境纪录(关闭默认的firewalle)
  23. 参考:http: //www .cnblogs.com /kevingrace/p/5799210 .html
  24. 将容器的80端口映射到dockers宿主机的9998端口
  25. [root@docker- test ~] # iptables -t nat -A PREROUTING -p tcp -m tcp --dport 9998 -j DNAT --to-destination 172.17.0.9:80
  26. [root@docker- test ~] # iptables -t nat -A POSTROUTING -d 172.17.0.9/32 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.16.10.214
  27. [root@docker- test ~] # iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 9998 -j ACCEPT
  28. 保存以上iptables规则
  29. [root@docker- test ~] # iptables-save > /etc/sysconfig/iptables
  30. 查看 /etc/sysconfig/iptables 文件,注意下面两行有关icmp-host-prohibited的设置一定要注释掉!否则nat转发会失败!
  31. [root@docker- test ~] # cat /etc/sysconfig/iptables
  32. # Generated by iptables-save v1.4.21 on Fri Aug 10 11:13:57 2018
  33. *nat
  34. :PREROUTING ACCEPT [32:1280]
  35. :INPUT ACCEPT [0:0]
  36. :OUTPUT ACCEPT [0:0]
  37. :POSTROUTING ACCEPT [0:0]
  38. -A PREROUTING -p tcp -m tcp --dport 9998 -j DNAT --to-destination 172.17.0.9:80
  39. -A POSTROUTING -d 172.17.0.9 /32 -p tcp -m tcp --sport 80 -j SNAT --to- source 192.16.10.214
  40. COMMIT
  41. # Completed on Fri Aug 10 11:13:57 2018
  42. # Generated by iptables-save v1.4.21 on Fri Aug 10 11:13:57 2018
  43. *filter
  44. :INPUT ACCEPT [0:0]
  45. :FORWARD ACCEPT [0:0]
  46. :OUTPUT ACCEPT [50:5056]
  47. -A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
  48. -A INPUT -p icmp -j ACCEPT
  49. -A INPUT -i lo -j ACCEPT
  50. -A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
  51. -A INPUT -p tcp -m state --state NEW -m tcp --dport 9998 -j ACCEPT
  52. #-A INPUT -j REJECT --reject-with icmp-host-prohibited
  53. #-A FORWARD -j REJECT --reject-with icmp-host-prohibited
  54. COMMIT
  55. # Completed on Fri Aug 10 11:13:57 2018
  56. 最后重启iptbales服务
  57. [root@docker- test ~] # systemctl restart iptables
  58. 查看iptables规则
  59. [root@docker- test ~] # iptables -L
  60. Chain INPUT (policy ACCEPT)
  61. target     prot opt source               destination
  62. ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
  63. ACCEPT     icmp --  anywhere             anywhere
  64. ACCEPT     all  --  anywhere             anywhere
  65. ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt: ssh
  66. ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:distinct32
  67. Chain FORWARD (policy ACCEPT)
  68. target     prot opt source               destination
  69. Chain OUTPUT (policy ACCEPT)
  70. target     prot opt source               destination
  71. [root@docker- test ~] # iptables -L -t nat
  72. Chain PREROUTING (policy ACCEPT)
  73. target     prot opt source               destination
  74. DNAT       tcp  --  anywhere             anywhere             tcp dpt:distinct32 to:172.17.0.9:80
  75. Chain INPUT (policy ACCEPT)
  76. target     prot opt source               destination
  77. Chain OUTPUT (policy ACCEPT)
  78. target     prot opt source               destination
  79. Chain POSTROUTING (policy ACCEPT)
  80. target     prot opt source               destination
  81. SNAT       tcp  --  anywhere             172.17.0.9           tcp spt:http to:192.16.10.214
  82. 然后访问http: //192 .168.10.214:9998/,就能转发访问到my-nginx9容器的80端口了!!!

以上6种方法是Docker端口映射到宿主机的常用方法,参见《Docker从入门到实践》。如遇到端口映射后无法通过宿主机访问的情况可参考波波另一篇笔记《Docker 端口映射到宿主机后, 外部无法访问对应宿主机端口

 

 

你想把广告放到这里吗?

发表评论

您必须 登录 才能发表留言!