Дополнительные сервисы#

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:

Пример конфигурации 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
Пример конфигурации Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  rules:
  - http:
      paths:
      - path: /example
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

Настройка HTTPS на Ingress Controller#

Эта инструкция обеспечит безопасность сервисов, которые обрабатывают чувствительные данные, поскольку HTTPS-соединения являются важной частью безопасного веб-сервиса и гарантируют конфиденциальность и целостность данных.

Для использования HTTPS на вашем Ingress Controller вам необходимо иметь:

  • Доменное имя для Elastic IP, который был назначен для Ingress Controller.

  • Закрытый ключ TLS и сертификат.

В данном примере мы будем дополнять конфигурацию Ingress из инструкции, описанной выше.

Чтобы защитить Ingress, укажите Kubernetes Secret, который содержит закрытый ключ TLS tls.key и сертификат tls.crt.

Пример конфигурации Kubernetes Secret
apiVersion: v1
kind: Secret
metadata:
  name: tls-secret
  namespace: ingress-nginx
data:
  tls.crt: base64 encoded cert
  tls.key: base64 encoded key
type: kubernetes.io/tls

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

Необходимые изменения в конфигурации Ingress
apiVersion: networking.k8s.io/v1beta1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  tls:
    - hosts:
      - "Your Domain"
      secretName: tls-secret
  rules:
  - host: "Your Domain"
    http:
      paths:
      - path: /example
        pathType: Prefix
        backend:
          serviceName: example-service
          servicePort: 80
Необходимые изменения в конфигурации Ingress
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: example-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  ingressClassName: nginx
  tls:
    - hosts:
      - "Your Domain"
      secretName: tls-secret
  rules:
  - host: "Your Domain"
    http:
      paths:
      - path: /example
        pathType: Prefix
        backend:
          service:
            name: example-service
            port:
              number: 80

После применения этих конфигураций вы сможете использовать защищённый протокол HTTPS для Ingress Controller.

EBS-провайдер#

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

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

EBS-провайдер поддерживает следующие версии Kubernetes: 1.33.1, 1.32.5, 1.31.9 и 1.30.2.

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

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

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

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

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

Для использования существующего диска в К2 Облаке в конфигурации 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, st3

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 в К2 Облаке поддерживает 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

Сценарий с использованием снимка диска#

Чтобы можно было делать снимки дисков, необходимо предварительно создать под с диском и Storage Class, а также Volume Snapshot Class.

Пример конфигурации Volume Snapshot Class для версий Kubernetes 1.20.9 и 1.18.2
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
  name: csi-aws-vsc
driver: ebs.csi.aws.com
deletionPolicy: Delete
parameters:
  csi.storage.k8s.io/snapshotter-secret-name: aws-secret
  csi.storage.k8s.io/snapshotter-secret-namespace: kube-system
Пример конфигурации Volume Snapshot Class для поддерживаемых версий Kubernetes.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotClass
metadata:
  name: csi-aws-vsc
driver: ebs.csi.aws.com
deletionPolicy: Delete
parameters:
  csi.storage.k8s.io/snapshotter-secret-name: aws-secret
  csi.storage.k8s.io/snapshotter-secret-namespace: kube-system

При создании Volume Snapshot Class с помощью этого запроса будет автоматически создан объект класса VolumeSnapshotClass, при этом для авторизации в облаке используются те же данные, что и в EBS-провайдере. Кроме того, вам потребуется Volume Snapshot.

Пример конфигурации Volume Snapshot для версий Kubernetes 1.20.9 и 1.18.2
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: ebs-volume-snapshot-2
  namespace: default
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: ebs-dynamic-claim
Пример конфигурации Volume Snapshot для поддерживаемых версий Kubernetes.
apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: ebs-volume-snapshot-2
  namespace: default
spec:
  volumeSnapshotClassName: csi-aws-vsc
  source:
    persistentVolumeClaimName: ebs-dynamic-claim

