Парадигма программирования Golang в контексте Kubernetes

Docker API Google etcd

предисловие

Эта статья организована в соответствии с выступлением Чжан Лея, гостя станции Gopher Meetup в Ханчжоу. Тема выступления — «Парадигма программирования на основе Golang в контексте Kubernetes». В этой статье будут представлены следующие аспекты:

1. Причины выбора Golang для проектов Kubernetes

2. Шаблоны проектирования Kubernetes

3. Демонстрация контроллера

4. Парадигмы программирования для проектов Kubernetes

5. Резюме

Почему проекты Kubernetes выбирают Golang?

Первая часть начинается с того, что такое Kubernetes. Позиционирование Kubernetes очень ясное и простое.Это фреймворк для оркестрации и управления расписанием контейнеров.Он был инициирован Google и также является производным проектом с открытым исходным кодом проекта Google Borg/Omega. На данный момент это один из самых популярных проектов с открытым исходным кодом в мире (первое место занимает Linux, четвертое — Kubernetes), а это значит, что его активность в сообществе и скорость разработки проекта достаточно высоки. Подобный быстро итеративный проект на уровне платформы реализован в Golang, и он больше полагается на Golang, чем на другие проекты, отчасти из-за тесной связи между Golang и Google, а отчасти потому, что проект пишется в процессе разработки и разработки, Инженеры Google представили множество уникальных шаблонов проектирования, о которых мы и поговорим.

В отличие от других проектов, многие проекты говорят, что большинство причин использования Golang заключаются в том, что разработка Golang очень удобна, его производительность хорошая или его параллельное программирование превосходно. Но для такого проекта, как Kubernetes, это не главные причины. В конце концов, проект Google Borg написан на C++, и если что-то подобное должно быть выпущено как проект с открытым исходным кодом, почему бы не использовать C++? По крайней мере, внутренние библиотеки могут быть общими, и для C++ вполне естественно писать проект на уровне платформы. Но не об этом в первую очередь думает проект Kubernetes, это вы все здесь. В чем смысл? Kubernetes нуждается в разработчиках Golang для поддержки этого проекта, что является самым важным моментом в проекте с открытым исходным кодом в то время. Вы можете быть немного удивлены. Мы все знаем, что Google не очень хорош в открытом исходном коде. До Kubernetes дела Google с открытым исходным кодом были не очень надежными, но после Kubernetes, включая следующий TensorFlow, это огромный успех. происходят изменения? Это потому, что Google впервые видит роль, которую сообщество может сыграть в успехе этих проектов, и это огромное преимущество, которое может дать такой язык программирования, как Golang. У меня есть еще один пример — контейнерный проект LMCTFY. Это внутренняя реализация контейнера Google, следующая за открытым исходным кодом Docker, написанная на C++, и я думаю, что немногие использовали ее. Однако сам этот проект намного мощнее, чем Docker того же периода, и его функции очень полны, особенно его часть управления ресурсами, ведь, как всем известно, сама cgroup — это вещь Google. Однако такой проект умер, так и не успев сделать ПК с Docker, в итоге все пришли к выводу, что виноват C++. В чем смысл? Всем известно, что Docker успешен, потому что Docker может предоставить нам дружественную и лаконичную операцию, с которой можно работать очень легко. Пользовательский интерфейс или API системного контейнера. И где LMTFY потерпел неудачу? Он отказался от User Friendly. Можете попробовать. Очень хлопотно компилировать и устанавливать. Иногда нужно Apache Kernal. Это первая проблема. Вторая и самая важная причина — слишком высок порог для контрибьюторов.Успех Docker заключается в 1400 Controlbuters за ним, а про проект LMCTFY говорить не приходится — слишком хлопотно в него вносить свой вклад. Вот почему при работе над проектом Kubernetes люди вообще не выбирали C++. Вы можете подумать об этом, Google использовал C++ для создания контейнеров с открытым исходным кодом.Вы даже знаете, что этот контейнер с открытым исходным кодом является тем, который использует сам Google.Пользователи не могут справиться с такими вещами.Если вы сделаете другой контейнер на основе C++. , такие как огромные проекты, такие как Kubernetes, могут ли пользователи его удерживать? Как будто кто-то жалуется, что Google такой грубый и не открывает нам исходный код Borg? Предполагая, что Borg действительно с открытым исходным кодом, Google взял его и поместил здесь для вас. Здесь написаны миллионы строк на C++. Кто из вас уверен, что сможет это сделать?

Это главная причина, по которой Kubernetes очень близок к сообществам Golang и Golang.

Поскольку некоторые люди не являются пользователями Kubernetes, я представлю проект Kubernetes отдельно. Основное внимание в проекте Kubernetes уделяется контейнеру. Теперь у меня есть контейнер.После того, как у меня есть этот контейнер, первая концепция, выдвинутая Kubernetes, такова: не один контейнер, а группа контейнеров. Эта концепция похожа на отношения между процессами и группами процессов в нашей операционной системе, то есть, когда я пишу операционную систему и высокоуровневую операционную систему, я могу не управлять одним процессом, но я надеюсь управлять группой процессов. Это понятие есть в Kubernetes, оно называется co-scheduling, то есть существует связь между несколькими контейнерами. В Kubernetes считается, что существует взаимосвязь между несколькими контейнерами, которые называются подами. Под — это атомарная единица планирования в Kubernetes, а также самая базовая модель, используемая для управления заданиями, поэтому она не управляет напрямую контейнерами.Конечно, у пода может быть только один контейнер.

Вторая концепция заключается в том, что поды могут иметь много копий, чтобы я мог обрабатывать больше трафика и эластично масштабироваться.Такие требования называются масштабированием.Такие операции создадут серию одинаковых подов в Kubernetes, такую ​​группу подов Как описать в Kubernetes , мы называем это развертыванием. Развертывание описывает, во-первых, как определяется сам Pod, а во-вторых, у меня есть несколько копий этого Pod.

