Tips & tricks у працы з 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, запатрабуецца плыўна выканаць reweight на ёй да нуля. Такім чынам мы змяншаем колькасць дадзеных у OSD за кошт балансавання ў іншыя OSD. Для гэтага выконваюцца наступныя каманды:
Плыўнае балансаванне неабходна, Каб не страціць дадзеныя. Гэта асабліва актуальна, калі ў OSD знаходзіцца вялікі аб'ём даных. Каб дакладна пераканацца, што пасля выканання каманд reweight усё прайшло паспяхова, можна выканаць ceph -s ці ж у асобным акне тэрмінала запусціць ceph -w для таго, каб назіраць за зменамі ў рэальным часе.
Калі OSD "спустошана", можна прыступіць да стандартнай аперацыі па яе выдаленні. Для гэтага перавядзем патрэбную OSD у стан down:
Заўвага: калі вы выкарыстоўваеце версію 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 (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. Падобную аперацыю мы ўжо выконвалі ў першым кейсе, калі "асушалі" вузел - з той толькі розніцай, што зараз спатрэбіцца нязначна паменшыць. 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. Час выканання залежыць у першую чаргу ад памеру выявы:
Пасля канвертавання застанецца LVM-выява, які будзе карысны ў выпадку, калі міграваць ВМ у RBD не атрымаецца і давядзецца адкочваць змены. Таксама - для магчымасці хутка адкаціць змены - зробім бэкап канфігурацыйнага файла віртуальнай машыны:
… і адрэдагуемы арыгінал (vm_name.xml). Знойдзем блок з апісаннем дыска (пачынаецца з радка <disk type='file' device='disk'> і заканчваецца на </disk>) і прывядзем яго да наступнага ўвазе:
У пратакол source паказваецца адрас да сховішча ў 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 - будзем рады ўбачыць іх у каментарах!