☸️ Обновление ConfigMap и secrets без перезапуска пода в K8s |

☸️ Обновление ConfigMap и secrets без перезапуска пода в K8s

Мануал

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

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

Вместо этого конфигурация и данные загружаются из внешнего источника.

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

Kubernetes использует концепцию secrets и configmaps для отделения информации о конфигурации от образов контейнеров.

Приложениям часто требуется доступ к конфиденциальной информации.

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

Для хранения такой конфиденциальной информации используются secrets.

☸️ Шифрование секретов Kubernetes | Используем secrets

Конфигмапы используются в тех случаях, когда данные не являются конфиденциальными.

Информация, содержащаяся в конфигмапе, не требует защиты, и данные хранятся в виде обычного текста.

Данные в секрете (secrets) не хранятся в виде обычного текста, а кодируются Base64.

На момент написания этой статьи Kubernetes имеет следующие известные ограничения для поддержки runtime обновления configmap и secrets без перезапуска:

  • Configmap и/или secrets, когда они смонтированы как тома. Если эти ресурсы используются как переменные окружения, то обновление во время выполнения не поддерживается.
  • Контейнер, использующий ConfigMap в качестве монтируемого тома subPath, не будет получать обновления ConfigMap.

Создадим секрет

Мы создадим фиктивный секрет, который будем использовать для тестирования обновления времени выполнения на нашей установке:

У меня уже есть SSH ключ, который я скопирую в текущий PATH, а затем создам секрет с помощью команды CLI:

# cp ~/.ssh/id_rsa ssh-privatekey

# kubectl create secret generic secret1 --from-file=ssh-privatekey --type=kubernetes.io/ssh-auth
secret/secret1 created

Убедитесь, что секрет создан:

kubectl get secret

Создадим ConfigMap

Давайте также создадим один ConfigMap для демонстрации:

]# cat file.txt 
samplevar: samplevalue

]# kubectl create configmap cm1 --from-file=file.txt 
configmap/cm1 created

]# kubectl get cm
NAME               DATA   AGE
cm1                1      3s

Итак, теперь у нас есть новый конфигмап “cm1”, созданный в нашем пространстве имен по умолчанию.

Создадим деплоймент

Нам понадобится deploymenty или набор подов, на которых мы сможем проверить шаги из этой статьи.

Я создам небольшой депйломент nginx и 1 replicaset и смонтирую наши configmap и секреты как volumeMounts.

apiVersion: apps/v1
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: nginx
  name: nginx
spec:
  replicas: 1
  selector:
    matchLabels:
      app: nginx
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - image: bcmt-registry:5000/secure-ssh:sudo
        name: nginx
        volumeMounts:
        - name: cm-volume
          mountPath: /etc/config
        - name: secret-volume
          mountPath: /etc/sshconfig
      volumes:
      - name: cm-volume
        configMap:
          name: cm1
      - name: secret-volume
        secret:
          secretName: secret1

Запустим деплой:

kubectl create -f nginx.yml

Проверьте, запущен ли под nginx.

]# kubectl get pods 
NAME                     READY   STATUS    RESTARTS   AGE
nginx-578dcf9879-bpp5m   1/1     Running   0          64s

Сохраните и выйдите из файла.

Команда kubectl edit откроет configmap для записи, используя EDITOR по умолчанию в вашем дистрибутиве.

Теперь проверьте содержимое вашего configmap.

Мы установили его в файл /etc/config/file.txt

# kubectl exec -it nginx-686b7b4785-p92qz -- cat /etc/config/file.txt
samplevar: value1

Как и ожидалось, новое значение переменной было добавлено без перезапуска пода:

# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-686b7b4785-p92qz   1/1     Running   0          5m1s

Автоматическое обновление секретов без перезапуска пода

Аналогичным образом попробуем обновить секрет Kubernetes, который мы создали в предыдущих шагах, с помощью команды kubectl edit.

Для пояснения я создал новый SSH-ключ:

# ssh-keygen -t rsa -f new-ssh-privatekey -P ""

Затем преобразуйте закрытый ключ в формат base64

