K8S для начинающих. Первая часть

Kate

Administrator
Команда форума

Предисловие​

Технологический прогресс не стоит на месте, особенно если это касается области IT. Еще в 2014 году, когда Google открыл исходный код проекта Kubernetes, который вобрал в себя лучшее из Borg и Omega - внутренних систем Google, его мало кто знал и использовал. Но прошло 7 лет и K8S (он же Kubernetes) стал успешным open-source проектом, который используется по всему миру. В большинстве компаний инфраструктура построена на K8S - от маленьких проектов до огромных кластеров и облаков, которые обеспечивают бесперебойную доступность сервисов. Давайте коснемся Kubernetes и расскажем, как им пользоваться на практике. Но сначала надо спросить, а что такое этот ваш Kubernetes и для чего он собственно нужен. Подойдет ли он для ваших проектов.

Что такое Kubernetes?​

Слово “Kubernetes” происходит от древнегреческого κυβερνήτης, что означает капитан, рулевой, пилот; тот, кто управляет. В сокращении “K8S” цифра 8 - это восемь букв между K и S. Это платформа с открытым исходным кодом для развертывания, масштабирования, управления и контроля контейнеризованных приложений либо сервисов.
Kubernetes делает следующее:

  • Управляет и запускает контейнеры
  • Балансирует сетевой трафик между узлами кластера Kubernetes и количеством реплик контейнеров
  • Осуществляет контроль состояния, автоматические развертывания и откаты реплик контейнеров внутри узлов кластера Kubernetes
  • Осуществляет распределение нагрузки между узлами кластера Kubernetes
  • Предоставляет автоматическое монтирование систем хранения для контейнеров
  • Предоставляет декларативный API и CLI для управления
  • И еще множество полезных, и не очень, модулей и сервисов, которые можно развернуть для управления автоматизацией, инфраструктурой и контейнерами
Kubernetes не делает следующее:

  • Не собирает контейнеры с исходным кодом вашего приложения или сервиса
  • Не предоставляет процессы и решения непрерывной интеграции (CI)
  • Не включает в себя решения и системы сбора журналов и метрик
  • Не включает в себя решения и системы хранения данных
  • Не включает в себя решения и системы хранения контейнеров (registry)
  • Не включает в себя решения и системы от всех бед и болячек инфраструктуры
Kubernetes или K8S — это не просто система оркестрации. Техническое определение оркестрации — это выполнение определенного рабочего процесса: сначала сделай A, затем B, затем C. Напротив, Kubernetes содержит набор независимых, компонуемых процессов управления, которые непрерывно переводят текущее состояние к предполагаемому состоянию. Неважно, как добраться от А до С. Не требуется также и централизованный контроль. Это делает систему более простой в использовании, более мощной, надежной, устойчивой и расширяемой.
Однако все вышеизложенные определения так и не дают нам ключевого понимания,почему и зачем нужен Kubernetes. Основной фактор использования Kubernetes в технологических компаниях, где ведется активная разработка приложений, - это гибкий подход к разработке. Сегодня подход в построении архитектуры приложений изменился - приложения больше не выглядят как монолит кода или один большой сервис, где весь функционал был в одном репозитории. Раньше сборки проектов занимали достаточно много времени, но с приходом контейнеров и таких методологий как DevOps приложения стали модульными, и теперь за каждую функцию или группу функций отвечают определенные сервисы этого приложения. Это можно сравнить с кирпичиками конструктора LEGO: из всех деталей складывается наше приложение, каждый сервис мы можем достать, чтобы что-то изменить и протестировать и вставить обратно в нашу конструкцию. Главная идея состоит в том, чтобы быстро внедрять новый функционал в уже имеющееся приложение.

Но что если у нас таких сервисов тысячи, каждый за что-то отвечает и работает сам по себе? А если еще развернуты несколько реплик для отказоустойчивости? Как управлять всем и уделить внимание каждому из них? Как понять, что сервис правильно работает и взаимодействует с другими? Для этого есть специальные системы, оркестраторы в своем роде, такие как HashiCorp Nomad, Docker Swarm и Kubernetes. Последний используется активнее всего, так как предоставляет более гибкий функционал в контексте управления всей конструкцией приложения.