Третий вопрос - получить доступ к этой связке Pod'ов. Как я могу получить к ним равномерный доступ? Я сделаю LB с функцией автоматического обнаружения. LB этого Pod Replicas называется Service в Kubernetes. Идя дальше, недостаточно иметь этот сервис, я хочу выставить его внешнему миру, эта штука называется Ingress в Kubernetes. Реализация Ingerss может быть Nginx, HAproxy или даже F5.Ключ в том, что он может обеспечить баланс нагрузки L7 и открыть его для внешнего мира.

Далее пользователь сказал, что этот Pod особенный. Я хочу запустить Daemon, и мне нужно запустить копию на каждой ноде, не больше и не меньше. Это называется Daemon. Как работать с такой моделью в Kubernetes, мы называем это DaemonSet. В Kubernetes это гарантирует, что такой Pod всегда будет иметь только одну силу на каждой машине, и даже если машина не работает, он все равно даст вам расписание. Теперь требуется мой Pod, у моего контейнера есть состояние, например развертывание Cassandra, Два узла с номерами 1 и 0 разные.Как вы с этим справляетесь?Мы называем это Topology State состоянием топологической структуры.Во втором случае я хочу развернуть MySQL,две мои реплики,я хочу сделать шардинг .Данные отличаются.После того, как ваш Pod развернут, требуется, чтобы хранящиеся в вас данные могли быть привязаны к экземпляру.Это также состояние, называемое Storage State.Как с этим справиться? В Kubernetes есть унифицированная модель StatefulSet для обработки таких вещей. ‘

Некоторые поды более особенные. Они запускаются только один раз, а затем завершаются после запуска. Например, если я добавляю 1 к 1, чтобы получить 2, и возвращаюсь к 2, затем закрываюсь. Такое задание на самом деле является моделью однократного запуска, которую мы назовите это в Kubernetes, это Job. Более того, это задание может выполняться не только один раз, но и регулярно.Это называется CronJob и соответствует обычному формату Unix CronJob, например, в определенное время в определенное время в определенный день.

Кроме того, количество пользователей говорило о том, что этот мой Pod нужно использовать.Например, для доступа к MySQL требуется Имя пользователя и Пароль MySQL.Где мне писать эту информацию?В Kubernetes такую ​​информацию можно писать в Etcd, зашифрованы и сохранены.Такой объект называется секретом. Например, пользователь сказал, что моему объекту нужно загрузить конфигурационный файл, куда ставить конфигурационный файл, мне нужно решить за меня, Kubernetes тоже хранит эти вещи в Etcd. Таким образом, вы можете видеть, что Kubernetes — очень плоский проект. Он используется для работы с типами заданий с помощью определенной специальной Модели, и вы используете ее модель для решения решаемой проблемы. Это очень важный момент в дизайне Kubernetes.

Теперь, когда модуль создан, я задаю ему автоматическое масштабирование, которое может быть основано на использовании ЦП или изменениях ресурсов, таких как количество запросов в секунду. Что мне делать? Подобные вещи также обрабатываются моделью в Kubernetes, но эта модель, называемая Pod Auto Scaller, похожа на небольшого демона, чтобы помочь вам в этом масштабировании, это тоже модель, как и другие. Они все плоские, и они все модели.Если вы видели такую ​​картинку, то знаете, что Kubernetes изначально был таким проектом.

Итак, как это используется? Я перечислю здесь несколько, например, вы можете запустить kubectl, что то же самое, что запустить docker, и указать, что число моих реплик равно 3, что означает, что мой Nginx должен запускать три копии, что также нормально. Но я предпочитаю второй, пишу файл yaml и сопоставляю все эти параметры.Например, мой образ Nginx, и я хочу три реплики.Я предпочитаю этот, потому что я могу управлять своими файлами конфигурации унифицированным способом.up, тогда я сразу kubectl create-f, используйте этот файл, чтобы сделать это. Например только что упомянутый мной HPB Auto-Scaler тоже можно прописать через этот конфигурационный файл.Мне нужно зайти в Scaler Target, то есть Nginx я упоминал ранее.Как только я совпадаю, мой масштаб максимум 10 и на по крайней мере 1. Один, каков мой целевой ресурс?Например, установленный здесь ЦП также можно изменить на любой формат метаданных, поддерживаемый метриками ресурсов, даже если формат метрик ресурсов не поддерживается, вы также можете определить модель Ресурс для входа в него.Опишите его, например QPS, или мой Хост Машинные данные могут быть. Затем, после завершения create-f, начните с этого файла.

Шаблоны проектирования Kubernetes

Возвращаясь к нашей теме, вся суть работы Kubernetes вращается вокруг объектов, хранящихся в этих Etcds. Это то, что мы называем API-моделью объектно-ориентированного программирования, которая просто является «объектно-ориентированной» в Container». модель имеет две операции: первая заключается в том, что я создаю объект в Etcd, следующая — то, что должен делать Kubernetes, она будет использовать парадигму программирования цикла управления, чтобы помочь вам перейти к согласованию для координации всех объектов API, работу Kubernetes, что это координация , Например, если у меня есть дополнительный Pod, он вызовет для меня операцию On-Add.Что мне делать после On-Add, нужно ли передать его Kubernetes или планировщику, эта логика должна быть написано в, и элемент управления Цикл срабатывает таким образом, просто посмотрите на пример, и вы все узнаете.

Например, если я хочу создать Pod, естественно, что этот запрос будет передан на Api-Server и сохранен в Etcd, то что будет дальше, во-первых, в Etcd будет такой объект, называемый Pod, а потом приходит ключ, в Kubernetes Все компоненты, Scheduler, Kubelet и т. д., все они поддерживают свой собственный Control Loop, что эквивалентно непрерывному циклу.Например, как и Scheduler, он будет следить за только что добавленным Pod в Ectd. Когда он найдет новый модуль, он запустит алгоритм планирования и найдет подходящий для вас узел. В это время расписание завершено. После того, как это будет сделано, он заполнит поле «Узел» модуля в качестве цели. Node для вас, и планировщик будет готов, он не будет делать что-то еще, он продолжает работать Loop, в то же время поле Node Pod в Etcd изменилось, и kubelet также является отдельным Control Loop.Он получает изменение поля Pod Staters Node.Когда он обнаруживает, что мое поле Pod Node было новым добавить или изменить его, а затем снова сопоставить и обнаружить, что имя Node - это я, он снимет эти данные и загонит их на мою машину.

