聊聊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表. # ...
随机推荐
- 关于python中的随机种子——random_state
random_state是一个随机种子,是在任意带有随机性的类或函数里作为参数来控制随机模式.当random_state取某一个值时,也就确定了一种规则. random_state可以用于很多函数,我 ...
- 【简】题解 P5283 [十二省联考2019]异或粽子
传送门:P5283 [十二省联考2019]异或粽子 题目大意: 给一个长度为n的数列,找到异或和为前k大的区间,并求出这些区间的异或和的代数和. QWQ: 考试时想到了前缀异或 想到了对每个数按二进制 ...
- Docker从入门到精通(二)——安装Docker
通过上面文章,我们大概知道了什么是Docker,但那都是文字功夫,具体想要理解,还得实操,于是这篇文章带着大家来手动安装Docker. 1.官方教程 https://docs.docker.com/e ...
- 论文翻译:2021_Low-Delay Speech Enhancement Using Perceptually Motivated Target and Loss
论文地址:使用感知动机目标和损失的低延迟语音增强 引用格式:Zhang X, Ren X, Zheng X, et al. Low-Delay Speech Enhancement Using Per ...
- HashMap的putAll方法介绍说明
jdk1.8 使用putAll时,新map中的值仅为旧map值所对应对象的引用,并不会产生新对象. 如下,使用for循环赋值! public void putAll(Map<? extends ...
- Excel.CurrentWorkbook数据源(Power Query 之 M 语言)
数据源: 任意超级表 目标: 将超级表中的数据加载到Power Query编辑器中 操作过程: 选取超级表中任意单元格(选取普通表时会自动增加插入超级表的步骤)>数据>来自表格/区域 M公 ...
- Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错
Spring5 AOP编程:关于org.springframework.beans.factory.BeanNotOfRequiredTypeException报错 先上错误详细信息: org.spr ...
- CF1106A Lunar New Year and Cross Counting 题解
Content 试求出在一个 \(n\times n\) 的地图 \(M\) 中,满足 \(1\leqslant i,j\leqslant n\) 且 \(M_{i,j}=M_{i+1,j+1}=M_ ...
- java 编程基础 反射方式获取泛型的类型Fileld.getGenericType() 或Method.getGenericParameterTypes(); (ParameterizedType) ;getActualTypeArguments()
引言 自从JDK5以后,Java Class类增加了泛型功能,从而允许使用泛型来限制Class类,例如,String.class的类型实际上是 Class 如果 Class 对应的类暂时未知,则使 C ...
- 当通过Struts2传值给后台时,如果是外键,传字符串那么会出现错误
当通过Struts2传值给后台时,如果是外键,传字符串那么会出现错误 如<input type="text" name="user.department" ...