Кластеры Kubernetes

Общая информация

Kubernetes был задуман корпорацией Google, как платформа контейнерной оркестрации с открытым исходным кодом для развёртывания, масштабирования и управления контейнерными приложениями. Платформа стала общепринятым стандартом контейнерной оркестрации и флагманским проектом Фонда развития облачных вычислений, который поддержали Google, AWS, Microsoft, IBM, Intel, Cisco и Red Hat.

Более подробно познакомиться с Kubernetes можно в нашем блоге и на официальном сайте.

Создавая уровень абстракции поверх группы экземпляров в Облаке КРОК, Kubernetes позволяет легко внедрять и использовать приложения, построенные с использованием микросервисной архитектуры.

Глоссарий

Кластер – основной элемент Kubernetes. Формируется из множества виртуальных или физических машин, каждая из которых выполняет определённую функцию: рабочего узла или мастер-узла.

Мастер-узел – управляющий (control-plane) узел кластера, на котором размещаются служебные приложения, необходимые для работы кластера.

Рабочий узел – вычислительный узел кластера, на котором выполняются пользовательские задачи.

Под (Pod) – совокупность контейнеров с общей сетью, одним IP-адресом и другими общими характеристиками (общие хранилища данных, лейблы).

Кластеры Kubernetes в Облаке КРОК

Эффективно распределяя трафик и масштабируя кластеры в безопасной и устойчивой инфраструктуре облака вы можете быстро запускать контейнеризованные приложения, интегрированные с сервисами Облака КРОК, а также управлять группами безопасности, связывать кластеры Kubernetes с существующими экземплярами, использовать объектное хранилище и настраивать VPN-соединения между вашей инфраструктурой и кластерами Kubernetes.

В веб-интерфейсе сервиса Кластеры Kubernetes можно выполнять следующие действия:

Сервис Кластеры Kubernetes предоставляет возможность установки в кластере дополнительных сервисов:

  • Ingress controller, который можно использовать для маршрутизации запросов, поступающих извне к сервисам, развёрнутым в Kubernetes.

  • EBS-провайдер, который позволяет Kubernetes управлять дисками в Облаке КРОК и использовать их в качестве Persistent Volumes.

  • Docker Registry, настроенный для использования в кластере Kubernetes. В registry можно хранить образы контейнеров для последующего развёртывания в Kubernetes.

В официальной документации Kubernetes вы можете ознакомиться со всеми возможностями, доступными для управления кластерами.

Для чего подойдет сервис Кластеры Kubernetes?

  • Для быстро развёртываемых и масштабируемых стендов для разработчиков.

  • Для сред с большим количеством изменений и релизов.

  • При плавающей нагрузке в зависимости от количества пользователей.

  • Если важен Time to market.

  • Для приложений с микросервисной архитектурой.

Перед началом работы

Чтобы начать работу с сервисом Кластеры Kubernetes выполните следующие действия:

  1. Создайте проект, если у вас его нет.

  2. В разделе IAM создайте пользователя c ролью Kubernetes Administrator или Cloud Administrator и добавьте его в проект.

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

  4. Если вам нужен EBS-провайдер, в разделе IAM создайте специального пользователя с ролью Kubernetes EBS Provider User и добавьте его в проект.

Важно

Роль Kubernetes Administrator имеет весь необходимый набор прав для работы с сервисом Кластеры Kubernetes, однако он не включает в себя многие операции с ресурсами в облаке, поэтому другие разделы веб-интерфейса могут быть недоступны.

Создание Кластера Kubernetes

Создание кластера можно разделить на две части: создание инфраструктуры и установка кластера. На текущий момент создание инфраструктуры заключается в создании нужного количества экземпляров заданной конфигурации из подготовленного шаблона. После успешного старта экземпляров запускается процесс установки кластера. При успешном завершении установки кластер переходит в состояние Готов.

Любое другое состояние кластера говорит о незавершённом процессе создания кластера. Кластер в состоянии Готов считается готовым к эксплуатации. Дополнительными сервисами считаются Ingress controller, Docker-registry и EBS-провайдер. Создание кластера включает в себя создание экземпляров, установку в них компонентов Kubernetes и опциональную установку дополнительных сервисов. При создании кластера с дополнительными сервисами, состояние Готов говорит и об их успешной установке.