Вы можете видеть все компоненты во всем Kubernetes, и координация между ними заключается в том, чтобы наблюдать за изменениями интересующих его объектов в Etcd, а затем решать, что я хочу делать после этого изменения. Мы называем такой шаблон проектирования, как этот Контроллер, но обратите внимание, что он управляется не событиями, а Управляемым уровнем, а не Управляемым краем (управляемым событиями). Что такое Управляемый событиями? Позвольте мне привести пример здесь ЦП одного из моих устройств сказал, теперь я готов, вы можете подойти ко мне, чтобы написать мне данные, что он будет делать, вы можете отправить импульс, ЦП находит этот импульс и знает что вы готовы, это событие, потому что вам нужно подтвердить событие, а затем ЦП должен иметь возможность прочитать это событие и зафиксировать это событие, которое является одним из видов. Подобно Openstack и CloudFoundry, вам нужно встроенное сообщение Очередь приходит и уходит на обработку этого Event, но в Kubernetes это не так, почему мы называем его Level Driven?Просто сбросьте мой на новое значение, с низкой частоты на высокую частоту, а второй уже не будет Произойдут изменения, пока вы не закончите обработку или не произойдет новое изменение в вашем состоянии. Кроме того, этот Уровень неизменен, поэтому для ЦП ему не нужно заботиться о Событии, ему не нужно заботиться о конкретных событиях, он только нужно посмотреть, изменилось ли мое состояние, если вы хотите сравнить, вы обнаружите, что есть преимущества и недостатки, но причина, по которой Kubernetes хочет это сделать, заключается в упрощении режима программирования.

Такой контроллер является ядром дизайна Kubernetes.Будь то Kubernetes, планировщик или диспетчер контроллеров, все они могут быть простыми, простыми или сложными контроллерами. Что они там делают, запуская цикл каждый день? Сначала получить статус Design интересующего объекта из Etcd, а затем найти способ получить фактический статус текущего объекта в моем кластере.Например, он фактически запускался 9. В настоящее время это означает, что новый Pod должен быть создан, поэтому в соответствии с изменением моего погружения решает, что я собираюсь делать дальше, так работают все контроллеры. Kubernetes предоставляет вам такой механизм Controller.С одной стороны, это может упростить его архитектуру, а с другой стороны есть надежда, что вы сможете сами написать Controller для расширения возможностей Kubernetes. Это основное, о чем мы сегодня поговорим.Может кто-то скажет, почему мои пользователи хотят расширить возможности Kubernetes? Причина все же в этой картинке, так как Kubernetes управляет всеми вещами через объект Etcd. Естественно, есть требование, чтобы моего объекта не было в определении Kubernetes. Что я могу сделать?

Типичный пример: мы можем определить объект с именем Network, который не является родным для Kubernetes, поскольку эта сеть имеет разные собственные реализации, и у меня нет возможности определить, как должна быть настроена сеть. Чтобы объект Network, подобный этому, управлялся Kubernetes и использовался Pod, он должен управляться в Kubernetes, поэтому при появлении Network может потребоваться привязать Network к Pod, а затем что-то сделать. только одна причина сделать это дальше.

Демонстрация контроллера

Далее напишем небольшую демку, которая заключается в написании Контроллера, в какой объект должен записывать Контроллер, я долго думал над этим, и решил написать в нем "Asta Xie". То есть пригласить Се Да в сообщество Kubernetes и пригласить Се Да в Kubernetes API. Затем я хочу написать контроллер. Я добавляю, удаляю и изменяю объект «Asta Xie», надеясь, что он сможет работать. Это самая базовая модель контроллера Kubernetes. После того, как я напишу это, я надеюсь, что смогу получить доступ напрямую через kubectl AstaXie, отпишитесь о статусе и свойствах Asta Xie.

Я начну с объяснения шаблона для написания этого. Прежде всего, вместо того, чтобы иметь Etcd, относитесь к нему как к базе данных.Я хочу написать Xie Da. Kubernetes не рекомендует вам использовать Etcd напрямую. Все операции с Etcd должны проходить через Kube-apiserver, что эквивалентно созданию слоя DAO, который поможет вам перевести эту операцию в Etcd. Это первый шаг. Второй шаг, сначала мне нужно сообщить Etcd, как определяется объект Asta Xie, первый называется типом. Второй нужно написать такое определение регистрации в Etcd, как это написать, это называется Register. Так как третий может поставить Се Да, как контролировать Асту дальше Се, как написать Controller, об этом будет сказано позже. Потом Контроллер говорил ранее, что взаимодействует с Etcd через watch API.В этой части, как реализовать этот watch, и нужно ли оперировать API, полученным Etcd, можно посмотреть позже. После того, как все это будет сделано, например, если пользователь хочет создать объект Asta Xie, kubectl создаст объект Asta Xie напрямую. После того, как этот объект появится, будет запущена операция добавления. Если такой объект обновляется, on-Add сработает. Операция Update, если объект удален, вызовет операцию On-delete. Как эти обработчики определены в Kubernetes, вся демонстрация посвящена этому. Это выглядит немного сложно, но на самом деле это очень просто, потому что все это рутина. Kubernetes уже определил для вас шаблон подпрограммы контроллера, давайте посмотрим, как заполнить этот шаблон. Первый шаг, Типы, заключается в том, чтобы определить, что такое Xie Da или Asta Xie, Объект должен быть создан в Mate в Kubernetes. Данные, по сути, это какие-то имена, Namespace, этим операциям пофигу. Начните напрямую писать NameSpace Се Да, как описал его Се Да. Поскольку это операция API, API необходимо кодировать и декодировать. Сначала это нужно определить в Kubernetes.

