Это многостраничный печатный вид этого раздела. Нажмите что бы печатать.

Вернуться к обычному просмотру страницы.

Основы Kubernetes

Основы Kubernetes

В данном руководстве вы познакомитесь с основами системы оркестрации кластеров Kubernetes. Каждый модуль содержит краткую справочную информацию по основной функциональности и концепциям Kubernetes, а также включает интерактивные онлайн-уроки. С их помощью вы научитесь самостоятельно управлять простым кластером и контейнеризированными приложениями, которые были в нём развернуты.

Пройдя интерактивные уроки, вы узнаете, как:

  • развёртывать контейнеризированное приложение в кластер;
  • масштабировать развёртывание;
  • обновить контейнеризированное приложение на новую версию ПО;
  • отлаживать контейнеризированное приложение.

Чем может Kubernetes помочь вам?

От современных веб-сервисов пользователи ожидают, что приложения будут доступны 24/7, а разработчики — развёртывать новые версии приложений по нескольку раз в день. Контейнеризация направлена на достижение этой цели, поскольку позволяет выпускать и обновлять приложения без простоев. Kubernetes гарантирует, что ваши контейнеризованные приложения будет запущены где угодно и когда угодно, вместе со всеми необходимыми для их работы ресурсами и инструментами. Kubernetes — это готовая к промышленному использованию платформа с открытым исходным кодом, разработанная на основе накопленного опыта Google по оркестровке контейнеров и вобравшая в себя лучшие идеи от сообщества.


1 - Создание кластера

1.1 - Использование minikube для создания кластера

Узнайте, что такое кластер Kubernetes. Узнайте, что такое minikube. Запустите Kubernetes-кластер.

Цели

  • Узнать, что такое кластер Kubernetes
  • Узнать, что такое minikube
  • Запустить кластер Kubernetes

Кластеры Kubernetes

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

Кластер Kubernetes состоит из двух типов ресурса:

  • Мастер (ведущий узел) управляет кластером
  • Рабочие узлы — машины, на которых выполняются приложения

Краткое содержание:

  • Кластер Kubernetes
  • Minikube

Kubernetes — платформа с открытым исходным кодом промышленного уровня, которая управляет размещением (планированием) и запуском контейнеров приложений в пределах компьютерных кластеров и между ними.


Схема кластера


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

Узел — это виртуальная машина или физический компьютер, который выполняет роль рабочего узла в кластере Kubernetes. У каждого узла есть Kubelet — агент, управляющий узлом и взаимодействующий с ведущим узлом Kubernetes. Узел также имеет инструменты для выполнения контейнерных операций, например, Docker или rkt. Кластер Kubernetes в промышленном окружении должен состоять как минимум из трёх узлов.

Ведущие узлы управляют кластером и узлами, которые используются для запуска приложений.

При развертывании приложений в Kubernetes вы сообщаете ведущему узлу запускать контейнеры приложений. Ведущий узел планирует выполнение контейнеров на узлах кластера. Узлы взаимодействуют с ведущим узлом посредством API Kubernetes, который предлагает ведущий узел. Кроме этого, конечные пользователи могут напрямую использовать API Kubernetes для работы с кластером.

Kubernetes-кластер может быть развернут на физических или виртуальных машинах. Чтобы начать работать с Kubernetes, можно использовать minikube. Minikube — это упрощённая реализация Kubernetes, которая создает виртуальную машину на вашем локальном компьютере и разворачивает простой кластер с одним узлом. Minikube доступен для Linux, macOS и Windows. В CLI-инструмент minikube встроены все необходимые функции для инициализации кластера и работы с ним, включая запуск, остановку, просмотр состояния и удаление кластера.

Теперь, когда вы знаете больше о том, что такое Kubernetes, перейдите к руководству Привет, minikube на своём компьютере.

2 - Развёртывание приложения

2.1 - Использование kubectl для развёртывания приложения

Узнайте про деплойменты приложения. Разверните первое приложение в Kubernetes с помощью kubectl.

Цели

  • Узнать про деплойменты приложения
  • Развернуть первое приложение в Kubernetes с помощью kubectl

Deployments в Kubernetes

