Публикация приложений Kubernetes

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

💡 Этот учебник переведен с английского с помощью ИИ. Чтобы просмотреть оригинал, вы можете перейти на английский оригинал

Введение

В этом практическом занятии (lab) вы научитесь развертывать приложения Kubernetes различными методами, включая создание внутренних и внешних служб (services), работу с метками (labels) и изучение основ Ingress. Вы начнете с настройки локального кластера Kubernetes с использованием Minikube, затем развернете пример приложения NGINX и сделаете его доступным как внутри кластера, так и снаружи. Вы также изучите использование меток для организации и выбора ресурсов, и, наконец, познакомитесь с Ingress и рассмотрите простой пример YAML-файла для Ingress.


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL kubernetes(("Kubernetes")) -.-> kubernetes/BasicsGroup(["Basics"]) kubernetes(("Kubernetes")) -.-> kubernetes/BasicCommandsGroup(["Basic Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/AdvancedCommandsGroup(["Advanced Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/TroubleshootingandDebuggingCommandsGroup(["Troubleshooting and Debugging Commands"]) kubernetes(("Kubernetes")) -.-> kubernetes/ConfigurationandVersioningGroup(["Configuration and Versioning"]) kubernetes/BasicsGroup -.-> kubernetes/initialization("Initialization") kubernetes/BasicCommandsGroup -.-> kubernetes/get("Get") kubernetes/BasicCommandsGroup -.-> kubernetes/create("Create") kubernetes/BasicCommandsGroup -.-> kubernetes/delete("Delete") kubernetes/AdvancedCommandsGroup -.-> kubernetes/apply("Apply") kubernetes/TroubleshootingandDebuggingCommandsGroup -.-> kubernetes/describe("Describe") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/label("Label") kubernetes/ConfigurationandVersioningGroup -.-> kubernetes/version("Version") subgraph Lab Skills kubernetes/initialization -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/get -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/create -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/delete -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/apply -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/describe -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/label -.-> lab-434647{{"Публикация приложений Kubernetes"}} kubernetes/version -.-> lab-434647{{"Публикация приложений Kubernetes"}} end

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

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

Сначала запустите кластер Minikube:

minikube start

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

😄  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 status
kubectl get nodes

Пример вывода для команды minikube status:

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

Пример вывода для команды kubectl get nodes:

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

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

  1. Minikube успешно запущен.
  2. Локальный кластер Kubernetes создан.
  3. Кластер готов к использованию.
  4. У вас есть однокомпонентный (single-node) кластер с возможностями управляющего узла (control plane).

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

На этом этапе вы узнаете, как создать и развернуть приложение Kubernetes с использованием манифеста YAML. Мы создадим простое развертывание (deployment) веб-сервера NGINX, чтобы продемонстрировать процесс определения и применения ресурсов Kubernetes.

Сначала создайте каталог для манифестов Kubernetes:

mkdir -p ~/project/k8s-manifests
cd ~/project/k8s-manifests

Создайте файл YAML для развертывания NGINX:

nano 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

Сохраните файл (Ctrl+X, затем Y, затем Enter).

Примените развертывание к кластеру Kubernetes:

kubectl apply -f nginx-deployment.yaml

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

deployment.apps/nginx-deployment created

Проверьте развертывание и поды (pods):

kubectl get deployments
kubectl get pods

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

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

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

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

Подождите, пока поды перейдут в состояние "Running", прежде чем продолжать.

Разберем манифест YAML:

  • apiVersion: Указывает версию API Kubernetes.
  • kind: Определяет тип ресурса (Deployment).
  • metadata: Предоставляет имя и метки (labels) для развертывания.
  • spec.replicas: Устанавливает количество реплик подов.
  • selector: Помогает развертыванию управлять правильными подами.
  • template: Определяет спецификацию пода.
  • containers: Указывает образ контейнера и порт.

Это развертывание создает три идентичных пода с NGINX, демонстрируя, как Kubernetes управляет контейнеризованными приложениями.

Создание сервиса (Service) с помощью YAML для доступа к приложению внутри или снаружи кластера

На этом этапе вы узнаете, как создавать сервисы (Services) Kubernetes для доступа к развертыванию (deployment) NGINX как внутри кластера, так и снаружи него. Мы продемонстрируем два распространенных типа сервисов: ClusterIP и NodePort.

Сначала перейдите в каталог проекта:

cd ~/project/k8s-manifests

Создайте файл YAML для сервиса типа ClusterIP:

nano nginx-clusterip-service.yaml

Добавьте следующий манифест сервиса:

apiVersion: v1
kind: Service
metadata:
  name: nginx-clusterip-service
spec:
  selector:
    app: nginx
  type: ClusterIP
  ports:
    - port: 80
      targetPort: 80

Теперь создайте файл YAML для сервиса типа NodePort:

nano nginx-nodeport-service.yaml

Добавьте следующий манифест сервиса:

apiVersion: v1
kind: Service
metadata:
  name: nginx-nodeport-service
spec:
  selector:
    app: nginx
  type: NodePort
  ports:
    - port: 80
      targetPort: 80
      nodePort: 30080

Примените обе конфигурации сервисов:

kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml

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

service/nginx-clusterip-service created
service/nginx-nodeport-service created

Проверьте сервисы:

kubectl get services

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

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        30m
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         1m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   1m

Для доступа к сервису типа NodePort получите IP-адрес Minikube:

minikube ip

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

192.168.49.2

Основные различия между типами сервисов:

  • ClusterIP: Доступ только внутри кластера.
  • NodePort: Предоставляет доступ к сервису на статическом порту по IP-адресу каждого узла (node).
  • Диапазон портов NodePort: 30000 - 32767.

Проверка конфигурации сервиса

На этом этапе вы узнаете, как использовать команду kubectl describe service для изучения подробной конфигурации сервисов Kubernetes и понимания их сетевых свойств.

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

cd ~/project/k8s-manifests

Подробно опишите сервис типа ClusterIP:

kubectl describe service nginx-clusterip-service

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

Name:              nginx-clusterip-service
Namespace:         default
Labels:            <none>
Annotations:       <none>
Selector:          app=nginx
Type:              ClusterIP
IP Family Policy:  SingleStack
IP Families:       IPv4
IP:                10.104.xxx.xxx
IPs:               10.104.xxx.xxx
Port:              <unset>  80/TCP
TargetPort:        80/TCP
Endpoints:         10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:  None
Events:            <none>

Теперь опишите сервис типа NodePort:

kubectl describe service nginx-nodeport-service

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

Name:                     nginx-nodeport-service
Namespace:                default
Labels:                   <none>
Annotations:              <none>
Selector:                 app=nginx
Type:                     NodePort
IP Family Policy:         SingleStack
IP Families:              IPv4
IP:                       10.108.yyy.yyy
IPs:                      10.108.yyy.yyy
Port:                     <unset>  80/TCP
TargetPort:               80/TCP
NodePort:                 <unset>  30080/TCP
Endpoints:                10.244.0.7:80,10.244.0.8:80,10.244.0.9:80
Session Affinity:         None
External Traffic Policy:  Cluster
Events:                   <none>

Проверьте конечные точки (endpoints) сервиса, чтобы убедиться в сетевой доступности:

kubectl get endpoints

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

NAME                        ENDPOINTS                               AGE
kubernetes                  192.168.49.2:8443                       45m
nginx-clusterip-service     10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m
nginx-nodeport-service      10.244.0.7:80,10.244.0.8:80,10.244.0.9:80   15m

Основная информация, которую нужно понять из описания сервиса:

  • Selector: Показывает, какие поды (pods) входят в состав сервиса.
  • IP: Внутренний IP-адрес сервиса в кластере.
  • Endpoints: Список IP-адресов и портов подов, которые обслуживают сервис.
  • Port и TargetPort: Определяют, как маршрутизируется трафик.
  • NodePort: Внешний порт для сервиса типа NodePort.

Использование меток (Labels) для организации и выбора ресурсов

На этом этапе вы узнаете, как использовать метки (labels) в Kubernetes для эффективной организации и выбора ресурсов. Метки - это пары ключ-значение, которые помогают управлять и организовать объекты Kubernetes.

Сначала проверьте текущие метки на ваших подах (pods):

kubectl get pods --show-labels

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

NAME                                READY   STATUS    RESTARTS   AGE   LABELS
nginx-deployment-xxx-yyy            1/1     Running   0          30m   app=nginx,pod-template-hash=xxx
nginx-deployment-xxx-zzz            1/1     Running   0          30m   app=nginx,pod-template-hash=yyy
nginx-deployment-xxx-www            1/1     Running   0          30m   app=nginx,pod-template-hash=zzz

Выберите поды с использованием определенных меток:

kubectl get pods -l app=nginx

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

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m
nginx-deployment-xxx-zzz            1/1     Running   0          30m
nginx-deployment-xxx-www            1/1     Running   0          30m

Давайте добавим пользовательскую метку к одному из подов:

kubectl label pods nginx-deployment-xxx-yyy environment=development

Замените nginx-deployment-xxx-yyy именем одного из ваших подов.

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

pod/nginx-deployment-xxx-yyy labeled

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

kubectl get pods -l app=nginx,environment=development

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

NAME                                READY   STATUS    RESTARTS   AGE
nginx-deployment-xxx-yyy            1/1     Running   0          30m

Удалите метку с пода:

kubectl label pods nginx-deployment-xxx-yyy environment-

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

pod/nginx-deployment-xxx-yyy unlabeled

Покажем использование выбора меток в сервисах:

kubectl describe service nginx-clusterip-service

Найдите раздел "Selector", который показывает, как сервисы используют метки для идентификации подов.

Основные моменты о метках:

  • Метки - это пары ключ-значение, прикрепленные к объектам Kubernetes.
  • Используются для организации, выбора и фильтрации ресурсов.
  • Можно добавлять, изменять или удалять динамически.
  • Сервисы и развертывания (deployments) используют метки для управления связанными подами.

Удаление и управление службами

На этом этапе вы узнаете, как удалять и управлять службами Kubernetes с помощью команд kubectl. Понимание управления службами является важным аспектом для поддержки и очистки ресурсов Kubernetes.

Сначала выведите список текущих служб:

kubectl get services

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

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-clusterip-service     ClusterIP   10.104.xxx.xxx   <none>        80/TCP         45m
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

Удалите определенную службу с помощью команды kubectl delete:

kubectl delete service nginx-clusterip-service

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

service "nginx-clusterip-service" deleted

Проверьте удаление службы:

kubectl get services

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

NAME                        TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)        AGE
kubernetes                  ClusterIP   10.96.0.1        <none>        443/TCP        1h
nginx-nodeport-service      NodePort    10.108.yyy.yyy   <none>        80:30080/TCP   45m

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

kubectl delete service nginx-nodeport-service,nginx-clusterip-service

Для более наглядного демонстрации удаления нескольких служб, давайте воссоздадим наши службы и затем удалим их вместе:

## Recreate services
kubectl apply -f nginx-clusterip-service.yaml
kubectl apply -f nginx-nodeport-service.yaml
## Delete multiple services at once
kubectl delete service nginx-clusterip-service nginx-nodeport-service

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

service "nginx-clusterip-service" deleted
service "nginx-nodeport-service" deleted

Проверьте, что все службы удалены (за исключением стандартной службы kubernetes):

kubectl get services

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

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

Основные моменты о удалении служб:

  • Удаление службы удаляет сетевой конечный точку
  • Поды не удаляются при удалении службы
  • Стандартная служба kubernetes не может быть удалена
  • Вы можете удалять службы по имени, с использованием YAML-файла или меток
  • Несколько служб можно удалить одновременно, перечислив их или используя селекторы меток

Введение в основы Ingress и демонстрация простого примера YAML-файла Ingress

На этом этапе вы узнаете о Kubernetes Ingress, мощном способе управления внешним доступом к службам в кластере Kubernetes.

Что такое Ingress?

Ingress - это объект API, который управляет внешним доступом к службам в кластере Kubernetes, обычно по протоколу HTTP. Ingress предоставляет следующие возможности:

  • Балансировка нагрузки: распределяет трафик между несколькими бэкенд-службами
  • Завершение SSL/TLS: обрабатывает безопасные соединения
  • Виртуальное хостинг на основе имени: маршрутизирует запросы к разным службам в зависимости от имени хоста
  • Маршрутизация на основе пути: маршрутизирует запросы к разным службам в зависимости от пути URL

Ingress состоит из двух компонентов:

  1. Ресурс Ingress: объект API Kubernetes, который определяет правила маршрутизации
  2. Контроллер Ingress: реализация, которая применяет правила, определенные в ресурсе Ingress

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

Включим надстройку Ingress в Minikube:

minikube addons enable ingress

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

💡  ingress is an addon maintained by Kubernetes. For any concerns contact minikube on GitHub.
🔉  ingress was successfully enabled

Создадим развертывание для двух примеров приложений:

kubectl create deployment web1 --image=nginx:alpine
kubectl create deployment web2 --image=httpd:alpine

Опубликуем эти развертывания как службы:

kubectl expose deployment web1 --port=80 --type=ClusterIP --name=web1-service
kubectl expose deployment web2 --port=80 --type=ClusterIP --name=web2-service

Создадим YAML-файл Ingress:

nano ingress-example.yaml

Добавим следующую конфигурацию Ingress:

apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
    - http:
        paths:
          - path: /web1
            pathType: Prefix
            backend:
              service:
                name: web1-service
                port:
                  number: 80
          - path: /web2
            pathType: Prefix
            backend:
              service:
                name: web2-service
                port:
                  number: 80

Основные компоненты этой конфигурации Ingress:

  • metadata.annotations: специфические настройки для контроллера Ingress
  • spec.rules: определяют, как трафик маршрутизируется к службам
  • path: путь URL, который будет сопоставлен
  • pathType: способ сопоставления пути (Prefix, Exact или ImplementationSpecific)
  • backend.service: служба и порт, на которые будет маршрутизирован трафик

Применим конфигурацию Ingress:

kubectl apply -f ingress-example.yaml

Проверим ресурс Ingress:

kubectl get ingress

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

NAME              CLASS   HOSTS   ADDRESS        PORTS   AGE
example-ingress   nginx   *       192.168.49.2   80      1m

Проверим детали Ingress:

kubectl describe ingress example-ingress

Пример вывода покажет правила маршрутизации и бэкенд-службы.

Тестирование Ingress:

## Получить IP-адрес Minikube
minikube ip

## Протестировать доступ к службам через Ingress
curl $(minikube ip)/web1
curl $(minikube ip)/web2

Каждая команда должна вернуть страницу по умолчанию соответствующего веб-сервера.

В производственных средах Ingress можно настроить с использованием:

  • Нескольких правил на основе имени хоста
  • TLS-сертификатов для HTTPS
  • Механизмов аутентификации
  • Ограничения скорости
  • Пользовательских настроек тайм-аута
  • Аффинности сессии
  • И многих других расширенных функций

Для более полного изучения Ingress обратитесь к документации Kubernetes и рассмотрите возможность изучения документации по специальным контроллерам Ingress, таким как NGINX Ingress или Traefik.

Итоги

В этом практическом занятии вы узнали, как запустить и проверить локальный кластер Kubernetes с использованием Minikube, что является важным аспектом для разработки и тестирования приложений Kubernetes на вашем локальном компьютере. Затем вы создали и развернули простое развертывание (deployment) веб-сервера NGINX с использованием манифеста YAML, продемонстрировав процесс определения и применения ресурсов Kubernetes. Кроме того, вы научились создавать сервис Kubernetes для публикации вашего приложения внутри или снаружи кластера, а также использовать метки (labels) для организации и выбора ресурсов. Наконец, вы изучили основы Kubernetes Ingress и рассмотрели простой пример YAML для Ingress.