Развертывание приложений на Kubernetes

KubernetesBeginner
Практиковаться сейчас

Введение

В этой лабораторной работе вы научитесь развертывать приложения в кластере Kubernetes. Мы начнем с настройки среды Kubernetes с использованием Minikube. Затем вы изучите основные команды kubectl для взаимодействия с вашим кластером и управления ресурсами Kubernetes. Далее вы создадите простой YAML-файл манифеста, примените его к вашему кластеру и проверите статус развертывания. Наконец, вы узнаете, как получить доступ к вашему развернутому приложению с помощью kubectl proxy.

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

Запуск кластера Kubernetes

На этом шаге мы запустим кластер Kubernetes с помощью Minikube. Minikube — отличный инструмент для разработки и изучения Kubernetes, поскольку он позволяет запускать одноузловой кластер Kubernetes в виртуализированной среде. Затем мы проверим, что кластер работает корректно и готов к использованию.

Сначала откройте терминал. Здесь вы будете вводить команды для взаимодействия с вашим компьютером. Чтобы запустить кластер Minikube, введите следующую команду и нажмите Enter:

minikube start

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

😄  minikube v1.29.0 on Ubuntu 22.04
✨  Automatically selected the docker driver
📌  Using Docker driver with root permissions
🔥  Creating kubernetes in kubernetes cluster
🔄  Restarting existing kubernetes cluster
🐳  Preparing Kubernetes v1.26.1 on Docker 20.10.23 ...
🚀  Launching Kubernetes ...
🌟  Enabling addons: storage-provisioner, default-storageclass
🏄  Done! kubectl is now configured to use "minikube" cluster and "default" namespace

После запуска Minikube давайте проверим, что он работает и кластер Kubernetes готов. Выполните следующие команды одну за другой, нажимая Enter после каждой команды:

minikube status
kubectl get nodes

Команда minikube status сообщит вам статус самого Minikube. Команда kubectl get nodes будет взаимодействовать с вашим кластером Kubernetes и получать информацию об узлах (компьютерах) в вашем кластере. Поскольку Minikube является одноузловым кластером, вы должны увидеть один узел в списке.

Вот пример вывода, который вы можете увидеть:

minikube
type: Control Plane
host: Running
kubelet: Running
apiserver: Running
kubeconfig: Configured

NAME       STATUS   ROLES           AGE   VERSION
minikube   Ready    control-plane   1m    v1.26.1

Разберем, что нам говорит этот вывод:

  1. Статус minikube показывает Running для host, kubelet и apiserver. Это указывает на то, что основные компоненты Minikube работают корректно.
  2. kubectl get nodes показывает узел с именем minikube и статусом Ready. Ready означает, что этот узел готов к запуску приложений. control-plane в разделе ROLES указывает на то, что этот узел действует как плоскость управления (control plane) для кластера Kubernetes, управляя и оркестрируя кластер.

Эти команды подтверждают, что:

  1. Minikube работает в виртуальной машине.
  2. Кластер Kubernetes был создан и настроен Minikube.
  3. Кластер Kubernetes находится в состоянии Ready и готов к использованию.
  4. У вас есть одноузловой кластер Kubernetes, где узел minikube выступает в роли плоскости управления.

Изучение основных команд и синтаксиса kubectl

На этом шаге мы изучим основные команды kubectl. kubectl — это инструмент командной строки, который позволяет взаимодействовать с вашим кластером Kubernetes. Он необходим для управления ресурсами Kubernetes. Мы продемонстрируем, как использовать kubectl для просмотра ресурсов и понимания базового управления объектами Kubernetes.

Начнем с изучения пространств имен (namespaces) в вашем кластере Kubernetes. Пространства имен — это способ организации ваших ресурсов Kubernetes. По умолчанию кластеры Kubernetes имеют несколько пространств имен для системных компонентов и пользовательских ресурсов. Чтобы увидеть список пространств имен, выполните следующую команду:

kubectl get namespaces

Эта команда выведет список всех доступных в вашем кластере пространств имен. Пример вывода:

