Установка#

Установка DropApp#

Все шаги, приведенные в этой инструкции, описывают последовательность действий для установки DropApp на операционные системы Platform V SberLinux OS Server и ОС Альт 8 СП.

Отличия процесса установки DropApp на Platform V SberLinux OS Server в Исполнении «OS Core» от процесса установки в Исполнении «OS Server» приведены в разделе «Установка DropApp на Platform V SberLinux OS Core».

Примечание

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

Развертывание кластера DropApp с помощью Ansible#

Подготовка файла inventory#

Подготовьте файл inventory для playbook развертывания и настройки кластера. Пример файла:

[c01_fstec:children]
; IP pools for c01
; NN.MM.OO.11-20 control planes
; NN.MM.OO.21-30 workers
; NN.MM.OO.41-50 services\shared
c01_fstec_control_plane
c01_fstec_workers
 
[c01_fstec_control_plane]
cp01.c01.example.ru       ansible_host=NN.MM.OO.11
 
[c01_fstec_workers]
w01.c01.example.ru        ansible_host=NN.MM.OO.21
w02.c01.example.ru        ansible_host=NN.MM.OO.22

Файл располагается в каталоге ./inventory.

Генерация сертификатов#

  1. Используйте файл ./certs.sh, чтобы сгенерировать первоначальные сертификаты для Harbor и Dex.

Скрипт сгенерирует сертификаты в папке /tmp.

  1. Перенесите файлы в каталог files/ssl/<file_inventory_group_name>.

    Где: <file_inventory_group_name> - имя группы из файла inventory.

Подготовка файла с параметрами шаблонов#

  1. В каталоге ./group_vars отредактируйте файл с параметрами:

    • укажите диапазон адресов для Metallb;

    • укажите ссылки на образы в стартовом реестре;

    • укажите dns имена для Dex, Grafana, Harbor;

    • пути к сгенерированным ранее сертификатам для Dex, Harbor;

    • адрес IPA сервера и УЗ для подключения.

  2. Отредактируйте файл vars/vars_fstec.yml:

    • укажите ссылки на RPM-пакеты из состава дистрибутива, размещенные в стартовом репозитории;

    • в параметре docker укажите базовый путь до образов в стартовом репозитории:

    # конфигурация кластера
    k8sversion: v1.25.16
    dns_version: v1.9.3
    etcd_version: 3.5.12
    
    # url репозитория с дистрибутивами RPM
    # base_repo_url: <path>/dapp-sl8/14944/x86_64      # без завершающей косой черты
    base_repo_url: <path>/9.0/SBEL_fstec-9.0-20240424.1/sberlinux-9-for-x86_64-dapp-rpms     # без завершающей косой черты
    # ссылки на RPM-пакеты
    kubelet:  "{{ base_repo_url }}/Packages/k/kubelet-1.25.16-dapp1.4.2+1.sl9.2.x86_64.rpm"
    kubectl:  "{{ base_repo_url }}/Packages/k/kubectl-1.25.16-dapp1.4.2+1.sl9.2.x86_64.rpm"
    kubeadm:  "{{ base_repo_url }}/Packages/k/kubeadm-1.25.16-dapp1.4.2+1.sl9.2.x86_64.rpm"
    cri_o:    "{{ base_repo_url }}/Packages/c/cri-o-1.25.4-dapp1.3.0+2.sl9.1.x86_64.rpm"
    helm:     "<path>/packages/golang-helm-3/3.11.1/2.sl8/x86_64/helm-3.11.1-2.sl8.x86_64.rpm"
    iproute_tc: <path>/9.0/SBEL_fstec-9.0-20240424.0/sberlinux-9-for-x86_64-baseos-rpms/Packages/i/iproute-tc-6.2.0-5.sl9.x86_64.rpm
    
    
    # cri-o параметры
    enable_proxy: false
    
    registry: <url>
    # auth_example_registry - аутентификация в частных реестрах example_registry DropApp
    # проверить, что vault_auth_example_registry заполнен в vault.yml и заполнить при необходимости
    auth_example_registry: "{{ vault_auth_example_registry }}"
    
    # docker: хранилище образов для компонентов bootstrap
    docker: "<path>/fstec/1.4.2"                  # без завершающей косой черты
    

    Где:

    • <path> - папка;

    • <url> - адрес ресурса в сети.

  3. В roles/bootstrap_cluster/templates обновите ссылки на образы во всех вложенных файлах.

Автоматическая безопасная установка кластера и компонентов с помощью ansible-ролей#

Для установки компонентов DropApp кластера используйте ansible-роль create-cluster.yml.

Пример запуска:

ansible-playbook -i inventory/dapp.ini -K -l c01_fstec --user <username_with_sudo_rights> create-cluster.yml --check
ansible-playbook -i inventory/dapp.ini -K -l c01_fstec --user <username_with_sudo_rights> create-cluster.yml

Где: <username_with_sudo_rights> - имя пользователя с правами sudo.

Роль устанавливает кластер DropApp и копирует kubelet config в текущую папку.

Используйте следующие команды, чтобы загрузить конфигурацию и проверить состояние pods:

export KUBECONFIG=$(pwd)/config
kubectl get pod -A

Пример вывода на этом этапе:

NAMESPACE     NAME                                            READY   STATUS              RESTARTS   AGE
kube-system   coredns-66898788b6-jl9pq                        0/1     ContainerCreating   0          49s
kube-system   coredns-66898788b6-xdnr5                        0/1     ContainerCreating   0          49s
kube-system   etcd-cp01.c01.example.ru                      1/1     Running             3          65s
kube-system   kube-apiserver-cp01.c01.example.ru            1/1     Running             3          64s
kube-system   kube-controller-manager-cp01.c01.example.ru   1/1     Running             3          66s
kube-system   kube-scheduler-cp01.c01.example.ru            1/1     Running             3          65s

Pods coredns на этом этапе не запущены.

Установка bootstrap-роли#

Установите bootstrap-роль bootstrap-cluster.yml:

ansible-playbook -i inventory/dapp.ini -K -l c01_fstec --user <username_with_sudo_rights> bootstrap-cluster.yml --check
ansible-playbook -i inventory/dapp.ini -K -l c01_fstec --user <username_with_sudo_rights> bootstrap-cluster.yml

Пример вывода команды kubectl get pods -A после установки:

NAMESPACE           NAME                                             READY   STATUS      RESTARTS        AGE
cert-manager        cert-manager-784b58f48-vmgpg                     1/1     Running     0               3m42s
cert-manager        cert-manager-cainjector-6c9c57dc65-6ccjc         1/1     Running     0               3m42s
cert-manager        cert-manager-webhook-666dc48d64-b9mz9            1/1     Running     0               3m42s
connaisseur         connaisseur-deployment-67c9f57fdd-b8dqr          1/1     Running     0               4m13s
connaisseur         connaisseur-deployment-67c9f57fdd-hsktj          1/1     Running     0               4m13s
connaisseur         connaisseur-deployment-67c9f57fdd-zwsdc          1/1     Running     0               4m13s
dex                 dex-865bfb57fb-d2gvx                             1/1     Running     0               8m8s
gatekeeper-system   gatekeeper-audit-7f6fb9b648-wvp4s                1/1     Running     2 (6m54s ago)   7m2s
gatekeeper-system   gatekeeper-controller-manager-7b85c67f8d-b86st   1/1     Running     0               7m2s
gatekeeper-system   gatekeeper-controller-manager-7b85c67f8d-c62zq   1/1     Running     0               7m2s
gatekeeper-system   gatekeeper-controller-manager-7b85c67f8d-xbplq   1/1     Running     0               7m2s
harbor              harbor-core-5f7799df46-kgzcv                     1/1     Running     0               4m31s
harbor              harbor-database-0                                1/1     Running     0               4m31s
harbor              harbor-jobservice-656d4547cb-hb8qg               1/1     Running     1 (4m ago)      4m31s
harbor              harbor-portal-66f8bcf87b-g8wlw                   1/1     Running     0               4m31s
harbor              harbor-redis-0                                   1/1     Running     0               4m31s
harbor              harbor-registry-6d74d69d47-9k9s8                 2/2     Running     0               4m31s
harbor              harbor-trivy-0                                   1/1     Running     0               4m31s
ingress-nginx       ingress-nginx-admission-create-twwkp             0/1     Completed   0               8m52s
ingress-nginx       ingress-nginx-admission-patch-hqsg4              0/1     Completed   1               8m52s
ingress-nginx       ingress-nginx-controller-7995cbbc8c-mvctn        1/1     Running     0               8m52s
kube-system         cilium-46l66                                     1/1     Running     0               9m38s
kube-system         cilium-58lph                                     1/1     Running     0               9m38s
kube-system         cilium-operator-b8dc9d6cc-98qx6                  1/1     Running     0               9m38s
kube-system         cilium-operator-b8dc9d6cc-zldcr                  1/1     Running     0               9m38s
kube-system         cilium-rqzrq                                     1/1     Running     0               9m38s
kube-system         coredns-66898788b6-jl9pq                         1/1     Running     0               11m
kube-system         coredns-66898788b6-xdnr5                         1/1     Running     0               11m
kube-system         etcd-cp01.c01.example.ru                       1/1     Running     3               11m
kube-system         hubble-relay-76c58d5fcc-2hh28                    1/1     Running     0               9m38s
kube-system         hubble-ui-55c8f9bbcc-5xvxd                       2/2     Running     0               9m38s
kube-system         kube-apiserver-cp01.c01.example.ru             1/1     Running     3               11m
kube-system         kube-controller-manager-cp01.c01.example.ru    1/1     Running     3               11m
kube-system         kube-scheduler-cp01.c01.example.ru             1/1     Running     3               11m
kube-system         okd-console-deployment-5c4db497c8-bcqk9          1/1     Running     0               8m28s
logging             loki-0                                           1/1     Running     0               2m30s
logging             loki-alertmanager-0                              1/1     Running     0               2m30s
logging             loki-grafana-748bff6fb7-h7b9h                    1/1     Running     0               2m30s
logging             loki-promtail-4tf9z                              1/1     Running     0               2m30s
logging             loki-promtail-dxbzl                              1/1     Running     0               2m30s
logging             loki-promtail-zx7lf                              1/1     Running     0               2m30s
metallb-system      controller-798f989b7b-x2zxf                      1/1     Running     0               9m10s
metallb-system      speaker-7827j                                    1/1     Running     0               9m10s
metallb-system      speaker-bw9dr                                    1/1     Running     0               9m10s
metallb-system      speaker-rkfdm                                    1/1     Running     0               9m10s
trivy-system        scan-vulnerabilityreport-5bcdc96c49-xl7tq        0/1     Init:0/1    0               2m26s
trivy-system        trivy-operator-b99c465cd-sh7xw                   1/1     Running     0               7m34s

