Translate

середа, 9 березня 2022 р.

Kubernetes. Part V: Configure And Use Ingress. MetalLB

Ця стаття вже п'ята з серії статей про Kubernetes. Перед її прочитанням рекомендую ознайомитись хоча б з базовими об'єктами кластеру та їх використанням для вирішення задач.

Сервіси Kubernetes надають можливість створення постійних точок входу до контейнерів додатків, що працюють в подах, проте IP адреси сервісів обираються з діапазону оверлейної мережі, і тому є видимими лише в межах кластеру. Тож у разі необхідності доступу до таких додатків ззовні існують наступні варіанти:

• hostNetwork: true. Под, створений із такою опцією, матиме можливість бачити мережеві інтерфейси Kubernetes хосту, де його було запущено.

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  hostNetwork: true
  containers:
  - name: influxdb
    image: influxdb

Порт такого додатку буде прослуховуватись на всіх інтерфейсах вузла. Використання цієї опції не рекомендовано, адже в цьому випадку вичерпується простір портів хост-машини, що зі зростанням кількості працюючих додатків може з легкістю призвести до конфліктів. Більш того, у разі перестворення поду, він може "переселитись" на інший вузол, що додасть складності в його пошуках. Виключенням можуть слугувати поди утиліт, котрим дійсно необхідний вищезгаданий доступ задля управлінням мережею і т.п.

Задеплоїмо вищезгаданий поді та знайдемо на якому вузлі він оселився:

$ kubectl get pod -o wide
NAME      READY   STATUS    RESTARTS   AGE   IP            NODE   
influxdb   1/1     Running   0          38h   10.30.0.141   k8s-s-a


$ kubectl get nodes -o wide
NAME      STATUS   ROLES   AGE     VERSION   INTERNAL-IP
...
k8s-s-a   Ready    <none>  4d16h   v1.23.4   192.168.1.48


І перевіримо чи порт справді відкритий:

$ ssh 192.168.1.48
$ netstat -tulpn | grep influx
tcp        0      0 127.0.0.1:4222   0.0.0.0:*   LISTEN      949214/influxd
tcp6       0      0 :::8086          :::*        LISTEN      949214/influxd


• hostPort: integer. Ця опція дозволяє поду активувати лише один порт на всіх інтерфейсах вузла Kubernetes. Yaml для створення такого поду буде виглядати наступним чином:

apiVersion: v1
kind: Pod
metadata:
  name: influxdb
spec:
  containers:
    - name: influxdb
      image: influxdb
      ports:
        - containerPort: 8086
          hostPort: 8086

Його, як і попередній варіант, дуже не рекомендовано використовувати по тим же причинам.

вівторок, 8 березня 2022 р.

Kubernetes. Part III: Objects And How To Use Them

Отже у нас вже є готовий налаштований кластер і, озброївшись необхідним теоретичним мінімумом, ми можемо переходити до подальшого вивчення Kubernetes. Цього разу ми поговоримо детальніше про основні примітиви (objects) Kubernetes, як вони взаємодіють між собою та як реалізовані.

Забігаючи наперед, основні команд для отримання даних про роботу об'єктів є наступні:
  • kubectl get object_type - перерахунок всіх об'єктів даного типу, котрі знаходяться в межах одного неймспейсу
  • kubectl describe object_type - детальна інформація про всі об'єкт даного типу, що також знаходяться в одному неймспейсі
Всі основні об'єкти перераховані нижче. Якщо замість object_type вказати all, то буде виведено все, що знаходиться в неймспейсі.

ПОД (POD). Створимо под, що буде складатись з одного docker-контейнера і буде доступний на порту 9876. Для цього використаємо образ з dockerhub mhausenblas/simpleservice:0.5.0:

$ kubectl run first-pod --image=mhausenblas/simpleservice:0.5.0 --port=9876

deployment "first-pod" created


Перевіримо чи новий под працює:

$ kubectl get pods

NAME                         READY     STATUS    RESTARTS   AGE
first-pod-2257828502-l6z96   1/1       Running   0          23s

$ kubectl describe pod first-pod-2257828502-l6z96 | grep IP:

IP:   10.34.0.25

Отже, в межах кластеру под працює за адресою 10.34.0.25. Із будь-якого вузла кластеру пересвідчимось в цьому, зробивши запит до додатку:

[cluster]$ curl 10.34.0.25:9876/info
{"host": "10.34.0.25:9876", "version": "0.5.0", "from": "10.32.0.1"}

Kubernetes. Part II: Setup Cluster With Kubeadm. Plugins

Після ознайомлення з теорією можна перейти і до практичної частини. Цього разу установимо кластер Kubernetes на bare-metal, тобто звичайні віртуальні машини чи залізні сервера, що не входять до існуючих IAAS платформ.

