Хмарний напій з Oracle Database, Helidon, Coherence та Kubernetes — Частина 9: Архітектура для високої доступності

Тепер, коли ми майже завершили налаштування всієї інфраструктури та елементів додатку, і наш додаток працює, давайте розглянемо, як спроектувати систему для забезпечення високої доступності. Наш Святий Грааль — це те, щоб не було єдиної точки відмови.

pic

Індіана Джонс з Святим Граалем

Тепер, якщо ми проаналізуємо нашу архітектуру нижче:

pic

ми можемо визначити 4 основні зони відмови:

  1. Дані
  2. Мікросервіси
  3. Інфраструктура додатку та хмарна інфраструктура
  4. Хмарний регіон

Ми збираємося розглянути кожну з цих зон. Зазначимо, що багато з них ми вже обговорювали раніше. Для тих, що ми вже розглядали докладніше, ми просто надамо інструкції з посиланнями на детальні пояснення, і ви зможете звертатися до них у зручний для вас час.

Обов'язкові умови: 2 регіони

Відмови регіонів — це рідкісні та надзвичайні події. У хмарі Oracle є багато рівнів резервування, вбудованих для забезпечення доступності: від зон доступності та зон відмов до резервованого живлення і мережі, від апаратного забезпечення до програмного та патчів — хмара Oracle пропонує серйозну стійкість. Однак є клієнти, які вимагають, щоб їхні робочі навантаження були стійкими навіть за межами місцевих географічних районів, іноді для виконання регуляторних вимог або через просто фізичний страх перед законами Мерфі.

Це неминуче означає запуск робочих навантажень хоча б у 2 окремих регіонах. Для цілей цієї статті ми будемо використовувати лише 2 регіони: Сідней (c1) і Мельбурн (c2), 2 кластери OKE та 2 екземпляри Oracle Autonomous DB.

Розглянемо кожен з етапів.

Налаштування аварійного відновлення для Oracle Autonomous DB

Oracle Autonomous DB ще не працює в активному-активному режимі між регіонами. Але за кілька кліків або кілька рядків коду Terraform ви можете вибрати пірингові регіони, де запускати інстанс аварійного відновлення для вашої Autonomous DB. Коли ви налаштовуєте базу даних-standby через Autonomous Data Guard, вона автоматично реплікує дані до цільових регіонів.

Перейдіть на сторінку екземпляра Autonomous DB, і в лівому меню ви побачите розділ "Disaster Recovery" (Аварійне відновлення). Клікніть на нього, а потім натисніть "Add Peer Database" (Додати пірингову базу даних). Вам буде запропоновано вибрати Peer Region (Піринговий регіон):

pic

Вибір пірингового регіону для аварійного відновлення Autonomous DB

Залежно від розміру вашої бази даних, цей процес може зайняти від кількох хвилин до кількох годин. Оскільки ми створили нову базу даних для цієї статті, процес створення та синхронізації пірингової бази даних повинен зайняти лише кілька хвилин.

Створення основної інфраструктури для 2 кластерів OKE

Тим часом створіть 2 кластери OKE та пірингуйте їхні VCN. Ви можете використати приклад для мульти-кластерів в Terraform OKE модулі для створення інфраструктури та кластерів. Remote Peering Connections (RPC) вже будуть створені за вас, і все, що вам потрібно зробити, це встановити з'єднання між ними.

Для більш детального пояснення читайте мій попередній пост про це.

Після того, як ви підключите VCN, інфраструктура виглядатиме наступним чином:

pic

Підключені VCN

VCN підключено, і трафік може бути спрямований між ними.

Clustermesh з Cilium

Наступний крок вимагає використання Cilium CNI з OKE.
Якщо ви використовуєте покращені кластери OKE, тепер ви також можете відключити встановлення flannel, додавши наступне в кожну дефініцію модуля:

cluster_addons_to_remove = {  
 Flannel = {  
 remove_k8s_resources = true  
 },  
 KubeProxy = {  
 remove_k8s_resources = true  
 }  
}

Метою є можливість запустити розтягнутий кластер Coherence на OKE. Більше про це пізніше.

На цьому етапі ваші кластери мають бути підключені, і ви повинні мати змогу доступатися до подів і сервісів між кластерами:

pic

Підключені кластери OKE з Cilium

Пошук сервісів між кластерами з CoreDNS

Далі, розкрийте сервіс CoreDNS у кожному кластері, використовуючи приватний Network Load Balancer (NLB). Це робиться для того, щоб примусити CoreDNS в кожному кластері виконувати DNS-запити в іншому кластері:

pic

Причина в тому, що ми хочемо, щоб учасники Coherence могли знаходити потенційно існуючих учасників в іншому OKE кластері і створювати єдиний кластер Coherence. Знову ж таки, є детальне пояснення в попередній статті.

З цією налаштуванням ми тепер можемо використовувати CoreDNS для пошуку та виявлення існуючих учасників Coherence в обох OKE кластерах.

