Докер - масштабирующийся nginx и php-fpm отдельно

Часть запроса не включена при соответствии URL RewriteRule посмотрите эту часть документов:

Что подобрано?

Шаблон будет первоначально подобран против части URL после имени хоста и порта, и перед строкой запроса. Если Вы хотите соответствовать против имени хоста, порта или строки запроса, используйте RewriteCond с % {HTTP_HOST}, % {SERVER_PORT} или % {QUERY_STRING} переменные соответственно.

Как предложено документами, можно использовать выражение RewriteCond для соответствия на %{QUERY_STRING}:

RewriteCond %{QUERY_STRING} ^option=com_rsform&Itemid=8&lang=en$
RewriteRule ^index.php$ http://www.index.php

Обратите внимание, что это только работает, когда строка запроса является точно той, Вы соответствуете. Эквивалентная строка запроса, в которой порядок аргументов изменяется, f.i. option=com_rsform&lang=en&Itemid=8, не будет подобран. Так в этом случае я думаю, что Вы были бы лучше, чтобы отправить все запросы к Вашему Сценарию PHP и иметь тот взгляд на $_GET и решите, передать ли или нет.

11
задан 21 May 2015 в 01:26
5 ответов

Одно решение состоит в том, чтобы добавить, что дополнительные php-fpm экземпляры Вашему докеру - составляют файл и затем используют nginx в восходящем направлении, как упомянуто в других ответах на баланс загрузки между ними. Это сделано в этом докере в качестве примера - составляют repo: https://github.com/iamyojimbo/docker-nginx-php-fpm/blob/master/nginx/nginx.conf#L137

upstream php {
    #If there's no directive here, then use round_robin.
    #least_conn;
    server dockernginxphpfpm_php1_1:9000;
    server dockernginxphpfpm_php2_1:9000;
    server dockernginxphpfpm_php3_1:9000;
}

Это не действительно идеально, потому что он потребует изменения конфигурации nginx и докера-compose.yml, когда Вы захотите увеличиться или вниз.

Примечание, что 9 000 портов являются внутренними к контейнеру и не Вашему фактическому хосту, таким образом, не имеет значения, что у Вас есть несколько php-fpm контейнеров на порте 9000.

Докер приобрел Tutum этой осенью. У них есть решение, которое комбинирует контейнер HAProxy с их API для автоматической корректировки конфигурации подсистемы балансировки нагрузки к рабочим контейнерам, это - выравнивание нагрузки. Это - хорошее решение. Затем nginx указывает на имя хоста, присвоенное подсистеме балансировки нагрузки. Возможно, Докер далее интегрирует этот тип решения в их инструменты после приобретения Tutum. Существует статья об этом здесь: https://web.archive.org/web/20160628133445/https://support.tutum.co/support/solutions/articles/5000050235-load-balancing-a-web-service

Tutum в настоящее время является заплаченным сервисом. Владелец ранчо является проектом с открытым исходным кодом, который обеспечивает подобную функцию выравнивания нагрузки. У них также есть "владелец-ранчо-compose.yml", который может определить выравнивание нагрузки и масштабирование сервисной установки в докере-compose.yml. http://rancher.com/the-magical-moment-when-container-load-balancing-meets-service-discovery/ http://docs.rancher.com/rancher/concepts/#load-balancer

ОБНОВЛЕНИЕ 06.03.2017: я использовал проект, названный взаимная блокировка , который работает с Докером, чтобы автоматически обновить конфигурацию nginx и перезапустить ее. Также посмотрите @iwaseatenbyagrue ответ , который имеет дополнительные подходы.

5
ответ дан 20 November 2019 в 23:44

В случае, где Ваш Nginx и php-fpm контейнеры находятся на том же хосте, Вы можете настроить маленькое экземпляр dnsmasq на хосте, который будет использоваться контейнером Nginx и запускаете скрипт для автоматического обновления записи DNS, когда IP-адрес контейнера изменился.

я записал маленький сценарий , чтобы сделать это (вставляемый ниже), которые автоматически обновляют запись DNS, которая имеет то же имя как имя контейнеров и указывает на них на IP-адреса контейнеров:

#!/bin/bash

# 10 seconds interval time by default
INTERVAL=${INTERVAL:-10}

# dnsmasq config directory
DNSMASQ_CONFIG=${DNSMASQ_CONFIG:-.}

# commands used in this script
DOCKER=${DOCKER:-docker}
SLEEP=${SLEEP:-sleep}
TAIL=${TAIL:-tail}

declare -A service_map