Первое определение атрибута — Спец. Спецификация используется для описания Се Да, то есть для описания того, какие атрибуты есть у Аста Се. Во-вторых, состояние этого объекта, как утверждает Аста Се, также необходимо определить json, два. Один — Spec, другой — States, а потом напишем Spec. Как Spec описывает Се Да, прежде всего, Се Да должен будет освоить язык программирования, чтобы писать код. Тогда каковы характеристики Се Да, красавчик, кто-нибудь может сомневаться в этом? (нет). Определите эти два как один json. В этом случае определяется полный формат Asta Xie. Как видите, ничего сложного.Если вы хотите определить Сеть, напишите свой IP в этой части. Диапазон, IP-адрес Getway может быть написан.Сегодня мы будем полностью использовать Asta Xie, надеясь, что Asta Xie может быть мощным.

Кроме того, состояния могут определить Omit Empty, что означает, что его можно оставить пустым, это не проблема. Первый шаг выполнен, Типы, нужно обратить внимание на одно, на всех объектах есть Annotation, называется Kubernetes Deep Copy, что это значит? Потому что здесь, в API, нужно сделать много операций глубокого копирования. Эта операция будет напрямую управляться Deep Copy в Golang, но эффективность относительно невысока, поэтому в Kubernetes Google и народ напрямую написали библиотеку, которая поможет разработчикам генерировать Deep Copy для любого объекта. Метод копирования, это небольшая хитрость.

Определив тип Да Се, мы определяем два состояния для Да Се. Во-первых, мы предлагаем Да Се назвать его Приглашением, называемым Приглашенным. Второе призываем Да Да Се принять приглашение, которое называется Принятым. Это состояние необходимо менять туда и обратно. Последнему нужно определить список Се Да, ведь что делать со многими Се Да, нужно определить список, этот список тоже мертвый шаблон, просто ctl+c, ctl+v делается, тоже определить для него Deep Copy. ОК, с Типами покончено, Kubernetes уже умеет описывать объект Се Да. Второй шаг — как сообщить Kubernetes об этом Объекте, сказав, что в него можно записать, и вам нужно следить за вещами в Kubernetes. Прежде всего, вы должны присвоить Се Да множественное число. Для многих Се Да добавьте S. Во втором нужно указать группу AIP, к какой группе API он принадлежит, а затем сделать версию для этой группы, V1 или V2, которые все являются шаблонами, ctl+c, ctl+v. Затем вам нужно указать Kubernetes, какой объект регистрировать, просто напишите его здесь, называется Asta Се. Вы также можете написать набор списков AstaXie и не заботиться о других, потому что пока эти два типа зарегистрированы, Kubernetes будет знать, как обрабатывать, как читать и записывать объекты Asta Xie. Второй шаг Регистрации тоже закончен, надеюсь правильно написал. Затем третий шаг, теперь, когда есть Объект, как использовать клиент Kubernetes для работы с Asta Xie, вам нужно определить Клиента, и вы можете напрямую вызывать Клиента при написании кода в будущем, вместо того, чтобы писать запросы отдыха каждый раз. время. Как написать этот Клиент, Kubernetes уже все написал, весь код менять не надо, ни строчки менять не нужно. Что нужно изменить? Просто определите некоторые детали. Каковы детали объектов, которые будут созданы в будущем, которые в совокупности называются Customers в Kubernetes? Определение ресурса, объект, с которым в будущем будет иметь дело этот CRD, — Се Да, поэтому я дал Се Да имя. Имя тоже фиксированное, оно должно быть во множественном числе плюс группа, а остальные менять не нужно, в основном потому, что здесь четко написано.Этот CRD предназначен для работы с объектом Аста Се, так что все это ctl+c и ctl+v. Таким образом, чтобы написать этот код, наиболее распространенной операцией является выбор всего и замена. Что ж, Клиент есть. До сих пор можно было добавлять и удалять объекты, за которые должен благодарить клиент, написанный на Kubernetes. Затем начните писать контроллер. На первый взгляд, контроллер звучит очень сложно, и ему нужны часы. Часы ничего не значат, а производительность часов нужно обрабатывать и оптимизировать. К счастью, все это делается за вас в Kubernetes. Поэтому, если вы действительно хотите написать Контроллер в Kubernetes, он не будет превышать десяти строк, от 38 до 63 строк, и добавить много комментариев, если убрать комментарии, то это может быть только шесть или семь строк, и вы может написать контроллер.

Как определяется контроллер? Во-первых, он должен уметь манипулировать некоторыми объектами, поэтому нужно обратить внимание на AstaXie Client, который воздействует на этот Источник, источник этих часов, и записывает этот Источник в Контроллер. Во-вторых, этот Контроллер единообразно определяется как Информер в Kubernetes.Почему он называется Информером?По сути, это часы Etcd, которые написали Wapper, запаковали его и сделали некоторые оптимизации производительности. Например, Информер здесь называется Shared Информер, то есть, если он разделяет некоторые Соединения и некоторые кэши Данных с другими Информерами, эту вещь можно копировать и вставлять напрямую без забот. Просто скажите контроллеру, что объект Asta Xie должен быть обработан, и пока изменяется одно место, изменить можно только одно место, а именно это место. Затем снова определите On-Update, On-Delete и шаблон. Здесь все копируется и вставляется, единственное место для написания кода - это On-Add, Операция при удалении, при обновлении. Из-за нехватки времени я пишу On-Add.Вы можете подумать, что On-Add может писать код, но это не нужно, потому что Kubernetes определил эти вещи.Сначала сделайте копию, сделайте глубокую копию, потому что здесь Ссылка , а затем скопируйте этот объект, чтобы сделать это самостоятельно. Что делать после получения копии AstaXie? Делайте то, что хотите, например, меняйте состояние AstaXie. Поскольку в начале это было приглашено, мы попросили г-на Се принять это приглашение, поэтому я сказал сбросить состояние копии. Сбросить на что? Сбросьте в новое состояние, измените его на Asta Се принял, Се Да принял наше приглашение. Второй попросил Се Да что-то сказать, что он сказал? Пусть Се Да скажет: AstaXie приняла приглашение Гарри, хорошо, Се Да сказала: «Для меня большая честь принять ваше приглашение присоединиться к Kubernetes».