NAME              STATUS   AGE
default           Active   10m
kube-node-lease   Active   10m
kube-public       Active   10m
kube-system       Active   10m

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

  • default: Пространство имен по умолчанию для создаваемых пользователем ресурсов, если не указано другое пространство имен.
  • kube-node-lease: Используется для аренды узлов (node leases), которые помогают плоскости управления отслеживать работоспособность узлов.
  • kube-public: Предназначено для ресурсов, которые должны быть общедоступными (хотя это редко используется для конфиденциальной информации).
  • kube-system: Содержит системные ресурсы, такие как основные компоненты Kubernetes.

Далее, давайте посмотрим на системные компоненты, работающие в пространстве имен kube-system. Многие основные компоненты Kubernetes работают как поды (pods) в этом пространстве имен. Чтобы просмотреть поды в определенном пространстве имен, используйте флаг -n или --namespace, за которым следует имя пространства имен. Выполните следующую команду, чтобы увидеть поды в пространстве имен kube-system:

kubectl get pods -n kube-system

Эта команда выведет список всех подов, работающих в пространстве имен kube-system. Пример вывода:

NAME                               READY   STATUS    RESTARTS   AGE
coredns-787d4945fb-j8rhx           1/1     Running   0          15m
etcd-minikube                       1/1     Running   0          15m
kube-apiserver-minikube             1/1     Running   0          15m
kube-controller-manager-minikube    1/1     Running   0          15m
kube-proxy-xb9rz                    1/1     Running   0          15m
kube-scheduler-minikube             1/1     Running   0          15m
storage-provisioner                 1/1     Running   0          15m

Этот вывод показывает имена подов, их статус READY (сколько контейнеров в поде готовы из общего числа), их STATUS (например, Running), сколько раз они были RESTARTED и их AGE. Это основные компоненты, которые обеспечивают работу Kubernetes.

Теперь давайте рассмотрим некоторые основные шаблоны команд kubectl. Общий синтаксис команд kubectl следующий:

kubectl [command] [TYPE] [NAME] [flags]

Разберем это:

  • kubectl: Сам инструмент командной строки.
  • [command]: Указывает, какое действие вы хотите выполнить. Распространенные команды включают:
    • get: Отобразить один или несколько ресурсов.
    • describe: Показать подробности о конкретном ресурсе.
    • create: Создать новый ресурс.
    • delete: Удалить ресурсы.
    • apply: Применить конфигурацию к ресурсу. Мы будем использовать это часто позже.
  • [TYPE]: Указывает тип ресурса Kubernetes, с которым вы хотите взаимодействовать. Распространенные типы ресурсов включают:
    • pods: Наименьшие развертываемые единицы в Kubernetes.
    • deployments: Управление наборами подов для масштабирования и обновлений.
    • services: Экспонирование приложений, работающих в подах.
    • nodes: Рабочие машины в вашем кластере Kubernetes.
    • namespaces: Логические группировки ресурсов.
  • [NAME]: Имя конкретного ресурса. Это необязательно; если вы опустите имя, kubectl будет работать со всеми ресурсами указанного типа.
  • [flags]: Необязательные флаги для изменения поведения команды (например, -n <namespace>, -o wide).

Рассмотрим несколько примеров:

## Получить все ресурсы в пространстве имен по умолчанию
kubectl get all

## Описать конкретный тип ресурса (узел 'minikube')
kubectl describe nodes minikube

Команда kubectl get all получит информацию обо всех типах ресурсов (сервисы, развертывания, поды и т. д.) в пространстве имен default. Пример вывода может выглядеть так:

NAME                 TYPE        CLUSTER-IP   EXTERNAL-IP   PORT(S)   AGE
service/kubernetes   ClusterIP   10.96.0.1    <none>        443/TCP   20m

Это показывает, что в пространстве имен default у нас есть service с именем kubernetes.

Команда kubectl describe nodes minikube предоставит много подробной информации об узле minikube, включая его статус, емкость, адреса и многое другое. Это полезно для понимания состояния и конфигурации ваших узлов.

Эти команды помогут вам:

  1. Просматривать ресурсы в вашем кластере Kubernetes.
  2. Получать подробную информацию о компонентах кластера и их текущем состоянии.
  3. Понимать базовую структуру команд и синтаксис kubectl.

Создание простого YAML-манифеста

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

