Перенос docker-compose на кластер docker-swarm с одним узлом

На данный момент я реализовал фляжное приложение, связанное с базой данных mysql, и вся реализация работает на одном веб-сервере.

Чтобы не раскрывать свое приложение публично, я запускаю его на локальном интерфейсе сервера и открываю только общедоступный интерфейс (порт 443) через haproxy, который перенаправляет трафик на интерфейс localhost.

Конфигурацию docker-compose и haproxy можно найти ниже

докер-составить:

version: '3.1'

services:

  db:
    image: mysql:latest
    volumes:
      - mysql-volume:/var/lib/mysql
    container_name: mysql
    ports:
      - 127.0.0.1:3306:3306
    environment:
            MYSQL_ROOT_PASSWORD: xxxxxx

  app:
    #environment:
    #  - ENVIRONMENT=stage
    #  - BUILD_DATETIME=$(date +'%Y-%m-%d %H:%M:%S')
    build:
      context: .
      dockerfile: Dockerfile
      #labels:
      #  - "build_datetime=${BUILD_DATETIME}"
    container_name: stage_backend
    ports:
      - 127.0.0.1:5000:5000

volumes:
  mysql-volume:
    driver: local

пример конфигурации haproxy:

global
        log /dev/log    local0
        log /dev/log    local1 notice
        # Default SSL material locations
        ca-base /etc/ssl/certs
        crt-base /etc/ssl/private
defaults
        log     global
        mode    http
        option  httplog
        option  dontlognull
        timeout connect 10s
        timeout client  30s 
        timeout server  30s

frontend test
        bind *:80
        bind *:443 ssl crt /etc/letsencrypt/live/testdomain.com/haproxy.pem alpn h2,http/1.1
        redirect scheme https if !{ ssl_fc }
        mode http
        acl domain_testdomain hdr_beg(host) -i testdomain.com
        use_backend web_servers if domain_testdomain

backend web_servers
        timeout connect 10s
        timeout server 100s
        balance roundrobin
        mode http
        server test_server 127.0.0.1:5000 check


Таким образом, haproxy работает на общедоступном интерфейсе как служба через systemd (не в контейнерах), а контейнеры работают на локальном хосте.

Вскоре это станет производственной установкой, поэтому я хочу развернуть кластер Docker Swarm с одним узлом только на этом сервере, поскольку реализация Docker Swarm более безопасна в производственной среде.

Мой вопрос в том, как я могу развернуть это на рое докеров.

  • Есть ли смысл оставить haproxy в качестве службы systemd и как-то заставить его перенаправлять запросы в кластер docker swarm?

  • Является ли более простой/лучшей реализацией также контейнеризация haproxy и размещение ее внутри кластера в качестве службы создания докеров?

Если я буду следовать второму подходу, как мне заставить его работать на интерфейсе, отличном от интерфейса приложения (haproxy --> public, flask & db --> localhost)

Опять же, я говорю здесь об одном сервере, поэтому я пытаюсь разделить сетевые интерфейсы и выставлять haproxy только на 443 на общедоступном интерфейсе.

В идеале я не хотел переходить с haproxy на обратный прокси-сервер nginx, так как я знаком с ним и с тем, как именно там работает завершение ssl, но я открыт для любой другой реализации, которая имеет больше смысла.

Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Развертывание модели машинного обучения с помощью Flask - Angular в Kubernetes
Kubernetes - это портативная, расширяемая платформа с открытым исходным кодом для управления контейнерными рабочими нагрузками и сервисами, которая...
Как создать PHP Image с нуля
Как создать PHP Image с нуля
Сегодня мы создадим PHP Image from Scratch для того, чтобы легко развернуть базовые PHP-приложения. Пожалуйста, имейте в виду, что это разработка для...
1
0
65
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Кажется, вы слишком много думаете о вещах и в процессе отбрасываете функции безопасности, которые предлагает докер.

во-первых, Docker предоставляет вам частную сеть из коробки как в режиме создания, так и в режиме роя. создается неявная сеть с именем <stack>_default, и к ней присоединяются службы, а разрешение DNS настраивается в каждом контейнере для разрешения каждого имени службы.

Итак, если ваше приложение и база данных не объявляют явно какие-либо сети, тогда применяются следующие неявные объявления, и ваше приложение может напрямую подключаться к базе данных, используя строку подключения mysql://db:3306.

Контейнеру db не нужно ни публиковать, ни пытаться защитить доступ к этому порту, доступ будут иметь только другие контейнеры, подключенные к сети [stack_]default.

networks:
  default: # implicit

services:
  app:
    networks:
      default: # implicit
    environment:
      MYSQL: mysql://db:3306 #

  db:
    networks:
      default: # implicit

На данный момент вам решать, запускать HAProxy как службу или нет. Лично я бы (сделал). В рое удобно иметь единую службу, которая обрабатывает вход :80 и :443, выполняет разгрузку, а затем использует сети докеров для направления трафика к другим службам на любом сервисе: порты обрабатывают эти соединения.

Я использую Traefik, а не HAProxy, так как он может использовать сервисные метки для динамической маршрутизации трафика, но в любом случае наличие HAProxy в качестве сервиса означает, что если вы продолжите его использовать, вам будет проще развертывать обновления конфигурации HAProxy.

Большое спасибо за ответ, немного прояснил ситуацию. Если я использую haproxy в качестве службы, и она не является частью кластера, сможет ли он разрешить каждый запущенный экземпляр контейнера приложения, просто указав имя контейнера в конфигурации haproxy?

csuser 27.01.2023 08:35

Если он работает как служба докеров И подключен к тем же сетям докеров, то он может использовать разрешение DNS докеров для разрешения имен служб.

Chris Becke 27.01.2023 09:54

Спасибо за быстрый ответ. Дело в том, что я хочу запустить haproxy на другом сетевом интерфейсе, чем будут работать контейнеры. Как я уже упоминал, у меня есть только 1 сервер, и я хочу запустить haproxy на общедоступном интерфейсе (чтобы быть доступным из Интернета) и контейнеры на локальном хосте (чтобы не открывать их общедоступному Интернету). Как это можно сделать?

csuser 27.01.2023 12:42

Как я уже сказал - вы слишком много думаете об этом. Docker обеспечивает такую ​​безопасность за счет виртуализации сетевых интерфейсов, и вы просто вообще не привязываете серверные службы к физическому интерфейсу. Если вы войдете в контейнер, вы увидите, что сеть по умолчанию соответствует устройству «eth0», имеющему частный IP-адрес. Docker создает эти vxlan с использованием правил iptables и может создавать многие из них, позволяя стекам сервисов, совместно размещенным на одном физическом хосте, иметь изолированные сети, которые другие стеки не могут перехватывать, не говоря уже о других сетевых хостах.

Chris Becke 27.01.2023 13:05

Другие вопросы по теме