Мы будем использовать Sealed Secret, который легко вписывается в автоматизированные рабочие процессы, такие как GitOps.

Вступление

Kubernetes использует декларативный подход к управлению ресурсами. Хотя обычно файлы манифеста Kubernetes хранятся в репозитории Git, хранение и управление секретами Kubernetes всегда было проблемой. Запечатанные секреты были разработаны для решения этой проблемы.

Sealed Secrets - это оператор Kubernetes, который позволяет хранить секреты в Git. Он использует шифрование с асимметричным ключом для шифрования секретов, так что только оператор в кластере Kubernetes может их расшифровать. Следовательно, зашифрованные SealedSecrets можно безопасно хранить в репозитории Git.

В этой статье мы установим оператор Sealed Secrets и продемонстрируем, как его использовать.

Sealed Secrets состоит из двух частей:

  • Оператор Sealed Secrets, работающий в кластере Kubernetes
  • Клиентский инструмент командной строки kubeseal, который используется для шифрования секретов и создания ресурсов SealedSecrets Kubernetes.

Предпосылки

kubectl подключен к кластеру Kubernetes

Установите kubeseal

kubeseal - это инструмент командной строки для шифрования секретов и создания SealedSecrets. В macOS вы можете установить kubeseal с помощью Homebrew.

brew install kubeseal

Вы можете найти инструкции по установке для других платформ здесь: https://github.com/bitnami-labs/sealed-secrets#installation

Создайте пространство имен Kubernetes для Sealed Secrets

Начнем с создания пространства имен для оператора Sealed Secrets.

kubectl create namespace sealed-secrets

Разверните оператора Sealed Secret

Загрузите манифесты Kubernetes для оператора Sealed Secret.

curl -L https://github.com/bitnami-labs/sealed-secrets/releases/download/v0.12.4/controller.yaml > sealed-secrets.yaml

Поскольку мы не хотим, чтобы оператор запускался в пространстве имен kube-system, мы используем sed, чтобы изменить его на sealed-secrets.

sed -i -e 's/kube-system/sealed-secrets/g' sealed-secrets.yaml

Теперь мы используем kubectl для развертывания оператора Sealed Secret:

kubectl apply -f sealed-secrets.yaml
service/sealed-secrets-controller created
rolebinding.rbac.authorization.k8s.io/sealed-secrets-service-proxier created
rolebinding.rbac.authorization.k8s.io/sealed-secrets-controller created
clusterrole.rbac.authorization.k8s.io/secrets-unsealer created
serviceaccount/sealed-secrets-controller created
customresourcedefinition.apiextensions.k8s.io/sealedsecrets.bitnami.com created
role.rbac.authorization.k8s.io/sealed-secrets-service-proxier created
role.rbac.authorization.k8s.io/sealed-secrets-key-admin created
clusterrolebinding.rbac.authorization.k8s.io/sealed-secrets-controller created
deployment.apps/sealed-secrets-controller created

При запуске оператора Sealed Secret он сгенерирует пару ключей RSA (открытый / закрытый), если она еще не существует. После этого он распечатает открытый ключ, который можно использовать для шифрования / создания SealedSecret.

Проверить развертывание

Проверьте развертывание, проверив статус модулей Kubernetes в пространстве имен sealed-secrets.

kubectl get pods --namespace sealed-secrets

NAME                                        READY   STATUS    RESTARTS   AGE
sealed-secrets-controller-6f5785b7f-m9hmq   1/1     Running   0          20m

Создайте демонстрационное пространство имен Kubernetes

kubectl create namespace demo

namespace/demo created

Создайте секрет Kubernetes

Используйте kubectl для создания локального секретного файла манифеста.

Нам нужно передать следующие варианты:

  • namespace=demo - укажите пространство имен, в котором должен находиться секрет
  • from-literal - Укажите пары секретный ключ = значение
  • output=yaml - Укажите выходной формат kubectl
  • dry-run=client - Только распечатайте секрет, не создавая его / не отправляя на сервер Kubernetes API.
  • > db-secret.yaml - указывает kubectl сохранять вывод в db-secret.yaml
kubectl create secret generic db-secret 
--namespace=demo 
--from-literal=username=admin 
--from-literal=password=Y4nys7f11 
--dry-run=client 
--output=yaml > db-secret.yaml

cat db-secret.yaml

apiVersion: v1
data:
  password: WTRueXM3ZjEx
  username: YWRtaW4=
kind: Secret
metadata:
  creationTimestamp: null
  name: db-secret
  namespace: demo

Как вы можете видеть выше, обычный ресурс Kubernetes содержит пару kev=value, где значение просто закодировано в base64, а не зашифровано.

Зашифруйте секрет Kubernetes

Используйте kubeseal, чтобы зашифровать db-secret. Результатом является ресурс SealedSecret, содержащий зашифрованный секрет.

Нам нужно передать следующие варианты:

  • controller-namespace=sealed-secret - укажите пространство имен, в котором запускается оператор Sealed Secret (по умолчанию kube-system)
  • format=yaml - Укажите выходной формат kubeseal (по умолчанию JSON)
  • < db-secret.yaml - указывает kubeseal на ввод db-secret.yaml.
  • > sealed-db-secret.yaml - указывает kubeseal сохранять вывод в sealed-db-secret.yaml.
kubeseal
--controller-namespace=sealed-secrets 
--format=yaml < db-secret.yaml > sealed-db-secret.yaml

cat sealed-db-secret.yaml

apiVersion: bitnami.com/v1alpha1
kind: SealedSecret
metadata:
  creationTimestamp: null
  name: db-secret
  namespace: demo