При создании Volume Snapshot с помощью этого запроса будут автоматически созданы объект класса VolumeSnapshot и снимки диска в облаке с учётом текущего состояния Persistent Volume Claim в кластере Kubernetes. Теперь этот Volume Snapshot можно использовать в качестве источника данных (dataSource) для Persistent Volume Claim.

Пример конфигурации Persistent Volume Claim
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-restore-claim
spec:
  dataSource:
    name: ebs-volume-snapshot-2
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-dynamic
  resources:
    requests:
      storage: 32Gi
Пример конфигурации Persistent Volume Claim в конфигурации пода
apiVersion: v1
kind: Pod
metadata:
  name: app-restored
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-restored
      mountPath: /data
  volumes:
  - name: persistent-storage-restored
    persistentVolumeClaim:
      claimName: ebs-restore-claim

Сценарий с увеличением размера диска#

Чтобы включить возможность увеличить размер диска, требуется указать поле allowVolumeExpansion со значением True в конфигурации Storage Class.

Размер диска с файловой системой можно изменить только для файловых систем xfs, ext3, ext4.

Пример конфигурации пода с динамически создаваемым диском на 8 ГиБ, размер которого можно увеличить
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
  name: ebs-dynamic
provisioner: ebs.csi.aws.com
allowVolumeExpansion: true
parameters:
  csi.storage.k8s.io/fstype: xfs
  type: gp2
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: ebs-dynamic-claim
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: ebs-dynamic
  resources:
    requests:
      storage: 8Gi
---
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

Для отправки запроса на увеличение размера ранее созданного диска требуется отредактировать поле spec.resources.requests.storage в конфигурации Persistent Volume Claim. Новое значение должно быть больше текущего размера диска и кратно 8 ГиБ.

Конфигурацию Persistent Volume Claim можно отредактировать с помощью команды:

kubectl edit pvc ebs-dynamic-claim

Изменение размера диска занимает некоторое время. Результат можно узнать, запросив текущую конфигурацию Persistent Volume Claim:

kubectl get pvc ebs-dynamic-claim -o yaml

После окончания операции поле status.capacity.storage должно содержать новый размер диска.

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

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

Для этого необходимо создать Secret с данными для авторизации пользователя, от имени которого будет происходить работа с 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, должна быть назначена проектная политика с разрешениями на следующие действия с инфраструктурным сервисом ec2 (см. подробнее, как создать политику и добавить пользователя в проект):

  • AttachVolume

  • CreateSnapshot

  • CreateVolume

  • DeleteSnapshot

  • DeleteVolume

  • DescribeInstances

  • DescribeSnapshots

  • DescribeVolumes

  • DescribeVolumesModifications

  • DescribeTags

  • ModifyVolume

Примечание

Вы можете назначить пользователю политику EKSCSIPolicy или EKSClusterPolicy — они предоставляют все необходимые разрешения. Пользователя с политикой EKSClusterPolicy можно задействовать также для работы с провайдерами ELB и Cluster Autoscaler.

После создания секрета примените конфигурацию (на примере версии 1.30.2):

kubectl apply -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/ebs.yaml

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

Для использования снимков дисков выполните следующие действия:

  1. Применить конфигурацию (на примере версии 1.30.2):

    kubectl create -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/crd/snapshot.storage.k8s.io_volumesnapshotclasses.yaml
    kubectl create -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/crd/snapshot.storage.k8s.io_volumesnapshotcontents.yaml
    kubectl create -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/crd/snapshot.storage.k8s.io_volumesnapshots.yaml
    kubectl create -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/snapshot-controller/rbac-snapshot-controller.yaml
    kubectl create -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/ebs/snapshot-controller/setup-snapshot-controller.yaml
    

В случае если установка пройдёт успешно (под с префиксом snapshot-controller* в имени будет запущен), в К2 Облаке можно будет делать снимки дисков, которые используются в качестве Persistent Volume Claim в 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

ELB-провайдер#

ELB-провайдер позволяет развернуть балансировщики нагрузки для кластера Kubernetes в К2 Облаке. Вы можете создать как сетевой балансировщик нагрузки, так и балансировщик нагрузки приложений для распределения как внешнего, так и внутреннего трафика (см. также официальную документацию Kubernetes).

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