Как только вы запустили кластер Kubernetes, вы можете развернуть на нём свои контейнеризированные приложения. Для этого вам нужно создать деплоймент (Deployment). Deployment в Kubernetes определяет, как создавать и обновлять экземпляры вашего приложения. После создания деплоймента control plane в Kubernetes запланирует запуск экземпляров приложения на отдельных узлах в кластере.

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

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

Краткое содержание:

  • Деплойменты
  • Kubectl

Deployment отвечает за создание и обновление экземпляров приложения


Развёртывание вашего первого приложения на Kubernetes


Вы можете создавать и управлять деплойментами через консольный инструмент Kubernetes под названием kubectl. Kubectl использует Kubernetes API для работы с кластером. В этом модуле вы узнаете про наиболее используемые команды kubectl, необходимые для создания деплойментов, которые будут запускать приложения в кластере Kubernetes.

При создании развертывания нужно указать образ контейнера приложения и количество запущенных реплик. Впоследствии эти параметры можно изменить. В модулях 5 и 6 рассказывается про масштабирование и обновление деплойментов.

Чтобы приложение запускалось в Kubernetes, оно должно быть упаковано в один из поддерживаемых форматов контейнеров

Для своего первого деплоймента возьмём приложение hello-node, упакованное в Docker-контейнер и использующее NGINX, чтобы выводить на экран все запросы. (Если вы ещё не пробовали создавать приложение hello-node и деплоить контейнер с ним, можете сначала выполнить инструкции из руководства "Привет, Minikube").

Вам также потребуется установленная утилита kubectl. По вопросам её инсталляции см. Установку инструментов.

Теперь, когда понятие деплойментов вам знакомо, давайте задеплоим первое приложение!


Основы kubectl

Общий формат команд kubectl выглядит так: kubectl действие ресурс

Эта команда выполнит указанное действие (например, create, describe или delete) с указанным ресурсом (например, node или deployment). Можно воспользоваться справкой через флаг --help после подкоманды, чтобы получить дополнительные сведения о возможных параметрах (например: kubectl get nodes --help).

Убедитесь, что kubectl настроена на подключение к вашему кластеру, выполнив команду kubectl version.

Убедитесь, что kubectl установлена и вы можете увидеть версию и у клиента, и у сервера.

Чтобы увидеть список узлов кластера, выполните команду kubectl get nodes.

Вы увидите доступные узлы. Позже Kubernetes выберет, куда задеплоить ваше приложение, руководствуясь данными о доступных узлах.

Деплой приложения

Давайте развернём первое приложение в Kubernetes с помощью команды kubectl create deployment. Для этого потребуется указать имя деплоймента и путь к образу приложения (используйте полный URL репозитория для образов, которые располагаются вне Docker Hub).

kubectl create deployment kubernetes-bootcamp --image=gcr.io/google-samples/kubernetes-bootcamp:v1

Отлично! Создав этот Deployment, вы только что развернули первое приложение. Команда привела к выполнению следующих действий:

  • поиск подходящего узла, на котором можно запустить экземпляр приложения (у нас доступен только 1 узел);
  • планирование (размещение) приложения для запуска на этом узле;
  • настройка кластера на повторное размещение экземпляра на новом узле, когда это потребуется.

Чтобы увидеть список деплойментов, выполните команду kubectl get deployments:

kubectl get deployments

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

Просмотр приложения

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

О других возможностях сделать приложение доступным вне кластера Kubernetes мы расскажем позже, в разделе Открытие доступа к приложению.

Команда kubectl proxy создаст прокси, который перенаправляет взаимодействие в частную сеть, доступную в рамках кластера. Во время своей работы прокси не выводит никаких сообщений, а остановить его можно нажатием на control-C.

Для запуска прокси потребуется открыть второе окно с терминалом.

kubectl proxy

Теперь у нас есть соединение между хостом (терминалом) и Kubernetes-кластером. Прокси обеспечивает прямой доступ к API из терминала.

Через эндпоинт от прокси можно увидеть все API. Например, с помощью curl мы можем напрямую через API узнать версию:

curl http://localhost:8001/version

Сервер API автоматически создаст эндпоинт для каждого пода в соответствии с именем пода, который будет также доступен через прокси.