spec:
  encryptedData:
    password: AgDj/I4L89v9km3cuYyckAe1/sNcjH67fjhPAjZep37bQ+CCxPvQzEXJrQvI0fzzjF0cHU003JYCFUok4DFMi8nMw9YnXM//JiyBGvlEhmmQ/VI+HgruWcOEIuWw+NfR6GWVn0dLidnYOwnvJG4sAx3iPXcR2oyivj2v5yICx4CgAOS88tZF1AaSxYqhbAYfnD8IiNdfH6+gwYXwLp2pS1f/HLawtmnvAZLVb9JqP1Nidvj34a79xVbGZ7wz04W55uU/gNNZkP5QIvJ49DZkx4JqmKLISrXziPkgt/ZqB+346oXEM+iKoPOgn0sX8M6NcY8hd7SiT9RJ3fQ4TDGOfufn8fTXVtleSN3tOicMpbMhZ7XP/0x1bvN72yYbMPAbZxf+G6Qs6CwlG0ftU/FrD3W5e38ypg5E9Uk7GW0o2A74IOrpmUswDDeR1j+0TGIlOYcwAuQREy1aDcgvm+9Cn1KFp0Fd+q0DxnGf2V31a22DoE1Bxj+R4Jq5bLzI0ZBt/VYO65b1MnXetz3cy3T8gKTFzeflorPU5GBIwKs7AeDUgvXpefp/XfW70afBKhk1la6LstBUjVP6TPI7yKpVWq0FgR0MjeyZFp4eEezDoQJOX/siy5/weWv7sOfifpDp2lxSqPcTd+c1wa512tb6KSapu0vvb7JL9VTyNWdw6Th2ymD2RWtOV8dRXTLXkzd9Q34/8Y0OR4n/cSY=
    username: AgB+7E5iWzUELYgjxwwwnAk1SlR+ZwQV7OafBsZIPA47KgSlp8Xys7slJ2STIQ4nfmg/UTJimTN8mNvF3QK6zEfAeglN75r0HxMe8aWPnJ4OrKwuy8LUpEIKtdlPHLnyHNF2v5Nos/Gej1cshuA27EliqCwRLE7Z4FCxwiUIX0zBraWOJcXXzVylRK3WA2uGrBsH9P9k7+V1h/B66K4djCL47uOLaBQTXRlW45av1cSsDWLpq1em/6Og+GA5txxsNaCDADR2ybqpPg6RRoC1ayf7z+cYrFV84Wc9KNb3+cxHjuEEW/c3PT0xqyqZq7Iqr6254SVTv1bB0joD7wK7yEPUFJSc8M3GnXsG3Eq81QgpjeKHY1uZnT4B5/ztxSeczQoKksjvICUeysb09tZMRgF80A74uAv4e0gyRXBEgk7uPQg/JTqKFo77qntK5lzAGSVJQlumAq8FBeAKwwzOJrltbC8yMprQzapXBj8Vo43gEY1Avkc2Pov/bceppuah2Q9JFPCetpEtI+lruRGlZUR9Iw3T4QcunLXfgC73xWiPY6B/I+dFh2oDoiabo4gonGDLEhtAmtQU6MARWVBbs6AFGHQYRdvU23Xc5ISocG69mwFwevtwkOHQtx+VOcMN1Tmnj5htCb1CaK+rD2xfHjaWZ3VjorWuUCG5kXz5pjeRw95s+h8ru2emRqokj1jUf6xqc03QIg==
  template:
    metadata:
      creationTimestamp: null
      name: db-secret
      namespace: demo

Теперь вы можете добавить этот ресурс SealedSecret в Git. Как видите, он содержит секрет, но значения зашифрованы. Только оператор Sealed Secret в кластере имеет закрытый ключ для расшифровки информации.

Примените ресурс SealedSecret

Используйте kubectl, чтобы применить ресурс SealedSecret.

kubectl apply -f sealed-db-secret.yaml

sealedsecret.bitnami.com/db-secret created

После применения SealedSecret срабатывает оператор Sealed Secret, который использует свой закрытый ключ для расшифровки информации и генерирует соответствующий секретный ресурс Kubernetes.

Проверить развертывание

Проверьте развертывание, проверив секреты SealedSecret и Kubernetes в пространстве имен demo.

kubectl get sealedsecrets,secrets -n demo

NAME                                 AGE
sealedsecret.bitnami.com/db-secret   55s
kubectl get secrets db-secret -n demo -o yaml

NAME                         TYPE                                  DATA   AGE
secret/db-secret             Opaque                                2      55s

apiVersion: v1
data:
  password: WTRueXM3ZjEx
  username: cHJvZHVzZXI=
kind: Secret
metadata:
  creationTimestamp: "2020-07-02T09:39:15Z"
  name: db-secret
  namespace: demo
  ownerReferences:
  - apiVersion: bitnami.com/v1alpha1
    controller: true
    kind: SealedSecret
    name: db-secret
    uid: 77d1231f-921c-4335-823f-643ec82fdb78
  resourceVersion: "55133137"
  selfLink: /api/v1/namespaces/demo/secrets/db-secret
  uid: 2df6c273-ca03-4523-b45d-f9849b39b92e
type: Opaque

Резюме

Sealed Secret был разработан, чтобы легко вписаться в автоматизированные рабочие процессы, такие как GitOps. После преобразования секрета Kubernetes в SealedSecret только оператор в кластере может расшифровать исходный секрет. Если вам интересно, вы также можете увидеть, как мы используем Terraform для создания кластера Kubernetes и управления им, нажав на ссылку. С SealedSecret создание и обновление секретов Kubernetes не требует высоких привилегий, что делает его простым и безопасным. Спасибо за прочтение!

Первоначально опубликовано на https://tomcode.com.