你可能需要知道的docker 的端口问题。
引言
docker 这个东西呢,对于我来说又爱又恨吧,爱的事情是可以很快速的进行部署项目,解决一些复杂和繁琐的问题,这也是docker 设计的初衷。恨得呢,本身我对于docker 来说是是一个小白用户,我只会 docker run xxxx 来完成我在github 找到的有趣应用,但是出了问题的时候,我需要去使用搜索引擎查阅的知识。
需要准备的东西?
- 掌握搜索引擎技能(下面的文章只会叫你如何进行使用基本的iptables)
- 一个大脑🧠
- 一台运行了Linux系统的电脑
- 掌握基本的Linux基本知识
抛出问题
应该在阅读这篇文章的人,都在很疑惑,为什么我在docker上使用 docker run -p 指令的时候,和宿主机进行绑定端口,本来我是想使用nginx 进行反代的,我自己的防火墙也没有放行这个端口,但从外部确确实实的可以访问。
为什么会出现这个问题?
在docker 官方文档上就有这个解释,docker 使用 -p 进行放行端口的时候,低层使用 iptables防火墙 FORWARD
将流量转发到docker 运行的容器里面。
我拿 Iptables防火墙 这篇文章的图进行来说明一下
因为 流量在进入iptables 防火墙的时候 会经过路由选择进行判定,这个流量是要转发还是要流入本机里面,由于docker 自身创建了一个单独的内网环境一般这个 IP段是 172.17.0.0/16
,然后流浪回去转入对应的容器里面。
解决办法
知道了为什么会出现这个问题,其实就可以知道其中一种解决办法了,就是不适用 -p 指令不让宿主机和容器进行绑定,然后使用nginx 进行,反向代理就可以了,一般情况下是,docker 使用 桥接网络模式 ,Docker 会为每个容器分配一个唯一的 IP 地址。可以查询这个docker 容器的ip 就可以实现反代,但是这个方法会有些问题,
- 有点麻烦,你需要创建一个docker 容器就要进行配置反代。
- nginx 不支持 udp 代理所以说还要安装和配置能代理udp 的软件实现反代。
- 还有一种办法就是直接在docker 的配置文件中关闭使用 IP tables 防护墙,交给其他防火墙进行保护例如 ufw 等
方法一: nginx 反向代理
使用这个方法需要拿到容器的IP
1 | sudo docker inspect <你的容器唯一id或者容器的名字> | grep "IPAddress" |
应该会返回,一下信息,例如我的这个测试容器的IP就是 172.17.0.4
1 | docker inspect nginx-8080 | grep "IPAddress" |
然后去你的nginx 配置新增你的配置文件
1 | server { |
如果你是使用BT面板进行管理的,只需要去网站 - 创建一个新的站点,然后打开配置选择反向代理,填入对应信息即可。
方法二: 修改docker 配置文件
这个方法就比较简单和直接,一般默认情况下docker 的配置文件会在 /etc/docker/daemon.json
如果没有这个 daemon.json
可以直接创建就行了。
注意如果你不会使用vi 或者是vim 编辑器的基本使用,你应该需要去学习一下vi或者vim 的简单使用即可。
1 | sudo vi /etc/docker/daemon.json |
加入这段配置
1 | { |
重启一下docker 以及docker 的守护进程
1 | sudo systemctl restart docker |
注意重启 docker 和docker的守护进程,会需要手动重启创建的docker 容器。在docker 容器重新启动之后 -p 只会绑定宿主机端口号,宿主机端口受现在防火墙进行管理。