Облако КРОК упрощает использование Kubernetes и позволяет разворачивать всю инфраструктуру для кластера нажатием одной кнопки Создать.

На первом шаге создания кластера задайте необходимые параметры:

  • Имя.

  • Версию Kubernetes, которая будет установлена на все узлы.

  • Подсеть, в которой будет создан кластер.

  • SSH-ключ для подключения к кластеру.

  • Группы безопасности, которые будут регулировать трафик на интерфейсах экземпляров в подсети.

  • Опцию Назначить Elastic IP для API-сервера. В случае выбора опции мастер-узлу будет назначен Elastic IP для внешнего доступа к API-серверу кластера.

На втором шаге выберите конфигурацию мастер-узла, на котором будут размещены служебные приложения, необходимые для работы кластера. Укажите тип экземпляра и характеристики диска: тип, размер и IOPS (если это возможно для данного типа). На этом шаге можно дополнительно включить опцию Отказоустойчивый кластер.

Примечание

Компоненты мастер-узла чувствительны к производительности. Рекомендуем использовать диски с высокой производительностью gp2: Универсальный (SSD), io2: Максимальный (SSD)

На третьем шаге необходимо указать конфигурацию рабочих узлов, где будут выполняться пользовательские задачи. Укажите необходимое количество рабочих узлов, тип экземпляра и характеристики диска: тип, размер и IOPS (если это доступно для данного типа). В случае выбора опции Использовать группы размещения, будут созданы группы размещения, в которых затем будут запускаться экземпляры для рабочих узлов кластера.

На четвертом шаге вы можете выбрать дополнительные сервисы, которые будут установлены в кластер:

  • Ingress controller для маршрутизации запросов. Для данного сервиса можно выбрать опцию Назначить Elastic IP для Ingress-controller.

  • Docker registry, для которого нужно задать параметры диска (тип, размер, IOPS), в котором будут храниться образы ваших контейнеров.

  • EBS-провайдер, в котором нужно выбрать учётную запись пользователя Облака КРОК для управления дисками.

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

  • Тип пользовательских данных. На данный момент поддерживаются два типа пользовательских данных: x-shellscript и cloud-config.

  • Пользовательские данные. При выборе типа x-shellscript, добавьте в это поле свой shell-скрипт. При выборе типа cloud-config, добавьте в это поле конфигурацию для cloud-config в формате YAML. Примеры действий, выполняемых cloud-config, и соответствующих конфигураций можно найти в официальной документации cloud-init.

Указанные пользовательские данные будут применены ко всем узлам кластера.

После выполнения предыдущих шагов нажмите Создать.

Примечание

Процесс создания кластера Kubernetes может занять от 5 до 15 минут.

При создании кластера дополнительно устанавливается приложение Cluster-manager, необходимое для корректной работы мониторинга и изменения количества рабочих узлов в кластере. Его удаление может повлечь некорректную работу сервиса Кластеры Kubernetes с кластером, из которого приложение будет удалено.

Для корректной работы кластера при его создании автоматически создаётся новая группа безопасности. В группу будут добавлены следующие правила:

  • разрешающее входящий трафик от интерфейсов, находящихся в этой же группе безопасности;

  • разрешающее весь исходящий IPv4-трафик.

В случае удаления кластера группа безопасности будет удалена.

Управление Кластером Kubernetes

Важно

Сервис не модифицирует существующие группы безопасности облака, поэтому для доступа к API-серверу кластера необходимо открыть доступ по порту 6443.

После создания кластера дождитесь, пока статус кластера изменится на Готов и загрузите его конфигурацию на локальный компьютер, нажав Получить настройки.

Для доступа к Kubernetes Dashboard установите на локальный компьютер утилиту kubectl, а затем в консоли операционной системы выполните следующие команды:

  1. Установите переменную окружения KUBECONFIG:

    для MacOS и Linux:

    export KUBECONFIG=<configuration file path>
    

    для Windows:

    set KUBECONFIG=<configuration file path>
    
  2. Активируйте прокси-сервер с помощью команды:

    kubectl proxy
    

    Важно

    Не закрывайте окно консоли, чтобы прокси-сервер продолжал работать.

  3. После этого откройте в браузере ссылку http://localhost:8001/api/v1/namespaces/kubernetes-dashboard/services/https:kubernetes-dashboard:/proxy/#

  4. Для входа в Dashboard выберите опцию Token и скопируйте токен для доступа в Kubernetes Dashboard со страницы кластера.