Понимание объектов Kubernetes

  • Pod: Самая базовая единица в Kubernetes. Pod — это как контейнер, который может содержать один или несколько контейнеров. Эти контейнеры внутри пода совместно используют одну и ту же сеть и хранилище. Думайте о поде как о представлении одного экземпляра вашего приложения.
  • Deployment: Развертывания используются для управления подами. Они гарантируют, что желаемое количество реплик подов всегда запущено. Если под выходит из строя, развертывание автоматически заменит его. Развертывания также обрабатывают обновления вашего приложения контролируемым образом, например, с помощью поэтапных обновлений (rolling updates).
  • Service: Сервисы предоставляют стабильный способ доступа к вашему приложению, работающему в подах. Поскольку поды могут создаваться и уничтожаться, их IP-адреса могут меняться. Сервис предоставляет фиксированный IP-адрес и DNS-имя, которые всегда указывают на набор управляемых им подов. Это позволяет другим частям вашего приложения или внешним пользователям надежно получать доступ к вашему приложению без необходимости отслеживать IP-адреса отдельных подов.

Вот диаграмма, иллюстрирующая взаимосвязи между этими объектами:

graph TD; A[Deployment] -->|Manages| B[Pods] B -->|Contains| C[Containers] B -->|Communicates via| D[Services] D -->|Exposes| E[External Clients]

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

Обзор YAML-манифеста

YAML-манифест в Kubernetes — это файл, написанный в формате YAML, который описывает объекты Kubernetes, которые вы хотите создать или управлять. YAML — это человекочитаемый язык сериализации данных. Использование YAML для манифестов Kubernetes имеет ряд преимуществ:

  1. Декларативное управление: Вы описываете желаемое состояние ваших ресурсов в YAML-файле (например, «Я хочу, чтобы работало 3 реплики моего приложения»). Kubernetes затем работает над тем, чтобы фактическое состояние соответствовало вашему желаемому состоянию. Это называется декларативным управлением.
  2. Контроль версий: YAML-файлы основаны на тексте и могут быть легко сохранены в системах контроля версий, таких как Git. Это позволяет отслеживать изменения в ваших конфигурациях Kubernetes с течением времени, откатываться к предыдущим конфигурациям и сотрудничать с другими.
  3. Повторное использование и переносимость: Вы можете повторно использовать YAML-манифесты в различных средах (разработка, тестирование, продакшн) с минимальными изменениями. Это делает ваши развертывания более последовательными и воспроизводимыми.

Теперь, когда вы понимаете основы объектов Kubernetes и YAML-манифестов, вы готовы создать свой первый манифест.

Создание YAML-манифеста

Сначала перейдите в каталог вашего проекта. Предполагается, что у вас есть каталог project в вашей домашней директории (~). Если у вас его нет, создайте его сейчас с помощью mkdir project. Затем измените текущий каталог на project с помощью cd project:

cd ~/project

Далее создайте новый каталог для хранения ваших манифестов Kubernetes. Назовем его k8s-manifests. Используйте команду mkdir, чтобы создать каталог, а затем cd, чтобы перейти в него:

mkdir -p k8s-manifests
cd k8s-manifests

Теперь вы создадите свой первый YAML-манифест-файл. Начнем с простого манифеста для пода NGINX. NGINX — популярный веб-сервер. Мы создадим под, который запускает один контейнер NGINX. Используйте текстовый редактор nano для создания файла с именем nginx-pod.yaml:

nano nginx-pod.yaml

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

apiVersion: v1
kind: Pod
metadata:
  name: nginx-pod
  labels:
    app: nginx
spec:
  containers:
    - name: nginx
      image: nginx:latest
      ports:
        - containerPort: 80

Давайте разберем каждую часть этого YAML-манифеста:

  • apiVersion: v1: Указывает версию API Kubernetes, используемую для создания этого объекта. v1 — это основная группа API, и она используется для фундаментальных объектов, таких как поды, сервисы и пространства имен.
  • kind: Pod: Указывает, что вы определяете ресурс Pod.
  • metadata:: Содержит данные о поде, такие как его имя и метки (labels).
    • name: nginx-pod: Устанавливает имя пода как nginx-pod. Так вы будете ссылаться на этот под в Kubernetes.
    • labels:: Метки — это пары ключ-значение, которые прикрепляются к объектам. Они используются для организации и выбора подмножеств объектов. Здесь мы добавляем метку app: nginx к этому поду.
  • spec:: Описывает желаемое состояние пода.
    • containers:: Список контейнеров, которые будут запущены внутри пода. В данном случае у нас только один контейнер.
      • - name: nginx: Устанавливает имя контейнера как nginx.
      • image: nginx:latest: Указывает образ контейнера для использования. nginx:latest ссылается на последнюю версию образа Docker NGINX из Docker Hub.
      • ports:: Список портов, которые будет предоставлять этот контейнер.
        • - containerPort: 80: Указывает, что контейнер будет предоставлять порт 80. Порт 80 — это стандартный порт HTTP.