Для начала узнаем имя пода и сохраним его в переменной окружения POD_NAME:

export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME

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

curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/

Чтобы новый деплоймент был доступен без использования прокси, потребуется сервис (объект Service), о котором будет рассказано в следующих разделах.

Когда всё готово, переходите к разделу Просмотр подов и узлов.

3 - Изучение приложения

3.1 - Просмотр подов и узлов

Узнайте, как диагностировать проблемы с Kubernetes-приложениями с помощью kubectl get, kubectl describe, kubectl logs и kubectl exec.

Цели

  • Узнать про поды Kubernetes
  • Узнать про узлы Kubernetes
  • Научиться диагностировать развёрнутые приложения

Поды Kubernetes

После того, как вы создали Deployment в модуле 2, Kubernetes создал под (Pod), в котором был размещён экземпляр вашего приложения. Под — это абстрактный объект Kubernetes, представляющий собой группу из одного или нескольких контейнеров приложения (например, Docker) и совместно используемых ресурсов для этих контейнеров. Ресурсами могут быть:

  • общее хранилище (тома);
  • сеть (уникальный IP-адрес кластера);
  • информация о том, как запускать каждый контейнер, например, версия образа контейнера или используемые номера портов.

Под представляет специфичный для приложения "логический хост" и может содержать разные контейнеры приложений, которые в общем и целом тесно связаны. Например, в поде может размещаться как контейнер с приложением на Node.js, так и другой контейнер, который получает некоторые данные для их дальнейшей публикации на веб-сервере Node.js. Все контейнеры в поде имеют одни и те же IP-адрес и пространство портов, всегда размещаются и планируются для выполнения на одном и том же узле.

Поды — неделимая единица в платформе Kubernetes. При создании деплоймента в Kubernetes создаются поды с контейнерами внутри (вместо того, чтобы непосредственно создавать контейнеры). Каждый объект Pod связан с узлом (Node), на котором он размещён, и остаётся там до окончания работы (согласно стратегии перезапуска) либо удаления. В случае неисправности узла такой же под будет запланирован для запуска на других доступных узлах кластера.

Краткое содержание:

  • Поды
  • Узлы
  • Основные команды kubectl

Под (Pod) — группа из одного или нескольких контейнеров приложений (например, Docker) и их общих хранилищ (томов), IP-адреса и информации о том, как их запускать.


Схема подов


Узлы

Под всегда работает в узле (Node). Узел — это рабочая машина в Kubernetes, которая в зависимости от кластера может быть либо виртуальной, либо физической. Каждый узел управляется компонентом под названием control plane. Узел может содержать несколько подов, которые control plane автоматически размещает ("планирует" для запуска) на разные узлы кластера. Автоматическое планирование (распределение подов по узлам) control plane учитывает доступные ресурсы на каждом узле.

В каждом узле Kubernetes как минимум работает:

  • Kubelet — процесс, отвечающий за взаимодействие между control plane и узлом; он управляет подами и запущенными контейнерами на рабочей машине.
  • Среда выполнения контейнера (вроде Docker), отвечающая за получение (загрузку) образа контейнера из реестра, распаковку контейнера и запуск приложения.

Контейнеры должны запускаться вместе в пределах одного пода только в случаях, когда они тесно связаны и должны совместно использовать ресурсы (например, диск).


Схема узла


Диагностика с помощью kubectl

В модуле 2 вы использовали инструмент командной строки kubectl. В этом (третьем) модуле вы продолжите его использовать, но для получения информации о развернутых приложениях и окружениях, в которых они работают. Наиболее распространенные операции выполняются с использованием следующих команд kubectl:

  • kubectl get — вывод списка ресурсов;
  • kubectl describe — вывод подробной информации о ресурсе;
  • kubectl logs — вывод логов контейнера в поде;
  • kubectl exec — выполнение команды в контейнере пода.

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

Теперь, когда вы познакомились поближе с компонентами кластера и командами, давайте исследуем приложение.

Узел — рабочая машина в Kubernetes, которая может быть как виртуальной, так и физической (в зависимости от используемого кластера). На одном узле могут быть запущены несколько подов.

Проверка конфигурации приложения