Для работы с кластером вы можете использовать любую удобную командную оболочку Kubernetes (Draft, Helm, Terraform и т.д.).

Изменение количества рабочих узлов кластера

В любой момент вы можете изменить количество рабочих узлов кластера. При увеличении количества рабочих узлов будет создан новый экземпляр, на него будут установлены необходимые компоненты кластера и в кластере произойдет переконфигурация для добавления нового узла. Во время этого процесса состояние кластера переходит в Не готов. После успешного окончания этого процесса кластер перейдет в состояние Готов. При уменьшении количества рабочих узлов будет запущен механизм вывода желаемого количества узлов в режим обслуживания и последующее удаление их из кластера средствами Kubernetes API. Затем произойдёт удаление освобождённых экземпляров. Во время этого процесса состояние кластера переходит в Не готов. После успешного окончания этого процесса кластер перейдет в состояние Готов.

Чтобы изменить количество рабочих узлов кластера перейдите на страницу кластера Kubernetes, нажмите на иконку редактирования параметра Количество рабочих узлов. Укажите требуемое количество узлов и сохраните изменения.

Если изменить количество рабочих узлов не удаётся, кластер продолжит работать. Запись со сведениями о сбое появится на вкладке Предупреждения.

Удаление Кластера Kubernetes

Удаление кластера заключается в удалении всех созданных для него экземпляров. Экземпляры созданные для дополнительных сервисов также удаляются. Все созданные EBS-провайдером диски будут доступны для удаления в подразделе Диски консоли управления.

Чтобы удалить кластер Kubernetes и связанные с ним сервисы (Container Registry, EBS-провайдер), нажмите Удалить.

Внимание

При удалении кластера диск с образами Docker Registry будет также удален!

Режим «Отказоустойчивый кластер»

В данном режиме кластер запускается в конфигурации с тремя мастер-узлами. Это позволяет сохранить работоспособность кластера при отказе одного мастер-узла. Если к отказавшему узлу был привязан Elastic IP, он будет переназначен на работоспособный мастер-узел.

Ingress controller

Если при создании кластера вы выбрали опцию Ingress Controller, то в кластере будет развёрнут дополнительный рабочий узел, который позволит настраивать доступ к сервисам, запущенным внутри кластера, через единую точку входа . Чтобы сервис стал доступен через Ingress Controller, нужно создать ресурс типа Ingress.

Ниже приведён пример конфигурации кластера с Ingress Controller Elastic IP: 185.12.31.21. В этом кластере развёрнут сервис, к которому необходимо предоставить доступ по адресу http://185.12.31.211/example

В кластере запущен сервис со следующей конфигурацией:

apiVersion: v1
kind: Pod
metadata:
  name: example
  labels:
    k8s-app: example
spec:
  containers:
  - name: example-app
    image: quay.io/coreos/example-app:v1.0
  imagePullSecrets:
  - name: regcred

---
kind: Service
apiVersion: v1
metadata:
  name: example-service
  namespace: default
spec:
  selector:
    k8s-app: example
  ports:
  - protocol: TCP
    port: 80
  type: LoadBalancer

Чтобы он стал доступен по адресу http://185.12.31.211/example, необходимо открыть порт 80 и создать следующую конфигурацию Ingress:

apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - http:
      paths:
      - path: /example
        pathType: Prefix
        backend:
          serviceName: example-service
          servicePort: 80

EBS-провайдер

Если при создании кластера вы выбрали опцию EBS-провайдер, то в кластер будет установлен сервис, который позволяет Kubernetes управлять дисками в Облаке КРОК и использовать их в качестве Persistent Volumes в Kubernetes. Сервис способен работать как с существующими дисками, так и создавать их самостоятельно.

Все созданные диски будут доступны в разделе Диски консоли управления.

Для использования дисков в качестве Persistent Volumes в Kubernetes, необходимо описать следующие конфигурации:

  1. Storage class – описание класса хранилища. Подробную информация о Storage class можно получить в официальной документации.

  2. Persistent Volume – описание непосредственно подключаемого диска и его характеристик.

  3. Persistent Volume Claim – запрос на Persistent Volume, в котором описываются требуемые характеристики диска. Если Persistent Volume с такими (или лучшими) характеристиками найден, Kubernetes будет использовать его.