После вставки содержимого сохраните файл и выйдите из nano. Для этого нажмите Ctrl+X (выйти), затем введите Y (да, сохранить) и, наконец, нажмите Enter, чтобы подтвердить имя файла и сохранить.

Теперь, когда вы создали файл nginx-pod.yaml, вам нужно применить его к вашему кластеру Kubernetes, чтобы создать под. Используйте команду kubectl apply с флагом -f, который указывает файл, содержащий манифест:

kubectl apply -f nginx-pod.yaml

Эта команда отправит манифест в ваш кластер Kubernetes, и Kubernetes создаст под в соответствии с определением. Вы должны увидеть вывод, похожий на этот:

pod/nginx-pod created

Чтобы проверить, что под был создан и работает, используйте команду kubectl get pods. Она выведет список всех подов в пространстве имен по умолчанию. Вы также можете использовать kubectl describe pod nginx-pod для получения подробной информации о nginx-pod. Выполните эти команды:

kubectl get pods
kubectl describe pod nginx-pod

Пример вывода для kubectl get pods:

NAME        READY   STATUS    RESTARTS   AGE
nginx-pod   1/1     Running   0          1m

Этот вывод показывает, что nginx-pod находится в состоянии READY (1 из 1 контейнера готов) и его STATUSRunning. Это означает, что ваш под NGINX был успешно создан и работает.

Теперь давайте создадим манифест для более сложного ресурса: Deployment. Deployment будет управлять набором подов, гарантируя, что запущено желаемое количество реплик. Создайте новый файл с именем nginx-deployment.yaml с помощью nano:

nano nginx-deployment.yaml

Вставьте следующее содержимое в nginx-deployment.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
        - name: nginx
          image: nginx:latest
          ports:
            - containerPort: 80

Выделим ключевые отличия и новые части по сравнению с манифестом nginx-pod.yaml:

  • apiVersion: apps/v1: Для Deployment используется версия API apps/v1, которая является частью группы API apps и обрабатывает ресурсы управления приложениями более высокого уровня.
  • kind: Deployment: Указывает, что вы определяете ресурс Deployment.
  • spec:: Секция spec для Deployment более сложна, поскольку она определяет, как Deployment будет управлять подами.
    • replicas: 3: Это новое. Оно указывает, что вы хотите, чтобы работало 3 реплики (копии) вашего пода. Deployment будет гарантировать, что всегда будет 3 пода, соответствующих критериям, определенным в template.
    • selector:: Селектор используется Deployment для идентификации подов, которыми он должен управлять.
      • matchLabels:: Определяет метки, которые должны быть у подов, чтобы они были выбраны этим Deployment. Здесь он выбирает поды с меткой app: nginx.
    • template:: template определяет спецификацию пода, которую Deployment будет использовать для создания новых подов. По сути, это то же определение пода, что и в нашем примере nginx-pod.yaml, включая metadata.labels и spec.containers. Важно: Метки, определенные здесь в template.metadata.labels, должны соответствовать selector.matchLabels, чтобы Deployment мог управлять этими подами.

Сохраните и выйдите из nano (Ctrl+X, Y, Enter).

Теперь примените этот манифест Deployment к вашему кластеру:

kubectl apply -f nginx-deployment.yaml

Вы должны увидеть вывод, похожий на:

deployment.apps/nginx-deployment created

Проверьте Deployment и созданные им поды. Используйте kubectl get deployments, чтобы проверить статус Deployment, и kubectl get pods, чтобы увидеть поды.

kubectl get deployments
kubectl get pods

Пример вывода:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           1m

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          1m
nginx-deployment-xxx-zzz            1/1     Running   0          1m
nginx-deployment-xxx-www            1/1     Running   0          1m
  • kubectl get deployments показывает, что nginx-deployment имеет READY 3/3, UP-TO-DATE 3 и AVAILABLE 3. Это означает, что Deployment успешно создал и управляет 3 подами, и все они готовы и доступны.
  • kubectl get pods теперь перечисляет три пода с именами, начинающимися с nginx-deployment-. Это поды, созданные и управляемые вашим nginx-deployment.