while true
do
    changed=false
    while read line
    do
        name=${line##* }
        ip=$(${DOCKER} inspect --format '{{.NetworkSettings.IPAddress}}' $name)
        if [ -z ${service_map[$name]} ] || [ ${service_map[$name]} != $ip ] # IP addr changed
        then
            service_map[$name]=$ip
            # write to file
            echo $name has a new IP Address $ip >&2
            echo "host-record=$name,$ip"  > "${DNSMASQ_CONFIG}/docker-$name"
            changed=true
        fi
    done < <(${DOCKER} ps | ${TAIL} -n +2)

    # a change of IP address occured, restart dnsmasq
    if [ $changed = true ]
    then
        systemctl restart dnsmasq
    fi

    ${SLEEP} $INTERVAL
done

Затем запустите свой nginx контейнер с --dns host-ip-address, где host-ip-address IP-адрес хоста в интерфейсе docker0.

Ваш конфигурация Nginx должна разрешить имена динамично:

server {
  resolver host-ip-address;
  listen 80;
  server_name @server_name@;
  root /var/www/@root@;
  index index.html index.htm index.php;

  location ~ ^(.+?\.php)(/.*)?$ {
    try_files $uri =404;
    include fastcgi_params;
    fastcgi_param SCRIPT_FILENAME $document_root$1;
    set $backend "@fastcgi_server@";
    fastcgi_pass $backend;
  }
}

Ссылки:

, Если Ваш nginx и php-fpm находятся на различных хостах, можно попробовать ответ @smaj.

0
ответ дан 20 November 2019 в 23:44

Можно использовать восходящий поток для определения нескольких бэкендов, как описано здесь:

https://stackoverflow.com/questions/5467921/how-to-use-fastcgi-next-upstream-in-nginx

Вы также хотели бы обновить конфигурацию каждый раз, когда новые бэкенды умирают/входят сервис с чем-то как:

https://github.com/kelseyhightower/confd

1
ответ дан 20 November 2019 в 23:44

Другой подход мог бы быть должен изучить что-то как шаблон консула .

И конечно, в какой-то момент, Kubernetes, возможно, должен быть упомянут.

Однако Вы могли считать немного больше 'битами строки и клейкой ленты' подход путем взгляда на то, что потребление событий докера могло сделать для Вас (работайте docker events --since 0 за быстрым образцом).

Это было бы довольно тривиально, чтобы иметь сценарий, смотрящий на эти события (принимающий во внимание, что существует несколько клиентских доступных пакетов, включая для Python, пойдите, и т.д.), исправляя файл конфигурации, и перезагружая nginx (т.е. с помощью подхода шаблона консула, но без потребности в консуле).

Для возвращения к исходной предпосылке, хотя: пока Ваши php-fpm контейнеры запускаются со своей собственной сети (т.е. не совместное использование того из другого контейнера, такого как nginx один), затем у Вас может быть столько контейнеров, слушающих на порте 9000, сколько Вы хотите - поскольку у них есть дюйм/с на контейнер, нет никакой проблемы с портами 'столкновения'.

, Как Вы масштабируетесь, это будет, вероятно, зависеть от того, какова Ваша конечная цель/use-case, но одна вещь, которую Вы могли бы рассмотреть, помещает HAproxy между nginx и Вашими php-fpm узлами. Одна вещь, которую это могло позволить Вам делать, просто назначают диапазон (и возможно создайте docker network) для Ваших php-fpm серверов (т.е. 172.18.0.0/24), и имеют HAproxy, настроенный, чтобы попытаться использовать любой IP в том диапазоне как бэкенд. Так как HAproxy имеет проверки состояния, он мог быстро определить, какие адреса живы, и используют их.

Видят https://stackoverflow.com/questions/1358198/nginx-removing-upstream-servers-from-pool для дискуссии о том, как nginx по сравнению с haproxy имеет дело с восходящими потоками.

, Если Вы не использовали специализированную сеть докера для этого, Вы могли бы потребность сделать некоторое ручное управление IP для Ваших php-fpm узлов.

0
ответ дан 20 November 2019 в 23:44

Хотя это сообщение с 2015, и я чувствую, что я - некролуг (жаль сообщество), я чувствую, что ценно добавить в данный момент:

В наше время (и так как Kubernetes был упомянут), когда Вы работаете с Докером, можно использовать Kubernetes или Docker Swarm очень легко для решения этой проблемы. Оба дирижера возьмут в Ваших узлах докера (один узел = один сервер с Докером на нем), и можно развернуть сервисы для них, и они будут управлять проблемами порта для Вас использующий оверлейные сети.

, Поскольку я являюсь более сведущим в Рое Докера, это - то, как Вы сделали бы это для приближения к этой проблеме (предполагающий, что у Вас есть единственный узел Докера):

Инициализируют рой:

docker swarm init

CD в Ваш корень проекта

cd some/project/root

создает стопку роя от Вашего докера-compose.yml (вместо того, чтобы использовать докера - сочиняют):

docker stack deploy -c docker-compose.yml myApp

Это создаст сервисную стопку роя докера, названную "myApp", и будет управлять портами для Вас. Это означает: только необходимо добавить один "порт: 9000:9000" определение Вашему php-fpm сервису в Вашем докере - составляет файл, и затем можно увеличить масштаб php-fpm сервиса, сказать 3 экземплярам, в то время как рой будет автоволшебно баланс загрузки запросы между этими тремя экземплярами без дальнейшей необходимой работы.

0
ответ дан 20 November 2019 в 23:44

Теги

Похожие вопросы