# cat new-ssh-privatekey | base64  --wrap=0
LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeENncFVHaXFPN2orN2wweWV5VEUyTHZRSWRqOW1TVndRc2hGVFVGUVE1TEVLeUlaClVsVWVHWWVXMWFycThHazA1UGNNaGRGWWUyQ1BSdTR3Yzgvc3grakJLRXdUcFVneGkvemZYcVhTaWExRkVucHkKTzBWQWlPOG9NQWg2RC9BbEswWDVDd0NxeG1SaC9KaVcxUTM3ZEN4djRmZnRZRjlUVjBTL3JPeUhqOTdUaUdFRwpMa2hIREpMaGVIUFVoVndNdzIyQnpDTEdtVE1YZVJTTk02TnNCNmhIOFNBamN1TTk0ZDhJZzJLRXh4aVVNY3FkCjd5SDhMYTFXVHZveTRzd3FnV0w5WnNScjNDZzY5TDRxTk56b0JoUEtybzI1a1RweE9iZG1PMzV3WUpTODFTNFYKNkRsdEFlV1FzNzZGR285LzI0b2Q2RVdpak14d281TjFKZVVsd1FJREFRQUJBb0lCQUN5WFBKME16Zlg1bmVvdAp3WFlBNjhhaEd6VTJrSitweFJWSlZZZTBXenloTm5yZnE0WHQxNFBTTU5XdG51NjcyOHhZNUwzZTB4Qm82T2trCjZGckxYM1lxVVE2S0RNVTczaGVHaW5pSGxZNjZsc01XbHJVbWp2OFI3cjdNam9MbEFtNE40QWxDUTVBSjdjUncKSTRtWFBod3dwZFptZDgyNm5jVnUyV3ZEOFNVaENtczQ0aldmcFVteFFNSjZuaUo4RkthdUp1MVc3ZEJubnhXUQpRY2Q2TUJuYU0xalVPUlRBWDdFVmR0Y0JwaFVDTU1vTnZSMEpmR040cGJ5elViSFN4MXFudlJOblNRQk1Pa2xlCjZueWNCL3p0M3hYVFpsekVtYVdoVVA0ajhSbDhqdkdiNVlCbVA0aDJPMlBhVUo3ZmJMWFk3VFk5ZEl1eE05ajcKd21NVldXRUNnWUVBNUE3YkV4RVdwcHBmMXAyUVNFeTFzRjBrNTQ4NkFvamFiLzF6MlIxYU40My9QaERTaWpKZgpXL1pJV2Q3NkplcjRSd2g1YmZsUTR1S3U1bzk4UjBBYVQ3TytValVjeC9jNmhjV2RxNUhTQS92SCtWamVHVjJhCmpWVkdTeXVmTzNTRnRJbnZZYUlpVUJ0WVVxYjQ1VFYyQWhkZnJucHRKbTFCeDA3VVIrWXJYMDBDZ1lFQTNEQzIKSkZwd09sR1RabGc4Y2RmRDl6NktvTmhha2RTcEZQUzIwQkQrZHNTL1FPRk9vWlloLzJIVFlDeVlpTStMRElOSAo3Q3pUL3RrbkNaN1RObTdUcHREU0VudE1GRm12eExERjU5ZXZGZy9tZ09MK3MzcUtwTzJSSUFVcTdpdVRLbzRUCkNmcm1SMHdjUHdLOTZ4SFBiLzlpNnAxbDdSRmpBb0tpTG9wWFRrVUNnWUJNckxuM0ZSMjZjZGlhL1dxUEJFdHAKdWtjNEd5MXp3TE5BUjhSMVVLc09WbzFrUHArcW12ajRvRHIvRERxcUdPL1VZZ01CZUhzN2JOOUU0U1QxaDVYUgpDaXVJMUJhVEhJbnVnOXhZM0xQeFp1dDY1K2YwTzBaRkVsQ0o0V2F0eEtWWFo3QzE4Sjc4czlUa0pRTTFmTjNxCkloV25RYjRFMTJMd01ZNnBoYmM3V1FLQmdRQ0szUUdScmFPSGMvamttNU1MTE1yK3UyZU1Cc1lmb0NFK0FSTGwKNTBIRHYxTHFaTzFGQkx6T0pYQzcvNFAzREFTaVVJemtTbVVzSE9EOHRUaDQ1SzRBVDBPY3VqdUJ2Z29Xbm5GQgpSSW03L1MwZWJZbTV3UGQ5Q2dIelVxNy9ZMlc5ZWJwU0dmUnVWSGFmMm1mUnZ2cTJwRFpLeGhjSXltVkpxUDhGCklPUHNqUUtCZ1FESnQ3bGxyNGIrV1pBUWNFbjdCUEdKaHZVUjF2SjN1V1QwZ3d0TUFvYXdXWk5QNm8vL3B5cXgKaVdRNjhBbFMvT0tuVXBKWEc1TTdCajEvM0N5azNRenU0RnNMbnZhVUp1UzdFUVN1L0F4dnhtZU9CR2p6Yy92YgoxTCt1b3Y3WjkvR0dSU1VaRy9mb1M1QkdDNW9hTDVRNXlZZkNLNzl1ZmFrNi9jZzZKS1FKbWc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=