Применение YAML-манифеста

На этом шаге мы более подробно рассмотрим команду kubectl apply и изучим различные способы применения манифестов Kubernetes. Основываясь на YAML-файлах из предыдущего шага, мы продемонстрируем различные методы применения манифестов.

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

cd ~/project/k8s-manifests

Давайте создадим новый подкаталог для дальнейшей организации наших манифестов. Создайте каталог с именем manifests и перейдите в него:

mkdir -p manifests
cd manifests

Теперь давайте создадим манифест для простого веб-приложения, который включает в себя как Deployment, так и Service в одном файле. Создайте новый файл с именем web-app.yaml с помощью nano:

nano web-app.yaml

Добавьте следующее содержимое в web-app.yaml:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-app
spec:
  replicas: 2
  selector:
    matchLabels:
      app: web
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: web
          image: nginx:alpine
          ports:
            - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  name: web-service
spec:
  selector:
    app: web
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Этот манифест определяет два ресурса Kubernetes в одном файле, разделенных ---. Это распространенный способ группировки связанных ресурсов. Давайте разберем, что нового:

  • Несколько ресурсов в одном файле: Файл web-app.yaml теперь содержит два отдельных определения ресурсов Kubernetes: Deployment и Service. Разделитель --- используется для их различения.
  • kind: Service: Это определяет ресурс Service.
    • spec.selector.app: web: Этот Service будет нацелен на поды, имеющие метку app: web. Это соответствует меткам, которые мы установили для подов, созданных Deployment web-app.
    • spec.type: ClusterIP: Указывает тип сервиса как ClusterIP. Это означает, что сервис будет доступен по внутреннему IP-адресу в кластере и обычно используется для связи между сервисами внутри кластера.
    • spec.ports: Определяет, как сервис сопоставляет порты с целевыми подами.
      • port: 80: Порт самого сервиса, к которому вы будете обращаться.
      • targetPort: 80: Порт целевых подов, на который сервис будет перенаправлять трафик.

Теперь давайте применим этот манифест, используя различные методы.

Метод 1: Применение всего файла

Это самый распространенный способ применения манифеста. Используйте kubectl apply -f, за которым следует имя файла:

kubectl apply -f web-app.yaml

Эта команда создаст как Deployment, так и Service, определенные в web-app.yaml. Вы должны увидеть вывод, похожий на:

deployment.apps/web-app created
service/web-service created

Метод 2: Применение из каталога

Вы можете применить все манифесты в каталоге одновременно. Если у вас есть несколько файлов манифестов в каталоге manifests, вы можете применить их все, указав каталог вместо конкретного файла:

kubectl apply -f .

Символ . представляет текущий каталог. kubectl будет искать YAML-файлы в этом каталоге и применять их все. Это полезно, когда вы организовали свои манифесты в несколько файлов внутри каталога.

Метод 3: Применение из URL (необязательно)

kubectl apply также может применять манифесты непосредственно из URL. Это полезно для быстрого развертывания примеров приложений или конфигураций, размещенных в Интернете. Например, вы можете развернуть мастер-развертывание Redis из репозитория примеров Kubernetes:

kubectl apply -f https://raw.githubusercontent.com/kubernetes/examples/master/guestbook/redis-master-deployment.yaml

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

Давайте рассмотрим некоторые дополнительные параметры для kubectl apply.

Dry Run (Тестовый прогон)

Вы можете использовать флаг --dry-run=client, чтобы имитировать применение манифеста без фактического внесения изменений в кластер. Это полезно для проверки правильности вашего манифеста и для просмотра того, какие ресурсы будут созданы или изменены:

kubectl apply -f web-app.yaml --dry-run=client

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

Подробный вывод

Для более подробного вывода от kubectl apply вы можете использовать флаг -v с уровнем детализации (например, -v=7). Более высокие уровни детализации предоставляют более подробную информацию, которая может быть полезна для отладки:

kubectl apply -f web-app.yaml -v=7

Это выведет гораздо больше информации о выполняемых запросах к API и обработке манифеста.