Давайте проверим, что приложение, которое мы развернули ранее, работает. Воспользуемся командой kubectl get и посмотрим на существующие поды:

kubectl get pods

Если работающих подов нет, подождите несколько секунд и выведите их список снова. Как только увидите работающий под, следуйте инструкциям ниже.

Теперь, чтобы увидеть, какие контейнеры находятся внутри этого пода и какие образы использовались при сборке этих контейнеров, выполним команду kubectl describe pods:

kubectl describe pods

Здесь можно увидеть подробности о контейнере пода: IP-адрес, используемые порты и список событий, относящихся к жизненному циклу пода.

У подкоманды describe подробный вывод. В частности, он затрагивает концепции, которые мы ещё не рассматривали, но не волнуйтесь — они станут понятнее в дальнейшем.

Примечание: подкоманду describe можно использовать для получения информации о многих примитивах Kubernetes, включая узлы (Nodes), поды (Pods) и деплойменты (Deployments). Вывод describe предназначен для чтения человеком, не для использования в скриптах.

Просмотр приложения в терминале

Вспомним, что поды работают в изолированной, частной сети, поэтому нам нужен прокси для доступа к ним — так мы сможем производить отладку и взаимодействовать с ними. Для этого мы во втором терминале воспользуемся командой kubectl proxy, чтобы запустить прокси. Откройте новое окно терминала и выполните:

kubectl proxy

Теперь мы снова получим имя пода и обратимся к нему через прокси. Чтобы получить имя пода и записать его в переменную окружения POD_NAME, выполним:

export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')"
echo Name of the Pod: $POD_NAME

Чтобы увидеть вывод приложения, выполним запрос через curl:

curl http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/

Здесь URL указывает на маршрут к API пода.

Просмотр логов контейнера

Всё, что обычное приложение отправляет в стандартный вывод (standard output), становится логами контейнера в поде. Получить эти логи можно с помощью команды kubectl logs:

kubectl logs "$POD_NAME"

Примечание: указывать название контейнера не требуется, потому что в данном поде у нас единственный контейнер.

Выполнение команд в контейнере

Когда под запущен и работает, в его контейнерах можно выполнять команды. Для этого воспользуемся подкомандой exec и передадим имя пода в качестве параметра. Выведем список переменных окружения в контейнере:

kubectl exec "$POD_NAME" -- env

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

Далее запустим Bash-сессию в контейнере пода:

kubectl exec -ti $POD_NAME -- bash

Откроется консоль в контейнере, в котором работает NodeJS-приложение. Исходный код приложения находится в файле server.js:

cat server.js

Также можно убедиться, что приложение запущено и работает, обратившись к нему через curl:

curl http://localhost:8080

Примечание: мы здесь использовали localhost, поскольку выполняли команду внутри пода NodeJS. Если у вас не получается подключиться к localhost:8080, проверьте, что запускали команду kubectl exec, а сейчас вызываете команду из пода.

Чтобы закрыть подключение к контейнеру, введите exit.

Когда всё готово, переходите к разделу Создание сервиса для открытия доступа к приложению.

4 - Открытие доступа к приложению

4.1 - Создание сервиса для открытия доступа к приложению

Узнайте о сервисах в Kubernetes. Разберитесь, какое отношение к сервисам имеют лейблы и селекторы. Сделайте приложение доступным вне кластера Kubernetes.

Цели

  • Узнать о сервисах в Kubernetes
  • Разобраться, какое отношение к сервисам имеют лейблы и селекторы
  • Сделать приложение доступным вне кластера Kubernetes

Обзор сервисов Kubernetes

Под — это расходный материал в Kubernetes. У них есть свой жизненный цикл. Когда рабочий узел прекращает работу, запущенные поды в узле также уничтожаются. После этого ReplicaSet попытается автоматически вернуть кластер обратно в требуемое состояние, создавая новые поды, чтобы поддержать работоспособность приложения. Другим примером жизни и смерти подов может служить бэкенд для обработки изображений с 3 репликами. Поскольку это взаимозаменяемые реплики, они не влияют на фронтенд-часть, даже если под был уничтожен и пересоздан. Тем не менее, каждый под в кластере Kubernetes имеет уникальный IP-адрес — даже под на одном и том же узле. Поэтому необходим способ автоматической координации изменений между подами, чтобы приложения продолжали функционировать.

