...

Безопасное хранение данных в Kubernetes

Тема в разделе "ELMA365 On-Premises", создана пользователем s.lyalin, 27 июн 2024.

  1. s.lyalin

    s.lyalin Новичок

    Предисловие
    Часто на проектах встречается проблема безопасного хранения секретной информации, такой как, логин и пароль от какой-либо системы, используемой в рамках интеграций. Для таких случаев можно воспользоваться секретами Kubernetes и в нужный момент из них извлекать необходимые данных. Далее рассмотрим как это сделать.
    Ограничения
    1. Только для On-Premises
    2. При включении и выключении Пользовательского модуля ELMA365, придется заново вносить изменения в deployment переносимого сервиса
    Инструкция
    Рассмотрим механизм хранения секретов на примере ELMA365 On-Premises Standard, установку которой можно выполнить согласно статье.
    1. Для начала создадим файл с секретами auth.secrets.json и расположим его, например, по пути /backup/auth.secrets.json
      Код:
      
      {
          
      "Database": {
              
      "ConnectionString""Secret from kubernetes!!!"
          
      }
      }
    2. Создадим секрет auth-secrets в пространстве имен elma365-applets на основе файла auth.secrets.json с помощью следующей команды
      Код:
      
      docker exec elma365 kubectl -n elma365-applets create secret generic auth-secrets --from-file=/backup/auth.secrets.json
      
      
    3. Следующим шагом создадим Пользовательский модуль ELMA365 для которого подключим сервис EleWise.ELMA365.Service.Secrets, образ которого расположен по ссылке. При подключении сервиса следует указать следующие параметры
      [​IMG]
      [​IMG]
    4. Далее важно узнать имя deployment-а сервиса EleWise.ELMA365.Service.Secrets, для этого воспользуемся командой которая отобразит список всех deployment-ов расположенный в пространстве имен elma365-applets
      Код:
      
      docker exec elma365 kubectl -n elma365-applets get deployments
      
      
      Код:
      
      NAME                                                   READY   UP-TO-DATE   AVAILABLE   AGE
      orgstructurebuilder
      -1e642ebb44d4a8f80059a56ab6ed606c   1/1     1            1           5d12h
      secrets
      -7dcd4c4bf04b17ea37fb88e9de608c91               1/1     1            1           11h
      Из всего списка следует запомнить следующее имя secrets-7dcd4c4bf04b17ea37fb88e9de608c91, т.к. этот deployment относится к сервису EleWise.ELMA365.Service.Secrets
    5. Таким образом, можно приступить к обновлению deployment-а сервиса EleWise.ELMA365.Service.Secrets, добавив ссылку к секрету auth-secrets, благодаря чему появится возможность использования этого секрета в сервисе. Создадим файл с обновлением patch.deployment.secrets.yaml и расположим его, например, по пути /backup/patch.deployment.secrets.yaml
      Код:
      
      spec:
        
      template:
          
      spec:
            
      containers:
            - 
      nameservice
              volumeMounts
      :
              - 
      namesecrets
                mountPath
      : /app/secrets
                readOnly
      true
            volumes
      :
            - 
      namesecrets
              secret
      :
                
      secretNameauth-secrets
      Следует учитывать, что значение тега mountPath - это директория с которой будет ассоциирован секрет auth-secrets, точнее его файл auth.secrets.json. Так же стоит помнить, что рабочая директория сервиса EleWise.ELMA365.Service.Secrets - это /app, поэтому в переменной окружения было установлено значение secrets/auth.secrets.json
    6. Выполняем следующую команду для обновления deployment-а с именем secrets-7dcd4c4bf04b17ea37fb88e9de608c91
      Код:
      
      docker exec elma365 kubectl -n elma365-applets patch deployment secrets-7dcd4c4bf04b17ea37fb88e9de608c91 --patch-file /backup/patch.deployment.secrets.yaml
      
      
    7. Итак, после того как deployment обновлен, можно воспользоваться Методом API сервиса EleWise.ELMA365.Service.Secrets для получения значений секрета auth-secrets. Воспользуемся кодом ниже, для извлечения значения имеющего путь Database:ConnectionString
      Код:
      
      async function GetValue(): Promise<void> {
          try {
              const 
      response await Namespace.services.secrets.fetch(`api/v1/secrets?path=Database:ConnectionString`);
              const 
      json await response.json();
              if (
      response.ok) {
                  const 
      getSecretResult json as GetSecretResult;
                  if (
      getSecretResult.success) {
                      
      // Значение полученное из Kubernates
                      
      const value getSecretResult.value;
                  }
              } else {
                  const 
      errorResult json as ErrorResult;
                  
      // Ошибка полученная при извлечении значения из Kubernetes
                  
      const error errorResult.message;
              }
          } catch (
      error) {
              
      // Ошибка полученная при извлечении значения из Kubernetes
              
      const error error.message;
          }
      }
      type GetSecretResult = {
          
      successboolean;
          
      valuestring undefined;
      }
      type ErrorResult = {
          
      successboolean;
          
      messagestring undefined;
      }
      Если код отработает без ошибок, то получим следующее значение Secret from kubernetes!!!, которое расположено по пути Database:ConnectionString в файле auth.secrets.json секрета auth-secrets
    8. Таким образом можно хранить и извлекать значения секретов из Kubernetes. С исходным кодом сервиса EleWise.ELMA365.Service.Secrets можно ознакомится по этой ссылке
    Полезные команды Kubernetes
    Просмотр пространств имён

    Используйте следующую команду, чтобы вывести список существующих пространств имён в кластере
    Код:
    
    docker exec elma365 kubectl get ns
    
    
    Код:
    
    NAME                 STATUS   AGE
    default              Active   10d
    elma365
    -applets      Active   2d6h
    elma365
    -gsvtma       Active   10d
    ingress
    -nginx        Active   10d
    kube
    -node-lease      Active   10d
    kube
    -public          Active   10d
    kube
    -system          Active   10d
    local
    -path-storage   Active   10d
    Просмотр секретов
    Используйте следующую команду, чтобы вывести список секретов существующих в пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get secrets
    
    
    Код:
    
    NAME                          TYPE                             DATA   AGE
    my
    -secret                     Opaque                           2      30h
    orgstructurebuilder
    -secrets   Opaque                           1      5h28m
    regsecret                     kubernetes
    .io/dockerconfigjson   1      2d6h
    yandexsecret                  kubernetes
    .io/dockerconfigjson   1      2d6h
    Создание секрета
    Для создания секрета воспользуемся файлом orgstructurebuilder.secrets.json со следующим содержанием
    Код:
    
    {
        
    "Database": {
            
    "ConnectionString""Secret from kubernetes!!!"
        
    }
    }
    Используйте следующую команду, чтобы создать секрет orgstructurebuilder-secrets в пространстве имён elma365-applets. Стоит учитывать, что ELMA365 Standart находится внутри Docker-а, поэтому путь до файла должен быть верным
    Код:
    
    docker exec elma365 kubectl -n elma365-applets create secret generic orgstructurebuilder-secrets --from-file=/backup/orgstructurebuilder.secrets.json
    
    
    Просмотр секрета
    Используйте следующую команду, чтобы вывести детальную информацию о секрете orgstructurebuilder-secrets в формате json из пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get secrets orgstructurebuilder-secrets -o json
    
    
    Код:
    
    {
        
    "apiVersion""v1",
        
    "data": {
            
    "orgstructurebuilder.secrets.json""ewogICAgIkRhdGFiYXNlIjogewogICAgICAgICJDb25uZWN0aW9uU3RyaW5nIjogIlNlY3JldCBmcm9tIGt1YmVybmV0ZXMhISEiCiAgICB9Cn0K"
        
    },
        
    "kind""Secret",
        
    "metadata": {
            
    "creationTimestamp""2024-06-21T07:48:50Z",
            
    "name""orgstructurebuilder-secrets",
            
    "namespace""elma365-applets",
            
    "resourceVersion""779562",
            
    "uid""078c25ab-2ac5-4897-b770-653a25bbac0d"
        
    },
        
    "type""Opaque"
    }
    Используйте следующую команду, чтобы вывести содержимое поля data секрета orgstructurebuilder-secrets в формате json. Стоит учитывать, что данная команда актуальна только для случая, если секрет создавался на основе файла
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get secrets orgstructurebuilder-secrets -o jsonpath='{.data.*}' base64 -d
    
    
    Код:
    
    {
        
    "Database": {
            
    "ConnectionString""Secret from kubernetes!!!"
        
    }
    }
    Просмотр подов
    Используйте следующую команду, чтобы вывести список подов существующих в пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get pods
    
    
    Код:
    
    NAME                                                              READY   STATUS    RESTARTS      AGE
    orgstructurebuilder
    -1e642ebb44d4a8f80059a56ab6ed606c-68c55qfcn7   1/1     Running   1 (11h ago)   30h
    Просмотр логов пода
    Используйте следующую команду, чтобы вывести логи пода orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c-68c55qfcn7 из пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets logs orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c-68c55qfcn7
    
    
    Код:
    
    infoMicrosoft.Hosting.Lifetime[14]
          
    Now listening onhttp://[::]:80
    infoMicrosoft.Hosting.Lifetime[0]
          
    Application startedPress Ctrl+C to shut down.
    infoMicrosoft.Hosting.Lifetime[0]
          
    Hosting environmentProduction
    info
    Microsoft.Hosting.Lifetime[0]
          
    Content root path: /app
    Просмотр развертываний
    Используйте следующую команду, чтобы вывести список развертываний существующих в пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get deployments
    
    
    Код:
    
    NAME                                                   READY   UP-TO-DATE   AVAILABLE   AGE
    orgstructurebuilder
    -1e642ebb44d4a8f80059a56ab6ed606c   1/1     1            1           31h
    Обновление развертывания
    Для обновления развертывания воспользуемся файлом patch.deployment.orgstructurebuilder.yaml с помощью которого добавим ссылку на секрет orgstructurebuilder-secrets
    Код:
    
    spec:
      
    template:
        
    spec:
          
    containers:
          - 
    nameservice
            volumeMounts
    :
            - 
    namesecrets
              mountPath
    : /app/secrets
              readOnly
    true
          volumes
    :
          - 
    namesecrets
            secret
    :
              
    secretNameorgstructurebuilder-secrets
    Используйте следующую команду, чтобы обновить развертывание orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c в пространстве имён elma365-applets. Стоит учитывать, что ELMA365 Standart находится внутри Docker-а, поэтому путь до файла должен быть верным
    Код:
    
    docker exec elma365 kubectl -n elma365-applets patch deployment orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c --patch-file /backup/patch.deployment.orgstructurebuilder.yaml
    
    
    Просмотр развертывания
    Используйте следующую команду, чтобы вывести детальную информацию о развертывании orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c в формате json из пространстве имён elma365-applets
    Код:
    
    docker exec elma365 kubectl -n elma365-applets get deployments orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c -o json
    
    
    Код:
    
    {
        
    "apiVersion""apps/v1",
        
    "kind""Deployment",
        
    "metadata": {
            
    "annotations": {
                
    "deployment.kubernetes.io/revision""1"
            
    },
            
    "creationTimestamp""2024-06-20T11:30:36Z",
            
    "generation"2,
            
    "labels": {
                
    "elma365.babysitter/company""head",
                
    "elma365.babysitter/extension-id""c699cca8-d136-4d61-9425-7195440381e7",
                
    "elma365.babysitter/extension-ns""ext_c699cca8-d136-4d61-9425-7195440381e7",
                
    "elma365.babysitter/service-code""orgstructurebuilder",
                
    "elma365.babysitter/service-id""019010a1-3a2b-7eb9-8525-cc6da06ff0dc",
                
    "elma365.babysitter/unique-name""orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c",
                
    "tier""babysitter-manageable"
            
    },
            
    "name""orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c",
            
    "namespace""elma365-applets",
            
    "resourceVersion""772893",
            
    "uid""f3b964ae-88ea-4a7e-bd8d-2997e520a4ea"
        
    },
        
    "spec": {
            
    "progressDeadlineSeconds"600,
            
    "replicas"1,
            
    "revisionHistoryLimit"10,
            
    "selector": {
                
    "matchLabels": {
                    
    "elma365.babysitter/unique-name""orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c"
                
    }
            },
            
    "strategy": {
                
    "rollingUpdate": {
                    
    "maxSurge""25%",
                    
    "maxUnavailable""25%"
                
    },
                
    "type""RollingUpdate"
            
    },
            
    "template": {
                
    "metadata": {
                    
    "creationTimestamp"null,
                    
    "labels": {
                        
    "elma365.babysitter/company""head",
                        
    "elma365.babysitter/extension-id""c699cca8-d136-4d61-9425-7195440381e7",
                        
    "elma365.babysitter/extension-ns""ext_c699cca8-d136-4d61-9425-7195440381e7",
                        
    "elma365.babysitter/service-code""orgstructurebuilder",
                        
    "elma365.babysitter/service-id""019010a1-3a2b-7eb9-8525-cc6da06ff0dc",
                        
    "elma365.babysitter/unique-name""orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c",
                        
    "tier""babysitter-manageable"
                    
    }
                },
                
    "spec": {
                    
    "containers": [
                        {
                            
    "env": [
                                {
                                    
    "name""BASE_ADDRESS",
                                    
    "value""http://192.168.19.84/"
                                
    },
                                {
                                    
    "name""ACCESS_TOKEN",
                                    
    "value""5da06433-b503-4b27-afca-44d96c938fee"
                                
    }
                            ],
                            
    "image""hubint/avtoban.elma365.orgstructurebuilder:latest",
                            
    "imagePullPolicy""Always",
                            
    "name""service",
                            
    "ports": [
                                {
                                    
    "containerPort"3005,
                                    
    "protocol""TCP"
                                
    }
                            ],
                            
    "resources": {},
                            
    "terminationMessagePath""/dev/termination-log",
                            
    "terminationMessagePolicy""File"
                        
    }
                    ],
                    
    "dnsPolicy""ClusterFirst",
                    
    "restartPolicy""Always",
                    
    "schedulerName""default-scheduler",
                    
    "securityContext": {},
                    
    "terminationGracePeriodSeconds"30
                
    }
            }
        },
        
    "status": {
            
    "availableReplicas"1,
            
    "conditions": [
                {
                    
    "lastTransitionTime""2024-06-20T11:30:38Z",
                    
    "lastUpdateTime""2024-06-20T11:30:38Z",
                    
    "message""Deployment has minimum availability.",
                    
    "reason""MinimumReplicasAvailable",
                    
    "status""True",
                    
    "type""Available"
                
    },
                {
                    
    "lastTransitionTime""2024-06-20T11:30:36Z",
                    
    "lastUpdateTime""2024-06-20T11:30:38Z",
                    
    "message""ReplicaSet \"orgstructurebuilder-1e642ebb44d4a8f80059a56ab6ed606c-68c55446b8\" has successfully progressed.",
                    
    "reason""NewReplicaSetAvailable",
                    
    "status""True",
                    
    "type""Progressing"
                
    }
            ],
            
    "observedGeneration"2,
            
    "readyReplicas"1,
            
    "replicas"1,
            
    "updatedReplicas"1
        
    }
    }
    Последнее редактирование: 28 июн 2024
  2. e.baigushkina

    e.baigushkina Участник

    Картинки отсутствуют

    [​IMG]