Проверьте ресурсы, созданные при применении web-app.yaml. Используйте kubectl get deployments и kubectl get services, чтобы перечислить Deployment и Service в вашем кластере:

## Список развертываний
kubectl get deployments

## Список сервисов
kubectl get services

## Описать развертывание, чтобы увидеть больше деталей
kubectl describe deployment web-app

Пример вывода для kubectl get deployments:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           3m33s
redis-master       0/1     1            0           23s
web-app            2/2     2            2           42s

Пример вывода для kubectl get services:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   8m28s
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    46s

Обратите внимание, что теперь у вас есть Deployment web-app с 2/2 READY репликами и web-service типа ClusterIP.

Давайте кратко обсудим разницу между декларативным и императивным управлением в Kubernetes, особенно в контексте kubectl apply и kubectl create.

  • kubectl apply: Использует декларативный подход. Вы определяете желаемое состояние в своих манифест-файлах, а kubectl apply пытается достичь этого состояния. Если вы запустите kubectl apply несколько раз с одним и тем же манифестом, Kubernetes внесет изменения только в том случае, если есть различия между желаемым состоянием в манифесте и текущим состоянием в кластере. kubectl apply обычно рекомендуется для управления ресурсами Kubernetes, поскольку он более надежен и проще в управлении изменениями с течением времени. Он отслеживает конфигурацию ваших ресурсов и позволяет вносить инкрементальные обновления.
  • kubectl create: Использует императивный подход. Вы напрямую инструктируете Kubernetes создать ресурс. Если вы попытаетесь запустить kubectl create для ресурса, который уже существует, это обычно приведет к ошибке. kubectl create менее гибок для управления обновлениями и изменениями по сравнению с kubectl apply.

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

Проверка статуса развертывания

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

Сначала убедитесь, что вы находитесь в каталоге manifests вашего проекта:

cd ~/project/k8s-manifests/manifests

Начнем со списка всех развертываний в текущем пространстве имен (по умолчанию это default, если вы его не меняли). Используйте команду kubectl get deployments:

kubectl get deployments

Эта команда предоставляет краткий обзор ваших развертываний. Пример вывода:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE
nginx-deployment   3/3     3            3           4m44s
redis-master       1/1     1            1           94s
web-app            2/2     2            2           113s

Вот что означает каждая колонка:

  • NAME: Имя развертывания.
  • READY: Показывает количество готовых реплик по сравнению с желаемым количеством реплик (например, 3/3 означает, что 3 желаемые реплики готовы).
  • UP-TO-DATE: Указывает, сколько реплик обновлено до последнего желаемого состояния.
  • AVAILABLE: Показывает, сколько реплик в настоящее время доступны для обслуживания трафика.
  • AGE: Как долго работает развертывание.

Чтобы получить более подробную информацию в расширенном формате, вы можете использовать флаг -o wide с командой kubectl get deployments:

kubectl get deployments -o wide

Пример вывода:

NAME               READY   UP-TO-DATE   AVAILABLE   AGE     CONTAINERS   IMAGES                      SELECTOR
nginx-deployment   3/3     3            3           4m58s   nginx        nginx:latest                app=nginx
redis-master       1/1     1            1           108s    master       registry.k8s.io/redis:e2e   app=redis,role=master,tier=backend
web-app            2/2     2            2           2m7s    web          nginx:alpine                app=web

Вывод -o wide включает дополнительные колонки, такие как CONTAINERS, IMAGES и SELECTOR, предоставляя больше контекста о развертывании.

Чтобы просмотреть поды, которые являются частью конкретного развертывания, вы можете использовать метки (labels). Помните, что в нашем манифесте web-app Deployment мы установили метку app: web для подов. Вы можете использовать эту метку для фильтрации подов с помощью kubectl get pods -l <label_selector>. Чтобы увидеть поды, связанные с развертыванием web-app, выполните:

kubectl get pods -l app=web

Пример вывода:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          10m
web-app-xxx-zzz           1/1     Running   0          10m

Это выводит список подов, соответствующих селектору меток app=web, которые являются подами, управляемыми Deployment web-app.

Для получения подробной информации о конкретном развертывании используйте команду kubectl describe deployment <deployment_name>. Давайте опишем развертывание web-app:

kubectl describe deployment web-app

