Миграция на Cassandra към Kubernetes: функции и решения

Миграция на Cassandra към Kubernetes: функции и решения

Редовно се сблъскваме с базата данни Apache Cassandra и необходимостта да я управляваме в рамките на базирана на Kubernetes инфраструктура. В този материал ще споделим нашата визия за необходимите стъпки, критерии и съществуващи решения (включително преглед на операторите) за мигриране на Cassandra към K8s.

„Който може да управлява една жена, може да управлява и държавата“

Коя е Касандра? Това е разпределена система за съхранение, предназначена да управлява големи обеми от данни, като същевременно гарантира висока наличност без нито една точка на повреда. Проектът едва ли се нуждае от дълго представяне, така че ще дам само основните характеристики на Cassandra, които ще бъдат от значение в контекста на конкретна статия:

  • Cassandra е написана на Java.
  • Топологията Cassandra включва няколко нива:
    • Възел - един разгърнат екземпляр на Cassandra;
    • Rack е група от екземпляри на Cassandra, обединени по някаква характеристика, разположени в един и същ център за данни;
    • Център за данни – съвкупност от всички групи инстанции на Cassandra, разположени в един център за данни;
    • Клъстерът е колекция от всички центрове за данни.
  • Cassandra използва IP адрес за идентифициране на възел.
  • За да ускори операциите по запис и четене, Cassandra съхранява част от данните в RAM.

Сега – към действителното потенциално преминаване към Kubernetes.

Контролен списък за трансфер

Говорейки за миграцията на Cassandra към Kubernetes, надяваме се, че с преместването ще стане по-удобно за управление. Какво ще е необходимо за това, какво ще помогне за това?

1. Съхранение на данни

Както вече беше изяснено, Cassanda съхранява част от данните в RAM - в Memtable. Но има друга част от данните, които се записват на диска - във формата SSTable. Към тези данни се добавя обект Дневник на ангажиментите — записи на всички транзакции, които също се записват на диск.

Миграция на Cassandra към Kubernetes: функции и решения
Напишете диаграма на транзакция в Cassandra

В Kubernetes можем да използваме PersistentVolume за съхраняване на данни. Благодарение на доказаните механизми, работата с данни в Kubernetes става все по-лесна всяка година.

Миграция на Cassandra към Kubernetes: функции и решения
Ние ще разпределим нашия собствен PersistentVolume за всеки Cassandra pod

Важно е да се отбележи, че самата Cassandra предполага репликация на данни, като предлага вградени механизми за това. Следователно, ако изграждате клъстер Cassandra от голям брой възли, тогава няма нужда да използвате разпределени системи като Ceph или GlusterFS за съхранение на данни. В този случай би било логично данните да се съхраняват на хост диска с помощта на локални постоянни дискове или монтаж hostPath.

Друг въпрос е дали искате да създадете отделна среда за разработчици за всеки клон на функцията. В този случай правилният подход би бил да се създаде един Cassandra възел и да се съхраняват данните в разпределено хранилище, т.е. споменатите Ceph и GlusterFS ще бъдат вашите опции. Тогава разработчикът ще бъде сигурен, че няма да загуби тестови данни, дори ако един от възлите на клъстера Kuberntes бъде загубен.

2. Мониторинг

На практика безспорният избор за внедряване на мониторинг в Kubernetes е Prometheus (говорихме за това подробно в свързан доклад). Как се справя Cassandra с износителите на метрики за Prometheus? И което е още по-важно, със съвпадащи табла за управление за Grafana?

Миграция на Cassandra към Kubernetes: функции и решения
Пример за появата на графики в Grafana за Cassandra

Има само два износителя: jmx_exporter и cassandra_exporter.

Ние избрахме първото за себе си, защото:

  1. JMX Exporter расте и се развива, докато Cassandra Exporter не успя да получи достатъчно подкрепа от общността. Cassandra Exporter все още не поддържа повечето версии на Cassandra.
  2. Можете да го стартирате като javaagent, като добавите флаг -javaagent:<plugin-dir-name>/cassandra-exporter.jar=--listen=:9180.
  3. Има един за него адекватно табло, което е несъвместимо с Cassandra Exporter.

3. Избиране на Kubernetes примитиви

Съгласно горната структура на клъстера Cassandra, нека се опитаме да преведем всичко, което е описано там, в терминологията на Kubernetes:

  • Възел Касандра → Под
  • Cassandra Rack → StatefulSet
  • Cassandra Datacenter → басейн от StatefulSets
  • Клъстер Касандра → ???

Оказва се, че липсва някакъв допълнителен обект, който да управлява целия клъстер Cassandra наведнъж. Но ако нещо не съществува, ние можем да го създадем! Kubernetes има механизъм за дефиниране на собствени ресурси за тази цел - Персонализирани дефиниции на ресурси.