Важно

По умолчанию для балансировщиков нагрузки доступен только один тип целевых ресурсов (target-type): instance.

Настройка кластера Kubernetes для работы с NLB#

Важно

При наличии нескольких подсетей в аннотации необходимо указать подсеть или подсети, где развёрнут кластер Kubernetes. Иначе при создании балансировщика нагрузки подсети будут выбраны произвольно.

Для создания сетевого балансировщика нагрузки необходимо добавить в Kubernetes следующий манифест для объекта Service:

Пример конфигурации Service для сетевого балансировщика внутренней нагрузки
apiVersion: v1
kind: Service
metadata:
  name: my-webserver
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxxxxx, subnet-xxxxxxx, subnet-xxxxxxx
spec:
  selector:
      app: web
  ports:
      - protocol: TCP
        port: 80
        targetPort: 80
  type: LoadBalancer

либо:

Пример конфигурации Service для сетевого балансировщика внешней нагрузки
apiVersion: v1
kind: Service
metadata:
  name: my-webserver
  annotations:
    service.beta.kubernetes.io/aws-load-balancer-scheme: "internet-facing"
    service.beta.kubernetes.io/aws-load-balancer-subnets: subnet-xxxxxxx, subnet-xxxxxxx, subnet-xxxxxxx
spec:
  selector:
      app: web
  ports:
      - protocol: TCP
        port: 80
        targetPort: 80
  type: LoadBalancer

Важно

При создании балансировщика в группу безопасности, которая была автоматически создана вместе с кластером Kubernetes, добавляется входящее правило для порта балансировщика нагрузки, разрешающее TCP-трафик с любых IP-адресов. Чтобы запретить добавление этого правила, в манифест Service необходимо включить следующую аннотацию: service.beta.kubernetes.io/aws-load-balancer-manage-backend-security-group-rules: "false".

Чтобы балансировщик нагрузки знал, куда направлять трафик, необходимо создать приложение в Kubernetes (deployment). В приложении должна быть указана та же метка, что и в селекторе балансировщика нагрузки (web в данном примере). Если не задать целевое приложение для балансировщика нагрузки, то сервис в Kubernetes и, соответственно, облачный балансировщик нагрузки не будут созданы.

Пример конфигурации Deployment
apiVersion: apps/v1
kind: Deployment
metadata:
   name: webserver
   labels:
     app: web
spec:
   selector:
     matchLabels:
       app: web
   replicas: 2
   template:
     metadata:
       labels:
         app: web
     spec:
       containers:
         - name: webserver
           image: nginx:latest
           ports:
           - containerPort: 80

Настройка кластера Kubernetes для работы с ALB#

Примечание

Если кластер Kubernetes был создан до 27.05.2025, то воспользуйтесь инструкцией по обновлению, чтобы ELB-провайдер поддерживал балансировщик нагрузки приложений.

Конфигурация кластера Kubernetes для работы с ALB имеет некоторые особенности, в частности:

  • в описании Ingress-контроллера необходимо указать DefaultBackend, поскольку балансировщики нагрузки приложений в К2 Облаке в качестве действия по умолчанию поддерживают только пересылку запросов (forward);

  • для балансировки трафика HTTPS в аннотацию для Ingress нужно включить alb.ingress.kubernetes.io/certificate-arn на созданные в IAM сертификаты, иначе ALB не создастся.

Важно

При наличии нескольких подсетей в аннотации для Service необходимо указать подсеть или подсети, где развёрнут кластер Kubernetes (см. пример аннотации в разделе Настройка кластера Kubernetes для работы с NLB).

Для создания балансировщика нагрузки приложений необходимо добавить в Kubernetes следующий манифест:

Пример манифеста с тестовым приложением
---
apiVersion: v1
kind: Namespace
metadata:
  name: game-2048
