През годините на съществуване на Pinterest 300 милиона потребители на услугата създадоха над 200 милиарда пина на повече от 4 милиарда дъски. За да обслужва тази армия от потребители и обширната база с съдържание, порталът е разработил хиляди услуги, започвайки от микросервизи, с които могат да се справят няколко CPU, и стигайки до гигантски монолити, които работят на цял парк от виртуални машини. И ето, настъпи моментът, в който погледът на компанията се спря на k8s. Какво привлече вниманието на „Pinterest“ към „кубчето“? За това ще научите от нашия превод на свежата статия от .

И така, стотици милиони потребители и стотици милиарди пина. За да обслужваме тази армия от потребители и обширната база с съдържание, разработихме хиляди услуги, започвайки от микросервизи, с които могат да се справят няколко CPU, и стигайки до гигантски монолити, които работят на цял парк от виртуални машини. Освен това, разполагаме с разнообразни рамки, които също могат да изискват ресурси на CPU, памет или достъп до операции за вход-изход.
По време на поддръжката на този зоопарк от инструменти, екипът за разработка се сблъсква с редица проблеми:
- Инженерите нямат унифициран начин за стартиране на работна среда. Stateless услуги, Stateful услуги и проекти в активна разработка се базират на абсолютно различни технологични стаковe. Това доведе до създаването на цял обучителен курс за инженерите, а също така сериозно усложнява работата на нашия инфраструктурен екип.
- Разработчиците, които разполагат с собствен парк от виртуални машини, създават огромно натоварване на вътрешните администратори. В резултат на това, толкова прости операции, като обновяване на ОС или AMI, се разпределят в срокове от седмици и месеци. Това води до повишаване на натоварването в, изглеждащите, абсолютно рутинни ситуации.
- Трудности при създаването на глобални инструменти за управление на инфраструктурата над вече съществуващите решения. Ситуацията се усложнява и от факта, че намирането на собственици на виртуалните машини не е лесно. Тоест, не знаем, дали можем безопасно да изтеглим тези ресурси за работа на други участъци от нашата инфраструктура.
Контейнерните системи за оркестрация са начин за унифициране на управлението на работното натоварване. Те ви отварят пътя към увеличаване на скоростта на разработка и опростяват управлението на инфраструктурата, тъй като всички ресурси, участващи в проекта, се управляват от една централизирана система.

Рисунка 1: Приоритети на инфраструктурата (надеждност, производителност на разработчиците и ефективност).
Екипът на Cloud Management Platform в Pinterest се запозна с K8s през 2017 г. До първата половина на 2017 г. документирахме голяма част от нашите производствени мощности, включително API и всичките ни уеб-сервери. След това проведохме внимателна оценка на различни системи за оркестрация на контейнерни решения, изграждане на клъстери и работа с тях. До края на 2017 г. решихме да използваме Kubernetes. Той беше достатъчно гъвкав и широко поддържан в общността на разработчиците.
До момента сме създали собствени инструменти за първично зареждане на клъстера, базирани на Kops, и прехвърлихме съществуващите компоненти на инфраструктурата на Kubernetes — като мрежа, сигурност, метрики, водене на журнали и управление на идентичността и трафика. Също така реализирахме система за моделиране на работните натоварвания за нашия ресурс, чиято сложност е скрита от разработчиците. Сега сме фокусирани върху осигуряване на стабилността на клъстера, неговото мащабиране и свързване на нови клиенти.
Kubernetes: пътят на Pinterest
Започването на работа с Kubernetes в мащабите на Pinterest като платформа, която ще бъде обичана от нашите инженери, доведе до множество трудности.
Като голяма компания вложихме значителни средства в инфраструктурни инструменти. За пример можем да посочим инструментите за сигурност, които обработват сертификати и разпределят ключове, компоненти за контрол на трафика, системи за откриване на услуги, компоненти за видимост и изпращане на журнали и метрики. Всичко това беше събрано не случайно: преминахме през нормалния процес на проби и грешки, затова желаехме да интегрираме всичко това в новата инфраструктура на Kubernetes вместо да преоткриваме стари механизми на новата платформа. Този подход определи миграцията по-лесно, тъй като всичката поддръжка на приложенията вече съществува, не е нужно да я създаваме от нулата.
От друга страна, моделите за прогнозиране на натоварвания в самия Kubernetes (например, разгръщания, задачи и набори Daemon) не са достатъчни за нашия проект. Тези проблеми с юзабилитета представляват огромни препятствия по пътя към преминаването на Kubernetes. Например, чували сме как разработчиците на услуги се оплакват от липсата или некоректната конфигурация на входа. Също така сме се срещали с неправилното използване на шаблонизатори, когато са създавани стотици копия със същата спецификация и задача, което е довело до ужасни проблеми с откритията.
Също така беше много трудно да се поддържат различни версии в един и същи кластер. Представете си сложността на клиентската поддръжка, ако трябва да работите веднага с множество версии на една и съща среда за изпълнение, с всички техни проблеми, бъгове и актуализации.
Потребителски ресурси и контролери на Pinterest
За да улесним процеса на внедряване на Kubernetes за нашите инженери, както и да опростим инфраструктурата и да ускорим работата й, разработихме собствените си определения на потребителски ресурси (CRD).
CRD предлагат следните функционални възможности:
- Обединяване на различни нативни ресурси на Kubernetes, така че да работят като единно натоварване. Например, ресурсът PinterestService включва разгръщане, входна служба и конфигурационна карта. Това позволява на разработчиците да не се притесняват за настройката на DNS.
- Внедряване на необходимата поддръжка на приложения. Потребителят трябва да се фокусира само върху спецификацията на контейнера според своята бизнес логика, докато контролерът на CRD внедрява всички необходими init-контейнери, променливи на средата и спецификации на pod. Това осигурява съвсем ново ниво на комфорт за разработчиците.
- Контролерите на CRD също управляват жизнения цикъл на собствените ресурси и подобряват наличността на отстраняване на проблеми. Това включва съгласуване на желаната и реалната спецификация, актуализиране на статуса на CRD и водене на логове за събития и не само. Без CRD разработчиците щяха да бъдат принудени да управляват многобройни набори от ресурси, което само би увеличило вероятността за грешки.
Ето един пример за PinterestService и вътрешен ресурс, който се управлява от нашия контролер:

Както може да се види по-горе, за да поддържаме потребителския контейнер, е необходимо да интегрираме контейнер за инициализация и няколко допълнения, за да осигурим безопасност, видимост и работа с мрежовия трафик. В допълнение, създадохме шаблони за конфигурационни карти и реализирахме поддръжка на шаблони PVC за пакетни задания, а също така проследяване на множество променливи на средата за следене на идентификация, потребление на ресурси и събиране на „мусор“.
Трудно е да си представим, че разработчиците биха искали да напишат тези конфигурационни файлове ръчно без поддръжка от CRD, а за по-нататъшната поддръжка и отстраняване на грешки в конфигурациите да не говорим.
Работен поток за разгръщане на приложения

На горната рисунка е показано как да се разгрърне потребителски ресурс Pinterest в кластер Kubernetes:
- Разработчиците взаимодействат с нашия кластер Kubernetes чрез CLI и потребителски интерфейс.
- Инструменти CLI / UI извлекат YAML файлове на конфигурацията на работния процес и други свойства на компилацията (същия идентификатор на версията) от Artifactory, след което ги изпращат в Job Submission Service. Тази стъпка гарантира, че в кластра ще се поставят само работещи версии.
- JSS е шлюз за различни платформи, включително Kubernetes. Тук се извършва аутентификация на потребителя, разпределение на квоти и частична проверка на конфигурацията на нашия CRD.
- След проверка на CRD на страна JSS информацията се изпраща на API на платформата k8s.
- Нашият CRD контролер проследява събития на всички потребителски ресурси. Той преобразува CR в нативни ресурси на k8s, добавя необходимите модули, задава съответните променливи на средата и извършва други помощни задачи, като по този начин гарантира достатъчна инфраструктурна поддръжка за контейнерни потребителски приложения.
- След това контролерът CRD предава получената информация на API на Kubernetes, за да бъде обработена от планировщика и да бъде стартирана в работа.
Забележка: това предварително производствено работно протокол за внедряване беше създадено за първите потребители на новата k8s платформа. В момента работим по усъвършенстването на този процес, за да се интегрираме напълно с нашата нова CI/CD. Това означава, че не можем да споделим всичко, свързано с Kubernetes. Очакваме с нетърпение възможността да споделим нашия опит и да разкажем за напредъка на екипа в тази насока в следващия ни блог пост „Създаване на CI/CD платформа за Pinterest“.
Видове специализирани ресурси
Въз основа на конкретните нужди на Pinterest, разработихме следните CRD, които отговарят на различни работни потоци:
- PinterestService — това са дългосрочни stateless услуги. Много от нашите основни системи са изградени на базата на набор от такива услуги.
- PinterestJobSet моделира пакетни задачи с пълен цикъл. В Pinterest съществува разпространен сценарий, при който няколко задания стартират едни и същи контейнери паралелно, независимо от другите подобни процеси.
- PinterestCronJob се използва широко за малки периодични натоварвания. Това е обвивка за нативната работа на cron с механизми за поддръжка на Pinterest, които отговарят за сигурност, трафик, логове и метрики.
- PinterestDaemon включва инфраструктурни демон- програми. Това семейство продължава да расте, тъй като добавяме все повече поддръжка за нашите клъстери.
- PinterestTrainingJob обхваща процесите на Tensorflow и Pytorch, осигурявайки същото ниво на поддръжка по време на работа, както и всички останали CRD. Понеже Pinterest активно използва Tensorflow и други системи за машинно обучение, имаше основания да изградим около тях отделен CRD.
Също така работим по PinterestStatefulSet, който скоро ще бъде адаптиран за бази данни и други stateful системи.
Поддръжка на среда за изпълнение
Когато модулът на приложението стартира в Kubernetes, той автоматично получава сертификат за собствена идентификация. Този сертификат се използва за достъп до секретното хранилище или за комуникация с други услуги чрез mTLS. Междувременно, конфигуриращият инструмент за инициализация на контейнери и Daemon ще зареди всички необходими зависимости преди стартиране на контейнерното приложение. Когато всичко е готово, транспортният sidecar и Daemon ще регистрират IP адреса на модула в нашия Zookeeper, за да могат клиентите да го открият. Всичко това ще работи, тъй като мрежовият модул е бил конфигуриран още преди стартиране на приложението.
По-горе са представени типични примери за поддръжка на натоварвания по време на изпълнение. За други типове натоварвания може да е необходима малко по-различна поддръжка, но всички те са представени под формата на sidecar на ниво pod, възлови или Daemon системи на ниво виртуални машини. Ние следим за осигуряване на разгръщането на всичко това в рамките на управляващата инфраструктура и за синхронизация между приложенията, което в крайна сметка значително снижава натоварването в отношение на техническите работи и поддръжка на клиентите.
Тестване и QA
Създадохме end-to-end тестови конвейер върху вече съществуваща тестова инфраструктура Kubernetes. Тези тестове обхващат всички наши клъстери. Нашият пайплайн премина през множество преустройства, преди да стане част от продуктовия клъстер.
Освен системите за тестване, имаме системи за наблюдение и уведомяване, които постоянно следят състоянието на компонентите на системата, потреблението на ресурси и други важни показатели, уведомявайки ни само при необходимост от човешка намеса.
Алтернативи
Разгледахме някои алтернативи на персонализираните ресурси, като мутационни контролери за достъп и системи за шаблони. Въпреки това, всички те са свързани със сериозни трудности в работата, така че избрахме пътя на CRD.
Мутиралият контролер за достъп е бил използван за въвеждане на sidcar-ове, променливи на средата и друга поддръжка по време на изпълнение. Въпреки това, той се сблъска с различни проблеми, като свързване на ресурси и управление на техния жизнен цикъл, докато при CRD тези проблеми не възникват.
Забележка: Системите за шаблони, като диаграмите Helma, също така се използват широко за стартиране на приложения с подобни конфигурации. Въпреки това, нашите работни приложения са твърде разнообразни, за да бъдат управлявани чрез шаблони. Освен това, по време на непрекъснато внедряване с използване на шаблони ще възникват твърде много грешки.
Предстоящата работа
В момента се справяме с комбинирана натовареност на всички наши клъстери. За да поддържаме подобни процеси от различен тип и размер, работим в следните направления:
- Съвкупността от клъстери разпределя големи приложения по различни клъстери за осигуряване на мащабируемост и стабилност.
- Осигуряване на стабилност, мащабируемост и видимост на клъстера за свързване на приложението и неговото SLA.
- Управление на ресурсите и квотите, за да не настъпват конфликти между приложенията, а мащабът на клъстера да бъде контролиран от наша страна.
- Нова платформа CI/CD за поддръжка и внедряване на приложения в Kubernetes.
Източник: habr.com