Миграция на Cassandra към Kubernetes: функции и решения
Деклариране на допълнителни ресурси за регистрационни файлове и предупреждения

Но самият персонализиран ресурс не означава нищо: в крайна сметка той изисква контрольор. Може да се наложи да потърсите помощ Оператор Kubernetes...

4. Установяване на подс

В параграфа по-горе се съгласихме, че един възел Cassandra ще се равнява на един pod в Kubernetes. Но IP адресите на капсулите ще бъдат различни всеки път. И идентифицирането на възел в Касандра се основава на IP адреса... Оказва се, че след всяко премахване на под, клъстерът на Касандра ще добавя нов възел.

Има изход и не само един:

  1. Можем да поддържаме записи чрез идентификатори на хост (UUID, които уникално идентифицират екземплярите на Cassandra) или чрез IP адреси и да ги съхраняваме в някои структури/таблици. Методът има два основни недостатъка:
    • Рискът от възникване на състояние на състезание, ако два възела паднат наведнъж. След покачването възлите на Cassandra едновременно ще поискат IP адрес от таблицата и ще се състезават за същия ресурс.
    • Ако възел на Cassandra е загубил данните си, вече няма да можем да го идентифицираме.
  2. Второто решение изглежда като малък хак, но въпреки това: можем да създадем услуга с ClusterIP за всеки възел на Cassandra. Проблеми с тази реализация:
    • Ако има много възли в клъстер Cassandra, ще трябва да създадем много услуги.
    • Функцията ClusterIP се реализира чрез iptables. Това може да се превърне в проблем, ако клъстерът Cassandra има много (1000... или дори 100?) възли. Макар че балансиране на базата на IPVS може да реши този проблем.
  3. Третото решение е да използвате мрежа от възли за възли на Cassandra вместо специална мрежа от подове, като активирате настройката hostNetwork: true. Този метод налага определени ограничения:
    • За подмяна на единици. Необходимо е новият възел да има същия IP адрес като предишния (в облаци като AWS, GCP това е почти невъзможно да се направи);
    • Използвайки мрежа от клъстерни възли, ние започваме да се конкурираме за мрежови ресурси. Следователно поставянето на повече от един pod с Cassandra на един клъстерен възел ще бъде проблематично.

5. Архивиране

Искаме да запазим пълна версия на данните на един възел на Cassandra по график. Kubernetes предоставя удобна функция за използване CronJob, но тук самата Касандра ни слага спиците.

Нека ви напомня, че Касандра съхранява част от данните в паметта. За да направите пълно архивиране, ви трябват данни от паметта (Memtables) преместване на диск (SSTables). В този момент възелът Cassandra спира да приема връзки, като напълно се изключва от клъстера.

След това резервното копие се премахва (моментална снимка) и схемата се записва (ключово пространство). И тогава се оказва, че просто резервно копие не ни дава нищо: трябва да запазим идентификаторите на данните, за които е отговорен възелът Cassandra - това са специални токени.

Миграция на Cassandra към Kubernetes: функции и решения
Разпределение на токени за идентифициране за какви данни са отговорни възлите на Cassandra

Примерен скрипт за архивиране на Cassandra от Google в Kubernetes може да бъде намерен на тази връзка. Единствената точка, която скриптът не взема предвид, е нулирането на данните към възела, преди да направи моментната снимка. Тоест архивирането се извършва не за текущото състояние, а за състояние малко по-рано. Но това помага да не се извади възелът от работа, което изглежда много логично.

set -eu

if [[ -z "$1" ]]; then
  info "Please provide a keyspace"
  exit 1
fi

KEYSPACE="$1"

result=$(nodetool snapshot "${KEYSPACE}")

if [[ $? -ne 0 ]]; then
  echo "Error while making snapshot"
  exit 1
fi

timestamp=$(echo "$result" | awk '/Snapshot directory: / { print $3 }')

mkdir -p /tmp/backup

for path in $(find "/var/lib/cassandra/data/${KEYSPACE}" -name $timestamp); do
  table=$(echo "${path}" | awk -F "[/-]" '{print $7}')
  mkdir /tmp/backup/$table
  mv $path /tmp/backup/$table
done


tar -zcf /tmp/backup.tar.gz -C /tmp/backup .

nodetool clearsnapshot "${KEYSPACE}"

Пример за bash скрипт за архивиране от един възел на Cassandra

Готови решения за Cassandra в Kubernetes

Какво се използва в момента за внедряване на Cassandra в Kubernetes и кое от тях отговаря най-добре на дадените изисквания?

