Съвети и трикове при работа с Ceph в натоварени проекти

Съвети и трикове в работата с Ceph в натоварени проекти

Използвайки Ceph като мрежово хранилище в проекти с различна натовареност, можем да се сблъскаме с различни задачи, които на пръв поглед не изглеждат лесни или тривиални. Например:

  • мигриране на данни от стар Ceph в нов с частично използване на предишни сървъри в новия клъстер;
  • решаване на проблема с разпределението на дисковото пространство в Ceph.

Справяйки се с такива задачи, се сблъскваме с необходимостта да извлечем OSD коректно без загуба на данни, което е особено актуално при големи обеми данни. За това ще става въпрос в статията.

Описаните по-долу методи са актуални за всяка версия на Ceph. Освен това ще се вземе под внимание фактът, че в Ceph може да се съхранява голям обем данни: за избягване на загуба на данни и други проблеми, някои действия ще бъдат „разделени“ на няколко по-други.

Предговор за OSD

Тъй като две от трите разглеждани рецепти са посветени на OSD (Object Storage Daemon), преди да навлезем в практическата част — накратко за това какво всъщност е това в Ceph и защо е толкова важно.

Първо, трябва да се каже, че целият Ceph-клъстер се състои от множество OSD. Колкото по-много са те, толкова по-голямо е свободното пространство за данни в Ceph. Оттук лесно можем да разберем главната функция на OSD: той съхранява данни на обекти Ceph в файловите системи на всички възли на клъстера и предоставя мрежов достъп до тях (за четене, запис и други заявки).

На същото ниво се задават параметри на репликация чрез копиране на обекти между различни OSD. И тук можем да се сблъскаме с различни проблеми, за решението на които ще става дума по-нататък.

Случай №1. Безопасно извличане на OSD от клъстера Ceph без загуба на данни

Необходимостта от извличане на OSD може да бъде предизвикана от извеждането на сървър от клъстера — например, за замяна с друг сървър, — което и се случи при нас, послужилко за повод за написването на статията. Така че, крайната цел на манипулациите е да извлечем всички OSD и mon’и на този сървър, за да може той да бъде спрян.

За удобство и изключване на ситуация, при която в процеса на изпълнение на командите грешим с указанието на нужния OSD, ще зададем отделна променлива, чиято стойност ще бъде номерът на изтрития OSD. Нека я наречем ${ID} — тук и по-долу такава променлива заменя номера на OSD, с който работим.

Нека погледнем състоянието преди началото на работата:

root@hv-1 ~ # ceph osd tree
ID CLASS WEIGHT  TYPE NAME      STATUS REWEIGHT PRI-AFF
-1       0.46857 root default
-3       0.15619      host hv-1
-5       0.15619      host hv-2
 1   ssd 0.15619      osd.1     up     1.00000  1.00000
-7       0.15619      host hv-3
 2   ssd 0.15619      osd.2     up     1.00000  1.00000

За да инициирате изтриването на OSD, е необходимо плавно да изпълните преразпределение на нея до нула. По този начин намаляваме количеството данни в OSD чрез балансировка към други OSD. За целта се изпълняват следните команди:

ceph osd reweight osd.${ID} 0.98
ceph osd reweight osd.${ID} 0.88
ceph osd reweight osd.${ID} 0.78

… и така нататък до нула.

Плавната балансировка е необходима, за да не загубите данни. Това е особено важно, ако в OSD се съдържат големи обеми данни. За да се уверите, че след изпълнението на командите преразпределение всичко е преминало успешно, можете да изпълните ceph -s или в отделен прозорец на терминала да стартирате ceph -w за да следите промените в реално време.

Когато OSD е „опразнена“, можете да преминете към стандартната операция за нейното изтриване. За целта ще преведем желаната OSD в състояние надолу:

ceph osd down osd.${ID}

„Изваждаме“ OSD от клъстера:

ceph osd out osd.${ID}

Спираме услугата OSD и демонтираме раздела й във ФС:

systemctl stop ceph-osd@${ID}
umount /var/lib/ceph/osd/ceph-${ID}

Изтриваме OSD от CRUSH картата:

ceph osd crush remove osd.${ID}

Изтриваме потребителя OSD:

ceph auth del osd.${ID}

И накрая, изтриваме самата OSD:

ceph osd rm osd.${ID}

Забележка: ако използвате версия Ceph Luminous или по-висока, описаните по-горе действия за изтриване на OSD могат да бъдат сведени до две команди:

ceph osd out osd.${ID}
ceph osd purge osd.${ID}