Перенастройка приложений на использование образов из Harbor#

После установки, при выполнении ansible-роли boostrap_cluster, приложения Harbor, Loki, Grafana AlertManager разворачиваются с использованием томов EmptyDir. Для промышленной эксплуатации необходимо переконфигурировать их на использование постоянных томов - Persistent Volumes.

Для этого необходимо:

  1. Установить и настроить StorageProvider. В составе DropApp используется Trident, при необходимости можно использовать иной адаптер.

  2. Зарегистрировать StorageClass.

  3. Настроить Persistent Volume Claims для использования StorageClass Persistent Volumes.

Установка DropApp на Platform V SberLinux OS Core#

Установка DropApp на Platform V SberLinux OS Core выполняется аналогичным образом, как на Platform V SberLinux OS Server, за исключением установки RPM-пакетов DropApp.

Подробнее про безопасную настройку SberLinux OS Core смотрите в документе «ОС «Platform V SberLinux OS Server». Руководство по установке».

Установка дополнительных Node в кластер DropApp#

Установка дополнительных Node в кластер DropApp приведена на примере установки ОС Альт 8 СП на Node.

Подготовка пакетов для развертывания кластера DropApp на ОС Альт 8 СП#

Примечание

В приведенном сценарии все команды должны выполняться с правами пользователя с административными полномочиями root.

ОС Альт 8 СП поддерживает работу с RPM-пакетами.

Для добавления ОС Альт 8 СП в качестве Worker Node в существующий кластер DropApp используйте пакеты:

  • cri-o_alt-<component_version>.rpm;

  • cri-tools-alt-<component_version>.rpm;

  • kubernetes-client-alt-<component_version>.rpm;

  • kubernetes-common-alt-<component_version>.rpm;

  • kubernetes-crio-alt-<component_version>.rpm;

  • kubernetes-kubeadm-alt-<component_version>.rpm;

  • kubernetes-kubelet-alt-<component_version>.rpm;

  • kubernetes-node-alt-<component_version>.rpm.

Где: <component_version> - версия компонента.

Подготовка кластера к установке#

