Кластеризация Oracle Identity Management

О кластеризации IDM было уже сказано не раз, подборку материалов по этой теме можно найти в конце статьи. Я же хочу далее обратить внимание на практическую сторону вопроса. Да, во всех встречавшихся мне документах достаточно подробно и широко рассмотрены многочисленные вопросы обеспечения HA для продуктов Fusion Middleware, в общем, и Identity management, в частности. Однако же им не хватает деталей конкретной реализации: как заставить все перечисленные отдельные HA компоненты работать совместно?

Ниже описано, как все это работает в нашей картине мира на кластере из нескольких серверов в разных ДЦ.

Об архитектуре системы

Я не буду описывать, как конкретно кластеризуется каждый из компонентов: для этого есть документация. Проблема обеспечения отказоустойчивости состоит в том, что необходимо каким-то образом связать разнородные компоненты (ldap сервера, java приложения, web-сервера на apache) так, чтобы автоматически о выходе из строя одного из них узнавали все элементы мозаики и больше к нему не обращались. Ключевое архитектурное решение здесь – использовать для общения с любым компонентом, даже внутри системы, балансеры. В документации также есть явное упоминание этого: “All components in the Oracle Identity Management software stack require a hardware load balancer when deployed in a high availability configuration”. Единственное, что не так в этой цитате – использование hardware балансировщиков. В действительности нет необходимости приобретать какое-то дополнительное оборудование, со всем задачами справляются software решения.  У нас это были OHS, haproxy и nginx. Каждый для своего компонента и со своим набором фич. С одной стороны, это решило проблему связей между компонентами: ходи в балансер и не думай о том, что там с риал-серверами за ним. С другой стороны, позволило выбирать способы определения живости сервера в зависимости от его свойств. Например, web-сервер может быть вполне себе живой формально, но при этом отдавать на любой запрос HTTP 500-ю ошибку.

Для начала стандартная картинка, какие компоненты участвуют в процессе аутентификации пользователя в OeBS:

datafloweagРис. Потоки запросов процесса аутентификации пользователя OeBS

На этой картинке каждый компонент должен быть задублирован, а каждая стрелка потока данных должна идти через балансер. Часть компонентов инфраструктуры уже были кластеризованы и исходная диспозицция была такова:

  1. Oracle Database – RAC из 2-х Node
  2. EBS Applicaton – Кластер из 2-х Node
  3. Пользователи ходят через внешний балансер, так что проблемы маршрутизации и доступности сервиса на уровне TCP/IP нас не волнуют.

Общение Webgate с кластером серверов AccessGate

AccessGate – приложение java в контейнере weblogic, Webgate – модуль для Apache совместно с модулем OHS. Так что здесь делаем все по стандартной схеме:

  • Заводим NodeManager
  • Создаем Weblogic cluster
  • В конфигах модуля каждого webgate прописываем настройки кластера AccessGate:

<Location /ebsauth_OEBS>
SetHandler weblogic-handler
WebLogicCluster server1:7043,server2:7043
RequestHeader set IS_SSL ssl
WLProxySSL on
</Location>

Общение webgate с кластером OAM

OAM, как и AccessGate – приложение java в контейнере weblogic, так что, подобно accessgate, приложение устанавливается в кластер weblogic. И, как у любого сервера weblogic, для него можно задать номера HTTP/HTTPS портов. Однако же эти порты предназначеня для общения с внешним миром. Номера портов для общения с webgate другие и прописываются в конфиге OAM. Очевидно, OHS для доступа использоваться не может, и все адреса машин кластера OAM прописываются в настройках webgate – файле ObAccessClient.xml, а за работу в кластерной конфигурации отвечает сам webgate. Проблем с этим нет и все работает “из коробки”.

<ValNameList
xmlns="http://www.oblix.com"
ListName="primaryServer1">
<NameValPair
ParamName="host"
Value="server1"></NameValPair>
<NameValPair
ParamName="port"
Value="5574"></NameValPair>
<NameValPair
ParamName="numOfConnections"
Value="1"></NameValPair>
</ValNameList>
<ValNameList
xmlns="http://www.oblix.com"
ListName="primaryServer2">
<NameValPair
ParamName="host"
Value="server2"></NameValPair>
<NameValPair
ParamName="port"
Value="5574"></NameValPair>
<NameValPair
ParamName="numOfConnections"
Value="8"></NameValPair>
</ValNameList>

Общение пользователей и кластера OeBS с Webgate и OAM

Для всех внешних систем компонены кластера IDM представляют собой комплект web-серверов. Общение с ними может осуществляться как через OHS (о настройке accessgate было выше, о дополнительных шагах для OAM можно почитать в пункте 9.2.3.12 Configure Access Manager to Work with Oracle HTTP Server), так и через внешние балансеры. Мы использовали внешний балансер nginx, в основном по причинам:

  1. Историческим, есть готовая развитая инфраструктура: мониторинг, примеры конфигов, опыт использования.
  2. Диагностическим: nginx позволяет вести расширенные логи и отслеживать процесс общения клиента и сервера
  3. Функциональным: в upstream модуле nginx возможно контролировать способы определения доступности сервера на основе анализа его кодов ответа, а также управлять балансировкой. На старте проекта это позволило диагностировать и найти workaround части критичных ошибок среды. Сейчас все беды в прошлом, но знайте, если вы ставите Patch 17602754 – RACING CONDITION DURING LOING LEADS TO DEADLOCK – это то, что очень нам досаждало

