Kubernetes — это открытая платформа для автоматизации развертывания, масштабирования и управления контейнеризированными приложениями. Он был создан для решения проблем, с которыми сталкиваются разработчики и системные администраторы при переходе от монолитной архитектуры к микросервисам. В традиционной модели развертывания приложений возникали сложности из-за различий в инфраструктуре и конфигурациях между средами разработки, тестирования и промышленной эксплуатации. Kubernetes решает эти проблемы, предоставляя единую платформу, которая абстрагирует сложности базовой инфраструктуры. Это позволяет разработчикам развертывать и управлять приложениями согласованно в различных средах, обеспечивая переносимость и масштабируемость.
История Kubernetes начинается внутри Google. Компания более десяти лет использовала систему под названием Borg для управления своими контейнерами. В 2014 году Google решил открыть часть этих технологий, что привело к созданию проекта Kubernetes. С тех пор проект перешел под управление Cloud Native Computing Foundation (CNCF) и стал одним из самых активных проектов с открытым исходным кодом.
Kubernetes, как и Docker, делает акцент на использовании контейнерных технологий. Но если Docker фокусируется на упаковке и распространении приложений, то Kubernetes выводит контейнеризацию на новый уровень, предоставляя инструменты для автоматизации развертывания, масштабирования и операций с контейнерами.
Шпаргалка по Kubernetes становится незаменимым инструментом, предоставляя быстрый доступ к основным командам для плавного управления развертыванием. Это ваш надежный проводник в быстро меняющейся среде Kubernetes, повышающий продуктивность, минимизирующий ошибки и обеспечивающий эффективную навигацию через сложные задачи.
Основы работы с Kubernetes
Для эффективной работы с Kubernetes необходимо понимать его архитектуру и ключевые компоненты. Давайте разберемся с ними и посмотрим, как они взаимодействуют между собой.
Nginx + Kubernetes Добрый день всем!
Я решил попробовать использовать Kubernetes.
Вот что я сделал на текущий момент:
1) У меня сервер на Ubuntu.
2) Запустил... Kubernetes не работает localhost Добрый день!
Пытался поставить kubernetes-dashboard на новом кластере. Выполнял все пункты по мануалу из документации Kubernetes, curl по... Node.js аппа на Kubernetes Или кто проворачивал такое? Есть какие грабли? Как там с process.env переменными? Запуск docker образа в kubernetes Контейнер в docker запускаю так:
docker run --cap-add=SYS_ADMIN -ti -e "container=docker" -v /sys/fs/cgroup:/sys/fs/cgroup centos7-bitrix-app-mtt...
Ключевые компоненты и архитектура
Kubernetes работает по архитектуре клиент-сервер, состоящей из плоскости управления (control plane) и набора узлов (nodes), на которых запускаются контейнеры. Плоскость управления — это мозг всего кластера. Она отвечает за принятие глобальных решений о кластере и обнаружение и реагирование на события в кластере. Вот основные компоненты плоскости управления:1. API-сервер — точка входа для всех административных задач. Он обрабатывает запросы (через REST API), проверяет их и выполняет необходимые обновления состояния.
2. Планировщик (Scheduler) — распределяет рабочие нагрузки между узлами, учитывая доступность ресурсов и другие ограничения.
3. Менеджер контроллеров (Controller Manager) — отвечает за поддержание корректного состояния системы. Он содержит контроллеры, которые следят за различными аспектами кластера (ноды, реплики, сервисы и т.д.).
4. etcd — распределенное хранилище ключ-значение, в котором хранится конфигурация и состояние всего кластера. Узлы (Nodes) — это рабочие машины (физические или виртуальные), на которых запускаются контейнеризированные приложения. На каждом узле работают несколько компонентов:1. Kubelet — агент, который следит за состоянием подов на узле и обеспечивает их работу.
2. Kube-proxy — сетевой прокси, который поддерживает сетевые правила и позволяет осуществлять сетевое взаимодействие с подами.
3. Container Runtime — программное обеспечение, которое запускает контейнеры (например, Docker, containerd, CRI-O). Поды (Pods) — это минимальная единица развертывания в Kubernetes. Под может содержать один или несколько контейнеров, которые совместно используют одно пространство имен сети и могут взаимодействовать друг с другом по localhost.
Командная строка kubectl: базовые команды
Kubectl — это командная строка для управления кластером Kubernetes. Вот некоторые базовые команды, которые пригодятся для начала работы:
Bash | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Получить информацию о кластере
kubectl cluster-info
# Проверить версию Kubernetes
kubectl version
# Просмотреть конфигурацию кластера
kubectl config view
# Посмотреть все доступные API-ресурсы
kubectl api-resources
# Получить список всех объектов во всех пространствах имен
kubectl get all --all-namespaces |
|
Для работы с подами вам пригодятся следующие команды:
Bash | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| # Создать или обновить под из файла конфигурации
kubectl apply -f <файл_конфигурации_пода>
# Получить список всех подов в пространстве имен по умолчанию
kubectl get pods
# Получить список всех подов во всех пространствах имен
kubectl get pods --all-namespaces
# Получить подробную информацию о конкретном поде
kubectl describe pod <имя_пода>
# Просмотреть логи пода
kubectl logs <имя_пода>
# Открыть интерактивную оболочку внутри контейнера
kubectl exec -it <имя_пода> -- /bin/bash
# Удалить под
kubectl delete pod <имя_пода>
# Проброс портов между локальной машиной и подом
kubectl port-forward <имя_пода> <локальный_порт>:<порт_пода> |
|
При работе с кластером иногда требуется управлять узлами:
Bash | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| # Получить информацию об узлах в кластере
kubectl get nodes
# Подробная информация о конкретном узле
kubectl describe node <имя_узла>
# Добавить метку к узлу
kubectl label nodes <имя_узла> <метка>
# Пометить узел как неготовый к планированию (для обслуживания)
kubectl cordon <имя_узла>
# Разрешить планирование на ранее помеченном неготовым узле
kubectl uncordon <имя_узла>
# Безопасно эвакуировать все поды с узла перед обслуживанием
kubectl drain <имя_узла> |
|
Модель пространств имён (Namespaces) для организации ресурсов
Пространства имен в Kubernetes — это виртуальные кластеры внутри физического кластера. Они помогают организовать ресурсы, особенно в больших средах с множеством пользователей и команд. Основные команды для работы с пространствами имен:
Bash | 1
2
3
4
5
6
7
8
| # Получить список всех пространств имен
kubectl get namespaces
# Создать новое пространство имен
kubectl create namespace <имя_пространства>
# Показать детали о конкретном пространстве имен
kubectl describe namespace <имя_пространства> |
|
Пространства имен полезны для:- Изоляции ресурсов между разными командами или проектами.
- Разделения среды разработки, тестирования и производства.
- Применения квот и ограничений ресурсов на уровне команды или проекта.
- Управления доступом на уровне пространств имен.
По умолчанию Kubernetes имеет несколько системных пространств имен:default — пространство имен по умолчанию для пользовательских ресурсов.
kube-system — пространство имен для системных компонентов Kubernetes.
kube-public — пространство имен для общедоступных ресурсов.
kube-node-lease — пространство имен для отслеживания доступности узлов.
Чтобы указать пространство имен при создании ресурса, можно использовать флаг -n или --namespace :
Bash | 1
| kubectl create -f my-resource.yaml -n my-namespace |
|
Или указать пространство имен в самом файле конфигурации YAML:
YAML | 1
2
3
4
5
6
7
| apiVersion: v1
kind: Pod
metadata:
name: my-pod
namespace: my-namespace
spec:
# ... |
|
Для создания уникальных идентификаторов и группировки связанных ресурсов в Kubernetes используются метки (labels) и селекторы (selectors). Метки — это пары ключ-значение, прикрепленные к объектам, которые позволяют гибко категоризировать и выбирать ресурсы. Они используются для идентификации и группировки связанных ресурсов. Мастер-компонент (Master) — это компоненты плоскости управления в Kubernetes, управляющие общим состоянием кластера. К ним относятся API-сервер, etcd, планировщик и контроллер-менеджер.
Жизненный цикл Pod в Kubernetes
Поды (Pods) являются фундаментальным элементом в архитектуре Kubernetes, и понимание их жизненного цикла критично для эффективной работы с кластером. Жизненный цикл пода состоит из нескольких стадий, которые важно учитывать при проектировании приложений.
Когда вы создаете под, он проходит через следующие основные состояния:1. Pending (Ожидающий) — под принят системой Kubernetes, но один или несколько контейнеров еще не запущены. Это может происходить во время загрузки образа или планирования пода на узел.
2. Running (Работающий) — под привязан к узлу, и все его контейнеры запущены. По крайней мере один контейнер работает или в процессе запуска/перезапуска.
3. Succeeded (Успешно завершенный) — все контейнеры в поде успешно завершили выполнение и не будут перезапущены. Это типично для подов, выполняющих разовые задачи.
4. Failed (Неудачный) — все контейнеры в поде завершились, и хотя бы один завершился с ошибкой. Контейнер считается завершенным с ошибкой, если его процесс завершился с ненулевым статусом выхода.
5. Unknown (Неизвестный) — состояние пода не может быть получено. Часто это происходит из-за проблем связи с узлом, на котором работает под. Важно отметить, что поды сами по себе эфемерны — они не предназначены для самовосстановления при сбоях узла. Именно поэтому редко используются одиночные поды — обычно их создают через контроллеры высшего уровня, такие как Deployments или StatefulSets.
Во время своего жизненного цикла поды могут испытывать различные события:- Проверки готовности (Readiness Probes) определяют, когда контейнер готов принимать трафик. Если проверка не пройдена, под временно исключается из балансировки нагрузки.
- Проверки живости (Liveness Probes) определяют, когда контейнер нуждается в перезапуске. Если проверка не пройдена многократно, контейнер будет перезапущен.
- Политики перезапуска (Restart Policies) определяют поведение при завершении контейнера. Возможны варианты: Always (всегда перезапускать), OnFailure (перезапускать только при ошибке), Never (никогда не перезапускать).
Мое наблюдение: многие разработчики недооценивают важность правильной настройки проверок готовности и живости. Неправильно сконфигурированные проверки могут привести к частым необоснованным перезапускам или, наоборот, к ситуации, когда неработоспособные контейнеры продолжают получать трафик.
При проектировании подов важно учитывать их эфемерный характер. Приложения должны быть спроектированы так, чтобы справляться с внезапными перезапусками и миграцией между узлами. Это часто означает, что состояние приложения должно храниться вне пода, например, в персистентном хранилище или в внешней базе данных. Эффективное управление жизненным циклом пода — это баланс между обеспечением высокой доступности приложения и оптимальным использованием ресурсов кластера. Понимание того, как Kubernetes создает, планирует и управляет подами, является ключевым для создания надежных и масштабируемых приложений.
Практическое руководство
После знакомства с основами Kubernetes пришло время перейти к практике. В этом разделе мы рассмотрим, как развернуть ваше первое приложение, как эффективно управлять модулями и контейнерами, и как работать с конфигурационными файлами.
Развертывание первого приложения
Развертывание приложения в Kubernetes обычно начинается с создания манифеста - YAML-файла, описывающего желаемое состояние вашего приложения. Вот пример простого развертывания веб-приложения:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apiVersion: apps/v1
kind: Deployment
metadata:
name: web-app
spec:
replicas: 3
selector:
matchLabels:
app: web
template:
metadata:
labels:
app: web
spec:
containers:
- name: web-container
image: nginx:latest
ports:
- containerPort: 80 |
|
Этот манифест описывает развертывание с именем web-app , которое создаст три реплики пода, каждая с контейнером на основе образа nginx:latest.
Чтобы применить этот манифест, сохраните его в файл (например, deployment.yaml ) и выполните команду:
Bash | 1
| kubectl apply -f deployment.yaml |
|
После успешного применения манифеста вы можете проверить статус развертывания:
Bash | 1
| kubectl get deployments |
|
Чтобы сделать ваше приложение доступным извне кластера, вам понадобится создать сервис:
YAML | 1
2
3
4
5
6
7
8
9
10
11
| apiVersion: v1
kind: Service
metadata:
name: web-service
spec:
selector:
app: web
ports:
- port: 80
targetPort: 80
type: LoadBalancer |
|
Примените этот манифест командой:
Bash | 1
| kubectl apply -f service.yaml |
|
Теперь ваше приложение должно быть доступно через внешний IP-адрес, который вы можете найти командой:
Я заметил, что новички часто недооценивают важность меток (labels) при создании манифестов. Метки играют критическую роль в связывании различных ресурсов Kubernetes. Например, в примере выше сервис находит поды для маршрутизации трафика с помощью селектора app: web , который соответствует метке, указанной в шаблоне пода.
Управление модулями и контейнерами
После развертывания приложения вам понадобится управлять его жизненным циклом. Вот несколько полезных команд:
Bash | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
| # Получить список всех подов
kubectl get pods
# Подробная информация о поде
kubectl describe pod <имя_пода>
# Просмотр логов контейнера в поде
kubectl logs <имя_пода> [-c <имя_контейнера>]
# Выполнение команды в контейнере
kubectl exec -it <имя_пода> [-c <имя_контейнера>] -- <команда>
# Удаление пода (обычно автоматически пересоздается контроллером)
kubectl delete pod <имя_пода> |
|
Для управления развертываниями используйте:
Bash | 1
2
3
4
5
6
7
8
9
10
11
| # Масштабирование развертывания
kubectl scale deployment <имя_развертывания> --replicas=5
# Обновление образа в развертывании
kubectl set image deployment/<имя_развертывания> <контейнер>=<новый_образ>
# Получение истории развертывания
kubectl rollout history deployment/<имя_развертывания>
# Откат к предыдущей версии
kubectl rollout undo deployment/<имя_развертывания> |
|
Работа с конфигурационными файлами
Конфигурационные файлы (ConfigMaps) и секреты (Secrets) позволяют отделить конфигурацию от кода приложения, что является важной практикой в мире контейнеров. Вот пример создания ConfigMap:
YAML | 1
2
3
4
5
6
7
8
| apiVersion: v1
kind: ConfigMap
metadata:
name: app-config
data:
database.host: "db.example.com"
database.port: "5432"
features.enabled: "true" |
|
Применение:
Bash | 1
| kubectl apply -f configmap.yaml |
|
Теперь вы можете использовать этот ConfigMap в поде:
YAML | 1
2
3
4
5
6
7
8
9
10
11
| apiVersion: v1
kind: Pod
metadata:
name: app-pod
spec:
containers:
- name: app-container
image: my-app:latest
envFrom:
- configMapRef:
name: app-config |
|
Для хранения конфиденциальной информации, такой как пароли или токены API, используйте Secrets:
Bash | 1
2
3
4
5
6
7
8
9
| # Создание секрета из командной строки
kubectl create secret generic db-credentials \
--from-literal=username=admin \
--from-literal=password=super-secret-password
# Или из файлов
kubectl create secret generic tls-certificates \
--from-file=cert.pem \
--from-file=key.pem |
|
Использование секретов в поде аналогично использованию ConfigMap:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
| apiVersion: v1
kind: Pod
metadata:
name: secure-app-pod
spec:
containers:
- name: secure-app-container
image: secure-app:latest
env:
- name: DB_USERNAME
valueFrom:
secretKeyRef:
name: db-credentials
key: username
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password |
|
Стратегии обновления приложений
В Kubernetes существует несколько стратегий обновления приложений:1. RollingUpdate (Плавное обновление) - дефолтная стратегия, при которой Kubernetes постепенно заменяет старые поды новыми, обеспечивая нулевой простой.
2. Recreate (Пересоздание) - все старые поды завершаются, затем создаются новые. Это приводит к простою, но может быть необходимо для приложений, которые не поддерживают одновременное выполнение нескольких версий. Пример настройки стратегии в манифесте развертывания:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
| apiVersion: apps/v1
kind: Deployment
metadata:
name: my-app
spec:
replicas: 3
strategy:
type: RollingUpdate
rollingUpdate:
maxSurge: 1
maxUnavailable: 0
# ... остальная часть манифеста |
|
Параметры maxSurge и maxUnavailable контролируют процесс обновления:maxSurge определяет, сколько подов может быть создано сверх желаемого количества.
maxUnavailable определяет, сколько подов может быть недоступно во время обновления.
На практике я заметил, что установка maxUnavailable: 0 и небольшого значения для maxSurge (например, 1 или 25%) обеспечивает плавное обновление без снижения доступности, хотя и занимает больше времени.
Настройка проверок работоспособности (Liveness и Readiness Probes)
При работе с контейнеризированными приложениями у нас нередко возникает необходимость проверять их здоровье и готовность. Kubernetes предлагает два типа проверок для этого: проверки живости (Liveness Probes) и проверки готовности (Readiness Probes). Проверки живости определяют, когда контейнер нуждается в перезапуске. Если приложение зависло или не отвечает, Kubernetes автоматически перезапустит контейнер, что повысит доступность сервиса. Вот пример настройки проверки живости через HTTP:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: web-container
image: my-web-app:latest
livenessProbe:
httpGet:
path: /health
port: 8080
initialDelaySeconds: 15
periodSeconds: 10
failureThreshold: 3 |
|
Параметр initialDelaySeconds указывает, сколько секунд после запуска контейнера должно пройти, прежде чем начнутся проверки. Это критично для приложений с долгим временем запуска. periodSeconds определяет частоту проверок, а failureThreshold - количество последовательных неудачных проверок до перезапуска контейнера. Проверки готовности, в свою очередь, определяют, готов ли контейнер обрабатывать запросы. Если проверка готовности не проходит, под временно исключается из балансировки нагрузки:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
| apiVersion: v1
kind: Pod
metadata:
name: web-app
spec:
containers:
- name: web-container
image: my-web-app:latest
readinessProbe:
tcpSocket:
port: 8080
initialDelaySeconds: 5
periodSeconds: 10 |
|
В этом примере мы используем TCP-проверку - Kubernetes просто пытается установить TCP-соединение с контейнером через указанный порт. Кроме HTTP и TCP проверок, можно использовать проверку через выполнение команды:
YAML | 1
2
3
4
5
6
7
| readinessProbe:
exec:
command:
- cat
- /tmp/ready
initialDelaySeconds: 5
periodSeconds: 5 |
|
Здесь Kubernetes выполняет команду внутри контейнера. Если команда завершается с кодом 0, проверка считается успешной.
Многие начинающие разработчики путают назначение проверок живости и готовности. Проверка живости определяет, когда контейнер нужно перезапустить, а проверка готовности - когда контейнер готов принимать трафик. Как правило, проверка готовности должна быть более строгой, так как она гарантирует, что пользователи будут взаимодействовать только с полностью функциональными подами. Правильная настройка этих проверок существенно повышает надежность ваших приложений в Kubernetes. Вы можете быть уверены, что неработоспособные контейнеры будут своевременно перезапущены, а пользовательский трафик будет направлен только на работающие экземпляры.
Продвинутые техники
После освоения основ Kubernetes пора погрузиться в более сложные аспекты этой платформы. Продвинутые техники позволят вам повысить надежность, эффективность и безопасность ваших развертываний. Давайте рассмотрим наиболее полезные из них.
Масштабирование и балансировка нагрузки
Одно из главных преимуществ Kubernetes — возможность автоматического масштабирования приложений в зависимости от нагрузки. Существует несколько способов масштабирования в Kubernetes:
Горизонтальное масштабирование подов
Простейший способ масштабирования — изменение количества реплик развертывания:
Bash | 1
| kubectl scale deployment my-deployment --replicas=5 |
|
Однако ручное масштабирование не всегда практично. Для автоматизации этого процесса можно использовать Horizontal Pod Autoscaler (HPA).
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: webapp-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: webapp
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70 |
|
Этот HPA автоматически масштабирует развертывание webapp , поддерживая среднюю загрузку CPU на уровне 70%. Минимальное количество подов — 2, максимальное — 10.
Вертикальное масштабирование
В некоторых случаях вместо добавления большего количества подов эффективнее увеличить ресурсы (CPU и память) существующих подов. Для этого можно использовать Vertical Pod Autoscaler:
YAML | 1
2
3
4
5
6
7
8
9
10
11
| apiVersion: autoscaling.k8s.io/v1
kind: VerticalPodAutoscaler
metadata:
name: webapp-vpa
spec:
targetRef:
apiVersion: "apps/v1"
kind: Deployment
name: webapp
updatePolicy:
updateMode: "Auto" |
|
VPA автоматически анализирует использование ресурсов подами и рекомендует или автоматически применяет новые запросы и лимиты ресурсов.
Балансировка нагрузки
Для маршрутизации трафика к масштабированным подам Kubernetes использует Сервисы. Есть несколько типов сервисов:- ClusterIP: Экспонирует сервис только внутри кластера.
- NodePort: Экспонирует сервис на определенном порту каждого узла кластера.
- LoadBalancer: Создает внешний балансировщик нагрузки и назначает ему фиксированный внешний IP.
- ExternalName: Сопоставляет сервис с DNS-именем.
Для внешнего доступа к приложению чаще всего используется тип LoadBalancer:
YAML | 1
2
3
4
5
6
7
8
9
10
11
| apiVersion: v1
kind: Service
metadata:
name: webapp-service
spec:
selector:
app: webapp
ports:
- port: 80
targetPort: 8080
type: LoadBalancer |
|
Для более сложной маршрутизации можно использовать Ingress-контроллер, который обеспечивает HTTP-маршрутизацию на основе хостов и путей:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: webapp-ingress
spec:
rules:
- host: "webapp.example.com"
http:
paths:
- path: /api
pathType: Prefix
backend:
service:
name: api-service
port:
number: 80
- path: /
pathType: Prefix
backend:
service:
name: frontend-service
port:
number: 80 |
|
Этот Ingress направляет запросы к webapp.example.com/api на сервис api-service , а все остальные запросы — на frontend-service .
Управление секретами и конфигурациями
Эффективное управление конфигурациями и секретами — ключевой аспект разработки и эксплуатации облачных приложений.
Внешние хранилища секретов
Хотя встроенные Secrets в Kubernetes шифруются при хранении в etcd, для усиленной безопасности часто используются внешние хранилища секретов, такие как HashiCorp Vault или AWS Secrets Manager. Интеграция с ними обычно осуществляется через CSI (Container Storage Interface) драйверы или операторы.
Например, для интеграции с HashiCorp Vault можно использовать Vault Operator:
YAML | 1
2
3
4
5
6
7
8
| apiVersion: vault.banzaicloud.com/v1alpha1
kind: Vault
metadata:
name: vault
spec:
size: 1
image: vault:1.6.2
bankVaultsImage: banzaicloud/bank-vaults:latest |
|
Затем можно запросить секреты из Vault:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
| apiVersion: v1
kind: Pod
metadata:
name: webapp
annotations:
vault.security.banzaicloud.io/vault-addr: "https://vault:8200"
vault.security.banzaicloud.io/vault-role: "webapp"
vault.security.banzaicloud.io/vault-path: "kubernetes"
vault.security.banzaicloud.io/vault-skip-verify: "true"
vault.security.banzaicloud.io/vault-agent: "true"
spec:
containers:
- name: webapp
image: webapp:latest
env:
- name: DB_PASSWORD
value: vault:secret/data/database#password |
|
Управление конфигурационными файлами
Для сложных приложений часто требуются не просто отдельные переменные окружения, а целые конфигурационные файлы. ConfigMap позволяет хранить такие файлы:
Bash | 1
| kubectl create configmap app-config --from-file=app.properties |
|
Затем можно монтировать этот файл в контейнер:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
| apiVersion: v1
kind: Pod
metadata:
name: webapp
spec:
containers:
- name: webapp
image: webapp:latest
volumeMounts:
- name: config-volume
mountPath: /etc/config
volumes:
- name: config-volume
configMap:
name: app-config |
|
Обновление конфигураций без перезапуска
Обновление ConfigMap или Secret не приводит к автоматическому перезапуску подов, использующих эти ресурсы. Для динамического обновления конфигурации можно использовать ConfigMap Reload или сходные решения:
YAML | 1
2
3
4
5
6
7
8
9
10
| apiVersion: apps/v1
kind: Deployment
metadata:
name: webapp
spec:
template:
metadata:
annotations:
configmap.reloader.stakater.com/reload: "app-config"
# остальная часть спецификации |
|
С такой аннотацией под будет автоматически перезапущен при изменении ConfigMap app-config .
Важно понимать, что даже с автоматическими перезапусками изменение конфигурации может привести к временной недоступности сервиса. Для приложений, требующих высокой доступности, лучше использовать стратегию обновления с нулевым простоем, например, blue-green deployment или canary releases.
Я на собственном опыте убедился, что правильное управление конфигурациями критически важно для обеспечения стабильности и безопасности приложений. Неправильно настроенная интеграция с хранилищем секретов может привести к отказу всего приложения или, что еще хуже, к утечке чувствительной информации.
Мониторинг и отладка кластеров
Мониторинг кластеров Kubernetes — ключевой аспект обеспечения стабильной работы системы. Без эффективного мониторинга невозможно выявить проблемы до того, как они повлияют на пользователей.
Инструменты мониторинга
Для мониторинга кластеров Kubernetes часто используются следующие инструменты:1. Prometheus — популярная система мониторинга с открытым исходным кодом. Она собирает метрики из настраиваемых источников данных, хранит их локально и выполняет правила над ними для агрегации и генерации уведомлений.
2. Grafana — платформа для визуализации и аналитики. Она позволяет создавать информативные дашборды на основе данных из Prometheus и других источников.
3. cAdvisor — встроенный в Kubernetes агент, который собирает, агрегирует и экспортирует информацию об использовании ресурсов контейнерами. Для быстрого развертывания стека мониторинга можно использовать kube-prometheus:
Bash | 1
2
3
| git clone https://github.com/prometheus-operator/kube-prometheus
kubectl apply -f kube-prometheus/manifests/setup
kubectl apply -f kube-prometheus/manifests |
|
Отладка проблем
Когда что-то идет не так, важно уметь быстро диагностировать проблему. Вот несколько подходов к отладке:
1. Проверка логов подов и контейнеров:
Bash | 1
| kubectl logs <имя_пода> [-c <имя_контейнера>] |
|
2. Использование kubectl describe для получения детальной информации:
Bash | 1
| kubectl describe pod <имя_пода> |
|
3. Доступ к контейнеру для диагностики изнутри:
Bash | 1
| kubectl exec -it <имя_пода> -- /bin/bash |
|
4. Проверка состояния узлов:
Bash | 1
| kubectl describe node <имя_узла> |
|
Сетевые политики и изоляция трафика
Сетевые политики в Kubernetes позволяют контролировать поток трафика между подами, обеспечивая дополнительный уровень безопасности. Они особенно полезны в мультитенантных средах или при работе с конфиденциальными данными. Пример сетевой политики, которая разрешает входящий трафик только от подов с определенными метками:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
| apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
name: api-allow-frontend
spec:
podSelector:
matchLabels:
role: api
ingress:
- from:
- podSelector:
matchLabels:
role: frontend
ports:
- protocol: TCP
port: 8080 |
|
Эта политика разрешает трафик от подов с меткой role: frontend к подам с меткой role: api через порт 8080 по TCP.
Для применения сетевых политик необходимо, чтобы сетевой плагин кластера поддерживал их. Не все плагины поддерживают сетевые политики нативно. Например, Calico и Cilium предоставляют расширенные возможности для сетевых политик. Из моего опыта могу сказать, что настройка сетевых политик может быть трудной задачей. Начинайте с менее строгих правил, постепенно уточняя их, и всегда тестируйте изменения в среде разработки перед применением в продакшене.
Автоматическое масштабирование на основе метрик (HPA)
Horizontal Pod Autoscaler автоматически масштабирует количество подов на основе наблюдаемых метрик. По умолчанию HPA использует метрику CPU, но его можно настроить на использование пользовательских метрик. Пример HPA, который масштабирует развертывание на основе среднего использования CPU:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: api-hpa
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: api
minReplicas: 1
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 50 |
|
Частые проблемы и их решения
В этом разделе рассмотрим типичные проблемы, с которыми сталкиваются команды при использовании Kubernetes в продакшене, и эффективные стратегии их решения. Также обсудим оптимизацию производительности и затрат.
Проблема: Недостаток ресурсов
Одна из самых распространённых проблем — это ситуация, когда поды не могут быть запланированы из-за нехватки ресурсов. Симптомы: поды остаются в состоянии Pending с сообщением об ошибке, указывающим на недостаток CPU или памяти.
Решение:
Bash | 1
2
3
4
5
| # Проверка использования ресурсов узлами
kubectl top nodes
# Анализ требований к ресурсам пода
kubectl describe pod <имя_пода> |
|
Рекомендуется реалистично оценивать требования к ресурсам подов и настраивать соответствующие запросы (requests) и лимиты (limits). Для существующих приложений можно использовать VPA в режиме рекомендаций для анализа фактического использования ресурсов.
Проблема: Сетевые проблемы между сервисами
Частая проблема — сервисы не могут связаться друг с другом, хотя все компоненты, кажется, работают правильно.
Решение: Используйте временный отладочный под для проверки сетевого взаимодействия:
Bash | 1
| kubectl run network-test --rm -it --image=nicolaka/netshoot -- /bin/bash |
|
Внутри этого пода вы можете использовать инструменты вроде curl , dig и nslookup для отладки сетевых проблем.
Проблема: Утечка ресурсов
Со временем в кластере могут накапливаться неиспользуемые ресурсы: старые поды, задания, PVC и т.д.
Решение: Регулярная очистка неиспользуемых ресурсов:
Bash | 1
2
3
4
5
| # Удаление завершившихся подов
kubectl get pods --field-selector=status.phase=Succeeded,status.phase=Failed --all-namespaces -o name | xargs kubectl delete
# Поиск PVC без привязанных подов
kubectl get pvc --all-namespaces | grep Released |
|
Оптимизация производительности
Для оптимизации производительности кластера Kubernetes можно принять ряд мер:
1. Настройка запросов и лимитов ресурсов: Установите реалистичные значения для CPU и памяти, чтобы избежать планирования слишком большого количества подов на один узел.
2. Использование node affinity и anti-affinity: Правильное размещение подов может значительно улучшить производительность и надежность.
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
| affinity:
nodeAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
nodeSelectorTerms:
- matchExpressions:
- key: node-type
operator: In
values:
- compute-optimized
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution:
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- database
topologyKey: kubernetes.io/hostname |
|
3. Оптимизация образов контейнеров: Используйте многоэтапную сборку в Dockerfile, чтобы уменьшить размер итогового образа.
Bash | 1
2
3
4
5
6
7
8
9
10
11
| FROM node:14 AS build
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=build /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"] |
|
Примеры миграции монолитных приложений в микросервисы
Миграция монолитной архитектуры в микросервисную — сложный процесс, который лучше выполнять поэтапно:1. Анализ и разделение: Идентифицируйте компоненты, которые можно выделить в отдельные сервисы.
2. Стратегия странглера: Постепенно перенаправляйте функциональность от монолита к новым микросервисам.
3. API Gateway: Используйте для маршрутизации запросов между старым монолитом и новыми микросервисами. Пример конфигурации Ingress для реализации такой стратегии:
YAML | 1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
| apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
spec:
rules:
- host: app.example.com
http:
paths:
- path: /api/users(/|$)(.*)
pathType: Prefix
backend:
service:
name: users-service
port:
number: 80
- path: /api(/|$)(.*)
pathType: Prefix
backend:
service:
name: monolith-service
port:
number: 80 |
|
Оптимизация затрат на инфраструктуру
Kubernetes может быть дорогим удовольствием без правильного управления ресурсами. Вот несколько способов оптимизировать затраты:1. Автомасштабирование кластера: Настройте кластер для автоматического добавления и удаления узлов в зависимости от нагрузки.
2. Spot-инстансы: Используйте прерываемые инстансы для некритичных рабочих нагрузок.
3. Анализ и оптимизация запросов ресурсов: Регулярно пересматривайте настроенные запросы и лимиты ресурсов для подов.
4. Namespace Quotas: Устанавливайте квоты для пространств имен, чтобы предотвратить неконтролируемое использование ресурсов: YAML | 1
2
3
4
5
6
7
8
9
10
11
12
| apiVersion: v1
kind: ResourceQuota
metadata:
name: compute-quota
namespace: dev
spec:
hard:
pods: "10"
requests.cpu: "4"
requests.memory: 8Gi
limits.cpu: "8"
limits.memory: 16Gi |
|
Опыт показывает, что регулярный аудит использования ресурсов и настройка правильных запросов и лимитов могут сократить расходы на инфраструктуру на 30-50% без ущерба для производительности.
Возможно ли поднять в kubernetes proxy Задача.
Дано: На роутере настроены 10 ip-адресов внешних от провайдера. На сервере vmware поднято 10 виртуальных машин с прокси для того чтобы... Конфигурация ngnix для Kubernetes Deployment Подскажите, что не так с nginx.conf переданным в ConfigMap для k8s? У меня на порту сервиса сайт не открывается.
http {
server {
location... Где расположить БД для Kubernetes кластера в облаке Привет. Нагуглил и разобрал пример, как разместить Spring-овый микросервис в кубернетес-кластере. Схема такая:
Использовался один из... Деплой телеграм бота на Google Kubernetes Engine через GitLab CI Доброго времни суток. Прошу помощи у форумчан тк. сам не могу разобраться.
Как задеплоить бота на GKE через GitLab CI?
Использую стндартный... осваиваем uClinux Появилось желание освоить что-нибудь огромное и функциональное. Самое популярное это uClinux.
В гугле информации валом. Но почти вся та инфа хлам.... Осваиваем панель Standard На форме располагаются: семь разных кнопок с номерами или названиями дней недели сверху; список ListBox, задающий количество доступных кнопок (4 из... Шпаргалка по паттернам Написал для себя шпаргалку по паттернам проектирования.
Целью было сделать ее наиболее компактной и привести куски кода вместо текстовых описаний... Шпаргалка по командам 8х Не подскажите где можно взять КРАТКИЙ ЭЛЕКТРОННЫЙ учебник по 1с8х???
Вроде мисты под 77.
Перебрать документы, справочники, удалить, создать ... Шпаргалка по синтаксису Нашел интересную фичу: http://edunow.su/site/content/pascal/pascal_shpargalka, вдруг кому пригодятся... Шпаргалка по установке Установка Archlinux
Создаем раздел на который будем устанавливать
cfdisk /dev/sda
Форматируем его в ext4 (у меня логический раздел sda5) ... Шпаргалка ключевых слов Вообще была у меня идея создать типа шпаргалки для начинающих, типа если подзабыл что да как запустил и подсмотрел, в добавок запомнил как печатать,... Шпаргалка для php Есть ли шпора для php как на css подобно этому: http://htmlbook.ru/css/font-style
Интересует только моменты: Синтаксис и Значения - что бы можно...
|