docker - docker-compose 一个反向代理后面的应用程序,它也可以访问外部服务
问题描述
在本地服务器上,我启动了几个 gunicorn 实例,每个实例在唯一端口上运行不同的 Web 应用程序,作为内部网络其余部分的服务。现在我想将每个 gunicorn 实例放在它自己的 nginx 反向代理服务器后面,以实现更好的负载平衡。
我决定尝试将每个(nginx、gunicorn)对部署在自己的 Docker 容器中,只将其唯一的端口暴露给外界。我知道使用端口转发很容易 - 例如“5555:80”。但是,每个应用程序还可以访问独立于 Docker 在同一主机上运行的外部服务,例如数据库。
通过反复试验,我发现只有以“docker run --network=host ...”的方式运行Docker 容器才能访问外部服务(例如MySQL 或MongoDB)。这具有让容器共享主机网络的效果,但它也暴露了 gunicorn 打开的任何端口,这意味着它为客户端留下了绕过反向代理的方法。虽然这一切都在安全网络上的本地服务器上运行,但它似乎不是一个好的安全实践,因为它使后端容易受到拒绝服务攻击。
所以我想我想要两全其美 - 我希望每个(代理,gunicorn)对通过只有他们使用的专用网络相互交谈,同时我将一个端口(例如“5555”)暴露给网络,并且在 gunicorn 下运行的 web 应用程序仍然可以访问同一主机上的其他服务。
我的 nginx.conf 看起来像这样:
http {
upstream app {
server network1_app;
}
server {
location / {
proxy_pass http://app;
}
}
}
我的 docker-compose.yml 可能看起来像:
version: "3"
services:
proxy:
image: nginx:alpine
networks:
- host
- network1
volumes:
./nginx.conf:/etc/nginx/nginx.conf:ro
app:
build: ./app
networks:
- network1
ports: "5555:80" # Do I have to associate this with the "host" network somehow?
networks:
network1:
然后部署这个
docker stack deploy network1 -c docker-compose.yml
我是在正确的道路上,还是我让它太复杂了?完全不使用 Docker 会更直接吗?相反,我可以为此创建命名套接字。
如果可以的话,我喜欢使用 docker-compose,因为它封装了一些细节并使管理更容易(如果它有效的话)。它还为安全漏洞留下了更少的表面。
解决方案
在阅读了这个线程并进行了一些试验和错误之后,我发现问题在于主机 iptables 将请求丢弃到除了端口 22 (ssh) 之外的几乎任何东西。
例如:
$ docker run -it --rm --add-host host.docker.internal:xxx.xxx.xxx.xxx busybox telnet host.docker.internal 27017
超时。
但
$ docker run -it --rm --add-host host.docker.internal:xxx.xxx.xxx.xxx busybox telnet host.docker.internal 22
Connected to host.docker.internal
我可以通过 iptables 中的一个简单规则来克服这个问题:
-A INPUT -i docker0 -j ACCEPT
然后在我的 docker-compose.yaml 中添加一个部分:
extra-hosts:
- "host.docker.internal:xxx.xxx.xxx.xxx"
我暂时推迟了,因为我的项目负责人让我等待。
推荐阅读
- bash - bash 提示:突出显示正在输入的命令
- xampp - 本地主机说:拒绝连接
- mysql - 在 laravel 查询构建器上的 mysql 上使用变量,例如句子
- python - 可编辑微调器
- python - Kivy 弹出确认删除列表视图项目
- cucumber-jvm - 看起来 cucumber-jvm 并行和万能插件配置有问题
- makefile - 构建超级账本结构时出错:goshim.tar.bz2 中的“bzip2 数据创建错误”
- mongodb - 从特定父记录中删除子记录
- java - 在一个类中查找文件并在另一个类中输出/进度条
- rest - HAL 关系类型 (rel) 与链接名称属性