Пользователь создал Xie Da. Как только созданный им объект запускает обработчик добавления, мы можем изменить статус объекта на «Принято» в этом обработчике. Разве это не очень просто? После того, как вы завершите это изменение, естественно использовать Client, использовать операцию Put и метод put и записать новый объект Xie Da обратно в Etcd для обновления. На этом шаге нет проблем. Затем выполните еще одну операцию, перечислите все объекты AstaXie, чтобы увидеть, успешно ли выполнено обновление, завершено ли при добавлении, закончен ли код, а затем, как при удалении Это не изменится с On-Update, просто сделайте журнал, и Контроллер окончен.

На этом описанный код закончился. Пишем основную функцию для работы с этими вещами. Основная функция очень простая, и нам нужно определить, как передать Asta Xie Client новому. Что единственное, что нужно передать в качестве параметра? Это файл конфигурации Kubernetes. После установки Kubernetes он сгенерирует файл конфигурации, который определяет адрес и сертификат Kubernetes API. Просто используйте его, никаких других параметров не требуется, это очень просто. После того, как у вас есть этот клиент, возьмите этот клиент для инициализации контроллера, и у вас будет контроллер. Запустите его, запустите его, он остановится здесь и сделает бесконечный цикл, ожидая, пока вы создадите объект благодарности, выполните определенные вами операции On-Add, On-Delete, On-Update, этот код закончился, нажмите его Попробовать это на машине разработки. Столько всего изменилось, когда смотришь на него, ничего особенного. Это демо Аста Се, окей, нажми. Поднимитесь, отнесите его к моей машине для разработки, снимите это, хорошо, вы можете запустить его после того, как снимете. Основная функция написана, поехали. Во время бега посмотрите, как определить Асту Се этот ямл. Хорошо, Аста Се, в Kubernetes нет такой вещи, которую определяем мы сами. api version — это строка, которую мы только что написали сами. Мы можем написать ее небрежно. Во-первых, мы назовем объект Asta Xie, спасибо за номер один. На каком языке пишет Се Да, на Голанге, потом красивый = правда, начальное состояние Приглашен, мы что-то говорим Се Да, говоря, что хотим Пригласить Аста Се присоединиться Кубернетес. Итак, состояния определены, имя Се Да также установлено, и такой объект можно использовать. Проверьте, запущен ли контроллер, он говорит, что запуск контроллера выполнен успешно, ошибок компиляции нет. вполне нормально. Затем вы можете увидеть, знает ли Kubernetes такие объекты, как Xie Da. С помощью CRD у Kubernetes уже есть метаданные под названием Asta Xie или исходный объект. Только что данное определение является множественным числом от AstaXie, Asta Се, что означает, что мы можем манипулировать этим объектом. Объект уже есть в yaml, прямо kubectl create-f, а то тут yaml пишется, иди один.

Как я уже говорил ранее, мы можем создать kubectl и получить AstaXie с помощью Xie Dayi. Что, черт возьми, происходит? Глядя на журнал, я столкнулся с такой вещью в контроллере. Во-первых, добавьте объект Xie Da, там будет обработчик, который запускает On-Add, нажмите на недавно добавленную вещь Asta Xie, Language is Golang, Handsome is true, States также предлагается, это начальное состояние. Тогда что делал код, который мы сами написали в On-Add? мы ставим Асту Статус Се был обновлен, и обновление стало «Принято», а затем Се Да сказал слово: «Я принял приглашение Хоуп Гарри». После успешного выполнения операции Uptate запускается обработчик On-Uptate, который записывает два журнала. Наконец перечисляем Asta Xie, возвращаем результат и видим, что статус подтвержден как Accepted, ладно, это весь жизненный цикл Контроллера, помимо этого жизненного цикла, есть еще один, вы также можете удалить этот Asta Се пнул, Аста Се поблагодарила первокурсника.

Я хочу немного почистить здесь, потому что, если я только что упомянул Сеть, она может быть удалена здесь.Необходимо синхронно удалить некоторые пространства имен Сети и очистить некоторые устройства, все это делается здесь. В это время, когда мы оглядываемся назад и видим Аста Се, он должен исчезнуть Это процесс разработки и реализации полного контроллера, который очень прост. Это не особенно сложно, потому что он обертывает очень низкоуровневые, такие как часы, как информер, уведомление и совместное программирование на основе Etcd Среди них, как CoreOS Li Xiang, они проделали большую работу. Есть еще RedHat, у них есть команда напрямую, специализирующаяся на доле Работа информера значительно улучшила производительность Kubernetes. Короче говоря, стоять на плечах этих гигантов и делать вещи Контролера действительно намного проще, чем в одиночку Etcd.

