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

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

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

Я предпочел бы динамически генерировать и выбирать имя пула на основе запрошенного имени хоста, а не перечислять каждый пул в операторе 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 и выбрать порт по умолчанию или проигнорировать его?

ОДИН БОЛЬШЕ РЕДАКТИРОВАТЬ

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

1 ответ

Решение

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

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

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

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

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 могут добавлять номер порта, даже если это порт по умолчанию. Простой код может не отправлять заголовок Host. Вредоносный код может отправлять полностью поддельные заголовки Host. Вы можете поймать эти случаи с помощью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

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