Дешевий сервер із китайських запчастин. Частина 1, залізна

Дешевий сервер із китайських запчастин. Частина 1, залізна

Дешевий сервер із китайських запчастин. Частина 1, залізна
Розмита кішка постановки на фоні сервера, що настроюється. На задньому плані – мишка на сервері

Привіт, Хабре!

У житті кожної людини іноді назріває потреба апгрейду комп'ютера. Іноді це покупка нового телефону замість розбитого або в гонитві за свіжим андроїдом або камерою. Іноді – заміна відеокарти, щоб тягла гру на мінімалка. Іноді - установка SSD в ноутбук, на який ви вкорячали десяту вінду, а їй не дуже подобається жити на Core2Duo і 2.5 гігабайтах пам'яті, що адресується, і вона весь час вивантажує невикористовувані сторінки в файл підкачки, знищуючи і без того не велику швидкість обміну з 32- гіговий диск.

Моя історія – апгрейд сервера, який було зібрано ще першому курсі інституту. Мої потреби за минулі шість років зросли, і він, звичайно, отримав збільшення як в оперативній пам'яті, так і в дисковій. Проблема в тому, що з новими знаннями були отримані нові амбіції – бажання застосувати ці знання на практиці – і він з ними міг уже не впоратися.

Спочатку буде трохи нудного вступного тексту, а потім підуть картинки.

Чисто для того, щоб було зрозуміло, який сервер є зараз:

Процесор: Ядро i3-2130 4 потоки, 3.4 GHz
RAM: DDR3 8 GiB
SSD: 250 ГБ

Далі цей сервер згадуватися майже не буде, ці основні характеристики виключно для того, щоб було з чим порівнювати і було зрозуміло, чому ж я вирішив перебороти свою лінь і витратити час і гроші.

Я ще сам не впевнений, чому саме доведеться працювати на новому сервері, але деякі абстрактні думки змушують припускати такі завдання:

  • Хостинг пари-трійки статичних сайтів. Зараз цим займається nginx, але з не найкращим чином оформленими конфігами. Їх теж треба буде виправити, але про це – у другій частині.
  • Хостинг просто статичних файлів. Наприклад, картинок із цієї статті. Вони теж йдуть через nginx, але завантажуються через WinSCP, що незручно. Треба було б накопати подобу myOwnCloud, щоб можна було легко і невимушено заливати картинки на сервер.
  • Білд-сервер для пет-проектів. Нині це Дженкінс.
  • Різні стенди для цих проектів: девелоперський, інтеграційні тести та прод. До продажу поки що справи не дійшло, але стенд тільки один, хоча і в докері.
  • Якісь ігрові сервери, якщо друзям закортить пограти в щось, що вимагає сервера: Starbound, Minecraft, Squad (хоча там потрібно щонайменше людина сорок). І хоча CS 1.6.
  • Віртуалки для друзів, якщо їм раптом терміново потрібно щось десь хостити. Або для себе мати своєрідний VDI. Чим завантажити – знайдеться було б залізо.

Політично віддалені плани:

  • Торрентокачалка: щоб підтримувати рідкісні роздачі на рутрекері. Щоправда, треба розібратися з тим, як їх автоматизовано завантажувати, де їх зберігати, чи не буде провайдер проти постійного фону роздачі і, головне, чи не зацікавляться дядьки в погонах терабайтами, що цілеспрямовано розповсюджуються музики з книгами.
  • Точка виходу з якогось TORа: мило, але ні. З тієї ж причини.

Тим не менш, можна віддавати частину потужностей під аналог нині закритої SETI @ Home. Може, знайомий із цим хабраюзер підкаже, куди можна подіти запал?

Вибір платформи

Ага. З мотиваційною частиною розібралися: хочеться заліза, але незрозуміло під що. Треба визначитися, якого заліза хочеться.

На Хабрі регулярно згадується дешеве б/ушное обладнання: роздача серверів помаранчевою людиною або недавня стаття про б/ушні флеш-прискорювачі. Професійне обладнання коштує дорого. Для розробника у Москві терпимо, але дорого.

Втім, професійне обладнання тому й дороге, що у корпорацій багато грошей має техпідтримку та гарантію якості вищу, ніж у ширвжитку. Не завжди, але матожидання явно зміщене на краще.

