Это многостраничный печатный вид этого раздела.
Нажмите что бы печатать.
Вернуться к обычному просмотру страницы.
Руководства
В данном разделе документации Kubernetes можно найти руководства. В них рассказывается, как достичь определённой цели, а не просто выполнить одну задачу. Большинство уроков состоит из нескольких разделов, каждый из которых включает в себя шаги для последовательного выполнения. Перед тем как приступить к выполнению уроков, может быть полезно ознакомиться со словарем терминов для последующих обращений.
Основы
Конфигурирование
- Конфигурирование Redis с использованием ConfigMap
Приложения без состояния
Приложения с состоянием
Основы StatefulSet
Пример: WordPress и MySQL с персистентным хранилищем
Пример: Развёртывание Cassandra с Stateful Sets
Запуск ZooKeeper, A CP Distributed System
Кластеры
Сервисы
Что дальше
Если вы хотите создать руководство самостоятельно, обратитесь к странице Использование шаблонов страниц, чтобы узнать информацию и посмотреть шаблоны для составления руководств.
1 - Привет, Minikube
Это руководство демонстрирует, как запустить простое приложение в Kubernetes
с помощью minikube. Для этого используется образ контейнера с NGINX, который
выводит обратно текст всех запросов.
Цели
- Развернуть простое приложение в minikube.
- Запустить приложение.
- Посмотреть логи приложения.
Подготовка к работе
Руководство подразумевает, что вы уже настроили minikube
.
См. документацию minikube start для инструкций по его установке.
Вам также потребуется установить kubectl
.
См. Установку и настройку kubectl для инструкций по его установке.
Создание кластера minikube
Запуск панели (dashboard)
Откройте панель Kubernetes. Это можно сделать двумя способами:
Откройте новый терминал и запустите:
# Запустите в новом терминале и не закрывайте его.
minikube dashboard
Теперь можно вернуться к терминалу, где вы запускали minikube start
.
Примечание:
Команда dashboard
активирует дополнение dashboard и открывает прокси в веб-браузере по умолчанию.
В этой панели можно создавать такие Kubernetes-ресурсы, как Deployment и Service.
Если вы работаете в окружении с правами root, см. вкладку «Копирование URL для запуска».
По умолчанию панель доступна только из внутренней виртуальной сети Kubernetes.
Команда dashboard
создаёт временный прокси, чтобы панель была доступна извне внутренней виртуальной сети Kubernetes.
Чтобы остановить работу прокси, выполните Ctrl+C
для завершения процесса.
Когда команда завершит работу, панель останется запущенной внутри кластера Kubernetes.
Вы можете снова выполнить команду dashboard
, чтобы создать новую прокси для доступа к панели.
Если вы не хотите, чтобы minikube запускал веб-браузер, выполните команду dashboard
с флагом
--url
. В этом случае minikube
выведет URL, который вы можете открыть в любом браузере.
Откройте новый терминал и запустите:
# Запустите в новом терминале и не закрывайте его.
minikube dashboard --url
Теперь можно вернуться к терминалу, где вы запускали minikube start
.
Создание деплоймента
Под Kubernetes — это группа из одного или более контейнеров, связанных друг с другом для удобного администрирования и организации сети. В данном руководстве под включает в себя один контейнер. Деплоймент (Deployment) в Kubernetes проверяет здоровье пода и перезагружает контейнер пода в случае, если он прекратил работу. Деплойменты — рекомендуемый способ создания и масштабирования подов.
Используйте команду kubectl create
для создания деплоймента, который будет управлять подом. Под запустит контейнер с указанным Docker-образом.
# Запуск тестового образа контейнера с веб-сервером
kubectl create deployment hello-node --image=registry.k8s.io/e2e-test-images/agnhost:2.39 -- /agnhost netexec --http-port=8080
Посмотреть информацию о Deployment:
Вывод будет примерно следующим:
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
hello-node 1 1 1 1 1m
Посмотреть информацию о поде:
Вывод будет примерно следующим:
NAME READY STATUS RESTARTS AGE
hello-node-5f76cf6ccf-br9b5 1/1 Running 0 1m
Посмотреть события кластера:
Посмотреть конфигурацию kubectl
:
Примечание:
Больше информации о командах
kubectl
см. в
обзоре kubectl.
Создание сервиса
По умолчанию под доступен только при обращении по его внутреннему IP-адресу внутри кластера Kubernetes. Чтобы сделать контейнер hello-node
доступным вне виртуальной сети Kubernetes, необходимо представить под как сервис Service Kubernetes.
Сделать под доступным для публичного интернета можно с помощью команды kubectl expose
:
kubectl expose deployment hello-node --type=LoadBalancer --port=8080
Флаг --type=LoadBalancer
показывает, что сервис должен быть виден вне кластера.
Код приложения в тестовом образе прослушивает только TCP-порт 8080. Если вы сделали приложение доступным по другому порту командой kubectl expose
, клиенты не смогут подключиться к этому порту.
Посмотреть только что созданный сервис:
Вывод будет примерно следующим:
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
hello-node LoadBalancer 10.108.144.78 <pending> 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
Для облачных провайдеров, поддерживающих балансировщики нагрузки, для доступа к сервису будет предоставлен внешний IP адрес. В Minikube тип LoadBalancer
делает сервис доступным при обращении с помощью команды minikube service
.
Выполните следующую команду:
minikube service hello-node
Откроется окно браузера, в котором запущено ваше приложение и выводится его ответ.
Активация дополнений
В minikube есть набор встроенных дополнений (addons), которые могут быть включены, выключены и открыты в локальном окружении Kubernetes.
Отобразить текущие поддерживаемые дополнения:
Вывод будет примерно следующим:
addon-manager: enabled
dashboard: enabled
default-storageclass: enabled
efk: disabled
freshpod: disabled
gvisor: disabled
heapster: disabled
helm-tiller: disabled
ingress: disabled
ingress-dns: disabled
logviewer: disabled
metrics-server: disabled
nvidia-driver-installer: disabled
nvidia-gpu-device-plugin: disabled
registry: disabled
registry-creds: disabled
storage-provisioner: enabled
storage-provisioner-gluster: disabled
Включить дополнение, например, metrics-server
:
minikube addons enable metrics-server
Вывод:
metrics-server was successfully enabled
Посмотреть Pod и Service, которые вы только что создали:
kubectl get pod,svc -n kube-system
Вывод будет примерно следующим:
NAME READY STATUS RESTARTS AGE
pod/coredns-5644d7b6d9-mh9ll 1/1 Running 0 34m
pod/coredns-5644d7b6d9-pqd2t 1/1 Running 0 34m
pod/metrics-server-67fb648c5 1/1 Running 0 26s
pod/etcd-minikube 1/1 Running 0 34m
pod/influxdb-grafana-b29w8 2/2 Running 0 26s
pod/kube-addon-manager-minikube 1/1 Running 0 34m
pod/kube-apiserver-minikube 1/1 Running 0 34m
pod/kube-controller-manager-minikube 1/1 Running 0 34m
pod/kube-proxy-rnlps 1/1 Running 0 34m
pod/kube-scheduler-minikube 1/1 Running 0 34m
pod/storage-provisioner 1/1 Running 0 34m
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
service/metrics-server ClusterIP 10.96.241.45 <none> 80/TCP 26s
service/kube-dns ClusterIP 10.96.0.10 <none> 53/UDP,53/TCP 34m
service/monitoring-grafana NodePort 10.99.24.54 <none> 80:30002/TCP 26s
service/monitoring-influxdb ClusterIP 10.111.169.94 <none> 8083/TCP,8086/TCP 26s
Отключить metrics-server
:
minikube addons disable metrics-server
Вывод будет примерно следующим:
metrics-server was successfully disabled
Очистка
Теперь вы можете освободить ресурсы, созданные в кластере:
kubectl delete service hello-node
kubectl delete deployment hello-node
Остановите кластер minikube:
Удалите виртуальную машину minikube (опционально):
Если вы планируете использовать minikube в дальнейшем, чтобы больше узнать про Kubernetes, удалять инструмент не нужно.
Что дальше
- Руководство по деплою первого приложения в Kubernetes с kubectl.
- Больше об объектах Deployment.
- Больше о развёртывании приложения.
- Больше об объектах Service.
2.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 на своём компьютере.
А после этого переходите к Использованию kubectl для развёртывания приложения.
2.2.1 - Использование kubectl для развёртывания приложения
Узнайте про деплойменты приложения.
Разверните первое приложение в Kubernetes с помощью kubectl.
Цели
- Узнать про деплойменты приложения
- Развернуть первое приложение в Kubernetes с помощью kubectl
Deployments в Kubernetes
Как только вы запустили кластер Kubernetes, вы можете развернуть на нём свои контейнеризированные приложения. Для этого вам нужно создать деплоймент (Deployment). Deployment в Kubernetes определяет, как создавать и обновлять экземпляры вашего приложения. После создания деплоймента control plane в Kubernetes запланирует запуск экземпляров приложения на отдельных узлах в кластере.
После того, как экземпляры приложения были созданы, контроллер деплойментов Kubernetes будет непрерывно отслеживать их. Если узел, на котором размещен экземпляр, вышёл из строя или был удалён, контроллер деплойментов заменит этот экземпляр экземпляром на другом узле в кластере. Этот процесс представляет собой механизм самовосстановления, обеспечивающий работу кластера в случае возникновения аппаратных неисправностей либо технических работ.
До того, как появились системы оркестровки, для запуска приложений обычно использовались установочные скрипты, которые не перезапускались после сбоя компьютера. Создавая экземпляры приложений и поддерживая их работу на нескольких узлах, деплойменты Kubernetes используют принципиально другой подход к управлению приложениями.
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
Примечание: если порт 8001 недоступен, убедитесь, что выполенная вами ранее команда kubectl proxy
была запущена во втором терминале.
Сервер 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:8080/proxy/
Чтобы новый деплоймент был доступен без использования прокси, потребуется сервис (объект Service), о котором будет рассказано в следующих разделах.
2.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:8080/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
.
2.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). Чтобы остановить приложение, потребуется также удалить и его деплоймент.
2.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 подов была остановлена.
2.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=docker.io/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