Введение
В этом практическом занятии (lab) вы научитесь развертывать приложения Kubernetes различными методами, включая создание внутренних и внешних служб (services), работу с метками (labels) и изучение основ Ingress. Вы начнете с настройки локального кластера Kubernetes с использованием Minikube, затем развернете пример приложения NGINX и сделаете его доступным как внутри кластера, так и снаружи. Вы также изучите использование меток для организации и выбора ресурсов, и, наконец, познакомитесь с Ingress и рассмотрите простой пример YAML-файла для Ingress.
Запуск кластера 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
Эти команды подтверждают, что:
- Minikube успешно запущен.
- Локальный кластер Kubernetes создан.
- Кластер готов к использованию.
- У вас есть однокомпонентный (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 управляет контейнеризованными приложениями.
Создание сервиса с помощью 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
Для более наглядного демонстрации удаления нескольких служб, давайте воссоздадим наши службы и затем удалим их вместе:
## 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 состоит из двух компонентов:
- Ресурс Ingress: объект API Kubernetes, который определяет правила маршрутизации
- Контроллер 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.