На самом деле бизнесу нужен не Kubernetes, а система, которая позволит более быстрее подходить к изменению рынка и подстраиваться под его запросы предоставления набора новых услуг или вывода старых. В НАТ.Тех мы давно используем этот инструмент и чувствуем большую разницу, как для нас, так и для наших клиентов. Исходя из нашего опыта, бизнес чаще всего ценит такие возможности К8S как собирать и тестировать только часть приложения, с которой мы работаем, что в разы уменьшает объем необходимых ресурсов; добавлять и убирать сервисы «на лету», тестировать новый функционал в разных регионах и смотреть, как он себя показывает.

Именно для этого нам и нужен Kubernetes, который дает унификацию и гибкость в способе обслуживания и содержания сервисов приложения. Kubernetes предоставляет:

  • Быструю и автоматическую масштабируемость. При росте нагрузки можно быстро добавить необходимые узлы приложения, а также быстро их вывести, чтобы не тратить драгоценные ресурсы
  • Гибкий подход к эксплуатации. Мы можем быстро и легко построить структуру приложения, так как вся структура описывается в конфигурационных файлах - манифестах
  • Гибкий подход в управлении. Kubernetes не потребует перестройки инфраструктуры и прочего, если вы захотели провести тестирование, внедрить новый сервис или сделать деплой по методологии blue-green
  • Универсальность. С помощью манифестов легко переехать, если вы захотели поменять провайдера или переезжали в свой собственный кластер
  • Низкий порог вхождения в использование. Kubernetes довольно легок в освоении манифестов, потому что большую часть работы он делает за вас
Если вы задумываетесь о преимуществах, описанных выше, и можете точно сказать, что вам нужна гибкость в разработке и быстрое внедрение сервисов, адаптируемый подход и универсальность в управлении большим количеством сервисов и их реплик, то думаю, что пора попробовать Kubernetes и у себя.

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

Внедрение Kubernetes​

Kubernetes, так как он был реализован как облачное решение, предпочтительнее разворачивать именно в облаке.

Если вы решились ставить Kubernetes внутри, на своих собственных ресурсах, то вам придется позаботиться о развёртывании и обслуживании такой инфраструктуры вокруг кластера как: репозиторий для контейнеров, внешние или внутренние балансировщики, сетевые хранилища, хранилище секретов, решения для сбора логов и метрик. Также важна и внутренняя инфраструктура “кубера”: CertManager, Ingress, Istio и другие.

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

Компоненты и архитектура​

Давайте поверхностно коснемся архитектуры самого K8S и его важных компонентов.

Сам кластер K8S состоит из, барабанная дробь, рабочих узлов. В узлах или нодах (Nodes, Worker nodes), помимо контейнеров компонентов самого кластера, размещаются контейнеры наших проектов и сервисов.

Worker nodes состоит из компонентов:

  • kubelet - сервис или агент, который контролирует запуск компонентов (контейнеров) кластера
  • kube-proxy - конфигурирует правила сети на узлах
Плоскость управления (Master nodes) управляет рабочими узлами и подами в кластере. Там располагаются компоненты, которые управляют узлами кластера и предоставляют доступ к API.

Control plane состоит из компонентов:

  • kube-apiserver - предоставляет API кубера
  • etcd - распределенное key-value хранилище для всех данных кластера. Необязательно располагается внутри мастера, может стоять как отдельный кластер
  • kube-scheduler - планирует размещение подов на узлах кластера
  • kube-controller-manager - запускает контроллеры
  • kubelet - сервис или агент, который контролирует запуск основных компонентов (контейнеров) кластер

Виды контроллеров​

Deployments - контроллер, который управляет состоянием развертывания подов, которое описывается в манифесте, следит за удалением и созданием экземпляров подов. Управляет контроллерами ReplicaSet.