Сценарий использования существующего диска в Облаке КРОК

Для использования существующего диска в Облаке КРОК в конфигурации Persistent Volume в поле driver необходимо указать ebs.csi.aws.com, а в поле volumeHandle указать volume ID:

apiVersion: v1
kind: PersistentVolume
metadata:
  name: static-pv
spec:
  capacity:
    storage: 48Gi
  volumeMode: Filesystem
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-static
  csi:
    driver: ebs.csi.aws.com
    volumeHandle: vol-9991C120
    fsType: xfs
  nodeAffinity:
    required:
      nodeSelectorTerms:
      - matchExpressions:
        - key: topology.ebs.csi.aws.com/zone
          operator: In
          values:
          - ru-msk-vol51

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

В дальнейшем для использования этого диска достаточно создать Persistent Volume Claim, отвечающий характеристикам диска и использовать его в необходимом ресурсе. При этом важно, чтобы storageClassName этого Claim совпадал с указанным в Persistent Volume.

Пример конфигурации для создания пода с диском размером 20 ГиБ:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: static-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-static
  resources:
    requests:
      storage: 20Gi
---
apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
  persistentVolumeClaim:
    claimName: static-claim

Сценарий с созданием новых дисков

Для создания новых дисков в конфигурации Storage class в поле provisioner нужно указать ebs.csi.aws.com. В поле parameters можно указать параметры создаваемых дисков:

Параметр

Возможные значения

Значение по умолчанию

Описание

csi.storage.k8s.io/fsType

xfs, ext2, ext3, ext4

ext4

Файловая система, в которую будет отформатирован создаваемый диск

type

io2, gp2, st2

gp2

Тип диска

iopsPerGB

IOPS на гибибайт создаваемого диска. Необходим при указании дисков типа io2

В случае отсутствия какого-либо параметра будет использовано значение по умолчанию.

Пример конфигурации:

kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: ebs-dynamic
provisioner: ebs.csi.aws.com
volumeBindingMode: WaitForFirstConsumer
reclaimPolicy: Retain
parameters:
  csi.storage.k8s.io/fstype: xfs
  type: io2
  iopsPerGB: "50"
  encrypted: "true"

При создании новых дисков persistent volume будет создан по запросу Persistent Volume Claim.

Persistent volume в Облаке КРОК поддерживает accessModes только со значением ReadWriteOnce для EBS, ссылка на документацию kubernetes.

Пример запроса для создания пода с диском размером 4 ГиБ:

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-dynamic-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-dynamic
  resources:
    requests:
      storage: 4Gi

При создании пода, использующего этот запрос, Kubernetes автоматически создаст диск в облаке размером 4 ГиБ с характеристиками, указанными в storage class и присоединит его к этому поду.

Пример конфигурации пода:

apiVersion: v1
kind: Pod
metadata:
  name: app
spec:
  containers:
  - name: app
    image: centos
    command: ["/bin/sh"]
    args: ["-c", "while true; do echo $(date -u) >> /data/out.txt; sleep 5; done"]
    volumeMounts:
    - name: persistent-storage
      mountPath: /data
  volumes:
  - name: persistent-storage
    persistentVolumeClaim:
      claimName: ebs-dynamic-claim

Установка EBS-провайдера в свой кластер Kubernetes

Возможна установка EBS-провайдера отдельно от сервиса облака.

Для этого необходимо создать секрет с данными для авторизации пользователя, от имени которого будет происходить работа с облаком:

apiVersion: v1
kind: Secret
metadata:
  name: aws-secret
  namespace: kube-system
stringData:
  key_id: "<AWS_ACCESS_KEY_ID>"
  access_key: "<AWS_SECRET_ACCESS_KEY>"

Для корректной работы пользователь, данные которого подставляются в поля key_id и access_key должен обладать следующими привилегиями:

  • cl:attach_volume

  • cl:detach_volume

  • cl:describe_instances

  • cl:describe_volumes

и опционально для возможности создавать и удалять диски:

  • cl:create_volume

  • cl:delete_volume

После этого необходимо применить конфигурацию:

kubectl apply -f https://storage.cloud.croc.ru/kaas/deployment/ebs/ebs.yaml