Сервис (Service) в Kubernetes — это абстрактный объект, который определяет логический набор подов и политику доступа к ним. Сервисы создают слабую связь между подами, которые от них зависят. Сервис создаётся в формате YAML (рекомендуемый формат) или JSON, как и все остальные объекты в Kubernetes. Как правило, набор подов для сервиса определяется селектором лейблов (label selector) — ниже будет описано, в каких случаях может понадобиться сервис без указания селектора (selector) в его спецификации.

Хотя у каждого пода есть уникальный IP-адрес, эти IP-адреса не доступны за пределами кластера без использования сервиса. Сервисы позволяют приложениям принимать трафик. Сервисы могут быть по-разному открыты, в зависимости от значения поля type, указанного в спецификации сервиса:

  • ClusterIP (по умолчанию) — открывает доступ к сервису по внутреннему IP-адресу в кластере. Этот тип делает сервис доступным только внутри кластера;
  • NodePort — открывает сервис на том же порту каждого выбранного узла в кластере с помощью NAT. Делает сервис доступным вне кластера через <NodeIP>:<NodePort>. Является надмножеством ClusterIP.
  • LoadBalancer — создает внешний балансировщик нагрузки в текущем облаке (если это поддерживается) и назначает фиксированный внешний IP-адрес для сервиса. Является надмножеством NodePort.
  • ExternalName — открывает доступ к сервису по содержимому поля externalName (например, foo.bar.example.com), возвращая запись CNAME с его значением. При этом прокси не используется. Для этого типа требуется версия kube-dns 1.7+ или CoreDNS 0.0.8+.

Более подробно узнать о различных типах сервисах можно в руководстве Использование IP-порта источника. Также изучите Подключение приложений к сервисам.

Кроме этого, обратите внимание, что в некоторых случаях в сервисах не определяется selector в спецификации. Сервис без selector не будет создавать соответствующий эндпоинт (Endpoint). Таким образом, пользователь может вручную определить эндпоинты для сервиса. Ещё один возможный сценарий создания сервиса без селектора — это строгое использование type: ExternalName.

Краткое содержание

  • Открытие внешнего трафика для подов
  • Балансировка нагрузки трафика между подов
  • Использование лейблов

Сервис Kubernetes (Service) — это уровень абстракции, который определяет логический набор подов, перенаправляет внешний трафик, балансирует нагрузку и реализует service discovery для этих подов.


Сервисы и лейблы

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

Сервисы для выбора набора подов используют лейблы и селекторы. Лейблы — пары ключ-значение, добавленные к объектам; например, они могут использоваться чтобы:

  • идентифицировать объекты для окружений разработки, тестирования и production;
  • встроить теги версии;
  • классифицировать объекты через теги.


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

Создание нового сервиса

Давайте убедимся, что приложение работает. Воспользуемся командой kubectl get и посмотрим на существующие поды:

kubectl get pods

Если работающих подов нет, объекты из предыдущих разделов руководства была удалены. В таком случае вернитесь и повторно создайте деплоймент по инструкциям из раздела Использование kubectl для развёртывания приложения. После этого подождите несколько секунд и повторно запросите список подов. Как только увидите работающий под, можно следовать инструкциям ниже.

Далее посмотрим на список уже имеющихся сервисов в кластере:

kubectl get services

У нас есть сервис под названием kubernetes. Его по умолчанию создаёт minikube при запуске кластера. Чтобы создать новый сервис и сделать его доступным для внешних пользователей, воспользуемся командой expose с указанием типа сервиса NodePort в качестве параметра.

kubectl expose deployment/kubernetes-bootcamp --type="NodePort" --port 8080

Попробуем подкоманду get services ещё раз:

kubectl get services

Теперь у нас есть сервис под названием kubernetes-bootcamp. Мы можем увидеть, что у этого сервиса уникальный cluster-IP, внутренний порт и external-IP (IP соответствующего узла).

Чтобы выяснить, какой порт был открыт для внешнего мира (для сервиса со спецификацией type: NodePort), выполним подкоманду describe service:

