Translate

неділя, 9 січня 2022 р.

Redis Cluster

Я вже якось писав про базові можливості Redis і про способи забезпечення вищої доступності. Але цей цикл статей не був би повний без статті про Redis Cluster, інсталяції, що покриває як питання високої доступності, так і шардингу. 


1. INTRO

Redis Cluster має наступні переваги/особливості:

  • Висока доступність та горизонтальне масштабування до 1000 вузлів. Проте consistent hashing відсутній: при додаванні чи видаленні серверів із кластеру необхідно самому попіклуватись про рівномірний розподіл та переміщеня даних в кластері. Деякі з цих проблем вирішені в Enterprise версії.
  • Асинхронна синхронізація зі слейвами. Тобто кластер не гарантує консистентності операцій, тож при певному збігу обставин (наприклад фейловер процес) деякі дані можуть бути втраченими. Але це позитивно впливає на продуктивність.
  • Відсутність тразакцій/multiple-keys операцій (MULTI, EXEC, DISCARD, WATCH ), але це можна дещо пом'якшити із простановкою hash tag для ключів. Це пов'язано із самим процесом хешування (алгоритмом розміщення даних в кластері): перший ключ при записі може потрапити на перший сервер, а наступний після нього - на останній. Тож можливо код клієнта треба буде дещо змінити.
  • Одна із основних переваг Redis Cluster - це шардинг. Тобто великі об'єми даних можна розділити на групи серверів. У випадку Redis Sentinel він обмежений кількістю оперативної пам'яті сервера. До речі, Enterprise версія вміє використовувати кеш SSD-диску. 
  • Slave-вузли не простоюють, а забезпечують операції читання для кінцевих клієнтів. Хоч звісно можливі випадки надання не найсвіжіших даних через асинхронну природу реплікації.
  • Наявність replica migration. Тобто майстри, що мають декілька реплік, можуть ділитись реплікою із іншим майстром, який її потребує.

Із деталями будемо розбиратись в процесі налаштування. Cluster функціонал з'явився починаючи із версії 3, де його створенням та розподіленням даних в кластері ще займався ruby-скрипт. Наразі все інтегровано в redis-cli утиліту.

пʼятниця, 9 липня 2021 р.

Atlantis. Terraform Pull Request Automation


Цього разу піде мова про Atlantis, програму що автоматизує роботу із Terraform та в деяких випадках може значно спростити взаємодію із ним.

Atlantis - це самодостатній додаток на Golang, що слідкує за відкритими Pull Requests системи контролю версій за допомогою event-ів, що власне остання і надсилає. Під системою контролю версій мається на увазі Github, GitLab, Bitbucket чи Azure DevOps. Тобто це дещо складніше ніж просто Git, адже у неї має бути свій API, web-панель для рецензування та перегляду коду і т.п.

Із Atlantis зі змінами Terraform коду можна взаємодіяти напряму із web-панелі системи контролю версій, слідкувати за останніми змінами, перевіряти чи ці зміни були справді застосовані перед прийняттям коду в main вітку та застосовувати їх. Це справді може бути корисним та зручним, все залежить від процесів всередині команди та наскільки подібна логіка прийнятна.

У статті я розгляну 2 випадки установки та використання Atlantis. Перший, простіший, із застосуванням коду напряму через Terraform, а наступний - через, мабуть, найвідоміший wrapper Terragrunt. У якості системи контролю версій я буду використовувати Github, a сам Atlantis запустимо в Докері.


1. BASIC ATLANTIS USAGE


1.1. BASIC TERRAFORM CODE PREPARATION

Створимо тестовий репозиторій в GitHub для розміщення тестового Terraform коду. Не буду довго на цьому зупинятись, адже в даному процесі немає нічого особливого.

Опишемо створення звичайного EC2 інстансу за допомогою мови HCL останньої версії Terraform. На момент написання статті остання версія - це v1.0.1 

понеділок, 11 травня 2020 р.

Pulumi. Part II: AWS Subnets and Fargate

Минулого разу  ми торкнулись причин появи нового IaС продукту Pulumi та спробували розібратись із базовими принципами його роботи на прикладі створення простого AWS S3 buсket-у. Наразі ж спробуємо описати на Python-інтерфейсі Pulumi власний VPC із підмережами та ECS Fargate кластер, тобто значно ближчий до реального життя випадок. Також побачимо як користуватись S3-бекендом для збереження стейтів (checkpoints в термінології Pulumi), та що робити із відсутністю lock-ів на паралельний запуск того ж коду. У кінці спробуємо поговорити про нинішній стан речей та перспективи Pulumi. Всі описані нижче приклади можна буде знайти у наступному github-проекті https://github.com/ipeacocks/pulumi-aws-example

Отже для подальших дій необхідні:

1. CUSTOM VPC/SUBNETS IN FEW AZs

Якою має бути мережа, котру буде не дуже соромно лишати для prod-цілей? Має бути як мінімум декілька публічний підмереж у різних зонах доступності регіону (AZ, availability zone), декілька приватних та стільки ж NAT-шлюзів для з'єднання приватних підмереж із зовнішнім світом. NAT-шлюзи зобов'язані мати постійні IP-адреси (EIP) і лежати в публічних підмережах аналогічних зон доступності. Трафік публічних підмереж має прямувати на Internet-gateway, а приватних - на відповідний NAT-гейтвей своєї ж зони доступності. Спробуємо це реалізувати.

Експортуємо значення Programmatic Access:

$ export AWS_ACCESS_KEY_ID=AKIA1234563J76A
$ export AWS_SECRET_ACCESS_KEY=/xLmpmdp1V3abcdefghklmnopabcdefg2nKRDKO
$ export AWS_REGION=us-east-1

Створимо S3-bucket для стейтів Pulumi:

$ aws s3api create-bucket \
      --bucket pulumi-states-zeezpha \
      --region us-east-1

$ aws s3api put-bucket-versioning \
      --bucket pulumi-states-zeezpha \
      --versioning-configuration Status=Enabled

Назва бакету має бути унікальною, тому необхідно обрати якусь власну назву.

Укажемо для Pulumi, що ми збираємось зберігати стейти в створеному вище бакеті S3:

$ pulumi login s3://pulumi-states-zeezpha

четвер, 7 травня 2020 р.

Pulumi. Part I: Overview

Загальні практики вказують на те, що зберігати налаштування як код корисно навіть для будь-яких відносно простих систем. Тобто усі параметри, їх зміни та авторів досить легко переглядати і відслідковувати в системі контролю версій, а за необхідності їх можна повертати до попередніх значень, якщо щось пішло не за планом. У разі якщо стан системи описаний як код, дуже легко та швидко підняти аналогічну копію такої системи. Це чудова тенденція і вона прослідковується у всіх популярних продуктах для різних команд: наприклад у Jenkins є Pipelines, для побудови інфраструктур в основному використовується Terraform, а система моніторингу Prometheus взагалі розроблялась без відповідних GUI інтерфейсів і всі налаштування відбуваються через код. Загалом будь-який новий продукт розробляється із розрахунку на те, його налаштування буде зберігатись як код.

Часто кожний продукт пропонує свою специфічну мову (DSL, Domain-specific language) для опису логіки роботи систем. Наприклад, у Puppet є свій DSL для опису стану, котрий хоче набути ресурс, а у Terraform-a свій власний HCL (HashiCorp Domain Language) для опису ресурсів. DSL загалом використовується для декларативного підходу - цікавить саме ресурс, котрий буде побудовано, а не те як він буде побудовано і з якими етапами. В силу своєї специфічності DSL мови мають багато недоліків і якісь відносно складні речі на DSL виглядають просто жахливо. Модулі Terraform, що описують хоча б дещо комплексну систему, аж занадто не елегантні і їх часто соромно переглядати чи показувати комусь: те що в мові загального користування виглядає лаконічно - в Terraform-і це ж саме перетворюється на рядок в 100 символів і більше, який ще до того не можна розірвати! Тому не раджу нікому дивитись в чужі модулі Terraform, це може вплинути на психічний стан. Вже згаданий Puppet також далеко прорвався вперед і страждає від тих самих проблем, коли читабельно виглядають лише нескладні стандартні ресурси.

Я, як активний користувач Terraform, часто приходив до висновку, що Terraform-у складно виконувати всі покладені на нього завдання конфігурації інфраструктури та виливки додатків. Із однієї сторони в нього є купа різних провайдерів і автори його позиціонують як "швейцарський ніж" сучасного інженера, а із іншої сторони в Teraform-і у якості if використовують count. Із Terraform наприклад не можна реалізувати щось на зразок перевірки існування змінної чи запустити декілька раз той самий модуль (count недоступний під час запуску модуля), чи обійти два списки водночас (адже count лише один) і тому подібне.

Знову ж, я не хочу сказати, що Terraform поганий і з ним неможливо жити. Але варто одразу розуміти, що це DSL, і з однієї сторони його код досить простий і декларативний, а з іншої, по причинам описаними вище, із ним варто звикати до постійного copy-paste. Але може не потрібно? Можливо існує щось інше? Так існує, це Pulumi.

Перший публічний реліз Pulumi з'явився в 2018 році, завдяки зусиллям однойменного стартапу, що базується в Сіетлі. За ідею проекту було взято написання системи, що полишить практики використання специфічних DSL мов та буде ближчим для розробників, таким чином скоротивши розрив між ними та devops/operation командами, котрі займаються їх підтримкою. Хоча це досить контроверсійні аргументи, але не будемо наразі на цьому зупинятись. Перейдемо до більш конкретних речей.