Отже, мета - зібрати сервер з б/ушних (читай - дешевих) запчастин і залишити простір для незначного апгрейду в найближчі п'ять років. Такі запчастини дешевші за нові, а ресурсу для розміреного домашнього використання в них може бути ще достатньо. (Цю мету я вигадав вже після того, як зібрав сервер. Все в кращих традиціях написання диплома)

Як наслідок з мети, обладнання повинно мати одне з кращих співвідношень «папуга/рубль», де розрядність папуги залежить від типу обладнання: оперативність – обсяг (не швидкодія, ні), диск – обсяг (і швидкодія), процесор – тут складно. Нехай це будуть синтетичні папуги бенчмарку.

Бажано, щоб сервер прагнув безшумності. Екзотики у вигляді кастомних теплотрубок та безвентиляторних кулерів не обіцяю, але серверу призначено стояти в спальні aka віддаленому офісі aka моїй кімнаті, так що хотілося б, щоб він у режимі простою не ревів, як реактивний літак на зльоті.

Відправна точка - дешеві китайські ксеони, про які я дізнався в незапам'ятні часи, мабуть, теж Хабра. У коментарях до однієї з прохідних новин впав куточок холівара Intel проти AMD. Не порівняти не можна, раптом нові райзени дійсно кращі за інтелівські процесори – я не стежив за ними вже років п'ять, а то й більше.

Отже, у порівнянні беруть участь дві сторони з приблизно однаковим показником папуг на думку cpubenchmark: Ryzen 7 2700, Ryzen 7 2700x, пара Xeon E5-2689, пара E5-2690, пара E5-2696v2 та поточний Ядро i3-2130. Звичайно, я порівнював і інші процесори, наприклад, нові Core i7, нові Ryzen 7 і Ryzen 7 2600, але основний інтерес є саме цим зрізом: вони приблизно однакові за обчислювальною потужністю. Зрештою, це не спроба дозволити холівар, а вибір найбільш відповідного мені процесора. E5-2696v2 та i3-2130 представлені лише для порівняння з іншими б/ушними процесорами та поточним сервером.

AM4
LGA2011

7 2700х
7 2700
e5-2689
2x e5-2689
e5-2690
2x e5-2690
2x e5-2696v2
i3-2100

Ранг, папуги
17898
16021
10036
17945
10207
18967
23518
1839

Ціна, рублі
15200
12500
5000
10000
5500
11000
18000
1000

Тепломощність, Вт
105
65
115
230
135
270
260
65

Ядра, шт
16
16
16
32
16
32
24
4

Частота, ГГц
3,7
3,2
2,6
2,6
2,9
2,9
2,5
3,1

Папуги/рублі
1,18
1,28
2,01
1,79
1,86
1,72
1,31
1,84

Папуги/Вт
170,46
246,48
87,27
78,02
75,61
70,25
90,45
28,29


Таблицю розглядати нудно, давайте подивимося на графік абсолютних папуг:
Дешевий сервер із китайських запчастин. Частина 1, залізна

Я думав опустити цей графік, але тоді довелося б дивитись очима в таблицю, а це не всі люблять робити. Тож це навчальний графік. Зліва – шкала чого б там не було, у цьому випадку – абстрактних синтетичних папуг. Підписи знизу – процесори. Зліва – пара райзенів, по центру – пара одиночних та парних ксеонів. Плутано, так, але це факт. Праворуч – два ксеони другого покоління та процесор поточного сервера.

Ознайомившись із розташуванням процесорів, варто поглянути на графік вартості одного папуги:
Дешевий сервер із китайських запчастин. Частина 1, залізна

З нього видно, що найвигідніше – брати одиночний ксеон першого покоління. Подвійні ксеони трохи гірші за одинарні: вартість зросла вдвічі, а ккд – в 1.7 разу, тобто співвідношення знизилося. А ось ксеон другого покоління вже не вигідний: вартість папуги вже наближається до райзенів.

А райзени страшенно енергоефективні в перерахунку на папугу:
Дешевий сервер із китайських запчастин. Частина 1, залізна