---
apiVersion: apps/v1
kind: Deployment
metadata:
  namespace: game-2048
  name: deployment-2048
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: app-2048
  replicas: 5
  template:
    metadata:
      labels:
        app.kubernetes.io/name: app-2048
    spec:
      containers:
      - image: public.ecr.aws/l6m2t8p7/docker-2048:latest
        imagePullPolicy: Always
        name: app-2048
        ports:
        - containerPort: 80
---
apiVersion: v1
kind: Service
metadata:
  namespace: game-2048
  name: service-2048
spec:
  ports:
    - port: 80
      targetPort: 80
      protocol: TCP
  type: NodePort
  selector:
    app.kubernetes.io/name: app-2048
---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  namespace: game-2048
  name: ingress-2048
  annotations:
    alb.ingress.kubernetes.io/certificate-arn: arn:c2:iam::randomuuid:server-certificate/test
    alb.ingress.kubernetes.io/scheme: internet-facing
    alb.ingress.kubernetes.io/target-type: instance
    alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS": 443}]'
    alb.ingress.kubernetes.io/subnets: subnet-xxxxxxx,subnet-xxxxxxx,subnet-xxxxxx
  labels:
    app.kubernetes.io/name: app-2048
spec:
  ingressClassName: alb
  defaultBackend:
    service:
      name: service-2048
      port:
        number: 80

Важно

При создании балансировщика нагрузки приложений создаётся отдельная группа безопасности, куда добавляется входящее правило, разрешающее TCP-трафик на порт балансировщика нагрузки с любых IP-адресов (0.0.0.0). Правило транслируется в группу безопасности, которая была автоматически создана вместе с кластером Kubernetes. Данное правило не удаляется после удаления балансировщика и может повторно использоваться при создании нового балансировщика для того же кластера Kubernetes.

Установка ELB-провайдера в собственный кластер Kubernetes#

Если вы самостоятельно развернули кластер Kubernetes в К2 Облаке, то вы также можете использовать облачные балансировщики нагрузки для распределения трафика между его подами. Чтобы установить ELB-провайдер в свой кластер Kubernetes, необходимо выполнить следующие действия (на примере кластера Kubernetes версии 1.30.2):

  1. Добавить в проект пользователя с разрешениями на все действия с инфраструктурным сервисом ec2 и сервисом балансировки нагрузки elb. Вы можете назначить пользователю собственную политику с необходимыми разрешениями, либо готовую политику EKSNLBPolicy или EKSClusterPolicy. Пользователя с политикой EKSClusterPolicy можно задействовать также для работы с провайдерами EBS и Cluster Autoscaler.

  2. Группе безопасности, которая назначена узлам кластера в К2 Облаке, присвойте тег с ключём kubernetes.io/cluster/<имя кластера> и пустым значением.

  3. На каждый узел в кластере (и на присоединяемые впоследствии) установите providerId с помощью команды:

    kubectl patch node <nodename> -p '{"spec": {"providerID": "cloud/<instance-id>"}}'
    
  4. Примените конфигурацию Deployment для менеджера сертификатов:

    kubectl apply -f https://s3.ru-msk.k2.cloud/kaas/latest/deployment/1.30.2/nlb/cert-manager.yaml
    

    Важно

    Прежде чем выполнять дальнейшие действия, необходимо подождать 120 сек. до окончания инициализации менеджера сертификатов.

  5. Скачайте конфигурацию Deployment для секрета NLB:

    https://s3.k2.cloud/kaas/latest/deployment/1.30.2/nlb/nlb-secret.yaml

    Добавьте в неё идентификационные данные ранее созданного пользователя и примените конфигурацию командой:

    kubectl apply -f nlb-secret.yaml
    
  6. Скачайте следующие конфигурации для объектов Deployment:

    Примечание

    В файле deployment_patch.yaml может потребоваться заменить эндпоинты и cluster-name на актуальные. Например, в качестве эндпоинтов для ec2 и elb в регионе ru-spb нужно указать https://api.ru-spb.k2.cloud:443 и https://elb.ru-spb.k2.cloud:443, соответственно. Для региона ru-msk эндпоинты можно оставить без изменения.

    Для применения конфигураций выполните команду:

    kubectl apply -k <directory>
    

    где directory — каталог, куда были загружены файлы.