Теперь с помощью kubectl edit я отредактирую secret1 и добавлю обновленное значение для моего закрытого ключа:

# kubectl edit secret/secret1
# Please edit the object below. Lines beginning with a '#' will be ignored,
# and an empty file will abort the edit. If an error occurs while saving this file will be
# reopened with the relevant failures.
#
apiVersion: v1
data:
  ssh-privatekey: LS0tLS1CRUdJTiBSU0EgUFJJVkFURSBLRVktLS0tLQpNSUlFcEFJQkFBS0NBUUVBeENncFVHaXFPN2orN2wweWV5VEUyTHZRSWRqOW1TVndRc2hGVFVGUVE1TEVLeUlaClVsVWVHWWVXMWFycThHazA1UGNNaGRGWWUyQ1BSdTR3Yzgvc3grakJLRXdUcFVneGkvemZYcVhTaWExRkVucHkKTzBWQWlPOG9NQWg2RC9BbEswWDVDd0NxeG1SaC9KaVcxUTM3ZEN4djRmZnRZRjlUVjBTL3JPeUhqOTdUaUdFRwpMa2hIREpMaGVIUFVoVndNdzIyQnpDTEdtVE1YZVJTTk02TnNCNmhIOFNBamN1TTk0ZDhJZzJLRXh4aVVNY3FkCjd5SDhMYTFXVHZveTRzd3FnV0w5WnNScjNDZzY5TDRxTk56b0JoUEtybzI1a1RweE9iZG1PMzV3WUpTODFTNFYKNkRsdEFlV1FzNzZGR285LzI0b2Q2RVdpak14d281TjFKZVVsd1FJREFRQUJBb0lCQUN5WFBKME16Zlg1bmVvdAp3WFlBNjhhaEd6VTJrSitweFJWSlZZZTBXenloTm5yZnE0WHQxNFBTTU5XdG51NjcyOHhZNUwzZTB4Qm82T2trCjZGckxYM1lxVVE2S0RNVTczaGVHaW5pSGxZNjZsc01XbHJVbWp2OFI3cjdNam9MbEFtNE40QWxDUTVBSjdjUncKSTRtWFBod3dwZFptZDgyNm5jVnUyV3ZEOFNVaENtczQ0aldmcFVteFFNSjZuaUo4RkthdUp1MVc3ZEJubnhXUQpRY2Q2TUJuYU0xalVPUlRBWDdFVmR0Y0JwaFVDTU1vTnZSMEpmR040cGJ5elViSFN4MXFudlJOblNRQk1Pa2xlCjZueWNCL3p0M3hYVFpsekVtYVdoVVA0ajhSbDhqdkdiNVlCbVA0aDJPMlBhVUo3ZmJMWFk3VFk5ZEl1eE05ajcKd21NVldXRUNnWUVBNUE3YkV4RVdwcHBmMXAyUVNFeTFzRjBrNTQ4NkFvamFiLzF6MlIxYU40My9QaERTaWpKZgpXL1pJV2Q3NkplcjRSd2g1YmZsUTR1S3U1bzk4UjBBYVQ3TytValVjeC9jNmhjV2RxNUhTQS92SCtWamVHVjJhCmpWVkdTeXVmTzNTRnRJbnZZYUlpVUJ0WVVxYjQ1VFYyQWhkZnJucHRKbTFCeDA3VVIrWXJYMDBDZ1lFQTNEQzIKSkZwd09sR1RabGc4Y2RmRDl6NktvTmhha2RTcEZQUzIwQkQrZHNTL1FPRk9vWlloLzJIVFlDeVlpTStMRElOSAo3Q3pUL3RrbkNaN1RObTdUcHREU0VudE1GRm12eExERjU5ZXZGZy9tZ09MK3MzcUtwTzJSSUFVcTdpdVRLbzRUCkNmcm1SMHdjUHdLOTZ4SFBiLzlpNnAxbDdSRmpBb0tpTG9wWFRrVUNnWUJNckxuM0ZSMjZjZGlhL1dxUEJFdHAKdWtjNEd5MXp3TE5BUjhSMVVLc09WbzFrUHArcW12ajRvRHIvRERxcUdPL1VZZ01CZUhzN2JOOUU0U1QxaDVYUgpDaXVJMUJhVEhJbnVnOXhZM0xQeFp1dDY1K2YwTzBaRkVsQ0o0V2F0eEtWWFo3QzE4Sjc4czlUa0pRTTFmTjNxCkloV25RYjRFMTJMd01ZNnBoYmM3V1FLQmdRQ0szUUdScmFPSGMvamttNU1MTE1yK3UyZU1Cc1lmb0NFK0FSTGwKNTBIRHYxTHFaTzFGQkx6T0pYQzcvNFAzREFTaVVJemtTbVVzSE9EOHRUaDQ1SzRBVDBPY3VqdUJ2Z29Xbm5GQgpSSW03L1MwZWJZbTV3UGQ5Q2dIelVxNy9ZMlc5ZWJwU0dmUnVWSGFmMm1mUnZ2cTJwRFpLeGhjSXltVkpxUDhGCklPUHNqUUtCZ1FESnQ3bGxyNGIrV1pBUWNFbjdCUEdKaHZVUjF2SjN1V1QwZ3d0TUFvYXdXWk5QNm8vL3B5cXgKaVdRNjhBbFMvT0tuVXBKWEc1TTdCajEvM0N5azNRenU0RnNMbnZhVUp1UzdFUVN1L0F4dnhtZU9CR2p6Yy92YgoxTCt1b3Y3WjkvR0dSU1VaRy9mb1M1QkdDNW9hTDVRNXlZZkNLNzl1ZmFrNi9jZzZKS1FKbWc9PQotLS0tLUVORCBSU0EgUFJJVkFURSBLRVktLS0tLQo=