Треба визнати, що в цей момент я відчув гордість за прогрес людства та AMD. Це вже не екстенсивний шлях розвитку, це спроби вичавити максимум із шматка кремнію. E5-2690 вийшов у 2012 році, а Ryzen 7 2700 – у 2018. Триразове зростання енергоефективності за шість років – не вік для технології. А, та й Core i3-2100 десь зовсім непомітний у кутку. Не будемо про нього.

проміжний висновок: райзени рвуть у співвідношенні «продуктивність/енергія». Або це булинний різний спосіб вимірювання TDP у AMD та Intel. А вушні ксеони першого покоління рвуть за співвідношенням «продуктивність/ціна».

Таким чином, братиму ксеони. Ви ж не забули мети, яку я поставив на самому початку цього розділу?

Інше супутнє залізо

Насправді, вибір AMD vs Intel обмежує не тільки процесор, що застосовується. Процесори Zen+ використовують пам'ять стандарту DDR4 (тиц), а Sandy Bridge - DDR3 (тиц). DDR4-2933 теоретично в 1.87 рази швидше за DDR3-1600, якщо я хоч щось у цьому розумію. Ні, я пам'ятаю з інститутського курсу, як працює DDR, з усіма цими CS, RAS, CAS та іншими. І Burst Mode. Просто не хочу в це заглиблюватися, бо пам'ятаю дуже невиразно, та й DDR3 вже неявно обраний процесором, сенсу мучитися немає.

До того ж 16 гігів DDR4-2600 коштує стільки ж, скільки 32 гіга DDR3-1866 * з ECC...

* Воно не 1866, а 1778. Поняття не маю, чому похмурий китайський геній не зміг подужати 1866, але й не став спускатися до стандартних 1600 МГц.

Обмеження по сокету та типу пам'яті впливають і на вибір материнської плати: за ті ж 7к рублів можна взяти китайську плату з максимальними 256 гігабайтами оперативної пам'яті, а будь-яка AM4-сокетна має максимум 4 слоти під оперативку, тобто обмежена 64 гігабайтами.

Вибір двосокетної материнської плати веде за собою особливі вимоги до блоку живлення: у нього мають бути два восьмипінові контакти для живлення процесора. Може, від відеокарти і підійдуть, але там трохи різної форми штирі, я вирішив не ризикувати і не читати документацію, благо блоки живлення з потрібними вимогами існують.

Ще біля цієї материнської плати некультурно розташовані сокети: відстань між ними трохи менше 10 сантиметрів, що ускладнює встановлення двох кулерів паралельно. Спочатку я хотів поставити кулери так, щоб забір повітря походив із щілини між ними, але про це нижче.

Для зберігання даних я спочатку хотів взяти той SSD, який вже є у старому сервері, під систему, але вирішив взяти з роз'ємом M2 Crucial P1 на 1TB. На материнській платі є шість роз'ємів SATA, і в них я планував підключити шість жорстких дисків WD Red 2TB, але поки я роздумував, чи варто витрачати ще 12к рублів на них, їх вже купили. Отже, налаштування ZFS-рейду в другу частину статті не входить. Але це потім, розповідь про SSD. Набагато професійніший огляд на нього можна прочитати тут. Його фішка у тому, що він дешевий. Самі подивіться цей графік записи:

Дешевий сервер із китайських запчастин. Частина 1, залізна

На нього одночасно можна записати 75 гігабайт, а потім він стає гіршим за жорсткий диск. Дякую, що хоч не починає обертатися. А, і ще його можна перезаписати лише 200 разів. З чого він взагалі зроблений?

Насправді це не так страшно для того режиму, в якому я планую його використовувати: переважно читання даних і запис не критичних до швидкості запису даних. Ну мені хочеться на це сподіватися.

Ресурс перезапису у 200 разів відповідає приблизно 109 гігабайтам на день протягом п'яти років. 109 гігабайт на день – не те саме, що 75 гігабайт одночасно. Та й із читанням у нього все нормально. Не найкраща продуктивність серед M2 дисків, але відповідає тому рівню запису, що він показує в межах кеша.

збірка

Якщо раніше був переважно псевдотехнічний текст, перемежований графіками, то зараз підуть картинки, розбавлені художнім оповіданням.

