聊聊docker那些端口问题
今天来系统聊一聊docker的端口,常见的有容器内程序端口、容器端口、主机端口、Dockerfile中EXPOSE端口、docker-compose和docker run中的port等。
貌似很多端口,但连接时真实的端口仅程序端口和主机端口,其他都是对端口的声明,并不会实际开启端口的服务。
下面以nginx和redis镜像为例介绍下这些端口的关系:nginx程序端口80,映射主机端口30080;redis程序端口6379,映射主机端口36379。实际通信如下图

程序端口即容器端口
程序端口即实际容器端口,它们是同一个端口。不需要任何其他配置,容器启动后,本机或同网络其他容器通过容器内程序端口(即容器端口)访问该容器的服务。
以nginx为例,启动容器(名称web)
[root@localhost ~]# docker run -d --name web nginx
3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3cb58fd8e585 nginx "/docker-entrypoint.…" 17 seconds ago Up 15 seconds 80/tcp web
本地服务器验证访问容器端口,先查看容器ip,再用telnet 检查端口80通讯,返回如下高亮信息表示端口访问正常
[root@localhost ~]# docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' web
172.17.0.2
[root@localhost ~]# curl http://172.17.0.2:80
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
。。。。。
外网验证访问,连接不通
$ curl http://192.168.8.190:80
% Total % Received % Xferd Average Speed Time Time Time Current Dload Upload Total Spent Left Speed
0 0 0 0 0 0 0 0 --:--:-- 0:00:01 --:--:-- 0
curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused
Dockerfile中EXPOSE端口
- 结论:Dockerfile中的EXPOSE仅是对端口的声明,在ps或inspect时显示,但并不会实际开启端口的服务,实际端口有容器中程序的端口决定
1. 修改容器web内nginx的端口为88,重启生效
[root@localhost ~]# docker exec -it web /bin/bash
root@9ac59b2d523f:/# vi /etc/nginx/conf.d/default.conf
修改listen参数值为88
[root@localhost ~]# docker restart web
web
2.检查镜像的Dockerfile文件中Expose的端口:80
[root@localhost ~]# docker history nginx
IMAGE CREATED CREATED BY SIZE COMMENT
605c77e624dd 9 days ago /bin/sh -c #(nop) CMD ["nginx" "-g" "daemon… 0B
<missing> 9 days ago /bin/sh -c #(nop) STOPSIGNAL SIGQUIT 0B
<missing> 9 days ago /bin/sh -c #(nop) EXPOSE 80 0B
3.检查容器信息中显示的端口:80
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
c24aa7848e38 nginx "/docker-entrypoint.…" 39 seconds ago Up 37 seconds 80/tcp web
4.验证实际可访问端口。80拒绝连接,88访问正常
[root@localhost ~]# curl http://172.17.0.2:80
curl: (7) Failed connect to 172.17.0.2:80; 拒绝连接
[root@localhost ~]# curl http://172.17.0.2:88
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>
<p>If you see this page, the nginx web server is successfully installed and
working. Further configuration is required.</p> <p>For online documentation and support please refer to
<a href="http://nginx.org/">nginx.org</a>.<br/>
Commercial support is available at
<a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p>
</body>
</html>
容器端口映射主机端口
- 结论:若容器未指定主机映射端口,则主机外网络无法访问容器,仅本机网络范围可访问。
1. 启动容器,未指定主机映射端口时
[root@localhost ~]# docker run -d --name web nginx
3cb58fd8e585e0b015e7e42e9587df95359e1d133ff5371c6838fd303132d2ef
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
3cb58fd8e585 nginx "/docker-entrypoint.…" 17 seconds ago Up 15 seconds 80/tcp web
外网访问主机80端口,不通

2. 启动容器,指定主机映射端口30080映射容器80端口
[root@localhost ~]# docker run -d -p 30080:80 --name web nginx
04ef8440c357b81da934e91e786612b6027d20ea2e7cb3bd81ae91a9ca15a807
[root@localhost ~]# docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
04ef8440c357 nginx "/docker-entrypoint.…" 8 minutes ago Up 8 minutes 0.0.0.0:30080->80/tcp, :::30080->80/tcp web
外网访问主机30080,成功