Для подготовки кластера к установке выполните следующие шаги:

  1. Переименуйте host-сервер:

    hostnamectl set-hostname <newhostname>
    

    Где: <newhostname> - новое имя хоста.

    Если новое имя не начнет использоваться, введите команду:

    systemctl restart systemd-hostnamed
    

    Для просмотра статуса воспользуйтесь командой:

    hostnamectl status
    
  2. Отключите использование swap:

    • отключите использование swap на каждой виртуальной машине, для этого введите команду:

      swapoff -a
      
    • удалите из конфигурационного файла /etc/fstab все строки, которые содержат swap:

      sed -i '/swap/d' /etc/fstab
      
    • отключите службу dev-sda3.swap, которая создает unit, воспроизводящий swap в конфигурационном файле /etc/fstab при перезагрузке:

      systemctl umask dev-sda3.swap
      

      Где sda3 - актуальный раздел swap жесткого диска, по умолчанию номер раздела - 3.

    При использовании системы управления конфигурациями Ansible, отключение использования swap настроено в ansible-роли и происходит автоматически при развертывании кластера DropApp.

    Примечание

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

  3. Подключите официальные репозитории ОС Альт 8 СП:

    • очистите подключенные репозитории, удалив файлы из каталога sources.list.d:

      rm -rf /etc/apt/sources.list.d/*
      
    • подключите официальные репозитории:

      cat > /etc/apt/sources.list.d/altofficial.list  <<EOF
          rpm http://ftp.altlinux.org/pub/distributions/ALTLinux p10/branch/x86_64 classic
          rpm http://ftp.altlinux.org/pub/distributions/ALTLinux p10/branch/x86_64-i586 classic
          rpm http://ftp.altlinux.org/pub/distributions/ALTLinux p10/branch/noarch classic
      EOF
      
    • обновите базы данных пакетов:

      apt-get update
      

Установка компонентов#

  1. Установите зависимости:

    apt-get install -y containers-common runc cni-plugins conntrack-tools socat conmon ebtables
    
  2. Установите компоненты:

    rpm -ivh cri-o_alt-<component_version>.rpm
    rpm -ivh cri-tools-alt-<component_version>.rpm
    rpm -ivh kubernetes-client-alt-<component_version>.rpm
    rpm -ivh kubernetes-common-alt-<component_version>.rpm
    rpm -ivh kubernetes-crio-alt-<component_version>.rpm
    rpm -ivh kubernetes-kubeadm-alt-<component_version>.rpm
    rpm -ivh kubernetes-kubelet-alt-<component_version>.rpm
    rpm -ivh kubernetes-node-alt-<component_version>.rpm
    

    Где: <component_version> - версия компонента.

  3. Разрешите автозапуск Cri-O:

    systemctl enable --now crio kubelet
    
  4. Настройте доступ к приватному репозиторию:

    cat > /var/lib/kubelet/config.json   <<EOF 
    {
        "auths": {
            "<registry_adress>": {
                "auth": "***********"
            }
        }
    }
    EOF
    

    Где: <registry_adress> - регистрационный адрес.

  5. Настройте Cri-O в файле crio.conf:

    cat > /etc/crio/crio.conf   <<EOF  
     
    [crio]
    [crio.api]
    [crio.runtime]
    selinux = true
    [crio.image]
    registries = [
    "<registry_adress>"
    ]
    insecure_registries = [
    ]
    global_auth_file = "/var/lib/kubelet/config.json"
    pause_image = "<registry_adress>/fstec/1.4.2/dapp-kubernetes-2/pause:3.8"
    pause_image_auth_file = "/var/lib/kubelet/config.json"
    [crio.network]
    plugin_dirs = [
    "/opt/cni/bin",
    "/usr/libexec/cni",
    ]
    [crio.metrics]
    enable_metrics = true
    metrics_port = 9537
    [crio.tracing]
    [crio.stats]
    selinux = true
    plugin_dirs = [
    "/opt/cni/bin",
    "/usr/libexec/cni",
    ]
    EOF
    
  6. Перезапустите Cri-O:

    systemctl restart crio
    
  7. Перезапустите Kubelet:

    systemctl restart kubelet
    

Установка DropApp на ОС Альт 8 СП#

Для установки DropApp на ОС Альт 8 СП необходимо подключить Worker Node в кластер DropApp, для этого выполните следующие действия:

  1. На Master Node сгенерируйте временный токен и команду присоединения Worker Node к кластеру:

    kubeadm token create --print-join-command
    

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

    kubeadm join <kubeAPI_URL> --token <token> --discovery-token-ca-cert-hash sha256:<hash>
    

    Где:

    • <kubeAPI URL> — URL API-сервера вида IP-адрес:порт;

    • <token> — токен присоединения;

    • <hash> — хеш открытого ключа корневого центра сертификации (CA).

  2. На Worker Node ОС Альт 8 СП выполните команду присоединения к кластеру DropApp:

    kubeadm join <the_join_command_from_the_previous_step>
    
  3. На Master Node проверьте подключение:

    kubectl get nodes
    

Ручная установка компонентов, не установленных с помощью ansible-ролей#

Установка Apiserver-network-proxy#

Для установки Apiserver-network-proxy выполните следующие шаги:

  1. Создайте Deployme

  2. nt для Apiserver-network-proxy. Пример YAML-файла для Deployment:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: apiserver-network-proxy
    spec:
      selector:
        matchLabels:
          app: apiserver-network-proxy
      replicas: 1
      template:
        metadata:
          labels:
            app: apiserver-network-proxy
        spec:
          containers:
          - name: apiserver-network-proxy
            image: quay.io/coreos/apiserver-network-proxy:v0.0.1
            ports:
            - containerPort: 443
            env:
            - name: POD_NAME
              valueFrom:
                fieldRef:
                  fieldPath: metadata.name
            - name: POD_NAMESPACE
              valueFrom:
                fieldRef:
                  fieldPath: metadata.namespace
            - name: SERVICE_CERTIFICATE_FILE
              value: "/etc/certs/tls.crt"
            - name: SERVICE_KEY_FILE
              value: "/etc/certs/tls.key"
            volumeMounts:
            - mountPath: /etc/certs
              name: tls-certs
          volumes:
          - name: tls-certs
            secret:
              secretName: apiserver-network-proxy-tls
    

    В этом примере предполагается, что уже есть секрет с именем apiserver-network-proxy-tls, который содержит сертификаты и ключи для TLS. Если нет, необходимо создать его перед шагом 1.

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

    kubectl apply -f deployment.yaml
    

Установка ConfigMap-reload#

Для установки ConfigMap-reload выполните следующие шаги:

  1. Создайте новый ConfigMap, который будет содержать конфигурационные файлы. Это можно сделать с помощью следующей команды:

    kubectl create configmap my-config-map --from-file=./my-config.yml=/etc/my-app/config.yml
    

    Где:

    • my-config-map - это имя ConfigMap;

    • my-config.yml - это файл конфигурации, который хотите загрузить;

    • /etc/my-app/config.yml - это путь внутри контейнера, куда будет загружен файл.

  2. Создайте Deployment для ConfigMap-reload, который будет следить за изменениями в ConfigMap и перезагружать конфигурационный файл. Например:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: configmap-reload
    spec:
      selector:
        matchLabels:
          app: configmap-reload
      replicas: 1
      template:
        metadata:
          labels:
            app: configmap-reload
        spec:
          containers:
          - name: configmap-reload
            image: quay.io/crunchydata/configmap-reload:v0.12.0
            command: ["/bin/sh", "-c", "while :; do configmap-reload /etc/my-app/config.yml; sleep 1; done"]
            volumeMounts:
              - mountPath: /etc/my-app
                name: config-volume
          volumes:
            - name: config-volume
              configMap:
                name: my-config-map
    
  3. Примените Deployment с помощью команды:

    kubectl apply -f deployment.yaml
    

Установка CSI-external-attacher#

Для развертывания CSI-external-attacher выполните следующие шаги:

  1. Создайте новую учетную запись службы и предоставьте ей права для запуска CSI-external-attacher.

  2. Разверните CSI-external-attacher:

    kubectl create deploy/CSI-external-attacher.yaml
    

Вышеприведенная команда - для создания развертывания в DropApp. В данном случае, команда создает deployment, который запускает контейнер с драйвером DropApp.

CSI-external-attacher может работать в одном pod с другими внешними контроллерами CSI, такими как CSI-external-provisioner, CSI-external-snapshotter и CSI-external-resizer.

Установка CSI-external-resizer#

Для развертывания CSI-external-resizer выполните следующие шаги:

  1. Создайте новую учетную запись службы и предоставьте ей права для запуска CSI-external-resizer.

  2. Разверните CSI-external-resizer:

    kubectl create deploy/CSI-external-resizert.yaml
    

    Содержание манифеста будет следующим:

    CSI-external-resizer.yaml
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: csi-resizer
    spec:
      replicas: 1
      selector:
        matchLabels:
          external-resizer: mock-driver
      template:
        metadata:
          labels:
            external-resizer: mock-driver
        spec:
          serviceAccount: csi-resizer
          containers:
            - name: csi-resizer
              image: dappregistry/1.2/csi-resizer
              args:
                - "--v=5"
                - "--csi-address=$(ADDRESS)"
                - "--leader-election"
                - "--http-endpoint=:8080"
              env:
                - name: ADDRESS
                  value: /var/lib/csi/sockets/pluginproxy/mock.socket
              imagePullPolicy: "IfNotPresent"
              ports:
                - containerPort: 8080
                  name: http-endpoint
                  protocol: TCP
              livenessProbe:
                failureThreshold: 1
                httpGet:
                  path: /healthz/leader-election
                  port: http-endpoint
                initialDelaySeconds: 10
                timeoutSeconds: 10
                periodSeconds: 20
              volumeMounts:
                - name: socket-dir
                  mountPath: /var/lib/csi/sockets/pluginproxy/
    
            - name: mock-driver
             image: quay.io/k8scsi/mock-driver:canary
              imagePullPolicy: "IfNotPresent"
             env:
                - name: CSI_ENDPOINT
                  value: /var/lib/csi/sockets/pluginproxy/mock.socket
              volumeMounts:
                - name: socket-dir
                  mountPath: /var/lib/csi/sockets/pluginproxy/
    
          volumes:
            - name: socket-dir
              emptyDir:
    

Вышеприведенная команда - для создания deployment в DropApp. Deployment - это объект DropApp, который представляет собой развертывание приложения на нескольких nodes. В этом случае Deployment используется для развертывания драйвера DropApp на нескольких nodes кластера.

CSI-external-resizer может работать в одном pod с другими внешними контроллерами CSI, такими как CSI-external-attacher, **CSI-external-snapshotter и/или CSI-external-provisioner.

Установка CSI-external-snapshotter#

Для развертывания CSI-external-snapshotter выполните следующие шаги:

  1. Создайте новую учетную запись службы и предоставьте ей права для запуска CSI-external-snapshotter.

  2. Разверните CSI-external-snapshotter:

    kubectl create deploy/CSI-external-snapshotter.yaml
    

    Содержание манифеста будет следующим:

    CSI-external-snapshotter.yaml
    kind: StatefulSet
    apiVersion: apps/v1
    metadata:
      name: csi-snapshotter
    spec:
      serviceName: "csi-snapshotter"
      replicas: 1
      selector:
        matchLabels:
          app: csi-snapshotter
      template:
        metadata:
          labels:
            app: csi-snapshotter
        spec:
          serviceAccount: csi-snapshotter
          containers:
            - name: csi-provisioner
              image: dappregistry/csi-provisioner
              args:
                - "--v=5"
                - "--csi-address=$(ADDRESS)"
              env:
                - name: ADDRESS
                  value: /csi/csi.sock
              imagePullPolicy: IfNotPresent
              volumeMounts:
                - name: socket-dir
                  mountPath: /csi
            - name: csi-snapshotter
              image: dappregistry/csi-snapshotter
              args:
                - "--v=5"
                - "--csi-address=$(ADDRESS)"
                - "--leader-election=false"
              env:
                - name: ADDRESS
                  value: /csi/csi.sock
              imagePullPolicy: IfNotPresent
              volumeMounts:
                - name: socket-dir
                  mountPath: /csi
            - name: hostpath
              image: k8s.gcr.io/sig-storage/hostpathplugin
              args:
                - "--drivername=hostpath.csi.k8s.io"
                - "--v=5"
                - "--endpoint=$(CSI_ENDPOINT)"
                - "--nodeid=$(KUBE_NODE_NAME)"
              env:
                - name: CSI_ENDPOINT
                  value: unix:///csi/csi.sock
                - name: KUBE_NODE_NAME
                  valueFrom:
                    fieldRef:
                      apiVersion: v1
                      fieldPath: spec.nodeName
              imagePullPolicy: IfNotPresent
              securityContext:
                privileged: true
              volumeMounts:
                - name: socket-dir
                  mountPath: /csi
          volumes:
            - name: socket-dir
              emptyDir:
    

Вышеприведенная команда - для создания StatefulSet в DropApp.

Установка CSI-node-driver-registrar#

Для регистрации CSI Driver выполните следующие шаги:

  1. Получите доступ к сокету драйвера CSI (путь: /var/lib/kubelet/plugins/<drivername.example.com>/).

  2. Получите доступ к регистрационному сокету (путь: /var/lib/kubelet/plugins_registry/). Убедитесь, что плагин для регистрации доступен на хосте, на котором запущен DropApp. Обычно это можно проверить, выполнив команду kubectl get pods -n kube-system. Если виден pod с именем etcd-<host_name>, то плагин доступен.

  3. Проверьте работоспособность CSI-node-driver-registrar:

      containers:
        - name: csi-driver-registrar
          image: dappregistry/sig-storage/csi-node-driver-registrar
          args:
            - "--v=5"
            - "--csi-address=/csi/csi.sock"
            - "--kubelet-registration-path=/var/lib/kubelet/plugins/<drivername.example.com>/csi.sock"
          livenessProbe:
            exec:
              command:
              - /csi-node-driver-registrar
              - --kubelet-registration-path=/var/lib/kubelet/plugins/<drivername.example.com>/csi.sock
              - --mode=kubelet-registration-probe
            initialDelaySeconds: 30
            timeoutSeconds: 15
    

    Выше приведена конфигурация контейнера для DropApp, который используется для регистрации DropApp CSI Driver. В контейнере используется образ Docker, он содержит программу CSI-node-driver-registrar, которая регистрирует DropApp CSI Driver в кластере.

    Контейнер используется для запуска программы для регистрации драйвера DropApp. Драйвер - это компонент, который позволяет nodes DropApp подключаться к блочным устройствам, таким как диски или сетевые хранилища. В данном случае, контейнер используется для регистрации драйвера DropApp в системе.

    Флаг --mode=kubelet-registration-probe модифицирует CSI-node-driver-registrar в зонд, проверяющий, прошла ли регистрация подключаемого модуля kubelet успешно. Значение --kubelet-registration-path должно быть таким же, как задано в аргументах контейнера, --csi-address в этом режиме не требуется.

    Если --http-endpoint установлено, то CSI-node-driver-registrar предоставляет конечную точку проверки работоспособности по указанному адресу и пути /healthz, указывая, существует ли сокет регистрации.

  4. Примените спецификацию:

          containers:
            - name: csi-driver-registrar
              image: /sig-storage/csi-node-driver-registrar
              args:
                - "--csi-address=/csi/csi.sock"
                - "--kubelet-registration-path=/var/lib/kubelet/plugins/<drivername.example.com>/csi.sock"
                # Адрес не является существующим и приведен в качестве примера.
                - "--health-port=9809"
              volumeMounts:
                - name: plugin-dir
                  mountPath: /csi
                - name: registration-dir
                  mountPath: /registration
              ports:
                - containerPort: 9809
                  name: healthz
              livenessProbe:
                httpGet:
                  path: /healthz
                  port: healthz
                initialDelaySeconds: 5
                timeoutSeconds: 5
          volumes:
            - name: registration-dir
              hostPath:
                path: /var/lib/kubelet/plugins_registry/
                type: Directory
            - name: plugin-dir
              hostPath:
                path: /var/lib/kubelet/plugins/<drivername.example.com>/
                # Адрес не является существующим и приведен в качестве примера.
                type: DirectoryOrCreate
    

Выше представлен контейнер для DropApp, используемый для регистрации DropApp Controller Manager в кластере DropApp. В конфигурации контейнера используется образ Docker с программой CSI-node-driver-registrar. Контейнер также содержит два тома - /csi и /registration, которые используются для хранения данных регистрации DropApp Controller. Порт 9809 используется для проверки работоспособности контейнера. Liveness Probe проверяет работоспособность контейнера каждые 5 секунд.

Установка CSI-external-provisioner#

Следуйте последовательности действий, чтобы настроить поддержку емкости хранилища:

  1. Установите переменные среды POD_NAME и NAMESPACE:

    env:
    - name: NAMESPACE
      valueFrom:
      fieldRef:
      fieldPath: metadata.namespace
    - name: POD_NAME
      valueFrom:
      fieldRef:
      fieldPath: metadata.name
    
  2. Примените манифест:

    CSI-external-provisioner.yaml
    kind: Deployment
    apiVersion: apps/v1
    metadata:
      name: csi-provisioner
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: csi-provisioner
      template:
        metadata:
          labels:
            app: csi-provisioner
        spec:
          serviceAccount: csi-provisioner
          containers:
            - name: csi-provisioner
              image: dappregistry/1.2/csi-provisioner
              args:
                - "--csi-address=$(ADDRESS)"
                - "--leader-election"
                - "--http-endpoint=:8080"
              env:
                - name: ADDRESS
                  value: /var/lib/csi/sockets/pluginproxy/mock.socket
              imagePullPolicy: "IfNotPresent"
              volumeMounts:
                - name: socket-dir
                  mountPath: /var/lib/csi/sockets/pluginproxy/
              ports:
                - containerPort: 8080
                  name: http-endpoint
                  protocol: TCP
              livenessProbe:
                failureThreshold: 1
                httpGet:
                  path: /healthz/leader-election
                  port: http-endpoint
                initialDelaySeconds: 10
                timeoutSeconds: 10
                periodSeconds: 20
            - name: mock-driver
              image: quay.io/k8scsi/mock-driver:canary
              env:
                - name: CSI_ENDPOINT
                  value: /var/lib/csi/sockets/pluginproxy/mock.socket
              volumeMounts:
                - name: socket-dir
                  mountPath: /var/lib/csi/sockets/pluginproxy/
          volumes:
            - name: socket-dir
              emptyDir:
    
  3. Добавьте в командную строку флаг --enable-capacity.

  4. Добавьте StorageCapacity: true в информационный объект CSI Driver.

  5. Если в CSI-external-provisioner не развернут StatefulSet, настройте при помощи флага --capacity-ownerref-level какими объектами будет происходить управление CSIStorageCapacity.

  6. Настройте частоту опроса драйвера для обнаружения измененной емкости хранилища с помощью флага --capacity-poll-interval.

  7. Настройте количество рабочих потоков, используемых параллельно, с помощью флага --capacity-threads.

  8. Включите создание информации также для классов хранения, которые используют немедленную привязку тома с файлом, с помощью флага --capacity-for-immediate-binding.

Установка Curl#

Для установки Curl, выполните команду:

kubectl run -it --image=exemple regisry/curl:8.5.0 --restart=Never

Убедитесь, что pod curl создан:

kubectl get pods

В выводе отобразится запись curl --for condition=Ready.

Установка Envoy proxy#

Сценарий развертывания Envoy proxy в качестве балансировщика нагрузки перед службой headless service:

  1. Создайте сервис headless service со следующим YAML-файлом:

    apiVersion: v1
    kind: Service
    metadata:
      name: myapp
    spec:
      clusterIP: None
      ports:
      - name: HTTP
        port: 80
        targetPort: HTTP
        protocol: TCP
      selector:
        app: myapp
    

    Pods имеют метку appсо с именем myapp.

    Сервис headless service не предоставляет один IP-адрес и балансировку нагрузки для pods, имеет конфигурацию DNS с IP-адресом для всех pods, соответствующих селектору меток. Этот тип службы предназначен для использования в сценариях реализации балансировки нагрузки и самостоятельной поддержки соединения с pods.

  2. Проверьте записи DNS для сервиса внутри кластера DropApp:

    nslookup myapp
    

    В выводе отобразится:

    Server:         0.0.0.0
    Address:        0.0.0.0.10#53
    
    Non-authoritative answer:
    Name:   myapp.namespace.svc.cluster.local
    Address: 0.0.0.0
    Name:   myapp.namespace.svc.cluster.local
    Address: 0.0.0.0
    Name:   myapp.namespace.svc.cluster.local
    Address: 0.0.0.0
    

    В приведенном сценарии выведены отдельные записи с IP-адресами для трех pods в сводке DNS.

  3. Примените файл манифеста, выполните команду:

    kubectl apply -f ./dapp-envoy-proxy-deployment.yaml
    

    Содержание манифеста будет следующим:

    dapp-envoy-proxy-deployment.yaml
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: app-test-configmap
      labels:
        app: app-test-envoy
    data:
      envoy.yaml: |
        # Простая завершающая конфигурация Sidecar Envoy TLS 1.2.
        static_resources:
          listeners:
          - address:
              socket_address:
                address: 0.0.0.0
                port_value: 8080
            filter_chains:
            - filters:
              - name: envoy.filters.network.HTTP_connection_manager
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.network.HTTP_connection_manager.v3.HTTPConnectionManager
                  codec_type: AUTO
                  stat_prefix: ingress_HTTP
                  route_config:
                    name: local_route
                    virtual_hosts:
                    - name: service
                      domains: ["*"]
                      routes:
                      - match: { prefix: "/" }
                        route: { cluster: local_service_app }
                  HTTP_filters:
                  - name: envoy.filters.HTTP.router
                    typed_config: 
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
          clusters:
          - name: local_service_app
            connect_timeout: 0.25s
            type: STRICT_DNS
            lb_policy: ROUND_ROBIN
            load_assignment:
              cluster_name: local_service_app
              endpoints:
              - lb_endpoints:
                - endpoint:
                    address:
                      socket_address:
                        address: app-test-service.default.svc.cluster.local
                        port_value: 80
        admin:
          access_log_path: /dev/null
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 8082
    

    Флаг type: STRICT_DNS указывает тип обнаружения службы.

    Флаг lb_policy: LEAST_REQUEST позволяет выбрать различные алгоритмы балансировки из типов ROUND_ROBIN и LEAST_REQUEST.

    Флаг hosts: [{ socket_address: { address: myapp, port_value: 80 }}] указывает в поле address на доменное имя, с которого Envoy proxy должен получить записи для маршрутизации.

  4. Убедитесь в том, что deployment успешно получен:

    kubectl rollout status deployment.apps/sidecar-test-deploy -n default
    
  5. Внесите содержание манифестов в dapp-envoy-proxy-deployment.yaml:

    Ниже приведен фрагмент кода YAML-файла для развертывания приложения с названием app-test с тремя репликами. В этом приложении используется образ Ingress-nginx, и контейнер имеет порт HTTP на порту 80.

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: app-test-deploy
      labels:
        app: app-test
    spec:
      replicas: 3
      selector:
        matchLabels:
          app: app-test
      template:
        metadata:
          name: app-test-pod
          labels:
            app: app-test
        spec:
          containers:
            # Приложение было спроксировано.
            - name: app-test
              image: "nginx"
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
    

    Ниже представлен фрагмент кода из YAML-файла, который описывает кластерную службу для приложения app-test. Служба предоставляет доступ к приложению через порт 80 и имеет тип ClusterIP, что означает, что она доступна только внутри кластера. В файле также указаны метки и селектор для службы, которые позволяют ей быть найденной и управляемой в DropApp.

    apiVersion: v1
    kind: Service
    metadata:
      name: app-test-envoy-service
      labels:
        app: app-test-envoy
    spec:
      type: NodePort
      selector:
        app: app-test-envoy
      ports:
        - port: 8080
          targetPort: 8080
          nodePort: 3000
    

    Ниже приведен фрагмент кода YAML-файла для развертывания приложения Envoy proxy. Приложение использует образ Docker с именем example и контейнером app-test-envoy. Контейнер имеет один порт HTTP, который настроен на прослушивание на порту 8080. Контейнер также использует файл конфигурации /etc/envoy, который хранится в конфигурации DropApp.

    example-app-test-envoy.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: sidecar-test-deploy
      labels:
        app: sidecar-test
    spec:
      selector:
        matchLabels:
          app: sidecar-test
      template:
        metadata:
          name: sidecar-test-pod
          labels:
            app: sidecar-test
        spec:
          containers:
            # The application being proxied.
            - name: app
              image: "nginx"
              ports:
                - name: http
                  containerPort: 80
                  protocol: TCP
            # The sidecar.
            - name: sidecar
              image: dappregistry/envoy:distroless
              ports:
                - name: http
                  containerPort: 8080
                  protocol: TCP
              volumeMounts:
                - name: sidecar-config
                  mountPath: "/etc/envoy"
                  readOnly: true
          volumes:
            - name: app-config
              configMap:
                name: sidecar-test-configmap
    

    Ниже представлена конфигурация для Envoy proxy, которая используется для обработки запросов к серверу.

    Где:

    • apiVersion указывает на версию API, которой должна соответствовать конфигурация. В данном случае это v1;

    • kind указывает на тип объекта конфигурации. В данном случае это ConfigMap;

    • metadata содержит информацию о конфигурации, такую как имя и метки;

    • data содержит содержимое конфигурации, в данном случае файл envoy.yaml;

    • static_resources - это раздел конфигурации, который определяет статические ресурсы, такие как фильтры и слушатели;

    • listeners - это список слушателей, которые обрабатывают запросы. Каждый слушатель определяет адрес, на который будет отправлен запрос, и настройки фильтрации;

    • filter_chains - это раздел, который определяет, какие фильтры должны быть применены к запросу. В данном примере используется фильтр Envoy proxy для обработки HTTP-запросов;

    • name и typed_config определяют параметры фильтра;

    • route_config - это раздел, определяющий маршрутизацию запросов;

    • domains - это список доменов, к которым будет применяться маршрутизация;

    • routes - это список маршрутов, которые будут применены к запросам. Каждый маршрут определяет префикс запроса, который должен соответствовать, и действия, которые должны быть выполнены.

    В целом, данная конфигурация определяет настройки Envoy proxy для обработки запросов к серверу, который расположен на адресе 0.0.0.0 и прослушивает порт 8080.

    Настройки Envoy proxy для обработки запросов к серверу
    apiVersion: v1
    kind: ConfigMap
    metadata:
      name: sidecar-test-configmap
      labels:
        app: sidecar-test
    data:
      envoy.yaml: |
        static_resources:
          listeners:
          - address:
              socket_address:
                address: 0.0.0.0
                port_value: 8080
            filter_chains:
            - filters:
              - name: envoy.filters.network.http_connection_manager
                typed_config:
                  "@type": type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
                  codec_type: AUTO
                  stat_prefix: ingress_http
                  route_config:
                    name: local_route
                    virtual_hosts:
                    - name: service
                      domains: ["*"]
                      routes:
                      - match: { prefix: "/" }
                        route: { cluster: local_service }
                  http_filters:
                  - name: envoy.filters.http.router
                    typed_config: 
                      "@type": type.googleapis.com/envoy.extensions.filters.http.router.v3.Router
          clusters:
          - name: local_service
            connect_timeout: 0.25s
            type: STATIC
            lb_policy: ROUND_ROBIN
            load_assignment:
              cluster_name: local_service
              endpoints:
              - lb_endpoints:
                - endpoint:
                    address:
                      socket_address:
                        address: 127.0.0.1
                        port_value: 80
        admin:
          access_log_path: /dev/null
          address:
            socket_address:
              address: 0.0.0.0
              port_value: 8082
    
  6. Перенаправьте существующий порт на локальный:

    kubectl port-forward service/sidecar-test-service -n default --address localhost 8099:8080
    
  7. Введите команду для просмотра локального порта:

    Curl localhost:8099
    
  8. Проверьте, что выходные данные возвращают страницу nginx, а прокси-сервер является Envoy proxy.

Установка Hubble export stdout#

Hubble Exporter включается с помощью свойств ConfigMap. Он отключен, пока не будет задано значение пути к файлу для параметра hubble-export-file-path.

  1. Используйте Helm для установки Cilium с включенным Hubble Exporter:

    helm install Cilium ./Cilium \
      --set hubble.enabled=true \
      --set hubble.export.static.enabled=true \
      --set hubble.export.static.filePath=/var/run/Cilium/hubble/events.log
    

    Примечание

    В сценарии используется менеджер пакетов Helm. Данный инструмент не входит в состав продукта и требует дополнительной установки, при необходимости запросите у системного администратора.

  2. Дождитесь готовности Cilium pod:

    kubectl -n kube-system rollout status ds/Cilium
    
  3. Убедитесь, что журналы потоков хранятся в целевых файлах:

    kubectl -n kube-system exec ds/Cilium -- tail -f /var/run/Cilium/hubble/events.log
    

После настройки Hubble Exporter можно настроить решение для ведения журнала таким образом, чтобы оно использовало журналы из пути к файлу экспорта Hubble.

Чтобы отключить статическую настройку, удалите ключ hubble-export-file-path в ConfigMap Cilium-config и вручную очистите файлы журнала, созданные в указанном месте контейнера. Приведенная ниже команда перезапустит Cilium pods. Если редактировался ConfigMap, потребуется перезапуск Cilium pods.

Для перезапуска Cilium pods выполните:

Cilium config delete hubble-export-file-path

Установка Kube-state-metrics#

Для установки Kube-state-metrics примените манифест:

kubectl apply -f examples/standard

Установка Metrics-server#

Для установки Metrics-server, выполните команду:

kubectl apply -f <path_to_manifests>/metrics-server.yaml

Где: <path_to_manifests> - путь к каталогу, где находится Metrics Server.

Проверьте состояние службы Metrics Server, используя команду:

kubectl get pods --namespace kube-system | grep metrics-server

Если установка прошла успешно, в выводе отобразится pod Metrics Server в состоянии Running.

Установка Node-cert-exporter#

Запустите команду для развертывания набора демонов:

kubectl apply -f https://example.com/node-cert-exporter/master/deploy/daemonset.yml
# Адрес приведен в качестве примера, укажите полный путь к файлу конфигурации

Содержание манифеста будет следующим:

Node-cert-exporter.yaml
---
apiVersion: v1
kind: Namespace
metadata:
name: node-cert-exporter
spec:
finalizers:
- kubernetes
---
apiVersion: v1
kind: ServiceAccount
metadata:
name: node-cert-exporter
namespace: node-cert-exporter
---
apiVersion: extensions/v1beta1
kind: DaemonSet
metadata:
labels:
app: node-cert-exporter
name: node-cert-exporter
namespace: node-cert-exporter
spec:
selector:
matchLabels:
app: node-cert-exporter
template:
metadata:
name: node-cert-exporter
labels:
app: node-cert-exporter
annotations:
prometheus.io/scrape: 'true'
prometheus.io/port: '9117'
spec:
containers:
- image: ghcr.io/amimof/node-cert-exporter:latest
args:
- "--v=2"
- "--logtostderr=true"
- "--path=/host/etc/origin/node/,/host/etc/origin/master/,/host/etc/etcd/,/host/etc/kubernetes/pki/"
env:
- name: NODE_NAME
valueFrom:
fieldRef:
fieldPath: spec.nodeName
name: node-cert-exporter
ports:
- containerPort: 9117
name: HTTP
protocol: TCP
resources:
limits:
cpu: 250m
memory: 256Mi
requests:
cpu: 100m
memory: 128Mi
volumeMounts:
- mountPath: /host/etc
name: etc
readOnly: true
serviceAccount: node-cert-exporter
serviceAccountName: node-cert-exporter
volumes:
- hostPath:
path: /etc
type: ""
name: etc
updateStrategy:
type: RollingUpdate

Установка Node-exporter#

Для установки Node-exporter с помощью Helm необходимо выполнить шаги:

Примечание

В сценарии используется менеджер пакетов Helm. Данный инструмент не входит в состав продукта и требует дополнительной установки, при необходимости запросите у системного администратора.

  1. Создайте файл values.yaml с настройками для Node-exporter:

    image:
    repository: dropapp/coreos/node-exporter
    tag: v1.7.0
    

    Примечание

    Репозиторий приведен для примера и является несуществующим.

  2. Установите Node-exporter с помощью Helm:

    helm upgrade --install node-exporter ./node-exporter --values values.yaml
    

    В этом примере указывается путь к файлу values.yaml и устанавливается Node-exporter.

    После установки Node-exporter будет запущен в DropApp и доступен по адресу http://<Node Exporter IP>:9100.

    Node-exporter работает и предоставляет метрики на портe 9100.

  3. Убедитесь, что метрики экспортируются, указав URL-адрес /metrics конечной точки:

    curl http://localhost:9100/metrics
    

    Вывод отобразит следующее:

    go_gc_duration_seconds{quantile="0"} 3.8996e-05
    go_gc_duration_seconds{quantile="0.25"} 4.5926e-05
    go_gc_duration_seconds{quantile="0.5"} 5.846e-05
    # etc.
    

    Node-exporter предоставляет метрики, которые Prometheus может автоматически собирать и систематизировать, в том числе системных метрик с префиксом node_.

  4. Просмотрите показатели с выводом справочной информации о типе метрики:

    curl http://localhost:9100/metrics | grep "node_"
    

Установка OpenTelemetry Collector contrib#

Запустите команду для развертывания набора демонов:

kubectl apply -f https://example.com//open-telemetry/opentelemetry-collector/v0.91.0/examples/k8s/otel-config.yaml
# Адрес приведен в качестве примера.

Установка OpenTelemetry Operator#

Для установки OpenTelemetry Operator выполните следующие шаги:

  1. Создайте файл настройки dapp-opentelemetry-operator.yaml.

  1. Для установки OpenTelemetry Operator выполните:

    kubectl apply -f https://repoexample.ru/OpenTelemetry-operator.yaml
    
  2. Создайте экземпляр OpenTelemetry Collector:

    kubectl apply -f - <<EOF
    apiVersion: OpenTelemetry.io/v1alpha1
    kind: OpenTelemetryCollector
    metadata:
    name: simplest
    spec:
    config: |
        receivers:
        otlp:
            protocols:
            grpc:
            http:
        processors:
        memory_limiter:
            check_interval: 1s
            limit_percentage: 75
            spike_limit_percentage: 15
        batch:
            send_batch_size: 10000
            timeout: 10s
    
        exporters:
        debug:
    
        service:
        pipelines:
            traces:
            receivers: [otlp]
            processors: [memory_limiter, batch]
            exporters: [debug]
    EOF
    

    Это действие создаст экземпляр OpenTelemetry Collector с именем simplest. Этот экземпляр предоставляет порт jaeger-grpc для использования интервалов времени из инструментальных приложений и экспорта этих интервалов с помощью debug. debug записывает интервал в консоль (stdout) экземпляра OpenTelemetry Collector, который получает интервал.

    Node config содержит YAML, который должен быть передан базовым экземплярам OpenTelemetry Collector.

Установка Prometheus#

Предварительные условия развертывания: созданы правила RBAC для учетной записи службы Prometheus.

Развертывание Prometeus:

  1. Примените следующие манифесты для создания учетной записи службы и связки ClusterRole/ClusterRoleBinding:

    apiVersion: v1
    kind: ServiceAccount
    metadata:
      name: prometheus
    

    Выше приведен фрагмент кода, который описывает создание ServiceAccount в DropApp, где:

    • apiVersion указывает версию API DropApp, которой принадлежит этот объект. В данном случае это версия v1;

    • kind определяет тип объекта. В данном случае ServiceAccount;

    • metadata содержит информацию о ServiceAccount, такую как имя, которое может быть использовано для идентификации ServiceAccount.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRole
    metadata:
      name: prometheus
    rules:
    - apiGroups: [""]
      resources:
      - nodes
      - nodes/metrics
      - services
      - endpoints
      - pods
      verbs: ["get", "list", "watch"]
    - apiGroups: [""]
      resources:
      - configmaps
      verbs: ["get"]
    - apiGroups:
      - networking.k8s.io
      resources:
      - ingresses
      verbs: ["get", "list", "watch"]
    - nonResourceURLs: ["/metrics"]
      verbs: ["get"]
    

    Выше приведено описание объекта ClusterRole в DropApp, который предоставляет разрешения для работы с ресурсами в кластере, где:

    • apiVersion определяет версию API, к которой относится объект. В данном случае, это версия v1 для API группы rbac.authorization.k8s.io;

    • kind определяет тип объекта, в данном случае ClusterRole;

    • metadata содержит информацию об объекте, такую как его имя (name), которое может использоваться для его идентификации. Также здесь указаны правила, которые определяют, какие ресурсы и операции могут быть выполнены с ними;

    • rules определяет правила доступа к ресурсам. В данном примере, правила доступа включают получение списка, чтение и наблюдение за следующими ресурсами: nodes, nodes/metrics, services, endpoints, pods и configmaps. Также здесь указаны правила доступа к ресурсам из группы networking.k8s.io, включая ingresses;

    • nonResourceURLs определяет список URL-адресов, к которым можно получить доступ без указания ресурсов. В данном случае указан только один URL-адрес - /metrics;

    • verbs определяет список операций, которые могут быть выполнены над ресурсами. В данном случае указаны операции get, list и watch.

    apiVersion: rbac.authorization.k8s.io/v1
    kind: ClusterRoleBinding
    metadata:
      name: prometheus
    roleRef:
      apiGroup: rbac.authorization.k8s.io
      kind: ClusterRole
      name: prometheus
    subjects:
    - kind: ServiceAccount
      name: prometheus
      namespace: default
    

    Пользовательский ресурс Prometheus определяет характеристики StatefulSet (количество копий, запросы/ограничения ресурсов и т.д.), а также то, какие ServiceMonitors должны быть включены в поле spec.serviceMonitorSelector.

  2. Добавьте возможность ввода новых ServiceMonitors без необходимости перенастройки Prometheus, примените манифест:

    apiVersion: monitoring.operationsistem.com/v1
    kind: Prometheus
    metadata:
      name: prometheus
    spec:
      serviceAccountName: prometheus
      serviceMonitorSelector:
        matchLabels:
          team: frontend
      resources:
        requests:
          memory: 400Mi
      enableAdminAPI: false
    

    В сценарии развертывания Prometheus-operator (представлен выше) создается объект ServiceMonitor с меткой team: frontend. Манифест определяет, что объект Prometheus должен выбирать все ServiceMonitors с меткой team: frontend.

  3. Убедитесь, что экземпляр был запущен, введите команду:

    kubectl get -n default prometheus prometheus -w
    

    По умолчанию Prometheus запустит ServiceMonitors из текущего namespace. Чтоб выбрать ServiceMonitors из другого namespace, обновите поле spec.serviceMonitorNamespaceSelector в Prometheus.

Установка Trident#

Для установки Trident выполните шаги:

  1. Загрузите и распакуйте Trident-operator.

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

    apiVersion: dapp-trident-operator-template
    kind: OperatorGroup
    metadata:
    name: trident
    spec:
    targetNamespace: trident-system
    reconciliation: Periodic
    period: 1m
    
    operators:
    
    – name: trident.io/trident
    version: x.x.x
    

    Это создаст группу операторов Trident с именем Trident и настройкой периодической проверки ресурсов в целевой области Trident-system. Далее можно использовать оператор Trident для управления ресурсами в DropApp.

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

    Поместите файл backend.json в каталог установки setup:

    cp sample-input/<backend template>.json setup/backend.json
    

    Примеры файлов конфигурации для различных типов backend можно найти в sample-input каталоге.

  2. Выполните проверку возможности установки Trident:

    # ./tridentctl install --dry-run -n trident
    INFO Starting storage driver.                backend=setup/backend.json
    INFO Storage driver loaded.                  driver=ontap-nas
    INFO Dry run completed, no problems found.
    

    Флаг --dry-run позволяет выполнить проверку текущей среды и убедиться что Trident установится успешно без внесения изменений в среду.

    Флаг -n указывает namespace, в которое будет установлен Trident.

  3. Запустите установщик Trident:

    #./tridentctl install -n trident
    INFO Starting storage driver.                backend=setup/backend.json
    INFO Storage driver loaded.                  driver=ontap-nas
    INFO Starting Trident installation.          namespace=trident
    INFO Created service account.
    INFO Created cluster role.
    INFO Created cluster role binding.
    INFO Created PVC.
    INFO Created PV.                             pv=trident
    INFO Waiting for PVC to be bound.            pvc=trident
    INFO Created Trident deployment.
    INFO Waiting for Trident pod to start.
    INFO Trident pod started.                    namespace=trident pod=trident-7d5d659bd7-tzth6
    INFO Trident installation succeeded.
    
  4. Проверьте результат установки:

    kubectl get pod -n trident
    

    Вывод будет следующим:

    NAME                       READY     STATUS    RESTARTS   AGE
    trident-7d5d659bd7-tzth6   2/2       Running   1          14s
    
    # ./tridentctl -n trident version
    +----------------+----------------+
    | SERVER VERSION | CLIENT VERSION |
    +----------------+----------------+
    | v22.10.0       | v22.10.0         |
    +----------------+----------------+
    
  5. Создайте внутреннюю конфигурацию хранилища, из которой Trident будет выделять тома:

    ./tridentctl -n trident create backend -f setup/backend.json
    +-----------------------+----------------+--------+---------+
    |         NAME          | STORAGE DRIVER | ONLINE | VOLUMES |
    +-----------------------+----------------+--------+---------+
    | ontapnas_0.0.0.0    | ontap-nas      | true   |       0 |
    +-----------------------+----------------+--------+---------+
    
  6. Создайте класс хранилища:

    ./tridentctl -n trident get backend
    +-----------------------+----------------+--------+---------+
    |         NAME          | STORAGE DRIVER | ONLINE | VOLUMES |
    +-----------------------+----------------+--------+---------+
    | ontapnas_0.0.0.0     | ontap-nas      | true   |       0 |
    +-----------------------+----------------+--------+---------+
    
    cp sample-input/storage-class-basic.yaml.templ sample-input/storage-class-basic.yaml
    

    Класс хранилища в данном сценарии основан на sample-input/storage-class-basic.yaml.templ, который поставляется с установщиком, при этом вместо маркера __BACKEND_TYPE__ указывается название драйвера хранилища.

  7. Используйте kubectl для создания хранилища как объекта DropApp:

    kubectl create -f sample-input/storage-class-basic.yaml
    
  8. Проверьте базовый класс хранилища:

    kubectl get sc basic
    NAME      PROVISIONER
    basic     netapp.io/trident
    
    ./tridentctl -n trident get storageclass basic -o json
    {
      "items": [
        {
          "Config": {
            "version": "1",
            "name": "basic",
            "attributes": {
              "backendType": "ontap-nas"
            }
          },
          "storage": {
            "ontapnas_0.0.0.0": [
              "aggr1",
              "aggr2",
              "aggr3",
              "aggr4"
            ]
          }
        }
      ]
    }
    
  9. Создайте манифест постоянного тома для использования созданного класса хранилища sample-input/pvc-basic.yaml

  10. Убедитесь, что имя класса соответствует созданному в шаге 6:

  • создайте новый PVC с параметрами в кластере, указанными в файле pvc-basic.yaml:

kubectl create -f sample-input/pvc-basic.yaml
  • получите список PVC и установите опцию слежения за объектами, чтобы обновления отображались в реальном времени:

# Аргумент '-aw' позволяет наблюдать за процессом подготовки постоянного хранилища
kubectl get pvc -aw
NAME      STATUS    VOLUME    CAPACITY   ACCESS MODES   STORAGECLASS   AGE
basic     Pending                                       basic          1s
basic     Pending   default-basic-6cb59   0                   basic     5s
basic     Bound     default-basic-6cb59   1Gi       RWO       basic     5s
  1. Смонтируйте том в pod:

    cat << EOF > task-pv-pod.yaml
    kind: Pod
    apiVersion: v1
    metadata:
      name: task-pv-pod
    spec:
      volumes:
        - name: task-pv-storage
          persistentVolumeClaim:
          claimName: basic
      containers:
        - name: task-pv-container
          image: nginx
          ports:
            - containerPort: 80
              name: "HTTP-server"
          volumeMounts:
            - mountPath: "/usr/share/nginx/html"
              name: task-pv-storage
    EOF
    kubectl create -f task-pv-pod.yaml
    
  2. Убедитесь, что pod запустился:

    kubectl get pod -aw
    
  3. Убедитесь, что pod смонтирован в папке /usr/share/nginx/html:

    kubectl exec -it task-pv-pod -- df -h /usr/share/nginx/html
    Filesystem                                      Size  Used Avail Use% Mounted on
    0.0.0.0:/trident_demo_default_basic_6cb59  973M  192K  973M   1% /usr/share/nginx/html
    
  4. Удалите pod:

    kubectl delete pod task-pv-pod
    

    На данном шаге удален только pod, том продолжает существовать и может быть использован другими pods.

  5. Удалите том выполнив команду:

    kubectl delete pvc basic
    

Установка Vector#

Для установки Vector выполните шаги:

Примечание

В приведенном сценарии при запуске Vector указан namespace vector - название может быть изменено на усмотрение администратора.

  1. Создайте namespace vector:

    kubectl create namespace --dry-run=client -o yaml vector > namespace.yaml
    
  2. Выполните команду для развертывания Vector в кластере DropApp:

    vector agent deploy --config <Path_to_the_configuration_file>
    
  3. Дождитесь завершения процесса развертывания.

  4. Проверьте статус агента с помощью команды:

    vector agent status
    

Установка VictoriaMetrics, VictoriaMetrics-operator, VictoriaMetrics-cluster#

Для установки VictoriaMetrics, VictoriaMetrics-operator, VictoriaMetrics-cluster выполните следующие действия:

Примечание

В сценарии используется менеджер пакетов Helm. Данный инструмент не входит в состав продукта и требует дополнительной установки, при необходимости запросите у системного администратора.

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

    Copyhelm repo add vm https://<repoexample.ru>/helm-charts/
    # Укажите актуальный путь до локального репозитория
    
  2. Обновите репозиторий Helm:

    Copyhelm repo update
    
  3. Проверьте корректность настроек, введите команду:

    Copyhelm search repo vm/
    

    Вывод будет следующим:

    NAME                           CHART           VERSION     APP VERSION DESCRIPTION                                       
    vm/victoria-metrics-agent      0.7.20        v1.87.6     Victoria Metrics Agent - collects metrics from ...
    vm/victoria-metrics-alert      0.3.34        v1.87.6     Victoria Metrics Alert - executes a list of giv...
    vm/victoria-metrics-auth       0.2.23        v1.87.6       Victoria Metrics Auth - is a simple auth proxy ...
    vm/victoria-metrics-cluster    0.8.32        v1.87.6       Victoria Metrics Cluster version - high-perform...
    vm/victoria-metrics-k8s-stack  0.2.9         v1.87.6       Kubernetes monitoring on VictoriaMetrics stack....
    vm/victoria-metrics-operator   0.1.17        0.32.0      Victoria Metrics Operator                         
    vm/victoria-metrics-single     0.7.5         v1.87.6     Victoria Metrics Single version - high-performa...
    
  4. Установите кластер VictoriaMetricss с помощью Helm. Для переопределения образов для Helm можно использовать флаг --set в команде helm install:

       cat <<EOF | helm install vmcluster vm/victoria-metrics-cluster -f -
    vmselect:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8481"
    
    vminsert:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8480"
    
    vmstorage:
    podAnnotations:
          prometheus.io/scrape: "true"
          prometheus.io/port: "8482"
    EOF
    

    Запуск команды helm install vmcluster vm/victoria-metrics-cluster устанавливает кластер VictoriaMetrics в namespace по умолчанию внутри созданного кластера.

    Команда podAnnotations: prometheus.io/scrape: "true" и podAnnotations:prometheus.io/port: "some_port" запускает сбор метрик из pod vmselect, vminsert и vmstorage и из их портов.

    Вывод будет следующим:

    NAME: vmcluster
    LAST DEPLOYED: Thu Jun  1 09:41:57 2023
    NAMESPACE: default
    STATUS: deployed
    REVISION: 1
    TEST SUITE: None
    NOTES:
    Write API:
    

    Примечание

    Все образы в манифестах пользователей будут содержать информацию из реестра DropApp.

  5. Получите URL-адрес службы вставки vminsert VictoriaMetrics, выполнив команды:

    export POD_NAME=$(kubectl get pods --namespace default -l "app=vminsert" -o jsonpath="{.items[0].metadata.name}")
      kubectl --namespace default port-forward $POD_NAME 8480
    
  6. Обновите файл конфигурации Prometheus и добавьте в него следующие строки:

    prometheus.yml
        remote_write:
          - URL: "http://<insert-service>/insert/0/prometheus/"
    

    Где <insert-service> - insert-сервис.

  7. Получите доступ к API VictoriaMetrics через порт 8481 со следующим DNS-именем из кластера:

    vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local
    
  8. Получите URL-адрес службы VictoriaMetrics, выполнив команду:

    export POD_NAME=$(kubectl get pods --namespace default -l "app=vmselect" -o jsonpath="{.items[0].metadata.name}")
    kubectl --namespace $POD_NAME 8481
    
  9. Укажите URL-адрес службы в Grafana:

    Примечание

    В качестве источника данных необходимо выбрать Prometheus.

    Введите это поле URL в Grafana:

    http://<select-service>/select/0/prometheus/
    

    Где <select-service>- select-сервис.

  10. Убедитесь, что pods кластера VictoriaMetrics запущены и работают, выполнив следующую команду:

kubectl get pods

Вывод будет следующим:

NAME                                                           READY   STATUS    RESTARTS   AGE
vmcluster-victoria-metrics-cluster-vminsert-689cbc8f55-95szg   1/1     Running   0          16m
vmcluster-victoria-metrics-cluster-vminsert-689cbc8f55-f852l   1/1     Running   0          16m
vmcluster-victoria-metrics-cluster-vmselect-977d74cdf-bbgp5    1/1     Running   0          16m
vmcluster-victoria-metrics-cluster-vmselect-977d74cdf-vzp6z    1/1     Running   0          16m
vmcluster-victoria-metrics-cluster-vmstorage-0                 1/1     Running   0          16m
vmcluster-victoria-metrics-cluster-vmstorage-1                 1/1     Running   0          16m
  1. Установите vmagent из Helm, выполните следующую команду:

helm install vmagent vm/victoria-metrics-agent -f https://<repoexample.ru>.ru/guides/victoriametrics.yaml
# Укажите актуальный путь до локального репозитория

Полное содержание файла victoriametrics.yaml:

victoriametrics.yaml
remoteWriteUrls: - http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/

   config:
     global:
       scrape_interval: 10s

     scrape_configs:
       - job_name: vmagent
         static_configs:
           - targets: ["localhost:8429"]
       - job_name: "kubernetes-api-servers"
         kubernetes_sd_configs:
           - role: endpoints
         scheme: HTTPs
         tls_config:
           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
           insecure_skip_verify: true
         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
         relabel_configs:
           - source_labels:
               [
                 __meta_kubernetes_namespace,
                 __meta_kubernetes_service_name,
                 __meta_kubernetes_endpoint_port_name,
               ]
             action: keep
             regex: default;kubernetes;HTTPs
       - job_name: "kubernetes-nodes"
         scheme: HTTPs
         tls_config:
           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
           insecure_skip_verify: true
         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
         kubernetes_sd_configs:
           - role: node
         relabel_configs:
           - action: labelmap
             regex: __meta_kubernetes_node_label_(.+)
           - target_label: __address__
             replacement: kubernetes.default.svc:443
           - source_labels: [__meta_kubernetes_node_name]
             regex: (.+)
             target_label: __metrics_path__
             replacement: /api/v1/nodes/$1/proxy/metrics
       - job_name: "kubernetes-nodes-cadvisor"
         scheme: HTTPs
         tls_config:
           ca_file: /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
           insecure_skip_verify: true
         bearer_token_file: /var/run/secrets/kubernetes.io/serviceaccount/token
         kubernetes_sd_configs:
           - role: node
         relabel_configs:
           - action: labelmap
             regex: __meta_kubernetes_node_label_(.+)
           - target_label: __address__
             replacement: kubernetes.default.svc:443
           - source_labels: [__meta_kubernetes_node_name]
             regex: (.+)
             target_label: __metrics_path__
             replacement: /api/v1/nodes/$1/proxy/metrics/cadvisor
         metric_relabel_configs:
           - action: replace
             source_labels: [pod]
             regex: '(.+)'
             target_label: pod_name
             replacement: '${1}'
           - action: replace
             source_labels: [container]
             regex: '(.+)'
             target_label: container_name
             replacement: '${1}'
           - action: replace
             target_label: name
             replacement: k8s_stub
           - action: replace
             source_labels: [id]
             regex: '^/system\.slice/(.+)\.service$'
             target_label: systemd_service_name
             replacement: '${1}'
       - job_name: "kubernetes-service-endpoints"
         kubernetes_sd_configs:
           - role: endpoints
         relabel_configs:
           - action: drop
             source_labels: [__meta_kubernetes_pod_container_init]
             regex: true
           - action: keep_if_equal
             source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_scrape]
             action: keep
             regex: true
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_scheme]
             action: replace
             target_label: __scheme__
             regex: (HTTPs?)
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_path]
             action: replace
             target_label: __metrics_path__
             regex: (.+)
           - source_labels:
               [
                 __address__,
                 __meta_kubernetes_service_annotation_prometheus_io_port,
               ]
             action: replace
             target_label: __address__
             regex: ([^:]+)(?::\d+)?;(\d+)
             replacement: $1:$2
           - action: labelmap
             regex: __meta_kubernetes_service_label_(.+)
           - source_labels: [__meta_kubernetes_namespace]
             action: replace
             target_label: kubernetes_namespace
           - source_labels: [__meta_kubernetes_service_name]
             action: replace
             target_label: kubernetes_name
           - source_labels: [__meta_kubernetes_pod_node_name]
             action: replace
             target_label: kubernetes_node
       - job_name: "kubernetes-service-endpoints-slow"
         scrape_interval: 5m
         scrape_timeout: 30s
         kubernetes_sd_configs:
           - role: endpoints
         relabel_configs:
           - action: drop
             source_labels: [__meta_kubernetes_pod_container_init]
             regex: true
           - action: keep_if_equal
             source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_scrape_slow]
             action: keep
             regex: true
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_scheme]
             action: replace
             target_label: __scheme__
             regex: (HTTPs?)
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_path]
             action: replace
             target_label: __metrics_path__
             regex: (.+)
           - source_labels:
               [
                 __address__,
                 __meta_kubernetes_service_annotation_prometheus_io_port,
               ]
             action: replace
             target_label: __address__
             regex: ([^:]+)(?::\d+)?;(\d+)
             replacement: $1:$2
           - action: labelmap
             regex: __meta_kubernetes_service_label_(.+)
           - source_labels: [__meta_kubernetes_namespace]
             action: replace
             target_label: kubernetes_namespace
           - source_labels: [__meta_kubernetes_service_name]
             action: replace
             target_label: kubernetes_name
           - source_labels: [__meta_kubernetes_pod_node_name]
             action: replace
             target_label: kubernetes_node
       - job_name: "kubernetes-services"
         metrics_path: /probe
         params:
           module: [HTTP_2xx]
         kubernetes_sd_configs:
           - role: service
         relabel_configs:
           - source_labels:
               [__meta_kubernetes_service_annotation_prometheus_io_probe]
             action: keep
             regex: true
           - source_labels: [__address__]
             target_label: __param_target
           - target_label: __address__
             replacement: blackbox
           - source_labels: [__param_target]
             target_label: instance
           - action: labelmap
             regex: __meta_kubernetes_service_label_(.+)
           - source_labels: [__meta_kubernetes_namespace]
             target_label: kubernetes_namespace
           - source_labels: [__meta_kubernetes_service_name]
             target_label: kubernetes_name
       - job_name: "kubernetes-pods"
         kubernetes_sd_configs:
           - role: pod
         relabel_configs:
           - action: drop
             source_labels: [__meta_kubernetes_pod_container_init]
             regex: true
           - action: keep_if_equal
             source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port, __meta_kubernetes_pod_container_port_number]
           - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
             action: keep
             regex: true
           - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_path]
             action: replace
             target_label: __metrics_path__
             regex: (.+)
           - source_labels:
               [__address__, __meta_kubernetes_pod_annotation_prometheus_io_port]
             action: replace
             regex: ([^:]+)(?::\d+)?;(\d+)
             replacement: $1:$2
             target_label: __address__
           - action: labelmap
             regex: __meta_kubernetes_pod_label_(.+)
           - source_labels: [__meta_kubernetes_namespace]
             action: replace
             target_label: kubernetes_namespace
           - source_labels: [__meta_kubernetes_pod_name]
             action: replace
             target_label: kubernetes_pod_name

Где remoteWriteUrls: - http://vmcluster-victoria-metrics-cluster-vminsert.default.svc.cluster.local:8480/insert/0/prometheus/ настраивает vmagent для записи очищенных метрик в файл vmselect service.

Вторая часть этого yaml-файла добавляет раздел metric_relabel_configs, выводит метрики на панели управления Grafana.

  1. Выполните команду и убедитесь, что vmagent запущен:

kubectl get pods | grep vmagent

Вывод отобразит следующее:

vmagent-victoria-metrics-agent-69974b95b4-mhjph                1/1     Running   0          11m
  1. Добавьте репозиторий Grafana:

Copyhelm repo add grafana https://<repoexample.ru>/helm-charts
helm repo update
# Укажите актуальный путь до локального репозитория
  1. Добавьте источник данных VictoriaMetrics с названием релиза my-grafana:

my-grafana.yaml
helm install my-grafana grafana/grafana -f -
datasources:
   datasources.yaml:
      apiVersion: 1
      datasources:
      - name: victoriametrics
         type: prometheus
         orgId: 1
         url: http://vmcluster-victoria-metrics-cluster-vmselect.default.svc.cluster.local:8481/select/0/prometheus/
         access: proxy
         isDefault: true
         updateIntervalSeconds: 10
         editable: true

dashboardProviders:
   dashboardproviders.yaml:
   apiVersion: 1
   providers:
   - name: 'default'
      orgId: 1
      folder: ''
      type: file
      disableDeletion: true
      editable: true
      options:
         path: /var/lib/grafana/dashboards/default

dashboards:
   default:
      victoriametrics:
      gnetId: 11176
      revision: 18
      datasource: victoriametrics
      vmagent:
      gnetId: 12683
      revision: 7
      datasource: victoriametrics
      kubernetes:
      gnetId: 14205
      revision: 1
      datasource: victoriametrics

В результате применения манифеста выполнена следующая последовательность:

 * установлена **Grafana** из репозитория **Helm**;
 * подготовлен источник данных **VictoriaMetrics** с URL-адресом из шага 4;
 * добавлена информационная панель **VictoriaMetrics**: `https://<repoexample.ru>m/grafana/dashboards/11176-victoriametrics-cluster/`;
 * добавлена информационная панель для агента **VictoriaMetrics**: `https://<repoexample.ru>/grafana/dashboards/12683-victoriametrics-vmagent/`;
 * добавлена панель мониторинга для наблюдения метрик кластера {{product_name}}: `https://<repoexample.ru>/grafana/dashboards/14205-kubernetes-cluster-monitoring-via-prometheus/`.
  1. Просмотрите журнал вывода, скопируйте, вставьте и запустите адреса из шага 14.

  2. Чтобы получить пароль администратора Grafana, выполните команду:

kubectl get secret --namespace default my-grafana -o jsonpath="{.data.admin-password}" | base64 --decode ; echo
  1. Сохраните пароль в файл на компьютере.

  2. Чтобы получить доступ к сервису Grafana в веб-браузере, выполните следующую команду:

export POD_NAME=$(kubectl get pods --namespace default -l "app.kubernetes.io/name=grafana,app.kubernetes.io/instance=my-grafana" -o jsonpath="{.items[0].metadata.name}")
  1. Используйте команду для прослушивания порта 3000 на pod с именем, указанным в переменной окружения POD_NAME:

kubectl --namespace default port-forward $POD_NAME 3000
  1. Откройте в браузере http://127.0.0.1:3000/dashboards и выберите панель мониторинга Cluster Monitoring (via Prometheus). Используйте логин admin для входа и пароль который был получен в шаге 15.

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