Лучшие 10 хитростей и советов по Kubernetes

Original author: Sindhuja Cynixit
  • Translation


В интернете много справочной литературы, но иногда самыми ценными становятся самые простые советы. Команда 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

Mail.ru Group
Building the Internet

Similar posts

Comments 12

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

    Вот только нужно убедиться, что нет imagePullPolicy: Always, а то он будет игнорировать собранные локально образы
      0
      Основная боль — переключать kubectl между разными кластерами
        0
        kubectx эту задачу прекрасно решает.
          0

          А в чем боль?

            +1
            в ~/.bashrc просто добавить:

            alias kdev='export KUBECONFIG=/home/noname/.kube/dev'
            alias kprod='export KUBECONFIG=/home/noname/.kube/prod'

            Еще для себя нашел удобным добавить вот такой алиас:
            alias k='kubectl'
              +1
              делюсь своим маразмом. может кому пригодиться.
              оболочка zsh

              #kube
              export KUBECONFIG=$(find /Users/vasyansk/Documents/Configs/.kube -maxdepth 1 -type f -name '*' | tr "\n" ":") // выбирает все файлики с конфигами из папки где я их храню
              
              alias kex="export KUBECONFIG=$(find /Users/vasyansk/Documents/Configs/.kube -maxdepth 1 -type f -name '*' | tr '\n' ':')" //обновляет список контекстов, если добавился новый файл, что бы не перезапускать оболочку
              
              source <(kubectl completion zsh) // автозаполнение, недавно для себя открыл
              
              // основной - kube приятнее чем просто к или полное kubectl
              alias kube="kubectl"
              
              //куча алиасов. так привык, что за чужим компом курю бамбук, и тут поможет автозаполнение :)
              
              alias kaf="kubectl apply -f"
              alias kud="kubectl delete"
              alias kgd="kubectl get deployment"
              alias kgp="kubectl get pods"
              alias kgn="kubectl get nodes"
              alias kgi="kubectl get ingress"
              alias kgs="kubectl get service"
              alias kgj="kubectl get jobs"
              alias kgcj="kubectl get cronjobs"
              alias kgpv="kubectl get persistentvolume"
              alias kls="kubectl logs"
              alias kec="kubectl exec -ti"
              alias kd="kubectl describe"
              alias kgc="kubectl config get-contexts"
              
              // два последних как раз и переключают контекст кластеров между собой
              
              alias kcuamega="kubectl config use-context k8s-amega"
              alias kcumlm="kubectl config use-context k8s-mlm"
                0
                кстати kube-ps1 — просто бомбическая штука.
                в консоли сразу видишь в каком кластере ты сейчас «наведешь порядок»
                  0
                  А «стандартный» kubectl plugin чем не угодил?
                    0
                    судя по репе, ей всего 10 месяцев, а я пользуюсь кубом куда больше.
                    прикольно, что сокращения почти те же ))
                0
                kubectx вам в помощь
                0
                Дефолтные лимиты на контейнеры для неймспейса — так себе идея чаще всего. Мы ставим лимиты на неймспейс и контейнеры без явно указанных лимитов просто не запускаются. ИМХО так правильнее, выставление корректных лимитов — задача того, кто контейнер деплоит. Дефолты же часто приводят к «хз почему так медленно работает и падает по ООМ», так как тот, кто деплоит контейнер может про них и не знать.

                Исключения — неймспейсы для каких-то внешних шедуллеров с однотипными контейнерами, например под раннеры или контейнеры airflow отлично подходят дефолтные лимиты неймспейса.
                  0
                  Про «Наведите порядок»:
                  Мы стараемся делать максимально однозадачные неймспейсы, таким образом удаление приложения= удаление неймспейса. А это в свою очередь удаляет и все сопутствующие сущности.

                  Only users with full accounts can post comments. Log in, please.