неділя, 28 липня 2019 р.

WireGuard VPN. Part II: Setup And Usage

Минулого разу ми говорили про ідеї, що підштовхнули до створення мережевого тунелю WireGuard, та алгоритми, що лежать в його основі. Цього ж разу спробуємо налаштувати WireGuard і пересвідчимось, що VPN is fun again.

1. SETUP


WireGuard ще не включено до кодової бази ядра Linux і наразі розповсюджується як DKMS-модуль. У якості сервера Wireguard працює лише на Linux, а у якості клієнта - під усіма популярними операційними системами, в т.ч. мобільними, в основному як userspace-імплементація на мові Go.

Для демонстрації можливостей WireGuard ми скористаємось Ubuntu 18.04. Для неї пакети розповсюджуються через ppa-репозиторій. На кожному вузлі, що буде з'єднуватись тунелем, необхідно встановити наступні пакети:

# add-apt-repository ppa:wireguard/wireguard
# apt update
# apt install wireguard

Можливо також потрібно буде встановити пакети-заголовки для ядра:

# apt install linux-headers-$(uname -r) linux-headers-generic

Кожен вузол повинен мати свою пару асиметричних ключів, тож згенеруємо їх на кожному хості:

# cd /etc/wireguard/
# umask 077
# wg genkey | tee privatekey | wg pubkey > publickey


неділя, 2 червня 2019 р.

WireGuard VPN. Part I: Intro

WireGuard  - сучасний мережевий тунель, що працює на 3 рівні моделі OSI, повністю реалізований в просторі ядра Linux (хоча клієнти можуть працювати і в просторі користувача) завдяки чому досягається вища швидкість передачі даних на відміну від OpenVPN. Останній має значно більшу кодову базу (~120 тисяч рядків коду проти 4000 WireGuard) і лише частково працює в просторі ядра.

WireGuard розповсюджується як відкрите програмне забезпечення під ліцензією GPLv2. Хоч продукт вже і достатньо зрілий, проте, як говорить основний розробник і автор проекту Джейсон А. Доненфельд, його поки не варто використовувати в production-цілях, адже код ще не пройшов належний рівень аудиту безпеки. В майбутньому його планують повністю включити в ядро, а наразі він розповсюджується як окремий DKMS-модуль. Про WireGuard вже позитивно висловлювались Лінус Торвальдс та Грег Кроа-Хартман, порівнюючи його із витвором мистецтва.


вівторок, 25 грудня 2018 р.

Graphite. Stack Based On ClickHouse

Graphite - це моніторингова система, що працює за push-моделлю, тобто отримує дані від вузлів, а не опитує їх. Вона чудово підходить для збирання та аналізу метрик і, завдяки вбудованому механізму ущільнення даних (storage aggregation/rollup/retention/downsampling), ці дані можуть зберігатись на протязі дійсно пристойного часу (декілька років).

Graphite був написаний Крісом Дейвісом (Chris Davis), співробітником компанії Orbitz в 2006 році. Мова програмування оригінального проекту - Python, але наразі майже всі компоненти Graphite можна замінити на сторонні, написані на мові Go. Більш того, навіть бібліотеку Whisper для роботи з базою Graphite можна замінити на альтернативні рішення зі збереженням даних в базі Cassandra, ClickHouse і т.п. Якраз про останній і піде мова цього разу.

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

Спершу пройдемось по кожному із компонентів та опишемо їх призначення.

  • Carbon-clickhouse - демон, що працює у якості заміни оригінального Carbon та може писати отримані метрики від третіх систем в базу даних ClickHouse.
  • ClickHouse - OLAP база даних, що була розроблена в компанії Yandex, проте із 2021 року вона розвивається в межах окремої одноіменної компанії. Пізніше розповім про неї детальніше.
  • Graphite-clickhouse - проміжне програмне забезпечення для роботи між API сервісом та базою ClickHouse.
  • Carbonapi - API-сервер Graphite, написаний на мові Go. Теоретично замість нього може бути використано Graphite-web (оригінальна імплементація API та веб-панель) чи Graphite-api (лише API на Flask фреймворку)
  • Grafana - веб-панель на Go/NodeJS для побудови та відображення метрик. Вміє опитувати Graphite "із коробки", підтримує всі його API-функції. Для Grafana-и увесь описаний вгорі стек буде виглядати як звичайна інсталяція Graphite-у.

елементи наведені пунктиром - опціональні

У свою чергу Carbon-clickhouse та Graphite-clickhouse - по деяких опосередкованих даних розробки компанії Mail.ru, а Carbonapi - Booking.com.