При успешной установке будут запущены поды с префиксами aws-load-balancer-* и cert-manager-* в имени, после чего с кластером Kubernetes можно будет использовать балансировщик нагрузки К2 Облака.

Cluster Autoscaler#

Сервис Cluster Autoscaler позволяет управлять количеством узлов в группах рабочих узлов в кластере Kubernetes в К2 Облаке. Сервис добавляет узлы в группу рабочих узлов при нехватке ресурсов в ней и удаляет из группы — при избытке. При этом добавление и удаление узлов возможно в пределах заданного минимального и максимального количества узлов в группе рабочих узлов.

../../_images/k8s-CA-logic.png

Схема работы Cluster Autoscaler#

Cluster Autoscaler можно подключить к кластерам Kubernetes как созданным с помощью соответствующего облачного сервиса, так и развёрнутым вами самостоятельно в облачной инфраструктуре.

Ключевые возможности:

  • интеграция с группами Auto Scaling;

  • оптимизация затрат за счёт удаления неиспользуемых узлов;

  • поддержка бюджетов недоступности подов (Pod Disruption Budget, PDB) и корректного завершения работы;

  • работа с узлами, отмеченными для удаления (узлы cordon и drain).

Настройка EKS-кластера для работы с Cluster Autoscaler#

Для работы Cluster Autoscaler в кластере EKS достаточно включить его при создании кластера и указать в качестве пользователя любого пользователя с политикой EKSClusterAutoscalerPolicy или EKSClusterPolicy. Кроме этой политики пользователю не должно быть назначено других политик.

После включения Cluster Autoscaler будет по умолчанию включён для всех групп рабочих узлов кластера.

Переменные окружения для развёртывания#

Переменная

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

Описание

scan-interval

10s

Частота проверки состояния кластера

scale-down-delay-after-add

10m

Задержка перед уменьшением числа узлов после их добавления

scale-down-unneeded-time

10m

Время ожидания перед удалением неиспользуемого узла

scale-down-utilization-threshold

0.5

Порог использования удаляемого узла

max-node-provision-time

15m

Максимальное время ожидания нового узла

balance-similar-node-groups

false

Балансировка узлов между группами

Применить данные параметры к готовому кластеру с Cluster Autoscaler можно, отредактировав раздел конфигурации развёртывания cluster-autoscaler:

kubectl edit deployment/cluster-autoscaler -n kube-system

или выполнив соответствующую команду kubectl patch deployment. Например, чтобы задать новый параметр scan-interval=2s, выполните:

kubectl patch deployment cluster-autoscaler -n kube-system --type='json' -p='[{"op": "replace", "path": "/spec/template/spec/containers/0/command", "value": ["./cluster-autoscaler", "--cloud-provider=aws", "--skip-nodes-with-local-storage=false", "--scan-interval=20s", "--expander=least-waste", "--node-group-auto-discovery=asg:tag=k8s.io/cluster-autoscaler/k8stest01=owned", "--v=5", "--cloud-config=config/cloud.conf"]}]'

Соответственно, в вашем собственном кластере Kubernetes нужные параметры можно задать также в конфигурации развёртывания cluster-autoscaler/deployment.yaml.

Установка Cluster Autoscaler в собственный кластер Kubernetes#