Раптом вранці зателефонував кур'єр Пошти Росії і сказав, що сьогодні приїде з посилкою. Я зазвичай забираю посилки сам, а тут на карантині вирішили напружити відділ доставки, мабуть.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Зовнішній вигляд посилки

Хитрий китаєць упакував все в один пакет, хоча я замовляв чотирма різними замовленнями на аліекспресі, щоб не потрапити під мита про двісті євро.

Дешевий сервер із китайських запчастин. Частина 1, залізна
вміст коробки

До материнської плати поставляється цілий аркуш з інструкцією! Про сигнали спікера треба здогадуватись самому. На сайті написано, що помаранчеві слоти оперативної пам'яті – основні, треба ставити саме в них. Інструкція ж марна трохи менше, ніж повністю. Я кнопку ввімкнення по ній підключив. До речі, на коробці є єдиний напис – MOTHERBOARD. Вона не заслуговувала на окрему фотографію, але згадки безумовно заслужила.

Витягаємо корпус, пилососимо. Насправді, не варто його діставати, від нього виявилися одні муки. Але він естетично виглядає. Виглядав…

Дешевий сервер із китайських запчастин. Частина 1, залізна
Корпус, вид догори ногами

У корпусі є оповідні санки. (А я планую 3.5” диски. Прийде вийняти плату)

Дешевий сервер із китайських запчастин. Частина 1, залізна
Місце під диски

Ще на лицьовій панелі є вентилятори, що швидко замінюються. Напевно галасливі.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Вони управляються чимось складнішим, ніж просто прямо материнською платою

Знімаємо верхню кришку та дивимося, що всередині. Якщо відкрутити пару гвинтів, можна зрушити дисковий простір і звільнити місце для маніпуляцій. А материнська плата формату E-ATX займає майже все місце в сервері.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Рідний блок живлення

Блок живлення у мене просто так витягнути не вийшло, довелося відгвинтити всі гвинти на задній частині та майже розібрати весь корпус. З'ясувалося, що він тримався на двох гвинтах та шматку скотчу. Це було підло, але тепер я сам можу застосувати таку тактику.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Ось вона ліворуч, нещасна чорна смуга!

Я вже втомився вибирати найбільш вдалі фотографії, відсіювати ті, які не потрібні для оповідання, обрізати картинки та вантажити їх на сайт. Тим часом настає наступного дня, а у мене на столі лише китайські запчастини. Доводиться швидко оформляти замовлення і мчати в магазин на інший кінець Москви.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Біля входу до магазину

Торговий зал закритий, працює лише видача замовлень. Добре, що була сонячна погода, не знаю, як довелося б у дощ. Замовлення слід називати через відеодомофон, шкода, що це мало пояснюється. Було б непогано надрукувати хоч якусь інструкцію, крім «дотримуйтесь дистанції 2 метри». Очікування не довше десяти хвилин, здорове. Їдемо назад.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Два кулери, один блок живлення і малесенький SSD

Оскільки кулери, придатні за габаритами корпусу, були дорогі і галасливі, довелося вибрати негабаритний варіант. Це позбавило мук вибору з блоком живлення: тихий ATX-формату, але з ним доведеться зняти кришку, або одноюнітовий, але галасливий і дорожчий на дві тисячі рублів. Починаємо приміряти покупки. Початкова задумка двох кулерів - забирати повітря з центру, але ємність для дисків, що зрушується, внесла корективи і довелося переставити вентилятори на послідовний продув. Цікаво буде спостерігати на одному кристалі температуру на пару градусів вище, ніж на іншому.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Поки що без термопасти

Протираємо основу кулера та процесор спиртом. Питним. Але він уже кілька років як технічний, перорально краще не застосовувати. Поступово наносимо термопасту чимось плоским. Насправді, я погано розуміюся на нанесенні термопасти, але результати моїх робіт завжди приносили позитивний результат. Мабуть, тут складно напортачити, якщо навіть клей «Момент» здатний працювати роками, судячи з байків. Зазвичай використовую шматок непотрібної пластикової картки, але його під рукою не виявилося. Виявився її місці новомодний безногий четвертий пень. Не турбуйтеся, після процедури я протер його спиртом і поклав на полицю.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Щось дивне й хвилююче
Нанесення неідеальне, та й кулер я притискав не повністю: видно усунення «лисого» місця щодо центру.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Пристрілка