Ако след изпълнението на горепосочените действия изпълните командата ceph osd tree, трябва да е видно, че на сървъра, на който са извършени действията, вече няма OSD, за които са изпълнявани операции по-горе:

root@hv-1 ~ # ceph osd tree
ID CLASS WEIGHT  TYPE NAME     STATUS REWEIGHT PRI-AFF
-1       0.46857      root default
-3       0.15619      host hv-1
-5       0.15619      host hv-2
-7       0.15619      host hv-3
 2   ssd 0.15619      osd.2    up     1.00000  1.00000

Междувременно ще забележим, че състоянието на клъстера Ceph ще премине в HEALTH_WARN, а също и ще видим намаление на броя на OSD и размера на наличното дисково пространство.

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

Ако на този сървър не са останали OSD, след като бъдат изтрити, е нужно да изключите от OSD картата сървъра hv-2, изпълнявайки следната команда:

ceph osd crush rm hv-2

Премахваме мон от сървъра hv-2, като изпълнявате командата по-долу на друг сървър (т.е. в този случай — на hv-1):

ceph-deploy mon destroy hv-2

След това можете да спрете сървъра и да преминете към следващите действия (неговото повторно разгърне и т.н.).

Случай №2. Разпределение на дисковото пространство в вече създаден Ceph клъстер

Втората история ще започне с предисловие за PG (Placement Groups). Основната роля на PG в Ceph е преди всичко агрегирането на Ceph обекти и последващото им репликиране в OSD. Формулата, с помощта на която може да се изчисли необходимото количество PG, се намира в съответния раздел документацията Ceph. Там също е разгледан този въпрос и на конкретни примери.

Така че: едно от разпространените проблеми по време на експлоатация на Ceph е несбалансираното количество OSD и PG между пуловете в Ceph.

Първо, заради това може да възникне ситуация, при която се посочва твърде голямо количество PG в малък по обем пул, което всъщност е нерационално използване на дисковото пространство в клъстера. Второ, на практика се получава по-сериозен проблем: пренасищане на данните в един от OSD. Това води до превключване на клъстера първо в състояние HEALTH_WARN, а после и HEALTH_ERR. Всичко дължи на факта, че Ceph при изчисляването на наличния обем данни (можете да го разберете чрез MAX AVAIL в изхода на командата ceph df за всеки пул поотделно) разчита на обема на наличните данни в OSD. Ако поне в едно OSD няма достатъчно място, то няма да можете да запишете повече данни, докато данните не бъдат разпределени правилно между всички OSD.

Следва да уточним, че тези проблеми в по-голяма степен се решават на етапа на конфигурация на Ceph клъстера. Един от инструментите, които могат да се използват, е Ceph PGCalc. С негова помощ визуално се изчислява необходимото количество PG. Въпреки това, може да се прибегне и в ситуация, когато Ceph клъстерът вече е конфигуриран неправилно. Тук следва да уточним, че в рамките на работата по отстраняване вероятно ще ви се наложи да намалите броя на PG, а тази възможност не е налична в старите версии на Ceph (тя се появи само с версията Nautilus).

И така, представете си следната картина: статуса на клъстера — HEALTH_WARN заради факта, че в един от OSD свършва мястото. Това ще свидетелства за грешка HEALTH_WARN: 1 near full osd. По-долу е представен алгоритъм за излизане от такава ситуация.

Първо, е необходимо да разпределите наличните данни между останалите OSD. Подобна операция вече сме извършвали в първия случай, когато „осушавахме“ възела — с единствената разлика, че сега ще трябва да намалим незначително преразпределение. Например, до 0.95:

ceph osd reweight osd.${ID} 0.95

По този начин се освобождава дисково пространство в OSD и се коригира грешката в ceph health. Въпреки това, както вече беше споменато, този проблем предимно възниква поради неправилната настройка на Ceph в началните етапи: изключително важно е да направите реконфигурация, за да не се проявява в бъдеще.

В нашия конкретен случай всичко беше свързано с:

  • твърде голяма стойност replication_count в един от пуловете,
  • твърде високо количество PG в един пул и твърде малко — в друг.

Да се възползваме от вече споменатия калкулатор. В него наглядно е показано какво трябва да се въвежда и в принципе, няма нищо сложно. Задавайки необходимите параметри, получаваме следните препоръки:

Забележка: ако настройвате Ceph-клъстер от нулата, още една полезна функция на калкулатора ще бъде генерирането на команди, които ще създадат пулове от нулата с параметрите, посочени в таблицата.