Cluster Autoscaler можно также использовать для управления количеством рабочих узлов в кластере, который вы развернули самостоятельно. Чтобы установить Cluster Autoscaler в собственный кластер Kubernetes, необходимо выполнить следующие действия (на примере кластера Kubernetes версии 1.30.2):

  1. Добавьте в проект пользователя с разрешениями на следующие действия:

    Необходимые разрешения#

    Сервис

    Разрешение

    autoscaling

    DescribeAutoScalingGroups

    autoscaling

    DescribeAutoScalingInstances

    autoscaling

    DescribeLaunchConfigurations

    autoscaling

    DescribeScalingActivities

    autoscaling

    DescribeTags

    autoscaling

    SetDesiredCapacity

    autoscaling

    DetachInstances

    ec2

    DescribeImages

    ec2

    DescribeInstanceTypes

    ec2

    DescribeLaunchTemplateVersions

    ec2

    GetInstanceTypesFromInstanceRequirements

    ec2

    TerminateInstances

    eks

    DescribeNodegroup

    Вы можете назначить пользователю собственную политику с перечисленными разрешениями, либо готовую политику EKSClusterAutoscalerPolicy или EKSClusterPolicy. Пользователя с политикой EKSClusterPolicy можно задействовать также для работы с провайдерами EBS и ELB.

  2. Скачайте следующие конфигурации для объектов Deployment:

  3. Задайте в secret.yaml данные пользователя, созданного выше.

  4. Примените манифест с помощью команды:

    kubectl apply -k <путь до папки с kustomization.yaml>
    

    Если вы находитесь в папке с kustomization.yaml, достаточно выполнить:

    kubectl apply -k .
    

Пример#

Для иллюстрации работы Cluster Autoscaler создадим EKS-кластер с группой рабочих узлов и простое приложение webserver (группу рабочих узлов необходимо создать отдельно, например, в веб-интерфейсе). После создания приложения можно наблюдать автоматическое увеличение количества рабочих узлов в зависимости от параметров группы рабочих узлов. Вы можете поэкспериментировать с параметрами Минимальный объём группы, Максимальный объём группы, Желаемый объём группы, а также количеством реплик приложения (replicas).

Примечание

Пользователя user-eks-autoscaler необходимо создать заранее и назначить ему политику EKSClusterAutoscalerPolicy или EKSClusterPolicy.

Создание EKS-кластера без отказоустойчивости c Cluster Autoscaler на примере Kubernetes v1.33.1
open

import boto3
import os

def main():
    session = boto3.Session(
        aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
        aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
        region_name=""
    )

    eks_client = session.client(
        'eks',
        endpoint_url=os.getenv("EKS_URL"),
        verify=False,
    )

    legacy_parameters = {
        "masterConfig": {
            "highAvailability": False,
            "mastersInstanceType": "m5.large",
            "mastersVolumeType": "gp2",
            "mastersVolumeSize": 64,
            "masterPublicIp": "<your-master-IP>",
        },
        "ingressConfig": {
            "ingressRequired": False,
        },
        "dockerRegistryConfig": {
            "dockerRegistryRequired": False,
        },
        "clusterAutoscalerConfig": {
            "clusterAutoscalerRequired": True,
            "clusterAutoscalerUser": "user-eks-autoscaler"
        }
    }
    resourcesVpcConfig={
        "securityGroupIds": ["sg-xxxxxxxx"],
        "subnetIds": ["subnet-xxxxxxxx"],
    }
    kubernetesNetworkConfig={
        "ipFamily": "ipv4",
    }

    request = {
        "name": "k8s02-api-test",
        "version": "1.33.1",
        "remoteAccessConfig": {"ec2SshKey": "<YOUR-SSH-KEY>"},
        "resourcesVpcConfig": resourcesVpcConfig,
        "kubernetesNetworkConfig": kubernetesNetworkConfig,
        "legacyClusterParams": legacy_parameters,
    }

    clusters = eks_client.create_cluster(**request)

    print(clusters)

if __name__ == '__main__':
    main()
Создание простого приложения webserver в EKS-кластере для тестирования Cluster Autoscaler
open

apiVersion: apps/v1
kind: Deployment
metadata:
  name: webserver
  labels:
    app: web
spec:
  selector:
    matchLabels:
      app: web
  replicas: 6
  template:
    metadata:
      labels:
        app: web
    spec:
      containers:
        - name: webserver
          image: nginx:latest
          ports:
            - containerPort: 80
          resources:
            limits:
              cpu: "400m"
            requests:
              cpu: "200m"

Cluster Autoscaler FAQ#