kubectl describe предоставляет множество информации о развертывании, включая:

  • Name, Namespace, CreationTimestamp, Labels, Annotations: Основные метаданные о развертывании.
  • Selector: Селектор меток, используемый для идентификации подов, управляемых этим развертыванием.
  • Replicas: Желаемое, обновленное, общее, доступное и недоступное количество реплик.
  • StrategyType, RollingUpdateStrategy: Детали стратегии обновления (например, RollingUpdate).
  • Pod Template: Спецификация, используемая для создания подов для этого развертывания.
  • Conditions: Условия, указывающие на статус развертывания (например, Available, Progressing).
  • Events: Список событий, связанных с развертыванием, которые могут быть полезны для устранения неполадок.

Обратите внимание на разделы Conditions и Events в выводе describe. Эти разделы часто дают подсказки, если с вашим развертыванием возникли проблемы. Например, если развертывание не становится Available, в Events могут отображаться ошибки, связанные с извлечением образа, сбоями при создании пода и т. д.

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

kubectl get services

Пример вывода:

NAME          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
kubernetes    ClusterIP   10.96.0.1       <none>        443/TCP   10m
web-service   ClusterIP   10.106.220.33   <none>        80/TCP    2m47s

Это показывает web-service вместе с его TYPE (ClusterIP), CLUSTER-IP и открытыми PORT(S).

Для получения более подробной информации о сервисе используйте команду kubectl describe service <service_name>:

kubectl describe service web-service

Вывод describe service включает:

  • Name, Namespace, Labels, Annotations: Основные метаданные.
  • Selector: Селектор меток, используемый для идентификации целевых подов.
  • Type: Тип сервиса (ClusterIP в данном случае).
  • IP, IPs: IP-адрес кластера, назначенный сервису.
  • Port, TargetPort: Сопоставления портов, определенные для сервиса.
  • Endpoints: Показывает IP-адреса и порты подов, которые в настоящее время обслуживают этот сервис. Это очень важно. Если конечных точек нет, это означает, что сервис не подключен к каким-либо подам, вероятно, из-за несоответствия селектора.
  • Session Affinity, Events: Другие конфигурации сервиса и события.

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

  • Статус READY развертывания: Убедитесь, что он показывает желаемое количество реплик (например, 2/2 для web-app).
  • STATUS пода: Все поды должны быть в статусе Running.
  • Endpoints сервиса: Проверьте, что у сервиса есть конечные точки, и что они соответствуют IP-адресам ваших запущенных подов. Если конечных точек нет, устраните неполадки селектора сервиса и меток подов.
  • Проверьте наличие предупреждений или ошибок: Изучите вывод команд kubectl describe deployment <deployment_name> и kubectl describe service <service_name> на предмет любых необычных условий или ошибок в разделах Events.

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

Доступ к приложению с помощью kubectl proxy

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

Сначала убедитесь, что вы находитесь в каталоге проекта:

cd ~/project/k8s-manifests/manifests

Запустите kubectl proxy в фоновом режиме. Эта команда запустит прокси в отдельном процессе, позволяя вам продолжать использовать ваш терминал.

kubectl proxy --port=8080 &

Символ & в конце команды запускает ее в фоновом режиме. Вы должны увидеть вывод, похожий на:

Starting to serve on 127.0.0.1:8080

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

Теперь давайте найдем имена подов, которые являются частью вашего развертывания web-app. Вы можете снова использовать команду kubectl get pods -l app=web:

## Получить имена подов для 'web-app'
kubectl get pods -l app=web

Пример вывода:

NAME                      READY   STATUS    RESTARTS   AGE
web-app-xxx-yyy           1/1     Running   0          20m
web-app-xxx-zzz           1/1     Running   0          20m

Запишите одно из имен подов, например, web-app-xxx-yyy. Вы будете использовать это имя пода для построения пути API для доступа к веб-серверу NGINX, работающему в этом поде.

К ресурсам API Kubernetes можно получить доступ через определенные пути. Чтобы получить доступ к поду через kubectl proxy, вам нужно построить URL следующим образом:

http://localhost:8080/api/v1/namespaces/<namespace>/pods/<pod_name>/proxy/