Додаємо додатковий шар термоінтерфейсу до місць, де його явно не вистачає і трохи по інших місцях.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Єп, задовільно

Приступаємо до встановлення материнської плати. У сервері явно стояло щось іншого формату, і ті… е-е-е… штуцери, в які загвинчуються гвинти для фіксації материнської плати, розташовувалися не так на E-ATX плати. На жаль, у шматку металу, в який загвинчуються штуцери, не вистачило трьох отворів навпроти тих, що були в материнській платі. На щастя, самих штуцерів теж забракло трьох штук.

Через це материнська плата провисає в місцях кріплення 24-пінового конектора та PCI-E роз'ємів. З одного боку це текстоліт. З іншого боку, це китайський текстоліт, що ніколи не знаєш, чого від нього чекати. Але тиснути треба акуратно в будь-якому випадку, будь це навіть сертифікований військовий прийом текстоліт. Навіть ні, в такому випадку треба тиснути ще дбайливіше - він теж зроблений у Китаї, але штучна сертифікація та приймання збільшила вартість пристрою в кілька десятків разів.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Купа дірок і все не там

Пам'ятаєте блок живлення на скотчі? Історія циклічна, ось повторення:

Дешевий сервер із китайських запчастин. Частина 1, залізна
І так, мені це не подобається

Складання завершено, переносимо комп'ютер у кімнату до брата, віднімаємо клавіатуру та монітор у живого сервера і намагаємося включити його. З першого разу не виходить навіть у біос. Оскільки в ксеонах звичайно немає вбудованого графічного співпроцесора, а біос вивести на екран треба, ставимо якусь просту відеокарту. Боги, як вона шумить!

З другого разу вийти у біос теж не виходить. Шляхом перебирання винуватців приходимо до вирішення: помінявши місцями планки оперативної пам'яті і вийнявши SSD можна достукатися до біосу. Вставляємо на місце SSD і вмикаємо комп'ютер ще раз – біос вантажиться, диск визначається. Мабуть, щось скинулося при відсутній батареї CR2032.

До речі, бачите, що блок для жорстких дисків видається вперед більш ніж повинен? Він упирається в кулер. Це не ідеальний корпус для комп'ютерів класичного форм-фактора, що вдієш.

Дешевий сервер із китайських запчастин. Частина 1, залізна
Місце для первинного налаштування

Невеликий відступ із приводу шуму: з відеокартою рівень шуму був на рівні 27-30 децибел, а після встановлення операційної системи рівень шуму сервера знизився десь до 8-14 децибел. Точніше виміряти було складно, оскільки фоновий рівень шуму теж був десь у цьому діапазоні: будівництво метро на вулиці, кулі, що катаються у сусідів зверху, тупіт кішки та інше подібне. Сервер стоятиме в ікеївській шафі без дверцят, тому такий рівень шуму підійде.  

Бонус

Технічно, цей розділ відноситься не до вибору і збирання заліза, але на самостійну главу установка операційної системи не тягне. На багатьох ресурсах вже описана установка будь-чого на різні пристрої, і те, що станеться тут - абсолютно рядове явище. Плодити зайвий туторіал, до того ж, можливо, невірний, мені зовсім не хочеться.

Тим не менш, я опишу граблі, на які настав у процесі встановлення ОС.

Windows Server через відсутність ліцензії я ставити не став, та й звик більше взаємодіяти з лінуксовими серверами. На старому сервері стоїть Ubuntu, але на парі VPS, що мало використовуються, стоїть CentOS і на роботі – RHEL. Тому знайомитимемося ближче з CentOS 8.

Ідемо на будь-яке дзеркало, завантажуємо .torrent-файл - і за пару десятків хвилин викачуємо семигігабайтний образ.

Вставляємо флешку, знаходимо її та копіюємо образ на неї.