В этом разделе собрали рекомендации по работе с Cluster Autoscaler и ответы на часто возникающие вопросы.

  1. Как просмотреть события автомасштабирования?

    kubectl get events --field-selector involvedObject.kind=ClusterAutoscaler
    
  2. Как просмотреть логи с фильтрацией?

    kubectl logs deployment/cluster-autoscaler -n kube-system | grep -E "Scale (up|down)"
    
  3. Каковы лучшие практики по использованию Cluster Autoscaler?

    • Запрос ресурсов. Явно указывайте запросы ресурсов (requests) процессора и памяти для всех подов.

    • PodDisruptionBudget. Настройте бюджет недоступности подов для критичных приложений.

    • Headroom. Оставьте буфер ресурсов (10-20%) для непредвиденных нагрузок.

    • Разные группы узлов. Используйте отдельные группы для разных типов рабочей нагрузки.

    • Корректное завершение работы. Убедитесь, что приложения корректно обрабатывают SIGTERM.

    • Тестирование. Проверьте сценарии масштабирования в staging-окружении.

  4. Как отладить проблемы с масштабированием?

    Включите детальные логи:

    kubectl logs deployment/cluster-autoscaler -n kube-system -v=4
    
  5. Как предотвратить слишком частое масштабирование?

    • scale-down-delay-after-add увеличьте до 20-30 минут;

    • scale-down-unneeded-time увеличьте до 15-20 минут;

    • scan-interval увеличьте до 30 секунд.

  6. Почему Cluster Autoscaler не удаляет неиспользуемые узлы?

    Возможные причины:

    • на узле есть поды с safe-to-evict: false;

    • под не имеет ресурсных запросов (requests);

    • нарушен PodDisruptionBudget при удалении;

    • узел содержит системные поды kube-system без аннотации.

  7. Как работает Cluster Autoscaler?

    Работа Cluster Autoscaler основана на собираемой информации о свободных ресурсах на рабочих узлах, а также на информации о ресурсных запросах подов (requests). Если для создаваемого пода не хватает ресурсов на рабочих узлах, Cluster Autoscaler создаст новый рабочий узел в пределах доступного лимита группы Auto Scaling.

  8. Что будет, если Cluster Autoscaler не сможет добавить узлы?

    Cluster Autoscaler будет повторять попытки добавить узлы через определённые интервалы. Проверьте ограничения на количество ресурсов в вашей учётной записи облака.

  9. Можно ли использовать функциональность Cluster Autoscaler в собственных (self-hosted) кластерах Kubernetes?

    Да (см. подробнее).

  10. Может ли Cluster Autoscaler работать с разными типами экземпляров в одной группе Auto Scaling?

    Нет, группа Auto Scaling должна содержать экземпляры только одного типа.

  11. С какой метрикой/метриками работает Cluster Autoscaler?

    Cluster Autoscaler отслеживает метрики использования процессора, памяти и других ресурсов, предоставляемые Kubernetes.

  12. Как использовать Cluster Autoscaler с KEDA?

    KEDA может масштабировать объекты Deployment на основе различных триггеров. Если потребность в ресурсах, создаваемых KEDA, изменится, Cluster Autoscaler соответствующим образом масштабирует кластер. Для этого убедитесь, что KEDA настроен на запрос необходимых ресурсов.

  13. Как сделать так, чтобы Cluster Autoscaler не удалял узлы, на которых запущены важные приложения?

    Используйте PodDisruptionBudget для защиты важных приложений от принудительного удаления.

Kubernetes Dashboard#

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

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

  1. Настройте kubectl согласно инструкции.

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

  3. Получите токен для авторизации в облаке. Информацию о токене для доступа в Kubernetes Dashboard можно найти на вкладке Информация в разделе Кластеры Kubernetes.

    Если у вас нет доступа в К2 Облако или он ограничен, получить токен можно также с помощью команды:

    kubectl -n kubernetes-dashboard get secret $(kubectl -n kubernetes-dashboard get sa/admin-user -o jsonpath="{.secrets[0].name}") -o go-template="{{.data.token | base64decode}}"