Вы можете подумать, что эта демонстрация относительно проста, и есть реальный пример. Это поддерживаемый нами проект OpenStack Foundation, который называется Stackube. Этот проект заключается в том, что у меня есть Kubernetes, и я надеюсь использовать сеть и хранилище OpenStack, которые должны иметь дело с сетью, как с этим бороться? Мне нужно разобраться с Нейтроном. Я надеюсь, что Neutron сможет создать сеть с таким же именем по тенанту, тенант это Пространство имен в Kubernetes, и создать Сеть с тем же именем для меня, изолированную сеть 2-го уровня для меня, а затем написать CNI Плагин Neutron, контейнер этого модуля может подключаться к сети Neutron, это так просто, идея очень проста. Это должно быть написано в контроллере, зачем использовать контроллер? Прежде всего, я хочу врезать объект Network, который определяет сегмент сети, Getway, имя сети, идентификатор таланта сетевого объекта и другую информацию. Во-вторых, после того, как вам нужно добавить сеть в Kubernetes, в On-Add синхронизироваться с Call Neutron API, помогите мне создать такую ​​Сеть для меня, я буду использовать ее позже. Следующее, что необходимо сделать, — это создать набор DNS-сервера Kube при добавлении, который для меня является DNS-сервером Kube, поскольку после использования сети Neutron это будет изолированная сеть уровня 2. Модель установки Kube DNS-сервер для управления всеми модулями не работает, потому что модули в настоящее время изолированы в разных сетях уровня 2, и мне нужно иметь DNS Kube в каждой сети. Эта идея также очень распространена, поэтому в On-Add я делаю две вещи. Затем я снова разобрался с On-Delete, и тот факт, о котором я упоминал ранее, заключается в том, что после удаления этой сети я могу удалить созданное на модеме беспорядочное сетевое пространство имен. ОК, Обновление в основном используется для обновления статуса этой Сети, потому что, как и в случае с Нейтроном, его Сеть имеет полный набор статусов, и мне нужно его поддерживать. Вот и все, из-за нехватки времени я не буду вам об этом рассказывать. Если вы откроете этот код напрямую, то вы увидите его, если откроете. Звучит сложнее, но он точно такой же, как и модель только что. Контроллер еще такой короткий, а On-Add не будет длинным. Мы все еще делаем копию здесь. После копирования читайте информацию внутри, самое главное что я делаю это Добавляю Network to Driver, на самом деле это делается путем настройки API OpenStack.

Парадигмы программирования для проектов Kubernetes

Модель Kubernetes можно применить к очень сложным вещам, очень сложным состояниям, но с относительно низкими затратами, поэтому мы вводим парадигмы программирования. При этом такую ​​парадигму программирования можно распространить и на себя, например, без Kubernetes, но при написании такой штуки, называемой индустрией Orchestrator, эта модель, очевидно, очень помогает. На самом деле Docker's SwarmKit тоже опирается на эту модель. Он также сам пишет набор такого фреймворка. Процесс почти такой же. Вы можете видеть, что эта модель не является чем-то, что сделал Google, но у нее есть свои преимущества. .

Первая парадигма добила Контроллера, а вторая парадигма - почему проект Kubernetes до сих пор сильно опирается на Голанг, Самое главное, что от трети до половины его кода генерирует Генератор, а его Генератор довольно много . Я не стал перечислять все это здесь, может быть, около двух третей. Например, Client-gen, вы только что видели, что я написал операцию объекта Asta Xie, и вам нужно определить Client.Из этого очевидно, что он имеет шаблон, и поля похожи, поэтому такая вещь может полностью определить объект и тип, отсюда сгенерировать Kubernetes непосредственно для типа с помощью командной строки спокойный клиент. Это делается в Кубернете. Второй Conversion-gen, это, например, добавление функции в Kubernetes, такой как новая функция, такая как AstaXie, первый выпуск этой функции — α, второй — β, его API называется V1α1, первый выпуск — The два — это API типа V1β1.Как делать операции преобразования между ними тоже можно.Очевидно, такой код тоже может сгенерировать Generator.Каждое ускоренное поле — это небольшой бинарник в Kubernetes, который можно найти на всем пути вниз. Третий - только что упомянутый Deepcopy-gen. Вот пример того, как использовать Deepcopy-gen. Это очень просто, и вы даже можете использовать свой собственный проект для этого. идти прямо Получить установленный Kubernetes cmd — это установить двоичный файл Deepcopy-gen, а затем напрямую записать Deepcopy-gen в свой каталог, он сгенерирует пакет кодов для всех типов. Затем есть Default, который только что упоминался, если вы не устанавливаете его свойства для Asta Xie, каково значение этого значения по умолчанию?Очевидно, что есть этот шаблон, которому нужно следовать, поэтому все Defaults в Kubernetes также устанавливаются через этот параметр. .

Еще одна важная вещь - это go-go-Protobuf. В этом разница между использованием GRPC в Kubernetes и всеми остальными. Они не используют стандартный пакет GRPC, а используют go-go-protobuf, потому что его производительность относительно выше. , потому что с помощью этого набора инструментов Kubernetes инкапсулирует этот набор командных строк отдельно, а затем использует эту командную строку для генерации прото-файла в формате Kubernetes, который немного отличается от стандартного файла stander.

Ещё есть Информер-ген.У Информера-гена всего сейчас 10 строк кода в Контроллере.Он тоже мёртв.Просто поменяйте Тип,чтоб этот Информер тоже мог быть таким же.Напишите объект Аста Се, снова запустите этот двоичный файл и замените его. Сгенерируйте Asta Xie Informer, и все. Существуют также ключи OpenAPI, все они генерируются code-gen. Итак, каков конечный результат? Это эффект, то есть определите его сами в API, или определите сами, или определите Тип в Kubernetes разработчика.Весь код, необходимый для того, чтобы Тип в основном работал во всем процессе, готов, и тогда вы можно напрямую написать бизнес Логика включена Добавить, при удалении материала.

Если вам это интересно, вы можете увидеть, что в Kubernetes есть библиотека gengo, которая содержит все определения, основанные на Golang. Кроме того, есть go2idl, тоже родственный бинарник, его можно изучить, его можно импортировать, а вендор без проблем может его использовать.

Третий шаблон — это то, как Kubernetes использует развязку GRPC. Вы можете подумать о том, где Kubernetes нужно использовать gRPC.Самый важный момент — как отделить Kubernetes от Docker, проблемы вековой давности. Поскольку до версий 1.3 и 1.4 Kubernetes и другие проекты были одинаковыми, все они обращались напрямую к поставщику за клиентом Docker, а затем отправляли запросы демону Docker, что делало Kubelet частью Kubernetes особенно сложной в обслуживании.