frog@server:~$ lsblk
NAME   MAJ:MIN RM   SIZE RO TYPE MOUNTPOINT
sdb      8:16   1  14,6G  0 disk
└─sdb4   8:20   1  14,6G  0 part /media/localadmin/ANACONDA
sda      8:0    0 223,6G  0 disk
├─sda2   8:2    0    24G  0 part [SWAP]
├─sda3   8:3    0   128G  0 part /
└─sda1   8:1    0   243M  0 part /boot/efi
frog@server:~$ dd if=/home/frog/CentOS-8.1.1911-x86_64-dvd1.iso of=/dev/sdb
dd: failed to open '/dev/sdb': Permission denied
frog@server:~$ sudo !!
sudo dd if=/home/frog/CentOS-8.1.1911-x86_64-dvd1.iso of=/dev/sdb

І йдемо пити чай. За годину приходимо у впевненості, що все вже давно скопіювалося – але запрошення на введення не з'явилося. Отже, все ще копіюється. Окей, новий термінал, запитуємо у dd, скільки залишилось.

  PID TTY          TIME CMD
 1075 tty5     00:00:00 bash
 1105 tty5     00:00:00 sudo
 1106 tty5     00:00:00 su
 1112 tty5     00:00:00 bash
 1825 pts/18   00:00:00 sudo
 1826 pts/18   00:01:08 dd
 2846 pts/0    1-23:03:42 java
 5956 pts/19   00:00:00 bash
 6070 pts/19   00:42:15 java
 6652 pts/20   00:00:00 ps
 7477 tty4     00:00:00 bash
 7494 tty4     00:00:00 sudo
 7495 tty4     00:00:00 su
 7497 tty4     00:00:00 bash
frog@server:~$ kill -USR1 1826
-bash: kill: (1826) - Operation not permitted
frog@server:~$ sudo !!
sudo kill -USR1 1826

Відповідь у старому терміналі:

9025993+0 records in
9025993+0 records out
4621308416 bytes (4,6 GB, 4,3 GiB) copied, 13428,4 s, 344 kB/s

І ще через пару десятків хвилин:

14755840+0 records in
14755840+0 records out
7554990080 bytes (7,6 GB, 7,0 GiB) copied, 14971,5 s, 505 kB/s

Що це було? Воно його побайтно копіювало? Бідний ресурс флешки. Або перевіряло коректність запису. У будь-якому випадку, треба було man dd і використовувати великі блоки копіювання, і ще щось, що знадобилося одного разу при копіюванні 64-гігового HDD на 5400 обротів за хвилину. Але навіть він копіювався з більшою швидкістю, ніж третина USB 1.0.

А потім стандартний вибір флешки як Boot Device, Next, Next, Next, Finish. Жодних маніпуляцій з розміткою диска, налаштуванням Ethernet. Найпростіша установка ОС у 2020 році.

Висновок

Ця перша частина розповіді про налаштування нового сервера. Я б випустив його відразу повністю, але у мене в чернетках лежать ще дві недописані статті, які, як мені здається, цікавіше «yet another server build», а друга частина про налаштування софту погрожує закінчитися нескоро.

Підсумкова вартість склала 57973 XNUMX рубля. Ось розбивка детальніше, щоправда, посилання на аліекспрес показують уже трохи інші товари.

Оперативна пам'ять 32GB DDR3-1866 - 4 шт
19078 рублів

Процесор Xeon E5-2690 - 2 шт
10300 рублів

Материнська плата Jingsha X79 Dual Socket - 1 шт
9422 рубля

Блок живлення ExeGate ServerPRO RM-800ADS - 1 шт
4852 рубля

кулер ID-Cooling ID-CPU-SE-224-XT - 2 шт
3722 рубля

SSD Crucial P1 CT1000P1SSD8
10599 рублів

Корпус Noname
Безкоштовно

Орієнтовна вартість володіння - 3.89 руб / кВт * год * 0.8 кВт * 24 год * 31 день = 2315 руб / місяць. Але це якщо він молотитиме на всю котушку не перестаючи протягом місяця, у чому я дуже сумніваюся з причин відсутності таких завдань та живучості заліза. Для порівняння, вартість оренди аналогічного сервера із якісних деталей становить близько 25к руб/місяць.

Думаю, це цілком добрий сервер за свої гроші.

Джерело: habr.com

Додати коментар або відгук