kubectl describe services/kubernetes-bootcamp

Объявим переменную окружения NODE_PORT, в которую запишем значение назначенного порта узла:

export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"
echo "NODE_PORT=$NODE_PORT"

Теперь можно проверить, что приложение доступно вне кластера, с помощью curl, IP-адреса узла и порта, проброшенного вовне:

curl http://"$(minikube ip):$NODE_PORT"

Получим ответ от сервера. Сервис доступен внешнему миру.

Шаг 2: использование лейблов

Deployment автоматически создаёт лейбл для пода. Подкоманда describe deployment покажет его название (key):

kubectl describe deployment

Воспользуемся этим лейблом при выводе списка подов. Для этого вызовем команду kubectl get pods с флагом -l и нужными значениями лейблов в качестве параметра:

kubectl get pods -l app=kubernetes-bootcamp

То же самое можно делать при выводе списка сервисов:

kubectl get services -l app=kubernetes-bootcamp

Получим имя пода и запишем его в переменную окружения POD_NAME:

export POD_NAME="$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')"
echo "Name of the Pod: $POD_NAME"

Чтобы добавить новый лейбл, воспользуемся подкомандой label, для которой укажем тип объекта, имя объекта и значение нового лейбла:

kubectl label pods "$POD_NAME" version=v1

Новый лейбл добавится к поду (мы зафиксировали версию приложения для этого пода), а мы сможем убедиться в этом с помощью команды describe pod:

kubectl describe pods "$POD_NAME"

Как видно, лейбл добавился к нашему поду. Теперь мы можем получить список всех подов, использующих новый лейбл:

kubectl get pods -l version=v1

Наш под будет в этом списке.

Удаление сервиса

Чтобы удалить сервис, воспользуйтесь подкомандой delete service. В ней могут указываться и лейблы:

kubectl delete service -l app=kubernetes-bootcamp

Убедитесь, что сервис удалился:

kubectl get services

Вывод подтвердит, что сервис был удалён. Убедиться в том, что удалился соответствующий маршрут для внешнего трафика, можно через curl к доступному ранее IP и порту:

curl http://"$(minikube ip):$NODE_PORT"

Так можно убедиться, что приложение более недоступно снаружи кластера. Проверить, что приложение всё ещё работает, можно через curl, который будет выполнен внутри пода:

kubectl exec -ti $POD_NAME -- curl http://localhost:8080

Мы увидим, что приложение запущено. Оно функционирует, потому что за его работу отвечает деплоймент (Deployment). Чтобы остановить приложение, потребуется также удалить и его деплоймент.

Когда всё готово, переходите к разделу Запуск нескольких экземпляров приложения.

5 - Масштабирование приложения

5.1 - Запуск нескольких экземпляров приложения

Отмасштабируйте существующее приложение вручную с помощью kubectl.

Цели

  • Научиться масштабировать приложение с kubectl

Масштабирование приложения

В предыдущих модулях мы создали деплоймент (Deployment), а затем открыли к нему публичный доступ через сервис (Service). Деплоймент создал только один под, в котором работает наше приложение. По мере увеличения трафика необходимо будет промасштабировать приложение, чтобы оно могло справиться с возросшим потоком пользователей.

Если вы не работали с предыдущими разделами документации, начните с использования minikube для создания кластера.

Масштабирование осуществляется за счёт изменения количества реплик в развёртывании.

Краткое содержание:

  • Масштабирование деплоймента

Количество экземпляров можно указать прямо при создании деплоймента, используя параметр --replicas команды kubectl create deployment


Обзор темы масштабирования


В случае масштабирования деплоймента создаются новые поды, которые распределяются по узлам с доступными ресурсами. Масштабирование увеличит количество подов в соответствии с новым требуемым состоянием. Kubernetes также поддерживает автоматическое масштабирование подов, но эта тема не рассматривается в данном уроке. Кроме этого, возможно масштабирование до нуля: в таком случае завершается работа всех подов в деплойменте.

При запуске нескольких экземпляров приложения нужно правильно распределить трафик между ними. У сервисов есть встроенный балансировщик нагрузки, который распределяет сетевой трафик на все поды деплоймента, доступного извне. Сервисы постоянно отслеживают запущенные поды через их эндпоинты (endpoints), чтобы направлять трафик только на доступные поды.

