帮助已经运行的容器暴露端口
文章目录
使用Docker时经常会碰到某些容器需要额外打开端口调试的情况,而 docker-proxy 不支持用户在命令行创建新的端口映射,我们需要额外一些小技巧来实现端口转发。
0. 一些准备
关于如何取到容器的 ip :
|
|
1. 使用 iptables 转发端口
Docker本身也是使用 [docker-proxy 通过] iptables 创建端口映射,如果清空了 iptables 规则或者 nat 表中没有 Docker 规则链,docker在创建映射端口的容器时会报错提示下面类似的命令。
自定义一条转发,添加在 nat 表 DOCKER 链上:
|
|
按理说应该加在 nat 表里 DOCKER-USER 链上,但是发现有环境没有这个链,报错。关于 nat 表 DOCKER 和 DOCKER-USER 链一些说明:https://docs.docker.com/network/iptables/#add-iptables-policies-before-dockers-rules
查看是否已有规则:
|
|
删除上述添加的规则[谨慎]:
也就是把上面 -A 改成 -D
|
|
这种办法的缺点是,几乎只适用于 linux 系统,并且需要 sudo 登录到容器所在的宿主机上。
2. 使用 sshd 转发端口
在 Docker 宿主机上使用 ssh 转发到主网卡来暴露容器端口,例如使用命令:
|
|
缺点是需要有 ssh 服务和客户端搭配实现。
3. 使用 socat 转发端口
这里使用 socat 容器转发,可以随容器进程一起启动[需要设置 restart 参数]
|
|
参考:https://hub.docker.com/r/alpine/socat
通过转发 docker 网卡来实现,也需要登录到容器所在的宿主机上来操作。
4. 创建使用共享网络空间的容器暴露端口
涉及的 --link
说明:https://docs.docker.com/network/links/
有很多方法可以放在容器内转发端口,这里也使用 socat 举例
|
|
-p 8000:8000
直接换成 --network host
更灵活,根据实际情况来。
参考:https://stackoverflow.com/questions/19897743/exposing-a-port-on-a-live-docker-container
较之前的办法要求更容易达成。
利用 alpine/socat 镜像做一个简化版
|
|
启动方式:docker run -d --restart=unless-stopped -p 9080:${NEWPORT} --link ${CONTAINERNAME}:rs mysocat ``${NEWPORT}
|
|
转发 unix-connect : socat TCP-LISTEN:3306,reuseaddr,fork UNIX-CONNECT:/var/lib/mysql/mysql.sock
或者转发 docker.sock [不安全]:
|
|
小结
上面各种办法中,最通用的办法是创建容器,通过 –link 到原容器,使用端口转发工具创建新容器实现暴露端口。
简单的端口转发工具,例如 socat、gost 都不错。