1. Решения, базирани на диаграми StatefulSet или Helm

Използването на основните функции StatefulSets за стартиране на клъстер Cassandra е добър вариант. С помощта на шаблоните Helm chart и Go можете да предоставите на потребителя гъвкав интерфейс за внедряване на Cassandra.

Това обикновено работи добре... докато не се случи нещо неочаквано, като повреда на възел. Стандартните инструменти на Kubernetes просто не могат да вземат предвид всички характеристики, описани по-горе. Освен това този подход е много ограничен по отношение на това доколко може да бъде разширен за по-сложни употреби: подмяна на възел, архивиране, възстановяване, наблюдение и т.н.

представители:

И двете диаграми са еднакво добри, но са обект на проблемите, описани по-горе.

2. Решения, базирани на Kubernetes Operator

Такива опции са по-интересни, защото предоставят широки възможности за управление на клъстера. За проектиране на оператор Cassandra, като всяка друга база данни, добър модел изглежда като Sidecar <-> Controller <-> CRD:

Миграция на Cassandra към Kubernetes: функции и решения
Схема за управление на възли в добре проектиран оператор Cassandra

Нека да разгледаме съществуващите оператори.

1. Cassandra-оператор от instaclustr

  • GitHub
  • Готовност: Алфа
  • Лиценз: Apache 2.0
  • Реализирано в: Java

Това наистина е много обещаващ и активно развиващ се проект от компания, която предлага управлявани внедрявания на Cassandra. Както е описано по-горе, той използва контейнер с кош, който приема команди чрез HTTP. Написан на Java, понякога му липсва по-разширената функционалност на библиотеката client-go. Освен това операторът не поддържа различни стелажи за един център за данни.

Но операторът има такива предимства като поддръжка за мониторинг, управление на клъстери на високо ниво с помощта на CRD и дори документация за създаване на резервни копия.

2. Навигатор от Jetstack

  • GitHub
  • Готовност: Алфа
  • Лиценз: Apache 2.0
  • Внедрено в: Golang

Декларация, предназначена за внедряване на DB-as-a-Service. В момента поддържа две бази данни: Elasticsearch и Cassandra. Има толкова интересни решения като контрол на достъпа до база данни чрез RBAC (за това има свой собствен навигатор-apiserver). Интересен проект, който би си струвало да се разгледа по-отблизо, но последният ангажимент е направен преди година и половина, което явно намалява потенциала му.

3. Касандра-оператор от vgkowski

  • GitHub
  • Готовност: Алфа
  • Лиценз: Apache 2.0
  • Внедрено в: Golang

Те не го смятаха за „сериозно“, тъй като последният ангажимент към хранилището беше преди повече от година. Разработката на оператора е изоставена: най-новата версия на Kubernetes, съобщена като поддържана, е 1.9.

4. Касандра-оператор от Рук

  • GitHub
  • Готовност: Алфа
  • Лиценз: Apache 2.0
  • Внедрено в: Golang

Оператор, чието развитие не напредва толкова бързо, колкото ни се иска. Той има добре обмислена CRD структура за управление на клъстери, решава проблема с идентифицирането на възли, използващи услуга с ClusterIP (същият „хак“)... но това е всичко за сега. В момента няма мониторинг или резервни копия извън кутията (между другото, ние сме за мониторинг взехме го сами). Интересен момент е, че можете също да разположите ScyllaDB, като използвате този оператор.

NB: Използвахме този оператор с малки модификации в един от нашите проекти. Не са забелязани проблеми в работата на оператора през целия период на работа (~4 месеца работа).

5. CassKop от Orange

  • GitHub
  • Готовност: Алфа
  • Лиценз: Apache 2.0
  • Внедрено в: Golang

Най-младият оператор в списъка: първият ангажимент е направен на 23 май 2019 г. Вече има в арсенала си голям брой функции от нашия списък, повече подробности за които можете да намерите в хранилището на проекта. Операторът е изграден на базата на популярния оператор-sdk. Поддържа мониторинг извън кутията. Основната разлика от другите оператори е използването Плъгин CassKop, реализиран в Python и използван за комуникация между възлите на Cassandra.

Данни

Броят на подходите и възможните опции за пренасяне на Касандра в Kubernetes говори сам за себе си: темата е търсена.

На този етап можете да опитате някое от горните на свой собствен риск и риск: никой от разработчиците не гарантира 100% работа на своето решение в производствена среда. Но вече много продукти изглеждат обещаващи, за да опитате да ги използвате в стендовете за разработка.

Мисля, че в бъдеще тази жена на кораба ще бъде полезна!

PS

Прочетете също в нашия блог:

Източник: www.habr.com

Добавяне на нов коментар