Способів установки Kubernetes кластеру існує дуже багато. Всі ці перераховані варіанти різної актуальності, необхідно дивитись і перевіряти все уважно, щоб не витратити зайвого часу на марні спроби. Найбільш популярні способи:

  • minikube чи kind. Найпростіший спосіб установки Kubernetes на власний локальний PC. Буде корисний людям, котрі хочуть приступити до вивчення Kubernetes, не втрачаючи купу часу на його більш повноцінну установку, чи локального тестування роботи додатків, що потреують цього середовища.
  • kubeadm. Офіційний, доволі мануальний спосіб. Підтримує установку на звичайні bare-metal сервера чи віртуальні машини, що працюють під управлінням OS Linux. Наразі kubeadm також підтримує створення HA (High Availability) Master інсталяцій.
  • kops. Призначений для розгортання Kubernetes на AWS, для чого використовує API-виклики платформи. Написаний на мові Go. Як зазначено на github сторінці проекту, робота kops з GCE, OpenStack та DigitalOcean перебуває в статусі бета, а в майбутньому також планується підтримка інших хмарних платформ. Також підтримує розгортання HA Master конфігурацій.
  • kubespray. Це набір Ansible плейбуків для розгортання Kubernetes на платформах AWS, GCE, Azure, OpenStack, vSphere, bare-metal машинах і т.п. Має найбільш обширний список підтримки дистрибутивів Linux. Також підтримує установку HA Master конфігурацій. Це community-проект, детальніше про нього можна прочитати за посиланням.
  • K0s. Установка K8s по ssh але, на відміну від Kubespray, без залучення Ansible. Написаний на мові Go компанією Mirantis. Я йому присвятив окрему статтю в блозі, де і можна ознайомитись із деталями.
  • Варіанти, що пропонують провайдери хостингів чи клауди. На зразок AWS Elastic Kubernetes Service (EKS) чи Google Kubernetes Engine (GKE). Мабуть найпростіший варіант, котрий в тому числі найпростіший в обслуговуванні.
  • Та багато-багато інших варіантів

У цій статті ми розгорнемо власний кластер Kubernetes за допомогою утиліти kubeadm. Це буде не HA інсталяція (тобто не production-ready варіант) на основі операційної системи Ubuntu 20.04, що в свою чергу працюватиме в системі віртуалізації VirtualBox. Перелік адрес хостів та їх доменів наступний:

k8s-m-a  192.168.1.45
k8s-s-a    192.168.1.48
k8s-s-b    192.168.1.49

Як рекомендує офіційна документація, кожній віртуальній машині варто виділити як мінімум 2ГБ оперативної пам’яті і 2 ядра, інакше може не вистачити місця для запуску додатків.

середа, 23 лютого 2022 р.

Kubernetes. Part I: Overview

Яка ж мета існування всіх сучасних PaaS платформ? Які додатки варто на них запускати? Далеко не всі існуючі рішення є сенс запускати на таких платформах. Перш за все додаток має бути відповідно написаний, а точніше відповідати 12 вимогам (twelve-factor app методологія). Слідування цим вимогам може надати такі переваги вашому додатку:

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

- Збільшить переносимість частин коду між різними середовищами виконання.

- Підніме якість та зручність процесів CI/CD. Кожна частина продукту (мікросервіс) може оновлюватись окремо, головне - не пошкодити інтерфейс взаємодії (REST API і т.п.).

- Дозволить зручно горизонтально масштабувати додатки без значних змін архітектури.

Бажано також мінімізувати вагу додатків до хоча б 1ГБ, інакше завантаження та старт великих контейнерів (у випадку використання контейнерів як середовища, як зазвичай і є) може зайняти пристойну кількість часу. Якщо ж засунути в контейнер купу пакетів, компіляторів і т.п. - то це вже буде такий собі мікросервіс.

Я вже робив огляд та базову конфігурацію кластерних систем управління контейнерами, серед яких:

Mesos/Marathon (вже не підтримується)
Bosh/Cloud Foundry (туманне майбутнє)

А цього разу мова піде про Kubernetes (це ім'я часто пишуть як K8s, адже звучить схоже). Kubernetes - це система з відкритим вихідним кодом для автоматизації розгортання, масштабування та управління додатками (мікросервісами) в контейнерах. У якості системи контейнеризації (container runtime) використовує в основному containerd/cri-o, але є і інші, менш популярні. Все завдяки CRI-інтерфейсу, що зробив можливим відв'язку Kubernetes від Docker-у. Його і досі можна використовувати, але не варто. На низькому рівні, не залежно від того, яку імплементацію CRI було обрано, все рівно працює низькорівневий runC.

неділя, 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