前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >docker如何查看宿主机到容器端口映射

docker如何查看宿主机到容器端口映射

作者头像
时间静止不是简史
发布2022-09-13 17:30:37
14.9K0
发布2022-09-13 17:30:37
举报
文章被收录于专栏:Java探索之路

docker/Docker如何查看宿主机到容器端口映射关系

背景

前些天的时候, 在定位问题时发现docker emqx 连接websocket (8083)端口出现异常. 经过很长时间定位, 才发现是端口映射出现问题 为什么那么长时间才定位到端口映射方面出现了问题呢? 主要是因为对docker端口映射方面的知识点有所遗忘 为了能帮助你快速理解, 请思考下面的问题:

通过docker ps 查看某容器运行情况如下图, 你觉得该容器的 8083端口可以通过外网访问吗(排除防火墙相关问题)?

如果你觉得可以, 那建议你继续往下看. 如果你能够确定不可以, 那你考虑可以跳过本篇文章


如何查看宿主机到端口映射?

方式一(docker ps)

我们不妨回顾下, docker 如何建立端口的映射:

在建立端口映射时, 我们通常会采用docker run 容器id的方式去运行容器并添加容器到宿主机的映射. 下面是该命令介绍

代码语言:javascript
复制
docker run [OPTIONS] IMAGE [COMMOND] [ARGS...]

# OPTIONS 说明
	--name="容器新名字": 为容器指定一个名称;
	-d: 后台运行容器,并返回容器ID,也即启动守护式容器;
	-i:以交互模式运行容器,通常与 -t 同时使用;
	-t:为容器重新分配一个伪输入终端,通常与 -i 同时使用;
	-P: 随机端口映射;
	-p: 指定端口映射,有以下四种格式
	      ip:hostPort:containerPort
	      ip::containerPort
	      hostPort:containerPort
	      containerPort

# eg: 运行mysql 的 docker 镜像->将宿主机的3307端口映射到docker容器内部3306端口
docker run -p 3307:3306 --name mysql -v /datebase/mysql/conf:/etc/mysql/conf.d -v /datebase/mysql/logs:/logs -v /datebase/mysql/data:/var/lib/mysql -e MYSQL_ROOT_PASSWORD=root -d mysql:5.6

从上面我们可以看到, docker 指定端口的映射时宿主机端口到运行容器端口的映射

因此我们在运行docker ps中, 查看的结果就是按照宿主机端口->运行容器端口显示的

从上图可以看出, 宿主机的 3307端口绑定到了docker 容器中的3306端口, 0.0.0.0是真正表示网路中的本地.

因此一开始的:8083-8084/tcp代表放开docker容器内部8083,8084端口, 但无法通过宿主机访问到这两个端口,

因为他们之间没有建立端口映射, 下面列举了在docker ps下, 几种端口映射的介绍

代码语言:javascript
复制
0.0.0.0:3307->3306/tcp		# 当前宿主机网络的的3307端口绑定了docker容器的3306端口
:::3307->3306/tcp 			# ::等价于“0:0:0:0:0:0:0:0”的缩写,相当于IPv6的“0.0.0.0”,就是本机的所有IPv6地址. 这里相当于在ipv6中做了端口映射
							
27017/tcp					# 如果没有箭头 -> , 说明没有建立映射, 且当前代表的是docker容器内开放的端口

方式二(docker inspect)

  1. 根据上一种方式介绍, 我们可以知道: 当前只有 1883, 8883, 18083 这三个端口建立了映射(如下图所示).

  1. 我们可以通过使用 docker inspect 容器id, 查看容器的属性. 端口映射情况如在 NetworkSettings.Ports属性下 可以明显地看到, 在已建立端口映射的属性下会有 HostIpHostPort 两个子属性; 在没有建立映射情况下, 子属性为null

  1. 因此再根据 docker inspect 查的8083/tcp的子属性为null . 我们也可以从这里确认没有建立宿主机8083端口->容器8083端口的映射

如何添加宿主机到端口映射?

上面问题解决了, 但有新的问题出现了. 那就是: 当发现某些端口没有建立映射时, 我们如何添加这些端口映射关系呢? 你可以直接删除容器, 然后重新配置端口映射后再运行容器. 但如果在不删除容器的情况下. 依旧有两种方式:

方式一

第一种方式不做过多解释, 通过修改docker 基础配置文件, 然后重启docker 服务使其生效 传送门

  • 优点: 配置简单
  • 缺点: 需要在配置前关闭docker服务, 配置后再启动, 如果docker上的软件没有设置重启自启也会很麻烦

方式二

通过修改路由表的方式来添加端口映射. 本人也是通过这种方式进行动态修改 参考文章

  • 优点: 无需重启docker服务
  • 缺点: 配置较为麻烦

步骤

  1. 获取当前docker 容器ip, 用于后续配置使用
代码语言:javascript
复制
docker inspect 容器id | grep IPAddress

  1. 配置iptables
代码语言:javascript
复制
# 这里需要注意所有ip和端口的配置(黄色字体)
# 配置docker防火墙开放宿主机端口(这里开放8083)
sudo iptables -A DOCKER ! -i docker0 -o docker0 -p tcp --dport 8083 -d 172.17.0.16 -j ACCEPT
# 配置宿主机8083端口到docker的ip路由转发
sudo iptables -t nat -A POSTROUTING -p tcp --dport 8083 -s 172.17.0.16 -d 172.17.0.16 -j MASQUERADE
# 将容器的8083端口(后者)映射到宿主机的8083端口(前者)
sudo iptables -t nat -A DOCKER ! -i dokcer0 -p tcp --dport 8083 -j DNAT --to-destination 172.17.0.16:8083

查看配置结果

代码语言:javascript
复制
sudo iptables -t nat -nvL

如果没有生效, 可以重启下容器

代码语言:javascript
复制
sudo docker restart 容器id
本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2022-07-08,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • docker/Docker如何查看宿主机到容器端口映射关系
    • 背景
      • 如何查看宿主机到端口映射?
        • 方式一(docker ps)
        • 方式二(docker inspect)
      • 如何添加宿主机到端口映射?
        • 方式一
        • 方式二
    相关产品与服务
    容器镜像服务
    容器镜像服务(Tencent Container Registry,TCR)为您提供安全独享、高性能的容器镜像托管分发服务。您可同时在全球多个地域创建独享实例,以实现容器镜像的就近拉取,降低拉取时间,节约带宽成本。TCR 提供细颗粒度的权限管理及访问控制,保障您的数据安全。
    领券
    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档