Tips & tricks у працы з Ceph у нагружаных праектах

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. Для гэтага выконваюцца наступныя каманды:

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 з CRUSH map:

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 (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. Час выканання залежыць у першую чаргу ад памеру выявы:

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>) і прывядзем яго да наступнага ўвазе:

<disk type='network' device='disk'>
<driver name='qemu'/>
<auth username='libvirt'>
  <secret type='ceph' uuid='sec-ret-uu-id'/>
 </auth>
<source protocol='rbd' name='$ceph_pool/$vm_image_name>
  <host name='10.0.0.1' port='6789'/>
  <host name='10.0.0.2' port='6789'/>
</source>
<target dev='vda' bus='virtio'/> 
<alias name='virtio-disk0'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</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 - будзем рады ўбачыць іх у каментарах!

PS

Чытайце таксама ў нашым блогу:

Крыніца: habr.com

Дадаць каментар