首页 > 其他分享 >Docker容器内部端口映射到外部宿主机端口的方法总结

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

时间:2022-11-28 15:23:31浏览次数:41  
标签:80 -- 宿主机 tcp ACCEPT Docker root docker 端口映射

好记性不如烂笔头,将docker容器端口映射到宿主机的方法做一个总结,方便后边忘记了能快速的查询。

 

首先需要注意:

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

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

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

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

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

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

可以根据不同网卡的IP来绑定宿主机的IP地址

[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.0.134: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.0.134: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.0.134:8888就会拒绝!
容器my-nginx4绑定的宿主机外部ip是192.168.10.214,端口是9999,则访问http://192.168.0.134: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.0.134:8088: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.0.134:8088->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
容器my-nginx6无法访问,因为映射的是udp的80端口

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    //查看容器的IP地址
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.6",
                    "IPAddress": "172.17.0.6",

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

[root@docker-test ~]# docker run -ti -d --name my-nginx9 docker.io/nginx
990752e39d75b977cbff5a944247366662211ce43d16843a452a5697ddded12f
[root@docker-test ~]# docker ps
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS              PORTS            NAMES
990752e39d75        docker.io/nginx     "nginx -g 'daemon ..."   2 seconds ago       Up 1 second         80/tcp           my-nginx9

这个时候,由于容器my-nginx9在启动时没有指定其内部的80端口映射到宿主机的端口上,所以默认是没法访问的!
现在通过宿主机的iptables进行net转发

首先获得容器的ip地址
[root@docker-test ~]# docker inspect my-nginx9|grep IPAddress
            "SecondaryIPAddresses": null,
            "IPAddress": "172.17.0.9",
                    "IPAddress": "172.17.0.9",

[root@docker-test ~]# ping 172.17.0.9
PING 172.17.0.9 (172.17.0.9) 56(84) bytes of data.
64 bytes from 172.17.0.9: icmp_seq=1 ttl=64 time=0.105 ms
64 bytes from 172.17.0.9: icmp_seq=2 ttl=64 time=0.061 ms
.....

[root@docker-test ~]# telnet 172.17.0.9 80 
Trying 172.17.0.9...
Connected to 172.17.0.9.
Escape character is '^]'


centos7下部署iptables环境纪录(关闭默认的firewalle)
参考:http://www.cnblogs.com/kevingrace/p/5799210.html

将容器的80端口映射到dockers宿主机的9998端口
[root@docker-test ~]# iptables -t nat -A PREROUTING -p tcp -m tcp --dport 9998 -j DNAT --to-destination 172.17.0.9:80
[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
[root@docker-test ~]# iptables -t filter -A INPUT -p tcp -m state --state NEW -m tcp --dport 9998 -j ACCEPT

保存以上iptables规则
[root@docker-test ~]# iptables-save > /etc/sysconfig/iptables

查看/etc/sysconfig/iptables文件,注意下面两行有关icmp-host-prohibited的设置一定要注释掉!否则nat转发会失败!
[root@docker-test ~]# cat /etc/sysconfig/iptables
# Generated by iptables-save v1.4.21 on Fri Aug 10 11:13:57 2018
*nat
:PREROUTING ACCEPT [32:1280]
:INPUT ACCEPT [0:0]
:OUTPUT ACCEPT [0:0]
:POSTROUTING ACCEPT [0:0]
-A PREROUTING -p tcp -m tcp --dport 9998 -j DNAT --to-destination 172.17.0.9:80
-A POSTROUTING -d 172.17.0.9/32 -p tcp -m tcp --sport 80 -j SNAT --to-source 192.16.10.214
COMMIT
# Completed on Fri Aug 10 11:13:57 2018
# Generated by iptables-save v1.4.21 on Fri Aug 10 11:13:57 2018
*filter
:INPUT ACCEPT [0:0]
:FORWARD ACCEPT [0:0]
:OUTPUT ACCEPT [50:5056]
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 22 -j ACCEPT
-A INPUT -p tcp -m state --state NEW -m tcp --dport 9998 -j ACCEPT
#-A INPUT -j REJECT --reject-with icmp-host-prohibited
#-A FORWARD -j REJECT --reject-with icmp-host-prohibited
COMMIT
# Completed on Fri Aug 10 11:13:57 2018

最后重启iptbales服务
[root@docker-test ~]# systemctl restart iptables

查看iptables规则
[root@docker-test ~]# iptables -L
Chain INPUT (policy ACCEPT)
target     prot opt source               destination         
ACCEPT     all  --  anywhere             anywhere             state RELATED,ESTABLISHED
ACCEPT     icmp --  anywhere             anywhere            
ACCEPT     all  --  anywhere             anywhere            
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:ssh
ACCEPT     tcp  --  anywhere             anywhere             state NEW tcp dpt:distinct32

Chain FORWARD (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination        

[root@docker-test ~]# iptables -L -t nat
Chain PREROUTING (policy ACCEPT)
target     prot opt source               destination         
DNAT       tcp  --  anywhere             anywhere             tcp dpt:distinct32 to:172.17.0.9:80

Chain INPUT (policy ACCEPT)
target     prot opt source               destination         

Chain OUTPUT (policy ACCEPT)
target     prot opt source               destination         

Chain POSTROUTING (policy ACCEPT)
target     prot opt source               destination         
SNAT       tcp  --  anywhere             172.17.0.9           tcp spt:http to:192.16.10.214

然后访问http://192.168.10.214:9998/,就能转发访问到my-nginx9容器的80端口了!!! 

如果启动docker 容器时,有如下报错: /usr/bin/docker-current: Error response from daemon: driver failed programming external connectivity on endpoint my-nginx (db5a0edac68d1ea7ccaa3a1e0db31ebdf278076ef4851ee4250221af6167f9ac): (iptables failed: iptables --wait -t nat -A DOCKER -p tcp -d 0/0 --dport 8088 -j DNAT --to-destination 172.17.0.2:80 ! -i docker0: iptables: No chain/target/match by that name。

解决办法

1)不需要关闭防火墙
2)重启docker服务:systemctl restart docker
3)docker服务重启后,所有容器都会关闭,应立即批量启动全部容器:docker start `docker ps -a -q`
   启动的容器也会包括上面报错的容器,重启docker后,该容器就能正常启动和使用了!

 

标签:80,--,宿主机,tcp,ACCEPT,Docker,root,docker,端口映射
From: https://www.cnblogs.com/wutao-007/p/16932274.html

相关文章

  • 高效率编写Dockerfile
    前言在日常的开发和运维中,我们时长会使用Dockerfile脚本制作镜像。其实编写一个Dockerfile文件用到的标签并不会太多,但是不同的Dockerfile在制作后产生的镜像大小是不尽相......
  • 部署Docker管理面板Portainer
    相信很多人都会遇到部署了docker后想要有个可以管理的控制台,方便我们对docker服务进行管理,查看日志、查看内存占用等等,虽然docker命令都能查看,但是肯定没有图表可视化等来......
  • Docker容器操作
    1.从镜像启动一个容器1.1前台启动容器root@node16:~#dockerimagesREPOSITORYTAGIMAGEIDCREATEDSIZEroot@node16:~#dockerpullnginxUsingdefaultt......
  • Linux网络虚拟化和Docker网络--上
    Linux网络虚拟化1.Linux网络常见概念与操作1.1NameSpace定义​​简单理解namespace​​​​namespace​​是Linux上的网络隔离技术的名称。其实无论是Linux网络中还是其......
  • 当 xxl-job 遇上 docker → 它晕了,我也乱了!
    开心一刻公交车上,一位老大爷睡着了,身体依靠在背后的一位年轻小伙子身上小伙子一直保持站姿十几分钟,直到老人下车这位在校大学生,接受采访时说:”当时就觉得背后这......
  • ssh 如何连接docker
    1.确保容器已经跑起来,并映射出ssh需要的22端口。dockerrun-it-p12222:222.需要在docker容器中安装ssh的sever端sudoaptinstallopenssh-server......
  • 如何保存/同步多架构容器 Docker 镜像
    前言随着容器、芯片技术的进一步发展,以及绿色、节能、信创等方面的要求,多CPU架构的场景越来越常见。典型的应用场景包括:信创:x86服务器+鲲鹏ARM等信创服务器;个人......
  • 如何保存/同步多架构容器 Docker 镜像
    前言随着容器、芯片技术的进一步发展,以及绿色、节能、信创等方面的要求,多CPU架构的场景越来越常见。典型的应用场景包括:信创:x86服务器+鲲鹏ARM等信创服务器;个人......
  • 这 4 个超实用的 Docker 镜像构建技巧!你不会不知道吧?
    最近做了一个好玩的工具,叫 xbin.io。其中有一项工作是为不同的工具来构建Docker镜像,让他们都运行在Docker中(实际上,是兼容Dockerimage的其他 sandbox系统,没有直......
  • 第2-4-7章 docker安装WorkBench-规则引擎Drools-业务规则管理系统-组件化-中台
    目录8.WorkBench8.1WorkBench简介8.2安装方式8.2.1传统方式安装8.2.2docker安装droolsworkbench8.3使用方式8.3.1创建空间、项目8.3.2创建数据对象8.3.3创建DRL......