补充:在docker run中使用-p映射端口,在docker-compose中使用-port映射端口,效果相同。
容器间连接
访问上方已启动容器web,容器端口80,映射宿主机端口30080,容器ip:172.17.0.2,主机ip:192.168.8.190
- 总结:容器IP:容器Port,主机IP:主机Port,当ip与port匹配时才能访问通。
启动一个redis容器,从redis容器访问web容器服务。
[root@localhost ~]# docker run -d --name redis redis:6.0.8
[root@localhost ~]# docker exec -it redis /bin/bash
root@25d8d484aa5b:/data# curl http://172.17.0.2:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> ...........
root@25d8d484aa5b:/data# curl http://172.17.0.2:30080
curl: (7) Failed to connect to 172.17.0.2 port 30080: Connection refused
root@25d8d484aa5b:/data# curl http://192.168.8.190:30080
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
............
root@25d8d484aa5b:/data# curl http://192.168.8.190:80
curl: (7) Failed to connect to 192.168.8.190 port 80: Connection refused
聊聊docker那些端口问题的更多相关文章
- docker iptables 端口映射 nat
docker iptables 端口映射 nat #!/bin/bash pro='tcp' NAT_Host='Host_A' NAT_Port=8080 Dst_Host='Host_B' ...
- docker学习端口连接docker容器---第四章节
一.Docker容器连接 前面的第二章节,我们事先通过网络端口来访问运行在docker容器内的服务,我们也可以通过端口连接到一个docker容器 我们可以指定容器绑定的网络地址,如绑定127.0.0. ...
- docker学习端口映射---第二章节
一.运行一个web应用 首先,下载一个docker镜像: [root@k8s-01 ~]# docker pull training/webapp 运行webapp的容器: [root@k8s-01 ...
- 【docker】追加docker容器端口映射的方法
docker run可以指定端口映射,但是容器一旦生成,就没有一个命令可以直接修改.通常间接的办法是,保存镜像,再创建一个新的容器,在创建时指定新的端口映射. 但这样太麻烦了.现在有新方案来解决掉: ...
- Docker基础-端口映射与容器互联
1.端口映射实现访问容器 1.从外部访问容器应用 在启动容器的时候,如果不指定对应的参数,在容器外部是无法通过网络来访问容器内部的网络应用和服务的. 当容器中运行一些网络应用,要让外部访问这些应用时, ...
- docker动态绑定端口
一.背景 在创建容器的时候,我们可以使用命令 docker container run -p host:container container-name 的方式来绑定端口,还可以使用docker-co ...
- ip route,ip rule, iptables和docker的端口映射
iptables 默认5个表, 不可增加其他表 raw 用于配置数据包,raw 中的数据包不会被系统跟踪. filter 是用于存放所有与防火墙相关操作的默认表. nat 用于 网络地址转换(例如:端 ...
- docker映射端口与ssh访问或容器访问
映射端口 -d 后台执行 -p映射端口 --privileged 可以使用systemctl # docker run --privileged -d -p 9000:80 jiqing9006/ce ...
- 通过iptables限制docker容器端口
如何限制docker暴露的对外访问端口 docker 会在iptables上加上自己的转发规则,如果直接在input链上限制端口是没有效果的.这就需要限制docker的转发链上的DOCKER表. # ...
随机推荐
- 图形学之Unity渲染管线流程
Unity中的渲染管线流程 下图是<Unity Shader 入门精要>一书中的渲染流程图: ApplicationStage阶段:准备场景信息(视景体,摄像机参数).粗粒度剔除.定义每个 ...
- xtra+binlog增量备份脚本
目录 一.备份原理 innobackupex原理 binlog原理 特点 备份策略 二.环境准备 开启binlog 创建授权用户 安装innobackupex 三.添加脚本 全量备份 增量备份 bin ...
- Excel如何使用vlookup
一.vlookup的语法 VLOOKUP (lookup_value, table_array, col_index_num, [range_lookup]) ①Lookup_value为需要在数据表 ...
- oracle中net manager的配置
我们知道,要连接一个数据库需要知道四个参数: 1. 登陆用户名:user: 2. 登录密码:password: 3. 存放数据库的服务器地址(server_ip)和端口(server_port): 4 ...
- LuoguP7694 [COCI2009-2010#4] AUTORI 题解
Content 科学论文会大量引用一些早期的著作,因此在一个论文中出现两种不同的命名约定并不少见.这两种不同的命名约定分别是: 长变体,由每个作者姓氏的完整单词由连字符连接而成,例如 Knuth-Mo ...
- Java的垃圾回收机制:强制回收System.gc() Runtime.getTime().gc()
垃圾回收 当引用类型的实体,如对象.数组等不再被任何变量引用的时候.这块占用的内存就成为了垃圾.JVM会根据自己的策略决定是回收内存 注意: 垃圾回收只回收内存中的对象,无法回收物理资源(数据库连接, ...
- CentOS7下使用NFS文件共享给Window server 2012
CentOS7下使用NFS文件共享给Window server 2012 2018年08月24日 23:15:54 疼迅扣扣 阅读数:443 出自https://blog.csdn.net/u013 ...
- 原生XMLHTTPResponse,jQuery-Ajax 上传文件;iframe上传图片&预览;图片验证码小案例
原生AJAX Ajax主要就是使用 [XmlHttpRequest]对象来完成请求的操作,该对象在主流浏览器中均存在(除早起的IE),Ajax首次出现IE5.5中存在(ActiveX控件) 1.Xml ...
- Tornado WEB服务器框架 Epoll-- 【Mysql数据库】
5.1 数据库 与Django框架相比,Tornado没有自带ORM,对于数据库需要自己去适配.我们使用MySQL数据库. 在Tornado3.0版本以前提供tornado.database模块用来操 ...
- IDEA快速创建一个简单的SpringBoot项目(需要联网)
一.点击File-New-Project,选择Spring initializr ,选择jdk1.8及以上 二.填写相关信息,点击Next 3.选择Web -Spring Web,点击Next 4.输 ...