f5 LTM irule — можно ли сгенерировать имя пула в irule

Мне нужно настроить конфигурацию для многих подобных сред. У каждого будет свое имя хоста, которое следует шаблону, например. env1, env2 и т. д.

Я могу использовать пул для каждой среды и один виртуальный сервер с правилом, которое выбирает пул на основе имени хоста.

Я бы предпочел динамически генерировать и выбирать имя пула на основе запрошенного имени хоста, а не перечислять каждый пул в операторе switch. Его легче поддерживать, и он автоматически обрабатывает новые среды.

Код может выглядеть так:

when HTTP_REQUEST {
  pool [string tolower [HTTP:host]]
}

и имя каждого пула соответствует имени хоста.

Это возможно? Или есть лучший метод?

ИЗМЕНИТЬ

Я расширил свой выбор пула имен хостов. Сейчас я пытаюсь включить номер порта. Новое правило выглядит так:

when HTTP_REQUEST {
  set lb_port "[LB::server port]"
  set hostname "[string tolower [getfield [HTTP::host] : 1]]"
  log local0.info "Pool name $hostname-$lb_port-pool"
  pool "$hostname-$lb_port-pool"

}

Это работает, но я вижу в журналах ошибки отсутствия такого пула, потому что каким-то образом в пул поступает запрос порта 0. Кажется, это первый запрос, а за ним следует запрос с легитимным портом.

Wed Feb 17 20:39:14 EST 2016    info    tmm tmm[6519]       Rule /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST>: Pool name my.example.com-80-pool
Wed Feb 17 20:39:14 EST 2016    err tmm1    tmm[6519]   01220001    TCL error: /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST> - no such pool: my.example.com-0-pool (line 1) invoked from within "pool "$hostname-$lb_port-pool""
Wed Feb 17 20:39:14 EST 2016    info    tmm1    tmm[6519]       Rule /Common/one-auto-pool-select-by-hostname-port <HTTP_REQUEST>: Pool name my.example.com-0-pool

Что вызывает запрос порта 0? И есть ли обходной путь? например Могу ли я проверить порт 0 и выбрать порт по умолчанию или игнорировать его?

ЕЩЕ ОДНА ПРАВКА

Пересобрал виртуальный сервер, теперь ошибка ушла. Однако перестройка VS заключалась в том, чтобы просто переименовать его. Я почти уверен, что воссоздал настройки точно так же.


person dachiz    schedule 09.02.2016    source источник


Ответы (2)


Да, вы можете указать имя пула в строке. То, что у вас есть, будет работать, пока у вас есть пул с таким же именем. Хотя здесь нет примера такого способа, вы также можете проверить пул вики-страницу на DevCentral для получения дополнительной информации.

Кроме того, в моей среде я обычно создаю пулы с суффиксом _pool, чтобы отличать их от других объектов при просмотре файлов конфигурации. Итак, в своих iRules я бы сделал что-то вроде этого (по сути то же самое):

when HTTP_REQUEST {
    pool "[string tolower [HTTP::host]]_pool"
}
person Michael    schedule 10.02.2016

Простой случай, упомянутый Майклом, работает. Я бы рекомендовал удалить значение порта, если оно присутствует:

when HTTP_REQUEST {
    pool "pool_[string tolower [getfield [HTTP::host] : 1]]_[LB::server port]"
}

Имейте в виду, что клиенты могут отправлять частичное имя хоста. Если путь поиска DNS установлен на example.org, то клиент может нажать shared/, который сопоставляется с shared.example.org, но в заголовке HTTP::host будет просто shared. Некоторые библиотеки API могут добавлять номер порта, даже если он находится на порту по умолчанию. Простой код может не отправлять заголовок узла. Вредоносный код может отправлять полностью фиктивные заголовки хоста. Вы можете отловить эти случаи с помощью catch.

Вы также можете использовать группу данных для сопоставления имен хостов с пулами. Это позволяет нескольким хостам использовать один и тот же пул. Образец кода:

when HTTP_REQUEST {
    set host [string tolower [getfield [HTTP::host] ":" 1]]
    if { $host == "" } {
        # if there's no Host header, pull from virtual server name
        # we use: pool_<virtualserver>_PROTOCOL
        set host [getfield [virtual name] _ 2]
    } elseif { not ($host contains ".") } {
        # if Host header does not contain a dot, assume example.org
        set host $host.example.org
    }
    set pool [class match -value $host[HTTP::uri] starts_with dg_shared.example.org]
    if { $pool ne ""} {
        set matched [class match -name $host[HTTP::uri] starts_with dg_shared.example.org]
        set log(matched) $matched
        set log(pool) $pool
        if { [catch { pool $pool } ] } {
            set log(reason) "Failed to Connect to Pool"
            call hsllog log
            call errorpage 404 $log(reason) "https://[HTTP::host][HTTP::uri]" log
        }
    } else {
        call errorpage 404 "No Pool Found" "https://[HTTP::host][HTTP::uri]" log
    }
}

when SERVER_CONNECTED {
    if {!($pool ends_with "_HTTPS") } {
        SSL::disable serverside
    }
}

Это позволяет host.example.org/path1 находиться в другом пуле, чем host.example.org или host.example.org/path2, путем включения отдельных записей в группу данных. Я не включил здесь процессы hsllog и errorpage. Они выгружают массив журналов, а также другие переданные параметры.

Затем мы отключаем ssl на стороне сервера для пулов, которые не заканчиваются на _HTTPS.

Примечание. Как и в случае с динамически генерируемыми именами пулов, пользовательский интерфейс BIG-IP не ищет внутри групп данных ссылки на пулы, поэтому интерфейс позволяет удалить один из этих пулов, думая, что он не используется.

Мы используем BigIPReport для выявления потерянных пулов: https://devcentral.f5.com/s/articles/bigip-report

person Tim Riker    schedule 27.08.2019