kind: Secret
metadata:
  creationTimestamp: "2022-06-01T06:19:37Z"
  name: secret1
  namespace: default
  resourceVersion: "19944036"
  selfLink: /api/v1/namespaces/default/secrets/secret1
  uid: fcc91312-72d7-479a-9353-419e1c8dff64
type: kubernetes.io/ssh-auth

Сохраните и выйдите из файла.

Как и ожидалось, новое значение переменной было назаначено без перезапуска пода:

# kubectl get pods
NAME                     READY   STATUS    RESTARTS   AGE
nginx-686b7b4785-p92qz   1/1     Running   0          15m1s

Обновление ConfigMap/Secret как переменной окружения с перезапуском пода

Теперь, если вы определили какую-либо ConfigMap или Secret как переменную окружения, то их обновление автоматически перезапустит pod.

Вот пример:

Я создам еще один конфиг мап:

# kubectl create configmap cm2 --from-literal=color=blue
configmap/cm2 created

Теперь я примаплю его к нашей установке nginx в качестве переменной окружения:

# kubectl set env deployment nginx --from=configmap/cm1
deployment.apps/nginx env updated

Теперь, как только я ввожу эту команду, я вижу, что мои поды nginx перезапускаются, чтобы добавить новую переменную окружения.

Заключение

Монтирование конфигмапов и секретов в виде томов внутри контейнера дает конечному пользователю большую гибкость, поскольку эти значения можно изменять и обновлять внутри приложения на лету.

Однако при использовании этого подхода есть одна загвоздка.

Когда мы указываем путь монтирования, не существующий внутри контейнера, например, /etc/config или /etc/sshconfig, он создается автоматически внутри контейнера.

Однако, если путь уже существует внутри контейнера, все текущие файлы и каталоги внутри этого пути будут перезаписаны.

Чтобы избежать этого, в разделе volumeMounts используется опция subPath.

 

 

Пожалуйста, не спамьте и никого не оскорбляйте. Это поле для комментариев, а не спамбокс. Рекламные ссылки не индексируются!
Добавить комментарий