В случае, если установка произойдет успешно (все поды с префиксом ebs-csi-* в имени будут запущены), станет доступным использование дисков Облака КРОК в Kubernetes.

Docker Registry

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

Чтобы загружать в Docker Registry образы с локального компьютера, необходимо установить Docker.

После установки выполните команду и введите пароль:

docker login <IP-адрес docker-registry>

После этого загрузите образы, устанавливая для них тег, начинающийся с <IP-адрес docker-registry>:5000/. Например, для существующего образа quay.io/coreos/example-app:v1.0 тег будет таким:

docker tag quay.io/coreos/example-app:v1.0 185.12.31.211:5000/example-app:v1.0
docker push 185.12.31.211:5000/example-app:v1.0

В дальнейшем вместо публичного IP-адреса Docker Registry можно использовать приватный адрес, и наоборот.

Чтобы создать в кластере под из загруженного образа, используйте настроенные в кластере учётные данные regcred:

apiVersion: v1
kind: Pod
metadata:
  name: example
spec:
  containers:
  - name: example-app
    image: '172.31.0.4:5000/example-app:v1.0'
  imagePullSecrets:
  - name: regcred

Cluster-manager

Особенности cluster-manager

cluster-manager - это специфичное для Kubernetes инсталляций Облака КРОК приложение, которое отвечает за изменение количества рабочих узлов в кластере. Это приложение работает с Instance Metadata API и Kuberernetes API для обеспечения необходимой интеграции этих компонентов. Cluster-manager отвечает за:

  • мониторинг состояния кластера (Готов / Не готов);

  • безопасное удаление рабочих узлов.

Мониторинг состояния кластера

Cluster-manager постоянно запрашивает информацию о количестве рабочих узлов, зарегистрированных в Kubernetes кластере. Если это значение не соответствует фактическому количеству экземпляров в кластере, то состояние кластера становится Не готов. Такое поведение характерно для кластера во время добавления и удаления рабочих узлов, так как изначально происходит запуск экземпляра, и только спустя некоторе время этот экземпляр регистрируется в качестве рабочего узла кластера. Если количество зарегистрированных рабочих узлов в кластере соответствует количеству запущенных экземпляров, состояние кластера становится Готов.

Безопасное удаление узла

При получении уведомления об удалении рабочего узла cluster-manager, используя Kuberetes API, удаляет рабочий узел из кластера. После успешного удаления рабочего узла из кластера, запускается процесс удаления экземпляра.

Последствия удаления cluster-manager

Пользователям не рекомендуется изменять настройки этого приложения и конфигурацию его деплоя в кластер. Пользователь теряет возможность уменьшать количество рабочих узлов в кластере с помощью веб-интерфейса Облака КРОК:

  • при удалении cluster-manager из кластера;

  • при перемещении запущенного процесса с мастер-узла на один из рабочих узлов.

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

Установка в кластер

Cluster-manager автоматически устанавливается в каждый кластер, который создается в сервисе Кластеры Kubernetes Облака КРОК. Процесс cluster-manager запускается на мастер-узле кластера. При установке используются следующие настройки:

kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: cluster-manager
rules:
  - apiGroups:
      - ""
    resources:
      - nodes
    verbs:
      - list
      - get
      - delete
---
kind: ClusterRoleBinding
apiVersion: rbac.authorization.k8s.io/v1beta1
metadata:
  name: cluster-manager
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: cluster-manager
subjects:
- kind: ServiceAccount
  name: cluster-manager
  namespace: kube-system
---
apiVersion: v1
kind: ServiceAccount
metadata:
  name: cluster-manager
  namespace: kube-system

---
kind: Deployment
apiVersion: apps/v1
metadata:
  labels:
    k8s-app: cluster-manager
  name: cluster-manager
  namespace: kube-system
spec:
  replicas: 1
  selector:
    matchLabels:
      k8s-app: cluster-manager
  template:
    metadata:
      labels:
        k8s-app: cluster-manager
    spec:
      nodeSelector:
        node-role.kubernetes.io/master: ""
      containers:
        - name: cluster-manager
          image: dhub.c2.croc.ru/kaas/kubernetes-manager:v0.1.0
          imagePullPolicy: Always
          env:
            - name: PYTHONUNBUFFERED
              value: "1"
      serviceAccountName: cluster-manager
      tolerations:
        - key: node-role.kubernetes.io/master
          effect: NoSchedule