Multi-cluster, multi-network, multi-primary Istio

Далі давайте налаштуємо Istio в режимі multi-cluster, multi-network та multi-primary, щоб не було єдиної точки відмови на рівні мікросервісів. Ідея полягає в тому, що якщо запит користувача потрапляє, скажімо, в Сідней, а мікросервіс у Сіднеї зазнає відмови, ми хочемо використовувати можливості керування трафіком Istio (traffic management) та локального балансування навантаження, щоб перенаправити трафік в Мельбурн.

Встановіть Istio в обох кластерах і підключіть їх, щоб сформувати єдину службу mesh:

pic

Служба mesh з multi-cluster, multi-primary, multi-network

Налаштування з'єднання з базою даних для мульти-регіонів

У попередніх статтях, ми використовували Oracle Database Operator для прив'язки кластера OKE до Autonomous Database. Прив'язка бази даних автоматично створює wallet і зберігає його в Kubernetes Secret. Все, що нам залишиться зробити, це переконатися, що наш под змонтував секрет об'єму.

Oracle Net TNS String можна налаштувати для балансування навантаження та відновлення після відмов. Однак наразі є обмеження в тому, як генерується wallet для Autonomous DB. Фактично, коли у Autonomous DB є DR peer (дистанційний партнер по відновленню), wallet вказує тільки на основний екземпляр бази даних, і наразі немає можливості включити опції балансування навантаження та відновлення в згенерований wallet. Поки ми не виправимо це, ми налаштуємо цей крок вручну.

По-перше, завантажте wallet з консолі OCI та витягніть його. Потім відредагуйте файл tnsnames.ora.
За замовчуванням виглядатиме наступним чином:

tasksdb_high = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-sydney-1.oraclecloud.com))(connect_data=(service_name=gaba123456e_tasksdb_high.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))  

tasksdb_low = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-sydney-1.oraclecloud.com))(connect_data=(service_name=gaba123456e_tasksdb_low.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))  

tasksdb_medium = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-sydney-1.oraclecloud.com))(connect_data=(service_name=gaba123456e_tasksdb_medium.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))  

tasksdb_tp = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-sydney-1.oraclecloud.com))(connect_data=(service_name=gaba123456e_tasksdb_tp.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))  

tasksdb_tpurgent = (description= (retry_count=20)(retry_delay=3)(address=(protocol=tcps)(port=1522)(host=adb.ap-sydney-1.oraclecloud.com))(connect_data=(service_name=gaba123456e_tasksdb_tpurgent.adb.oraclecloud.com))(security=(ssl_server_dn_match=yes)))

Для кожного профілю, який ви хочете використовувати, додайте наступне:

tasksdb_${profile} = (description=  
 (failover=on)  
 (retry_count=20)(retry_delay=3)(connect_timeout=120)(transport_connect_timeout=3)  
 (address_list=(load_balance=on)  
 (address=(protocol=tcps)(port=1522)(host=adb.${region_primary}.oraclecloud.com)))  
 (address_list=(load_balance=on)  
 (address=(protocol=tcps)(port=1522)(host=adb.${region_peer}.oraclecloud.com)))  
 (connect_data=(service_name=gaba123456e_tasksdb_${profile}.adb.oraclecloud.com))  
 (security=(ssl_server_dn_match=yes))))

де профіль може бути “high”, “low”, “medium”, “tp” та “tpurgent”, ім’я сервісу — “gaba123456e…” а regionprimary та region_peer відповідають основним та резервним регіонам екземпляра Autonomous DB. Зверніть увагу, що ми додали наступне:

  1. failover=on
  2. список екземплярів ADB, включаючи DR peers
    3.
    load_balance=on

Перед створенням секретів, створіть простір імен (namespace), де ви будете розгортати додаток, і позначте його:

for c in c1 c2; do  
 kubectx $c  
 kubectl create ns todo  
 kubectl label namespace todo istio-injection=enabled  
done

Далі створіть секрети вручну, щоб зберігати wallet у обох кластерах:

export OJDBC=$HOME/database/ojdbc.properties  
export TNSNAMES=$HOME/database/tnsnames.ora  
export SQLNET=$HOME/database/sqlnet.ora  
export CWALLET=$HOME/database/cwallet.sso  
export EWALLET=$HOME/database/ewallet.p12  
export KEYSTORE=$HOME/database/keystore.jks  
export TRUSTSTORE=$HOME/database/truststore.jks  

for c in c1 c2; do  
 kubectx $c  
 kubectl -n todo create secret generic tasksdb-wallet --from-file=ojdbc.properties=$OJDBC --from-file=tnsnames.ora=$TNSNAMES \  
 --from-file=sqlnet.ora=$SQLNET --from-file=cwallet.sso=$CWALLET --from-file=ewallet.p12=$EWALLET --from-file=keystore.jks=$KEYSTORE \  
 --from-file=truststore.jks=$TRUSTSTORE  
