
Използвайки Ceph като мрежово хранилище в проекти с различна натовареност, можем да се сблъскаме с различни задачи, които на пръв поглед не изглеждат простички или тривиални. Например:
- мигриране на данни от стар Ceph в нов с частично използване на предишни сървъри в новия клъстер;
- решаване на проблема с разпределението на дисковото пространство в Ceph.
Справяйки се с такива задачи, ние се сблъскваме с необходимостта да извадим OSD правилно, без загуба на данни, което е особено актуално при големи обеми данни. За това ще става дума в статията.
Описание на методите по-долу е актуално за всички версии на Ceph. Освен това ще бъде взето предвид, че в Ceph могат да се съхраняват големи обеми данни: за да се предотвратят загуби на данни и други проблеми, някои действия ще бъдат "разделени" на няколко други.
Предговор относно OSD
Тъй като две от трите разглеждани рецепти са посветени на OSD (), преди да се потопим в практическата част — накратко за това какво изобщо е то в Ceph и защо е толкова важно.
На първо място, трябва да се каже, че целият Ceph клъстер се състои от много OSD. Колкото повече 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, е необходимо плавно да се изпълни reweight на него до нула. По този начин намаляваме количеството данни в OSD чрез балансировка в други OSD. За целта се изпълняват следните команди:
ceph osd reweight osd.${ID} 0.98
ceph osd reweight osd.${ID} 0.88
ceph osd reweight osd.${ID} 0.78… и така нататък до нула.
Плавното балансиране е необходимо, за да не загубим данни. Това е особено актуално, ако в OSD има голям обем данни. За да се уверим, че след изпълнението на командите reweight всичко е преминало успешно, можем да изпълним ceph -s или в отделен прозорец на терминала да стартираме ceph -w за да наблюдаваме промените в реално време.
Когато OSD е "освободена", можем да пристъпим към стандартната операция за нейното изтриване. За целта ще преместим нужния OSD в състояние down:
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 от :
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 Премахваме mon от сървера hv-2, като изпълните командата по-долу на друг сървър (т.е. в този случай — на hv-1):
ceph-deploy mon destroy hv-2След това можете да спрете сървъра и да преминете към следващите действия (повторното му разгръщане и т.н.).
Случай №2. Разпределение на дисковото пространство в вече създаден Ceph клъстер
Втората история ще започне с предисловие за PG (). Основната роля на 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 клъстера. Един от инструментите, които можете да използвате, е . С негова помощ наглядно се изчислява необходимото количество PG. Въпреки това, може да се прибегне и в ситуация, когато Ceph клъстера вече е неправилно конфигуриран. Тук трябва да уточните, че в рамките на работата по корекция вероятно ще трябва да намалите количеството PG, а тази възможност не е налична в старите версии на Ceph (тя се появи само с версията ).
Така, да си представим следната картина: статус на клъстера е HEALTH_WARN заради това, че в един от OSD свършва мястото. За това ще свидетелства грешка HEALTH_WARN: 1 near full osd. По-долу е представен алгоритъм за излизане от такава ситуация.
На първо място, трябва да разпределим наличните данни между останалите OSD. Подобна операция вече сме изпълнявали в първия случай, когато „успокоявахме“ възела – с единствената разлика, че сега е необходимо да намалим малко reweight. Например, до 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>) и ще го приведем към следния вид:
Нека разгледаме някои детайли:
- В протокола
източниксе посочва адресът на хранилището в Ceph RBD (това е адрес с обозначение на името на Ceph пула и RBD изображението, което беше определено на първия етап). - В блока
secretсе посочва типътceph, както и UUID на секретния ключ за свързване с него. Неговият uuid може да бъде получен с командаvirsh secret-list. - В блока
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