ReplicaSet - гарантирует, что определенное количество экземпляров подов всегда будет запущено в кластере.

StatefulSets - так же как и Deployments, управляет развертыванием и масштабированием набора подов, но сохраняет набор идентификаторов и состояние для каждого пода.

DaemonSet - гарантирует, что на каждом узле кластера будет присутствовать экземпляр пода.

Jobs - создает определенное количество подов и смотрит, пока они успешно не завершат работу. Если под завершился с ошибкой, повторяет создание, которое мы описали определенное количество раз. Если под успешно отработал, записывает это в свой журнал.

CronJob - запускает контроллеры Jobs по определенному расписанию.

Тестовые кластеры, где потренироваться​

Где можно потренироваться, если нет своего кластера, а платить за облако не хочется? Есть так называемые мини кластеры, которые можно запустить у себя на локальной машине - один из них kind https://kind.sigs.K8S.io/. Все, что нам потребуется, это установленный docker. Также есть Minikube https://Kubernetes.io/ru/docs/tasks/tools/install-minikube/ - для него уже потребуется гипервизор.

Kubectl: как пользоваться, основные команды​

При работе с кластером нам потребуется инструмент командной строки kubectl. https://Kubernetes.io/ru/docs/tasks/tools/install-kubectl/

Его можно установить на локальную машину и управлять несколькими кластерами с одной точки.

Основные команды, которые мы часто будем использовать:

Kubectl get [имя объекта] -n [Имя_пространства_имен] - команда get, как несложно понять из ее названия, выводит нужную нам информацию в основном виде таблицы. Также с помощью нее можно получить yaml, который хранится внутри кластера. Очень часто применяется ключ -n для указания пространства имен, где лежат объекты.

Примеры:

kubectl get services -n Имя_неймспейса - выводит все сервисы в пространстве имён
kubectl get pods --all-namespaces - выводит все поды во всех пространств имён
kubectl get pods -o wide - выводит все поды в текущем пространстве имён с подробностями в виде расширенной таблицы
kubectl get pods -n Имя_неймспейса - выводит все поды в пространстве имён
Kubectl apply -f [имя манифеста yaml] - команда apply применяет манифест к кластеру, управляет созданием объектов в кластере с помощью манифестов yaml. Если в манифесте не указано пространство имен, его можно задать с помощью ключа -n [Имя_пространства_имен].

Примеры:

kubectl apply -f ./my-manifest.yaml - создать ресурсы
kubectl apply -f ./my1.yaml -f ./my2.yaml - создать ресурсы из нескольких файлов
kubectl apply -f ./dir - создать ресурсы из всех файлов манифеста в директории
kubectl apply -f https://K8S.io/manifest - создать ресурсы из URL-адреса
Отличная шпаргалка по командам есть в документации https://Kubernetes.io/ru/docs/reference/kubectl/cheatsheet/

Тестовый кластер​

Давайте развернем свой k8s кластер на примере kind https://kind.sigs.k8s.io/

Первым делом нам понадобится установить docker https://docs.docker.com/engine/install/

После установим сам kind https://kind.sigs.k8s.io/docs/user/quick-start#installation

kind create cluster --name k8s-test-1
--name - ключ задает имя вашего кластера в kind, по умолчанию кластер будет называться kind, давайте назовем его k8s-test-1.

После выполнения команды посмотрим и убедимся, что все хорошо и наш кластер появился в списке.

~ % kind get clusters
k8s-test-1
Убедимся, что в kubectl добавился context нашего кластера

kubectl cluster-info --context kind-k8s-test-1
context - это конфигурация, которую вы используете для подключения к вашим кластерам

kind-k8s-test-1 - имя контекста нашего кластера, так как мы создали кластер в kind, имя будет начинаться с kind-[имя кластера в kind]

Что такое Pods​

Pods или поды — это абстрактный объект в кластере K8S, который состоит из одного или нескольких контейнеров с общим хранилищем и сетевыми ресурсами, а также спецификации для запуска контейнеров.

