10 простых советов для работы с Kubernetes

В интернете много справочной литературы, но иногда самыми ценными становятся самые простые советы. Эта статья — перевод подборки из десяти хитростей и советов, которые автор статьи собрала после года работы с Kubernetes. Советы не отсортированы по важности, но каждый найдет что-то полезное для себя.

Самая простая команда в работе с Kubernetes

Для начала, пожалуй, самое простое и полезное действие в работе с Kubernetes. Следующая команда включает автодополнение команд kubectl в оболочке bash:

echo "source <(kubectl completion bash)" >> ~/.bashrc

Автозаполнение kubectl пропишется в файл .bashrc и будет автоматически активироваться каждый раз при запуске оболочки. Это ускоряет набор длинных команд и параметров, таких как all-namespaces. Подробнее в справке Kubernetes по bash.

Ограничения по умолчанию на память и CPU в пространстве имен

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

Чтобы предотвратить такое, Kubernetes позволяет устанавливать ограничения по умолчанию для каждого пространства имен. Они прописываются в файле yaml для конкретного пространства имен. Вот пример такого файла:

apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container

Создайте такой yaml и примените к любому пространству имен. Например, к пространству имен limit-example. Теперь для любого контейнера, развернутого в этом пространстве имен, будет действовать лимит 512Mi, если для данного контейнера дополнительно не установлен другой индивидуальный лимит.

Уборка мусора в старых версиях Kubernetes

Kubelet по умолчанию начинает уборку мусора, когда var/lib/docker занимает 90 % доступного дискового пространства. Это прекрасно, однако, до версии Kubernetes 1.7 не было лимита по умолчанию на количество используемых индексных дескрипторов inode (инодов), которые соответствуют количеству файлов в файловой системе.

Потенциально ваш контейнер var/lib/docker может использовать только 50 % дискового пространства, но при этом иноды могут закончиться, что вызовет проблемы в работе воркеров.

В старых версиях kubelet от 1.4 до 1.6 придется добавить такой флаг:

--eviction-hard
=memory.available<100Mi,nodefs.available<10%,nodefs.inodesFree<5%

В 1.7 и более свежих версиях этот флаг установлен по умолчанию. Однако предыдущие версии на следят за лимитом инодов.

Minikube… маленький, но мощный локальный Kubernetes

Minikube — самый простой способ запустить локальный кластер Kubernetes. Он запускается простой командой:

minikube start

В результате выполнения этой команды у вас на компьютере работает настоящий кластер Kubernetes.

Источник иллюстрации

Хитрость в том, как собрать приложение и запустить его локально в этом кластере. Если не дать специальных указаний, Docker-образ будет собираться на вашем компьютере, а не в кластере.

Чтобы заставить Docker отправить образ в локальный кластер Kubernetes, докер-машине дается следующая команда:

eval $(minikube docker-env)

Теперь мы можем собирать приложения на локальном кластере Kubernetes.

Не раздавайте доступ kubectl всем подряд

Это кажется очевидным, но если несколько команд используют для своих приложений один кластер (для чего и был создан Kubernetes), не стоит просто выдавать всем подряд kubectl. Лучше разделить команды, выделив каждой из них свое пространство имен и разграничив доступ политиками RBAC.

Можно заморочиться, прописывая для каждого пода права на доступ, чтение, создание, удаление и другие операции. Но главное — ограничить доступ к секретам, разрешив его только администраторам. Так мы разграничим тех, кто может администрировать кластер, и тех, кто может просто развертываться в нем.

Управляйте бюджетами подов

Как гарантировать отсутствие простоев для приложения в кластере Kubernetes? PodDisruptionBudget и ещё раз PodDisruptionBudget.

Кластеры периодически обновляются, а узлы опустошаются. Ничто не стоит на месте, такова реальность. В каждый деплой с более чем одним инстансом следует обязательно включить PDB (PodDisruptionBudget). Он создается в простом файле yaml, который применяется к кластеру. Область покрытия конкретного PDB определяется селекторами меток.

/Примечание: Бюджет PDB учитывается только при обратимом нарушении бюджета (voluntary disruption). В ситуациях вроде аппаратных сбоев PDB не сработает.

Пример PDB:

apiVersion: policy/v1beta1
kind: PodDisruptionBudget
metadata:
  name: app-a-pdb
spec:
  minAvailable: 2
  selector:
      matchLabels:
        app: app-a

Два основных параметра — это matchLabels и minAvailable. В первом параметре указывается, для каких приложений действует бюджет. Например, если у меня есть деплои с метками app: app-a и app: app-b, то данный PDB будет применяться только к первому.

Параметр minAvailable учитывается при опустошении (очистке) узла. Например, в нашем примере во время опустошения вытесняются все инстансы app: app-a, кроме двух.

Это позволяет контролировать, сколько экземпляров приложения должно быть запущено в каждый момент времени.

Мониторинг исправности приложения

Такой мониторинг возможен двумя способами: с помощью проб Readiness или Liveness.

Первая проба (readiness) определяет готовность контейнера к приему трафика.

Вторая (liveness) показывает, исправен ли контейнер или его необходимо перезапустить.

Соответствующие конфигурации просто добавляются в yaml для развертывания. Там можно указать таймауты, время задержки и количество повторных проб. Более подробно о них смотрите документацию Kubernetes.

Метки везде

Метки — одно из фундаментальных понятий в Kubernetes. Они позволяют объектам свободно связываться друг с другом, а также создавать запросы на основе меток. В Kubernetes можно даже перейти к клиенту и наблюдать за событиями по конкретным меткам.

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

Допустим, вы используете один и тот же кластер для dev и qa. Это означает, что у вас может быть приложение app-a, одновременно работающее в обеих средах qa и dev. В этом случае мы можем обращаться отдельно к экземпляру приложения в конкретной среде, указав соответствующий параметр environment. Например, app: app-a и environment: dev для одного окружения, а app: app-a и environment: qa для второго.

Это позволяет обращаться к обоим экземплярам приложения, например, одновременно проводить тестирование.

Наведите порядок

Kubernetes — очень мощная система, но любая система в итоге способна увязнуть в большом количестве процессов. Kubelet запускает все указанные вами процессы и проверки, а также свои собственные.

Конечно, одна бесхозная служба не затормозит систему, а Kubernetes изначально рассчитан на масштабирование. Но если вместо одной службы появляется миллион, kubelet начинает захлебываться.

Если по какой-то причине вы удаляете развертывание (контейнер, образ, что угодно), просто убедитесь в полной очистке.

Познакомьтесь с Go

Главный совет мы приберегли напоследок. Изучите язык программирования Go.

Kubernetes разработан на Go, все расширения написаны на Go, а еще официально поддерживается клиентская библиотека client-go.

Ее можно использовать для разных и интересных вещей. Например, для расширения системы Kubernetes на свой вкус. Так, вы можете использовать собственные программы для сбора данных, развертывания приложений или простой очистки контейнеров.

Изучить язык программирования Go и освоить client-go — пожалуй, самый важный совет, который можно дать начинающим пользователям Kubernetes.

Залишити відповідь

Дякуємо, що поділились