Масштабирование выполняется с помощью изменения количества реплик в деплойменте.


Если у вас есть несколько работающих экземпляров приложения, можно выполнять плавающие обновления (rolling updates) без простоев. С ними мы познакомимся в следующем модуле. А пока перейдём к терминалу и промасштабируем наше приложение.

Масштабирование деплоймента

Для вывода списка депойментов воспользуйтесь подкомандой get deployments: kubectl get deployments

Вывод будет примерно следующим:

               NAME                  READY   UP-TO-DATE   AVAILABLE   AGE
               kubernetes-bootcamp   1/1     1            1           11m
               

У нас должен быть 1 под. Если его нет, выполните команду ещё раз. Вывод показывает следующую информацию:

  • NAME — названия деплойментов (Deployments) в кластере.
  • READY — соотношение CURRENT/DESIRED для его экземпляров (реплик).
  • UP-TO-DATE — количество реплик, которые были обновлены до желаемого состояния.
  • AVAILABLE — количество реплик, доступных для пользователей.
  • AGE — сколько времени приложение было запущено.

Чтобы увидеть ReplicaSet, созданные деплойментом, выполните: kubectl get rs

Обратите внимание, что название ReplicaSet всегда форматируется как [DEPLOYMENT-NAME]-[RANDOM-STRING]. Последний фрагмент генерируется случайным образом и использует pod-template-hash в качестве seed-значения.

Этот вывод будет содержать два важных столбца:

  • DESIRED — желаемое количество экземпляров (реплик) приложения. Это значение вы определяете, когда создаёте деплоймент.
  • CURRENT — количество реплик, которые работают в настоящий момент.

Далее отмасштабируем деплоймент до 4 реплик. Для этого воспользуемся командой kubectl scale, для которой укажем тип объекта (деплоймент), его название и количество желаемых экземпляров:

kubectl scale deployments/kubernetes-bootcamp --replicas=4

Снова выведем список деплойментов с помощью get deployments:

kubectl get deployments

Изменение применилось: теперь доступны 4 экземпляра приложения. Далее проверим, изменилось ли количество подов:

kubectl get pods -o wide

Теперь у нас 4 пода с разными IP-адресами. Это изменение было зафиксировано в логе событий деплоймента. Убедиться в этом можно подкомандой describe:

kubectl describe deployments/kubernetes-bootcamp

В выводе этой команды тоже видно, что теперь у нас 4 реплики.

Балансировка нагрузки

Проверим, что сервис балансирует трафик. Чтобы узнать внешний IP-адрес и порт, воспользуемся командой describe service, с которой уже познакомились в предыдущем модуле:

kubectl describe services/kubernetes-bootcamp

Объявим переменную окружения NODE_PORT со значением порта нашего узла:

export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"

echo NODE_PORT=$NODE_PORT

Далее обратимся через curl к проброшенному IP-адресу и порту. Выполните эту команду много раз:

curl http://"$(minikube ip):$NODE_PORT"

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

Масштабирование вниз

Чтобы уменьшить деплоймент до 2 реплик, снова обратимся к подкоманде scale:

kubectl scale deployments/kubernetes-bootcamp --replicas=2

С помощью подкоманды get deployments выведем список деплойментов, чтобы убедиться, что изменение применилось:

kubectl get deployments

Количество реплик уменьшилось до 2. Выведем список подов с get pods:

kubectl get pods -o wide

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

Когда всё готово, переходите к разделу Выполнение плавающего обновления.

6 - Обновление приложения

6.1 - Выполнение плавающего обновления

Выполнение плавающего обновления с помощью kubectl.

Цели

  • Выполнить плавающее обновление с помощью kubectl

Обновление приложения

Пользователи надеются, что приложения будут работать круглосуточно, а разработчики в свою очередь хотят развёртывать новые версии приложений по несколько раз в день. В Kubernetes это возможно благодаря механизму плавающих обновлений (rolling updates). Плавающие обновления позволяют обновить деплойменты без простоев, шаг за шагом заменяя старые поды на новые. Новые поды будут запущены на узлах, имеющих достаточно ресурсов.

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