done

Аналогічно, створіть конфігураційний файл Hibernate:



 update  

 jdbc:oracle:thin:@tasksdb_medium?TNS_ADMIN=/wallets/task_db  

 task_db_user  

 changeme  

 oracle.jdbc.OracleDriver  

 oracle.jdbc.datasource.impl.OracleDataSource  


 {autoCommit=false}  
 true  
 true  
 120  
 180  
 20  
 30  



І збережіть його в Kubernetes Secret:

export HIBERNATE_CFG_XML=$HOME/todo/hibernate.cfg.xml  
for c in c1 c2; do  
 kubectx $c  
 kubectl -n todo create secret generic hibernate-cfg --from-file=hibernate.cfg.xml=$HIBERNATE_CFG_XML  
done

Тепер ми можемо почати розгортати наш додаток.

Розгортання кластера Coherence через кластери

Тепер ми хочемо розгорнути Coherence як єдиний розтягнутий кластер як ми робили раніше:

pic

Coherence підключатиметься до доступної бази даних. У разі помилки запису, ми хочемо, щоб Coherence тримала оборону та намагалася знову підключитись, ініціюючи підключення знову.
У цьому прикладі ми налаштували Coherence в режимі write-behind у конфігурації кешу:

30
Створіть наступне для кластера c1 в Сіднеї, зберігаючи це в todo-dr-c1.yaml:

apiVersion: networking.istio.io/v1
kind: DestinationRule
metadata:
name: backend
namespace: todo
spec:
host: backend.todo.svc.cluster.local
trafficPolicy:
connectionPool:
http:
maxRequestsPerConnection: 1
loadBalancer:
simple: ROUND_ROBIN
localityLbSetting:
enabled: true
failover:
- from: AP-SYDNEY-1
to: AP-MELBOURNE-1
outlierDetection:
consecutive5xxErrors: 1
interval: 1s
baseEjectionTime: 1m
```

А наступне для кластера c2 в Мельбурні, зберігаючи це в todo-dr-c2.yaml:

apiVersion: networking.istio.io/v1  
kind: DestinationRule  
metadata:  
 name: backend  
 namespace: todo  
spec:  
 host: backend.todo.svc.cluster.local  
 trafficPolicy:  
 connectionPool:  
 http:  
 maxRequestsPerConnection: 1  
 loadBalancer:  
 simple: ROUND_ROBIN  
 localityLbSetting:  
 enabled: true  
 failover:  
 - from: AP-MELBOURNE-1  
 to: AP-SYDNEY-1  
 outlierDetection:  
 consecutive5xxErrors: 1  
 interval: 1s  
 baseEjectionTime: 1m

Тепер ви можете застосувати манифести:

for c in c1 c2; do  
 kubectx $c  
 kubectl apply -f $HOME/todo/todo-dr-$c.yaml  
done

Крос-регіональна висока доступність з OCI Traffic Steering

Цей крок передбачає, що ваш домен керується через OCI DNS.

У консоль OCI перейдіть до Networking > DNS Management > Traffic Management Steering Policies та виконайте наступні дії:

  1. Створіть політику керування трафіком (Traffic Steering Policy) і виберіть Load Balancer
  2. У секції Answer(s) додайте 2 записи типу A з IP-адресами вхідних шлюзів як Rdata і рівною вагою
  3. Додайте нову перевірку здоров'я (Health Check) і виберіть HTTP як протокол
  4. У секції Attached Domain(s) додайте todo в Subdomain. Виберіть відділ, в якому була створена зона DNS для вашого домену, і потім виберіть зону.
  5. Тепер ви можете отримати доступ до додатку через todo.domain.tld

Зазначте, що також можна використовувати DNS cname замість записів типу "A".

Наша настройка завершена:

pic

Висока доступність у кількох регіонах на Oracle Cloud

Підсумок

У цій статті ми об'єднали кілька технологій для досягнення високої доступності наших хмарних мікросервісів на OCI:

  • Oracle Autonomous Database
  • OCI Networking, включаючи DRG та RPC
  • OCI Kubernetes Engine як Kubernetes кластер
  • Cilium як CNI
  • Istio як сервісну мережу (service mesh)
  • Oracle Coherence
  • Helidon як фреймворк для мікросервісів
  • OCI Load Balancers
  • OCI DNS
  • OCI Traffic Steering

У наступній статті ми будемо симулювати відмови та перевіримо, наскільки стійка наша інфраструктура. Завершуючи, хочу подякувати моїм колегам Шону Леві (Shaun Levy), Тиму Міддлтону і Роману Греко за їхній внесок у цю статтю.

Перекладено з: A cloud native brew with Oracle Database, Helidon, Coherence and Kubernetes — Part 9 Architecting for High Availability

Leave a Reply

Your email address will not be published. Required fields are marked *