[Перевод] Лучшие 10 хитростей и советов по Kubernetes
В интернете много справочной литературы, но иногда самыми ценными становятся самые простые советы. Команда Kubernetes aaS от Mail.ru перевела подборку из десяти хитростей и советов, которые автор статьи собрала после года работы с 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.
Переведено при поддержке Mail.ru Cloud Solutions