Зачем? С одной стороны, после того, как вы увидите клиент Docker вендора, вам нужно измениться с Docker, а проект Docker особенно ненадежен, он стал очень быстрым, и он менял свое имя каждые несколько секунд, поэтому это очень хлопотно, как поддерживать такой Kubelet. Вторым важным моментом является то, что CoreOS подтолкнул rkt, сделав rkt вторым встроенным контейнерным движком в Kubernetes после docker. Таким образом, обслуживание среды выполнения контейнера intree очень проблематично, в результате чего эта часть кода в Kubernetes до версии 1.3 очень запутана, а ошибки нельзя исправить или исправить. Проблема времени выполнения передана в rkt, как это работает? Таким образом, в этом процессе вы, возможно, слышали о китайском лидере в Kubernetes, Дон Чен, который оказал большое давление на CRI, который представляет собой интерфейс среды выполнения контейнера, который представляет собой интерфейс, полностью основанный на GRPC, который объединяет Docker, rkt и другие среды выполнения. с Kubelet изолирован. Некоторые говорят, что там есть политическая борьба, и она должна быть. Как такое можно сделать в Kubernetes? Давайте посмотрим на дизайн CRI. Идея очень проста, то есть Kubernetes сейчас не делает эти операции, а Docker управляет Контроллером. Что касается Runtime, Kubelet выступает в роли клиента, вы можете взглянуть на Workflow. Например, если вы хотите перечислить поды в Kubelet, тогда ваш код — это метод песочницы списка Runtime Server, соответствующий интерфейсу, он определяет, какие операции должны поддерживаться интерфейсом, что соответствует операциям списка подов. Для такого рода операции Kubelet, как Клиент, отправляет этот запрос, не реализует его, и неважно, как он реализован, ключевой момент — кому это передать. То есть любой Runtime должен написать Shim. Как вы можете видеть, если вы говорите, хочет ли rkt написать прокладку, она должна быть написана. Docker также пишет такой Shim, который называется dockershim. Тогда dockershim встроен в Kubelet и другие прокладки спокойно вынимаются, поэтому очень простая и жесткая, но и очень эффективная развязка реализуется.

Шим, как реализация интерфейса, также действует как сервер GRPC, чтобы ответить на этот запрос, я помогу вам реализовать этот список Pod Sandbox, что я делаю? Я продаю Docker Client, отправляю запрос на получение в Docker API, получаю Контейнер, собираю его, собираю Контейнер в Pod и возвращаю — все это делаете вы, Kubelet это не волнует. Поэтому это очень стандартная практика использования CIA для достижения развязки в Kubernetes. Итак, как только это будет написано, вы обнаружите, что двум проектам, kubelet и docker, нужно только совместно поддерживать такой интерфейс, какие существуют методы, какие поля есть в каждом методе, какие типы есть в каждом поле и что такое возвращаемое значение?, есть несколько. Достаточно просто следить за ними.Независимо от того, каким станет Docker API в будущем, пока эти API все еще доступны, это идеальное состояние. Поэтому более поздний переход с Docker на moby не повлияет на Kubernetes, что является преимуществом разделения.

В этом процессе детали GRPC обсуждаться не будут. Через какое-то время у Се Да будет тема. Я считаю, что он может говорить намного лучше меня. Я просто скажу, что у Kubernetes есть несколько небольших советов, у которых каждый может поучиться. Например, часть go2idl, упомянутая ранее. Из-за использования go-go-protobutf, потому что все знают, что писать файлы протокола GRPC все еще довольно неприятно. Он пишет генератор, просто дайте объект, дайте Тип и сгенерируйте эту часть файла протокола.

Поэтому определите эту часть операции как скрипт, поместите его в библиотеку Kubernetes, а в будущем напишите докершим.Только нужно еще раз запустить скрипт, прото-файл, и соответствующую версию прото-файла. наконечник может узнать о процессе. Поддерживая такой генератор, мы поддерживаем прото-файл, который каждый может написать.

Кратко представим способ CRI. Много было сказано ранее, вот краткое упоминание, серая часть в Kubernetes — это его часть управления, которая отвечает за реагирование на запросы пользователей и, наконец, отображение всех Deployments, Pods и т. д. в Kubelet, который является операцией Pod. , добавить или удалить, или изменить, или проверить. Возможно, ранее была создана относительно большая вещь, и, наконец, она была сопоставлена ​​с операцией Pod. Такие операции с контейнерами будут переданы универсальному Часть Runtime выполняется не напрямую в Docker. Что такое общая среда выполнения? Он отвечает за отделение подов от API-интерфейсов контейнеров. Как правило, поды по-прежнему представляют собой группу. В частности, необходимо управлять контейнером. Такие операции должны выполняться универсальной средой выполнения. Развернув его, разделите его на методы CRI. Есть только три метода CRI: первый — как работать с песочницей Pod, то есть как реализовать Pod. Песочница; во-вторых, как работать с Container; в-третьих, как работать с Imge. Что такое Pod Sandbox? В Kubernetes есть специальный контейнер, называемый инфра-контейнером, который должен содержать сетевое пространство имен всего пода, так что все контейнеры в поде имеют общее пространство имен, которое напрямую обрабатывается в песочнице пода, что также напоминает вам о другая реализация Runtimes, вы можете создать свой собственный Pod Песочница. Например, rkt сам написал Pod. Даже без инфра контейнера, например, взять виртуальную машину в качестве Песочницы, не проблема, можно, гипер именно это и делает. Таким образом, это обеспечивает большую гибкость, так что Kubernetes не нужно заботиться об этих деталях времени выполнения. Далее некоторые операции с Container напрямую передаются в Container API, а dockershim можно найти напрямую, включая отправку запросов к Docker. А если вместо Docker использовать rkt или hyper? Нужно сделать такую ​​конфигурацию, очень просто. На основе CRI характеристики GRPC очень просты.Насколько это просто? Звучит сложно, как заставить Kubernetes поддерживать rkt? Просто добавьте контейнер на стороне Kubelet. Удаленная среда выполнения. Тогда кто конечная точка пульта, и какой носок подойдет.

После завершения этого процесса вы можете продолжать использовать стандартные вещи Kubernetes, такие как Kubeadm Init, Kubeadm Join для развертывания кластера, все это не повлияет на конфигурацию среды выполнения, поскольку это всего лишь изменение, соответствующее файлу конфигурации Kubelet, и его не нужно поддерживать Мне не нужно делать отдельный проект для управления этими вещами, мне не нужно ничего делать, это CRI. Это также последний шаблон, о котором я говорю.

