На локальном сервере я запустил несколько экземпляров gunicorn, каждый из которых запускал разные веб-приложения на уникальном порте в качестве службы для остальной части внутренней сети. Теперь я хочу разместить каждый экземпляр Gunicorn за собственным обратным прокси-сервером nginx для лучшей балансировки нагрузки.
Я решил попробовать развернуть каждую пару (nginx, gunicorn) в собственном контейнере Docker, открывая для внешнего мира только ее уникальный порт. Я знаю, что с переадресацией портов это достаточно просто - например, «5555: 80». Однако каждое приложение также обращается к внешним службам, таким как базы данных, которые работают на одном узле независимо от Docker.
Путем проб и ошибок я обнаружил, что контейнер Docker может получить доступ к внешней службе (например, MySQL или MongoDB), только если я запускаю его как «docker run --network = host. .. ». Это дает возможность контейнеру совместно использовать хост-сеть, но также предоставляет доступ к любым открытым портам, что означает, что он оставляет возможность клиенту обойти обратный прокси-сервер. Хотя все это выполняется на локальном сервере в защищенной сети, это не кажется хорошей практикой безопасности, поскольку оставляет внутреннюю часть открытой для атак типа «отказ в обслуживании».
Итак, я думаю, мне нужно лучшее из обоих миров - я хочу, чтобы каждая пара (прокси, пулеметчик) разговаривала друг с другом по частной сети, которую используют только они, в то время как я открываю один порт (например, «5555» ) в сеть, а веб-приложение, работающее под управлением Gunicorn, по-прежнему может получать доступ к другим службам на том же хосте.
Мой 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, если я могу, потому что он инкапсулирует некоторые детали и упрощает управление (если это работает). Это также оставляет меньше места для нарушения безопасности.