Разберем этот URL:

  • http://localhost:8080: Адрес, по которому работает kubectl proxy. По умолчанию он прослушивает порт 8080 в вашей текущей среде.
  • /api/v1: Указывает версию API Kubernetes (v1).
  • /namespaces/<namespace>: Пространство имен, в котором работает ваш под. В нашем случае это default.
  • /pods/<pod_name>: Имя пода, к которому вы хотите получить доступ. Замените <pod_name> на фактическое имя вашего пода (например, web-app-xxx-yyy).
  • /proxy/: Указывает, что вы хотите проксировать соединение к поду.

Чтобы упростить использование имени пода в URL, давайте сохраним имя первого пода в переменной оболочки. Выполните эту команду, которая использует kubectl get pods и jsonpath для извлечения имени первого пода с меткой app=web:

## Получить имя первого пода с меткой 'app=web'
POD_NAME=$(kubectl get pods -l app=web -o jsonpath='{.items[0].metadata.name}')
echo $POD_NAME ## Необязательно: вывести имя пода для проверки

Теперь вы можете использовать переменную $POD_NAME в вашей команде curl для доступа к стандартной странице NGINX, обслуживаемой вашим подом. Используйте curl для отправки HTTP-запроса по URL прокси. Замените ${POD_NAME} в URL на переменную, которую мы только что установили:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}/proxy/

Если все работает правильно, эта команда должна вернуть HTML-содержимое стандартной приветственной страницы NGINX. Пример вывода будет HTML-содержимым, начинающимся с:

<!doctype html>
<html>
  <head>
    <title>Welcome to nginx!</title>
    ...
  </head>
  <body>
    <h1>Welcome to nginx!</h1>
    ...
  </body>
</html>

Этот вывод подтверждает, что вы успешно получили доступ к веб-серверу NGINX, работающему внутри вашего пода, через kubectl proxy.

Давайте рассмотрим еще несколько вещей, которые вы можете сделать с kubectl proxy.

Список всех подов в пространстве имен по умолчанию через прокси:

Вы можете получить прямой доступ к API Kubernetes через прокси. Например, чтобы получить список всех подов в пространстве имен default, вы можете использовать следующий URL:

curl http://localhost:8080/api/v1/namespaces/default/pods/

Это вернет JSON-ответ, содержащий информацию обо всех подах в пространстве имен default.

Получение подробной информации о конкретном поде через прокси:

Чтобы получить подробную информацию о конкретном поде (аналогично kubectl describe pod), вы можете напрямую получить доступ к конечной точке API пода:

curl http://localhost:8080/api/v1/namespaces/default/pods/${POD_NAME}

Это вернет JSON-ответ с подробной информацией об указанном поде.

Остановка kubectl proxy:

Когда вы закончите использовать kubectl proxy, вам следует его остановить. Поскольку мы запустили его в фоновом режиме, вам нужно найти его идентификатор процесса (PID) и завершить его. Вы можете использовать команду jobs для вывода списка фоновых процессов:

jobs

Это покажет вам фоновые процессы, запущенные из вашей текущей сессии терминала. Вы должны увидеть kubectl proxy в списке. Чтобы остановить его, вы можете использовать команду kill, за которой следует идентификатор процесса. Например, если jobs показывает [1] Running kubectl proxy --port=8080 &, то идентификатор процесса — 1. Вы бы использовали:

kill %1

Замените %1 на идентификатор задания, показанный командой jobs. В качестве альтернативы вы можете найти идентификатор процесса с помощью ps aux | grep kubectl proxy, а затем использовать kill <PID>.

Ключевые моменты, которые следует помнить о kubectl proxy:

  • kubectl proxy создает безопасное, аутентифицированное соединение с сервером API Kubernetes.
  • Он позволяет вам получать доступ к ресурсам кластера (подам, сервисам и т. д.) из вашей текущей среды, как если бы вы находились внутри сети кластера.
  • Он очень полезен для отладки, разработки и исследования API Kubernetes.
  • Из соображений безопасности kubectl proxy доступен только на localhost (127.0.0.1). Он не предназначен для публичного предоставления сервисов.

Резюме

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

Вы перешли к созданию простых YAML-манифестов для пода (Pod) и развертывания (Deployment), применили их к вашему кластеру с помощью kubectl apply и проверили статус развертывания с помощью различных команд kubectl, таких как get и describe. Этот практический опыт позволил вам понять декларативный подход к развертыванию приложений на Kubernetes и как эффективно взаимодействовать с кластером.

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

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