Краткое содержание:

  • Обновление приложения

Плавающие обновления последовательно заменяют экземпляры подов на новые, тем самым позволяя обновить деплойменты без простоев


Обзор плавающих обновлений


Подобно масштабированию приложения, если деплоймент доступен извне, при обновлении сервис будет балансировать трафик только между доступными подами. Доступный под — это экземпляр, который может быть запущен для пользователей приложения.

С помощью плавающих обновлений можно:

  • переводить приложение из одного окружения в другое (через обновления образа контейнера);
  • откатываться к предыдущим версиям;
  • осуществлять непрерывную интеграцию и непрерывную доставку приложений без простоев.

Если деплоймент был открыт наружу, в процессе обновления сервис будет балансировать трафик только на доступные поды.


В инструкциях ниже мы обновим приложение до новой версии и потом откатим его обратно.


Обновление версии приложения

Чтобы получить список деплойментов, выполните подкоманду get deployments: kubectl get deployments

Для списка подов — подкоманду get pods:

kubectl get pods

Чтобы увидеть версию текущего образа в приложении, воспользуйтесь подкомандой describe pods и посмотрите на поле Image:

kubectl describe pods

Чтобы обновить версию образа приложения до v2, воспользуемся подкомандой set image, для которой укажем имя деплоймента и новую версию нужного образа:

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2

Эта команда перевела деплоймент на использование другого образа для приложения и инициировала плавающее обновление. Статус новых и старых подов (т. е. тех, которые будут остановлены) можно проверить с помощью подкоманды get pods:

kubectl get pods

Шаг 2: валидация обновления

Во-первых, убедимся, что приложение работает. Доступный извне IP-адрес и порт узнаем с помощью команды describe service:

kubectl describe services/kubernetes-bootcamp

Объявим переменную окружения NODE_PORT со значением порта нашего узла:

export NODE_PORT="$(kubectl get services/kubernetes-bootcamp -o go-template='{{(index .spec.ports 0).nodePort}}')"
echo "NODE_PORT=$NODE_PORT"

Далее обратимся через curl к проброшенному IP и порту:

curl http://"$(minikube ip):$NODE_PORT"

Каждый раз при вызове этой команды curl вам будет попадаться другой под. Обратите внимание, что все поды теперь работают с последней версией приложения (v2).

Проверить статус обновления можно также с помощью подкоманды rollout status:

kubectl rollout status deployments/kubernetes-bootcamp

Увидеть текущую версию образа приложения можно подкомандой describe pods:

kubectl describe pods

В поле Image у этого вывода убедитесь, что запущена последняя версия образа (v2).

Откат обновления

Выполним ещё одно обновление и попробуем развернуть образ, тегированный как v10:

kubectl set image deployments/kubernetes-bootcamp kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10

Вызовем get deployments, чтобы увидеть статус деплоймента:

kubectl get deployments

Обратите внимание, что вывод показывает недостаток желаемого количества доступных подов. Обратимся к подкоманде get pods, чтобы вывести полный список подов:

kubectl get pods

Здесь обратите внимание, что некоторые поды перешли в статус ImagePullBackOff.

Чтобы получить больше информации о проблеме, выполните подкоманду describe pods:

kubectl describe pods

В разделе Events вывода по проблемным подам можно увидеть, что новая версия образа (v10) не существует в репозитории.

Чтобы откатить деплоймент к последней работающей версии, воспользуйтесь подкомандой rollout undo:

kubectl rollout undo deployments/kubernetes-bootcamp

Команда rollout undo откатывает деплоймент к предыдущему известному состоянию (к образу v2). Обновления версионируются, поэтому можно откатиться к любому предыдущему известному состоянию деплоймента.

С помощью подкоманды get pods выведем список подов еще раз:

kubectl get pods

Четыре пода работают. Проверить, какие версии образа развёрнуты в этих подах, можно подкомандой describe pods:

kubectl describe pods

Деплоймент снова использует стабильную версию приложения (v2). Откат произошёл успешно.

Не забудьте очистить содержимое вашего локального кластера:

kubectl delete deployments/kubernetes-bootcamp services/kubernetes-bootcamp