Это главный объект в кластере, в нем прописаны, какие контейнеры должны быть запущены, количество экземпляров или реплик, политика перезапуска, лимиты, подключаемые ресурсы, узел кластера для размещения.

kube-scheduler планирует размещение пода на узлах кластера

kubelet на рабочем узле кластера запускает под

Любители забегать вперед и просто углубиться в тему могут почитать прекрасную статью на github.

Что такое Namespace​

Namespace или пространство имен — это абстрактный объект, который логически разграничивает и изолирует ресурсы между подами. Вы можете рассматривать пространство имен как внутренний виртуальный кластер, который поможет вам изолировать проекты или пользователей между собой, применить разные политики квот на свои проекты или выдать права доступа только на определенную область.

У нас уже есть пространства имен, которые создаются при создании кластера, - чтобы увидеть их, нужно выполнить команду:

kubectl get namespace
Ответ:

NAME STATUS AGE
default Active 1d
kube-system Active 1d
kube-public Active 1d
default — пространство имён по умолчанию для объектов без какого-либо другого пространства имён

kube-system — пространство имён для объектов, созданных Kubernetes. Там размещаются системные поды кластера

kube-public — создаваемое автоматически пространство имён, которое доступно для чтения всем пользователям (включая также неаутентифицированных пользователей)

Размещение объектов​

Давайте разместим свой первый объект в нашем тестовом кластере, для этого создадим свой namespace и положим туда простенький pod с nginx.

Чтобы создать свой namespace, нам нужно передать его спецификацию или манифест в формате yaml.

В файле .yaml создаваемого объекта Kubernetes необходимо указать значения для следующих полей:

apiVersion — используемая для создания объекта версия API Kubernetes. Стоит отметить, что из версии к версии версии api могут меняться

kind — тип создаваемого объекта

metadata — данные, позволяющие идентифицировать объект (name, UID и необязательное поле namespace)

spec — требуемое состояние объекта

Давайте создадим test-namespace.yaml со следующим содержанием:

apiVersion: v1
kind: Namespace
metadata:
name: test
И применим его с помощью команды:

kubectl apply -f test-namespace.yaml
Посмотрим на результат:

kubectl get namespace
NAME STATUS AGE
default Active 1d
kube-system Active 1d
kube-public Active 1d
test Active 10s
Как видим, наш namespace успешно создался. Приступим к созданию своего первого пода (pod). Давайте положим контейнер с NGINX в наш namespace.

Как и с namespace, опишем его. Создадим hello.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
name: nginx-hello
labels:
app: nginx-hello
spec:
replicas: 1
selector:
matchLabels:
app: nginx-hello
template:
metadata:
labels:
app: nginx-hello
spec:
containers:
- name: nginx-hello
image: nginxdemos/hello
ports:
- containerPort: 80
Применим его

kubectl apply -f hello.yaml
Если манифест применился то увидим:

deployment.apps/nginx-hello created
Узнаем развернулся ли наш контейнер

kubectl get pods -n test
~# kubectl get pods -n test
NAME READY STATUS RESTARTS AGE
nginx-hello-75cc4f9fb7-rv556 1/1 Running 0 9s

Как видим, наш контейнер создался. Сначала он был в статусе ContainerCreating, потом перешел в Running. Давайте проверим и убедимся, что контейнер работает и что-то нам отдает, для этого на поможет kubectl port-forward [имя контейнера] [порт на который будем перенаправлять]:[порт контейнера] -n [неймспейс].

К примеру

kubectl port-forward nginx-hello-75cc4f9fb7-rv556 30080:80 -n test
Зайдем через наш браузер на http://localhost:30080/

Если вы видите в браузере:

Server address:127.0.0.1:80
Server name:nginx-hello-75cc4f9fb7-rv556
Date:12/Nov/2021:11:40:36 +0000
То контейнер работает, неожиданно. :)

На этом в первой части всё - продолжение следует.

 
Сверху