В последней части я надеюсь кратко представить лучшие практики проекта Kubernetes.Выше упомянуты разработчики Kubernetes.Вот какая парадигма программирования предоставляется разработчикам здесь. На самом деле, это немного похоже на шаблон проектирования написания кода в реальности. Первое — декаплинг Kubernetes decoupling — это взаимосвязь между контейнерами и контейнерами Второе — это повторное использование, то есть образ не нужно много раз упаковывать туда-сюда, и в него запихивается много всего Простой бинарник может помочь вам сделать это дело. Окончательная реализация призвана помочь реализовать более разработанный метод развертывания на основе контейнеров, то есть ответить на вопрос, как развернуть распределенный MySQL на Kubernetes. Оказание услуг.

Первый пример sideCar можно понимать как шаблон проектирования. То есть для решения проблемы повторного использования образа у многих людей Docker Image пишется так: первым закинуть в него tomcat или бинарное приложение. Затем добавьте Logging Agent, потому что журналы должны быть извлечены, а журналы должны быть импортированы в Elastic Search или MangoDB, что является методом централизованного хранения. Не высоковата ли муфта зеркала? Например, если вы обновляете приложение в будущем, вам нужно переписать зеркало, и более хлопотным является обновление Logging. Агент, зеркало нужно переделать. В Kubernetes рекомендуется, чтобы агент ведения журнала получал свой собственный образ, который очень мал, и приложение также является собственным образом, а затем запускал два контейнера, по одному на каждый, всего два контейнера. Затем упакуйте контейнер в модуль. Поскольку том и сеть являются общими в модуле, они могут свободно обмениваться файлами и подключаться друг к другу. Вы можете напрямую читать локальные файлы, не поддерживая том. делать какой-то лабол, чтобы они были на одном механизме, не надо. Нет необходимости часто менять зеркало, это сторона машина. Таким образом, его можно распространить на любую ситуацию. В любом случае, есть несколько Контейнеров, и среди них есть импульс подумать об их зеркальном отображении. Этот импульс следует решить, сначала рассмотрев метод боковой машины.

Второй вопрос, возможно, вы уже задумывались над ним. Допустим, между этими подами, этими сайд-карами и контейнерами существует последовательная связь. Я хочу записать это в образ, но обеспечить последовательную последовательность запуска. , В Kubernetes, такое определение называется InitContainer. Это контейнер, который вы хотите запустить первым. Например, это MySQL. Перед запуском вам нужно выполнить некоторые сценарии инициализации, что является нормальным. Это может быть написано прямо в Docker, вам нужно сначала позвонить скрипт. Нет, образ всегда является приложением, когда будет выполняться скрипт, один образ, один контейнер и определить контейнер как InitContainer, он будет выполнен перед всеми пользовательскими контейнерами и гарантированно запустится после завершения выполнения Пользовательские контейнеры, и вы можете определить несколько, может потребоваться несколько шагов для инициализации без проблем. Это называется InitController.

Идя еще дальше, передняя часть — это то, как сделать несколько контейнеров для сотрудничества, а вторая — как сделать это сотрудничество в порядке, это второй шаблон.

Третий шаблон более продвинут, то есть это необходимо сделать сейчас, но я обнаружил, что каждый раз, когда мне нужно переопределить контейнер агента ведения журнала в поде и файле yaml развертывания, так долго это говорить , а писать очень хлопотно. . И вы обнаружите, что все поды, все развертывания одинаковы, естественно ли придумывать требование, может ли Kubernetes автоматически писать эту часть, и может ли он автоматически регистрировать это Агент вводится в него, что немного похоже на программирование аспектов Spring. Если вы пишете код, пусть Spring внедряет методы без изменения кода, например, следите за тем, чтобы журнал регистрировался перед выполнением каждого метода, вы можете использовать Spring для таких вещей, и Kubernetes также может делать такие вещи. Давайте посмотрим, yaml этого приложения такой короткий, просто запустите образ, а затем определите отдельную вещь под названием Initializer, которая также является новой вещью в Kubernetes под названием Initializer. Напишите, что нужно вставить в Etcd и сохраните. Затем напишите, что нужно внедрить в Deployment, что нужно отметить, что называется Logging Агент, агент ведения журнала — это содержимое между этой строкой и этой строкой. После того, как это будет определено, выполните kubectl create. В созданном поде должен быть только один контейнер, но он будет внедрен Kubernetes в контейнер агента ведения журнала в соответствии с определенным форматом. Это такая простая, полностью автоматизированная операция под названием Initializer.

Суммировать

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

Первый о том, как Kubernetes использует Golang. Сначала он представляет Kubernetes, а затем фокусируется на парадигме, демонстрирующей использование Golang в Kubernetes. Мы называем его контроллером, который также является ядром дизайна Kubernetes. Мы также писали о том, как добавить в него Asta Xie и написать контроллер для управления им.

Второй — это краткое введение в жемчужину кода Kubernetes, как реализовать каждый из них, можно найти в библиотеке.

Третий кратко представляет дизайн интерфейса на основе GRPC.

В-четвертых, я могу всем здесь порекомендовать библиотеку Kubernetes Util. В нем много всего, как и на Taobao, можно найти много интересных инструментов. Например, как сгенерировать действительно уникальный UEID, наверное, все рассматривали, как это сделать в Golang, в этой библиотеке полно таких мелочей. Это все, что нужно знать разработчикам Kubernetes.

Вторая часть представляет собой очень краткое введение в Kubernetes для разработчиков и то, какую парадигму программирования Kubernetes предоставляет разработчикам здесь.Если у вас есть какие-либо вопросы, вы можете общаться онлайн. Сегодня я не буду рассказывать больше, но мне нужно упомянуть второй вопрос, как помочь разработчикам разрабатывать приложения на основе контейнеров, что является ядром проекта Kubernetes.