Требований к балансеру достаточно много (3.4.1 Load Balancer Requirements), но ключевое его свойство – обеспечение Sticky routing capability. На старте проекта мы потратили достаточно много времени, пытаясь понять причину множества невразумительных ошибок и падений процесса аутентификации в самых неожиданных местах. Оказалось, что OHS, а вместе с ними webgate и OAM, весьма чувствителен к процессу аутентификации. Т.е. ничего страшного не произойдет, если через некоторое время клиент придет на другой сервер. Однако же первые несколько GET запросов HTTP в процессе аутентификации сессии должны придти на один и тот же сервер. Т.е. честный round robin get запросов не работает.
Описание оказалось длинее, чем реальный конфиг nginx, который в действительности тривиален, пример для webgate:

upstream webgate {
ip_hash;
server server1:2444 max_fails=10 fail_timeout=120;
server server2:2444 max_fails=10 fail_timeout=120;
}

server {
listen *:2443;
server_name webgate;

set $remote_protocol “https”;
ssl on;

location / {
proxy_pass $remote_protocol://$host;
proxy_set_header Host $host;
}
}

В конфиге мы не стали делать SSL Offloading, сейчас сервис этого не требует.
Общение Webgate и баз данных с OVD и OID
В вопросе балансировки ldap-запросов нас поджидала аналогичная предыдущему пункту диллема: использовать native средства или же проверенное сторонее решение? Аналогичным образом, решение было принято в пользу стороннего решения на базе haproxy. Решающим моментом здесь стало следующее соображение. Когда строится HA решение, всегда нужно учитывать, что любой компонент может выйти из строя. Что в таком случае прописывать в качестве IP-адреса сервера? Для клиентского доступа используется IPVS, но использовать его для связности компонент внутри системы представляется overkill. Остается localhost, т.е. каждый хост должен иметь свой собственный балансер. Устаналивать на каждый из них native средства – опять же, чрезмерно сложно. Учитывая, что для OeBS нам нужен enterprise user security и в oracle virtual directory будут ходить также все ноды real application cluster. В результате, лучшим решением стал haproxy, слушающий localhost, на каждом хосте в простейшей конфигурации:

listen OID :3061
mode tcp
option tcplog
log 127.0.0.1 local3 info
server server2 server2:3060 check
server server1 server1:3060 check backup

listen OIDS :3132
mode tcp
option tcplog
log 127.0.0.1 local3 info
server server2 server2:3131 check
server server1 server1:3131 check backup

listen OVD :6502
mode tcp
option tcplog
log 127.0.0.1 local3 info
server server2 server2:6501 check
server server1 server1:6501 check backup

Общение компонентов с БД и OeBS
Это оказалось сделать проще всего 🙂 Просто используется SCAN-адрес и адрес балансера OeBS.

Список полезной документации
1. Identity Management for Fusion Applications Reference Architecture http://www.ateam-oracle.com/identity-management-for-fusion-applications-reference-architecture

2. Long-lived TCP connections and Load Balancers http://www.ateam-oracle.com/long-lived-tcp-connections-and-load-balancers

3. Hostname References and Architecture Simplification in the IDM Build Out for Fusion Apps http://www.ateam-oracle.com/hostname-references-and-architecture-simplification-in-the-idm-build-out-for-fusion-apps/

4. Oracle® Fusion Middleware High Availability Guide 11g Release 2 (11.1.2), section 9 Configuring High Availability for Identity and Access Management Components http://docs.oracle.com/cd/E27559_01/doc.1112/e28391/iam.htm

5. Oracle® Fusion Middleware Enterprise Deployment Guide for Oracle Identity Management 11g Release 2 (11.1.2) http://docs.oracle.com/cd/E27559_01/admin.1112/e28212/toc.htm

Advertisements
Кластеризация Oracle Identity Management

3 thoughts on “Кластеризация Oracle Identity Management

  1. Ivan says:

    Извините, не совсем понятно. Узел каждого кластера находился в своем ЦОДе или каждый компонент кластеризовался в своем ЦОДе, а затем обращался к другим (кластеризованным) компонентам в другом ЦОДе? То есть, например OEBS-кластер работал в ЦОД1, а пользователи хранились с OID в ЦОД2?

    1. OeBS – это отдельный разговор 🙂 А компоненты IDM (сервера weblogic, OID) да, кластеризуется между разными ЦОД, т.е. есть 3 экземпляра OID по одному в каждом ДЦ.
      Однако всё равно, такая кластеризация не позволяет построить систему, полностью независимую от вылета целого ДЦ.
      Во-первых, для работы компонентов нужен экземпляр Oracle, а его между разными ЦОД размазать нельзя. И хотя вся система отлично переживает ситуацию failover (http://yandblogs.wordpress.com/2014/04/10/%D0%BA%D0%B0%D0%BA-%D0%B2%D0%B5%D0%B4%D0%B5%D1%82-%D1%81%D0%B5%D0%B1%D1%8F-standby-%D0%BF%D0%BE%D1%81%D0%BB%D0%B5-failover-primary-database/), все равно это ручные действия.
      Во-вторых, разные компоненты по-разному переживают потерю одного из ЦОД. Например, OAM. Представим ситуацию, ЦОД1 с OAM потерял связность с другими ДЦ и БД. Через некоторое время этому OAM становится плохо и на любой запрос он начинает писать java stack trace в свой out-файл, а клиенту отдавать страницу с ошибкой. Когда связность между ДЦ восстанавливается, часть клиентов начинает попадать на сломаный OAM и на любое своё действие получают ошибку. Это лечится либо автоматическим остановом OAM при пропадании связности либо, опять же, ручным презапуском.
      Тем не менее, даже эти ручные действия в правильной архитектуре занимают минуты, а часть ошибок отрабатываются автоматически. При этом эти ЦОД – реально географиески распределены, каждый имеет свой диапазон IP-адресов.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s