Помага последната колона — Suggested PG Count. В нашия случай полезен е и вторият, в който е посочен параметъра на репликация, тъй като решихме да променим и множителя на репликация.

Така, първо ще е необходимо да промените параметрите на репликация — това трябва да се направи на първо място, тъй като, намалявайки множителя, ще освободим дисково пространство. Докато изпълнявате командата, можете да забележите, че стойността на наличното дисково пространство ще се увеличава:

ceph osd pool $pool_name set $replication_size

След приключване, променяме стойностите на параметрите pg_num и pgp_num по следния начин:

ceph osd pool set $pool_name pg_num $pg_number
ceph osd pool set $pool_name pgp_num $pg_number

Важно: трябва последователно в всеки пул да променим количеството PG и да не променяме стойностите в другите пулове, докато предупрежденията не изчезнат „Degraded data redundancy“ и „n-number of pgs degraded“.

Можете също така да проверите, че всичко е минало успешно, по изходите на командите ceph health detail и ceph -s.

Кейс №3. Миграция на виртуална машина от LVM в Ceph RBD

В ситуации, в която проектът използва виртуални машини, инсталирани на наемани bare-metal сървъри, често възниква въпросът за отказоустойчивото хранилище. Освен това е много желателно да има достатъчно място в това хранилище... Друга разпространена ситуация: имате виртуална машина с локално хранилище на сървъра и е необходимо да увеличите диска, но нямате къде, тъй като на сървъра не е останало свободно дисково пространство.

Проблемът може да се реши по различни начини - например, чрез миграция на друг сървър (ако такъв съществува) или добавяне на нови дискове на сървъра. Но не винаги е възможно да се направи това, затова миграцията от LVM в Ceph може да стане отлично решение на този проблем. Избирайки този вариант, ние също така улесняваме по-нататъшния процес на миграция между сървърите, тъй като не е необходимо да преместите локалното хранилище от един хипервизор на друг. Единствената пречка е, че ще трябва да спрете виртуалната машина за времето на работа.

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

Пристъпваме към практическата част. В примера използваме virsh и, съответно, libvirt. Първо, уверете се, че пулът на Ceph, в който ще бъдат мигрирани данните, е свързан с libvirt:

virsh pool-dumpxml $ceph_pool

В описанието на пула трябва да има данни за свързване с Ceph с данни за удостоверяване.

Следващата стъпка е, че LVM образът се конвертира в Ceph RBD. Времето за изпълнение зависи предимно от размера на образа:

qemu-img convert -p -O rbd /dev/main/$vm_image_name rbd:$ceph_pool/$vm_image_name

След конверсията остава LVM образ, който ще бъде полезен в случай, че миграцията на виртуалната машина в RBD не успее и ще трябва да се върнат промените. Освен това — за бързо възстановяване на промените — ще направим резервно копие на конфигурационния файл на виртуалната машина:

virsh dumpxml $vm_name > $vm_name.xml
cp $vm_name.xml $vm_name_backup.xml

… и ще редактираме оригинала (vm_name.xml). Намираме блока с описанието на диска (започва с ред <disk type='file' device='disk'> и завършва на </disk>) и приведем его к следующему виду:

Разберем някои детайли:

  1. В протокола source се посочва адреса до хранилището в Ceph RBD (това е адрес с указание на името на Ceph пула и RBD образа, който бе определен на първия етап).
  2. В блока secret се посочва типът ceph, както и UUID на секрет за свързване. Неговият uuid може да се разбере с командата virsh secret-list.
  3. В блока host се посочват адресите на мониторите на Ceph.

След редактиране на конфигурационния файл и завършване на конверсията от LVM в RBD, може да приложите променения конфигурационен файл и да стартирате виртуалната машина:

virsh define $vm_name.xml
virsh start $vm_name

Сега е време да проверите дали виртуалната машина е стартирала коректно: това може да се направи, например, чрез SSH или чрез virsh.

Ако виртуалната машина работи коректно и не сте открили други проблеми, можете да изтриете LVM образа, който вече не се използва:

lvremove main/$vm_image_name

Заключение

С всички описани случаи се сблъскахме на практика — надяваме се инструкциите да помогнат и на други администратори да решат подобни проблеми. Ако имате коментари или други подобни истории от опита с Ceph — ще се радваме да ги видим в коментарите!

P.S.

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

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

Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри 🔥 Купете надежден хостинг за сайтове със защита от DDoS, VPS и VDS сървъри | ProHoster