给运行中的docker容器开放新的端口

本文讲述了作者在开发环境中通过socat工具临时开放MongoDB端口进行调试的过程,包括创建数据卷、网络配置和使用socat实现跨网络连接,以实现内外部访问的灵活性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

今天在公司部署开发环境的中间件。

目前有三个服务,mongodb nginx yapi,由于是开发环境,为了简单部署所以直接使用了docker容器来部署,并把mongodb的数据目录,nginx配置文件映射到宿主机。

我首先创建了一个volume用来存储mongodb的数据,防止容器被删除后数据丢失

sudo docker volume create mongodbdata

docker-compose.yml中用volumes挂载到/data/db

然后我创建了两个网络

sudo docker network create n-nginx

sudo docker network create n-mongodb

分别作为mongodb的服务网络和nginx转发时可以接触的网络

yapi服务同时加入了这两个网络,这使得它既可以连接内网中的mongodb 又可以被nginx转发到宿主机的端口上对外提供服务

(yapi 不能配置context Path也是一个坑,这个有机会再说)

然后问题来了,我想调试一下我内网中mongodb的数据,但是我的mongodb容器并没有对外开放任何一个端口,但是我是临时想开一个这个外网访问,又不想去改docker-compose。

我查询了一下百度,发现很多人会直接去配置ip-tables来将子网的端口放开,看到那一大堆配置我直接就放弃了,不仅不优雅,也不是临时访问一下这个需求的解决方案。

于是我继续搜索,发现有人提到这个socat,于是我去github主页看了一下,果然它的第二个use case就是我想要实现的效果,于是我就果断了试了一下

sudo docker run --publish 27017:27017 --link mongodb:target --net n-mongodb alpine/socat tcp-listen:27017,fork,reuseaddr tcp-connect:target:27017

用mongodb连接工具试了一下,果然就成功了。

如果加了-d 参数,这个容器可以以守护进程的方式一直运行,可以长期提供服务。不仅仅是一个临时的方案。当然如果是要永远开启,建议还是直接修改容器的启动参数。

另外,一个docker-compose.yml文件中配置多个外部网络好像有好几种实现方法,我贴一下我的实现方法,这一块我也不是特别明白,但是这样确定可用

services:
  network:
    - n-mongodb
    - n-nginx
networks:
  n-mongodb:
    external: true
  n-nginx:
    external: true
复制代码

如果是只连一个外部网络,网上的帖子还有另一种配置,我试了也是可用的

networks:
  default:
    external:
      name: n-nginx
复制代码

参考:

GitHub - alpine-docker/socat: Run socat command in alpine container

### 动态为运行中的Docker容器添加端口映射 在 Docker 中,默认情况下,`docker run` 命令用于创建并启动一个容器,并允许通过 `-p` 参数指定端口映射关系。然而,在某些场景下,可能需要对已经运行容器动态添加端口映射。 #### 方法概述 尽管 `docker run` 是最常见的端口映射方式[^3],但对于已经在运行容器,可以借助 `docker port` 和 `docker update` 的组合来间接实现动态端口映射的效果。不过需要注意的是,Docker 并未提供直接修改已运行容器端口映射的功能,因此通常采用以下替代方案: --- #### 方法一:重启容器以应用端口映射 如果容器支持重启动而不会影响服务状态,则可以通过以下步骤完成端口映射更: 1. **停止正在运行容器** 使用以下命令停止目标容器: ```bash docker stop <container_id> ``` 2. **删除旧容器实例** 删除当前容器以便重建它(注意保存数据卷以防丢失重要数据): ```bash docker rm <container_id> ``` 3. **基于原镜像重创建容器并附加端口映射** 创建带有额外端口映射的容器: ```bash docker run -d --name=<new_container_name> \ -p <existing_host_port>:<existing_container_port> \ -p <new_host_port>:<new_container_port> \ <original_image_name> ``` 4. **验证端口映射是否生效** 运行以下命令确认增加的端口已被正确绑定到宿主机上: ```bash docker ps | grep <new_container_name> ``` 此方法适用于大多数情况下的生产环境调整需求。 --- #### 方法二:利用网络模式共享宿主机端口 另一种解决办法是切换至 `--network="host"` 模式运行容器。在这种模式下,容器会直接继承宿主机上的所有开放端口,无需显式声明任何特定范围内的映射规则。但是要注意该选项仅限 Linux 系统可用,并且可能会带来潜在的安全隐患由于缺乏隔离机制所致[^2]。 执行如下指令即可启用 Host Networking Mode : ```bash docker run -it --net=host alpine ash ``` 对于已有处于其他默认桥接网卡 (bridge network) 下工作的实例来说 , 可尝试将其迁移到自定义 bridge 或者 macvlan 类型子网里去 ,从而获得更灵活可控权限分配策略的同时保留原有功能特性不变 。 --- #### 注意事项 无论采取哪种途径都需要权衡利弊得失 。 如果频繁变更端口设置的话建议考虑自动化工具如 Kubernetes 来简化流程提高效率 同时也要记得做好充分测试工作确保改动无误后再推广上线正式环境中使用 [^4]. ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值