Розповсюдження облікових даних з використанням Secret

Ця сторінка показує, як безпечно передати чутливі дані, такі як паролі та ключі шифрування, у Podʼи.

Перш ніж ви розпочнете

Вам треба мати кластер Kubernetes, а також інструмент командного рядка kubectl має бути налаштований для роботи з вашим кластером. Рекомендується виконувати ці настанови у кластері, що має щонайменше два вузли, які не виконують роль вузлів управління. Якщо у вас немає кластера, ви можете створити його, за допомогою minikube або використовувати одну з цих пісочниць:

Перетворення ваших секретних даних у base64

Припустимо, ви хочете мати дві частини секретних даних: імʼя користувача my-app та пароль 39528$vdg7Jb. Спочатку використайте інструмент кодування base64, щоб перетворити ваше імʼя користувача та пароль на base64. Ось приклад використання загальнодоступної програми base64:

echo -n 'my-app' | base64
echo -n '39528$vdg7Jb' | base64

Вивід показує, що base64 варіант вашого імені користувача — bXktYXBw, а base64 вашого пароля — Mzk1MjgkdmRnN0pi.

Створіть Secret

Ось файл конфігурації, який ви можете використати для створення Secret, що містить ваше імʼя користувача та пароль:

apiVersion: v1
kind: Secret
metadata:
  name: test-secret
data:
  username: bXktYXBw
  password: Mzk1MjgkdmRnN0pi
  1. Створіть Secret

    kubectl apply -f https://k8s.io/examples/pods/inject/secret.yaml
    
  2. Перегляньте інформацію про Secret:

    kubectl get secret test-secret
    

    Вивід:

    NAME          TYPE      DATA      AGE
    test-secret   Opaque    2         1m
    
  3. Перегляньте більш детальну інформацію про Secret:

    kubectl describe secret test-secret
    

    Вивід:

    Name:       test-secret
    Namespace:  default
    Labels:     <none>
    Annotations:    <none>
    
    Type:   Opaque
    
    Data
    ====
    password:   13 bytes
    username:   7 bytes
    

Створіть Secret безпосередньо за допомогою kubectl

Якщо ви хочете пропустити крок кодування Base64, ви можете створити такий самий Secret, використовуючи команду kubectl create secret. Наприклад:

kubectl create secret generic test-secret --from-literal='username=my-app' --from-literal='password=39528$vdg7Jb'

Це зручніше. Детальний підхід, показаний раніше, розглядає кожен крок явно, щоб продемонструвати, що відбувається.

Створіть Pod, який має доступ до секретних даних через Том

Ось файл конфігурації, який ви можете використати для створення Podʼа:

apiVersion: v1
kind: Pod
metadata:
  name: secret-test-pod
spec:
  containers:
    - name: test-container
      image: nginx
      volumeMounts:
        # ім'я повинно відповідати імені тома нижче
        - name: secret-volume
          mountPath: /etc/secret-volume
          readOnly: true
  # Дані секрету доступні контейнерам у Podʼі через том.
  volumes:
    - name: secret-volume
      secret:
        secretName: test-secret
  1. Створіть Pod:

    kubectl apply -f https://k8s.io/examples/pods/inject/secret-pod.yaml
    
  2. Перевірте, що ваш Pod працює:

    kubectl get pod secret-test-pod
    

    Вивід:

    NAME              READY     STATUS    RESTARTS   AGE
    secret-test-pod   1/1       Running   0          42m
    
  3. Отримайте доступ до оболонки в контейнері, що працює у вашому Podʼі:

    kubectl exec -i -t secret-test-pod -- /bin/bash
    
  4. Секретні дані доступні контейнеру через Том, змонтований у /etc/secret-volume.

    У вашій оболонці перегляньте файли у теці /etc/secret-volume:

    # Виконайте це в оболонці всередині контейнера
    ls /etc/secret-volume
    

    Вивід показує два файли, один для кожної частини секретних даних:

    password username
    
  5. У вашій оболонці gthtukzymnt вміст файлів username та password:

    # Виконайте це в оболонці всередині контейнера
    echo "$( cat /etc/secret-volume/username )"
    echo "$( cat /etc/secret-volume/password )"
    

    Вивід — ваше імʼя користувача та пароль:

    my-app
    39528$vdg7Jb
    

Змініть ваш образ або командний рядок так, щоб програма шукала файли у теці mountPath. Кожен ключ у масиві data Secretʼу стає імʼям файлу у цій теці.

Спроєцюйте ключі Secret на конкретні шляхи файлів

Ви також можете контролювати шляхи в томі, куди проєцюються ключі Secret. Використовуйте поле .spec.volumes[].secret.items, щоб змінити шлях для кожного ключа:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
      readOnly: true
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      items:
      - key: username
        path: my-group/my-username

При розгортанні цього Podʼа відбувається наступне:

  • Ключ username з mysecret доступний контейнеру за шляхом /etc/foo/my-group/my-username замість /etc/foo/username.
  • Ключ password з цього Secret не проєцюється.

Якщо ви отримуєте перелік ключів явно за допомогою .spec.volumes[].secret.items, розгляньте наступне:

  • Проєцюються тільки ключі, вказані у items.
  • Щоб використовувати всі ключі з Secret, всі вони повинні бути перераховані у полі items.
  • Усі перераховані ключі повинні існувати у відповідному Secret. Інакше Том не створюється.

Встановіть POSIX-права доступу до ключів Secret

Ви можете встановити POSIX права доступу до файлів для окремого ключа Secret. Якщо ви не вказали жодних дозволів, стандартно використовується 0644. Ви також можете встановити стандартно режим файлу POSIX для всього тому Secret, і ви можете перевизначити його за потреби для кожного ключа.

Наприклад, ви можете вказати режим стандартно так:

apiVersion: v1
kind: Pod
metadata:
  name: mypod
spec:
  containers:
  - name: mypod
    image: redis
    volumeMounts:
    - name: foo
      mountPath: "/etc/foo"
  volumes:
  - name: foo
    secret:
      secretName: mysecret
      defaultMode: 0400

Секрет Secret у /etc/foo; всі файли, створені томом секрету, мають дозволи 0400.

Визначте змінні середовища контейнера, використовуючи дані з Secret

Ви можете використовувати дані у Secret як змінні середовища у ваших контейнерах.

Якщо контейнер вже використовує Secret у змінній середовища, оновлення Secret не буде видно контейнеру, якщо він не буде перезапущений. Існують сторонні рішення для виклику перезавантажень, коли змінюються Secret.

Визначення змінної середовища контейнера з даними з одного Secret

  • Визначте змінну середовища як пару ключ-значення в Secret:

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    
  • Призначте значення backend-username, визначене у Secret, змінній середовища SECRET_USERNAME у специфікації Podʼа.

    apiVersion: v1
    kind: Pod
    metadata:
      name: env-single-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: SECRET_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-single-secret-env-variable.yaml
    
  • У вашій оболонці покажіть вміст змінної середовища контейнера SECRET_USERNAME.

    kubectl exec -i -t env-single-secret -- /bin/sh -c 'echo $SECRET_USERNAME'
    

    Вивід схожий на:

    backend-admin
    

Визначення змінних середовища контейнера з даними з декількох Secret

  • Як і у попередньому прикладі, спочатку створіть Secretʼи.

    kubectl create secret generic backend-user --from-literal=backend-username='backend-admin'
    kubectl create secret generic db-user --from-literal=db-username='db-admin'
    
  • Визначте змінні середовища у специфікації Podʼа.

    apiVersion: v1
    kind: Pod
    metadata:
      name: envvars-multiple-secrets
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        env:
        - name: BACKEND_USERNAME
          valueFrom:
            secretKeyRef:
              name: backend-user
              key: backend-username
        - name: DB_USERNAME
          valueFrom:
            secretKeyRef:
              name: db-user
              key: db-username
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-multiple-secret-env-variable.yaml
    
  • У вашій оболонці покажіть змінні середовища контейнера.

    kubectl exec -i -t envvars-multiple-secrets -- /bin/sh -c 'env | grep _USERNAME'
    

    Вивід схожий на:

    DB_USERNAME=db-admin
    BACKEND_USERNAME=backend-admin
    

налаштування всіх пар ключ-значення в Secret як змінних середовища контейнера

  • Створіть Secret, що містить декілька пар ключ-значення

    kubectl create secret generic test-secret --from-literal=username='my-app' --from-literal=password='39528$vdg7Jb'
    
  • Використовуйте envFrom, щоб визначити всі дані Secret як змінні середовища контейнера. Ключ з Secret стає імʼям змінної середовища у Pod.

    apiVersion: v1
    kind: Pod
    metadata:
      name: envfrom-secret
    spec:
      containers:
      - name: envars-test-container
        image: nginx
        envFrom:
        - secretRef:
            name: test-secret
    
  • Створіть Pod:

    kubectl create -f https://k8s.io/examples/pods/inject/pod-secret-envFrom.yaml
    
  • У вашій оболонці покажіть змінні середовища контейнера username та password.

    kubectl exec -i -t envfrom-secret -- /bin/sh -c 'echo "username: $username\npassword: $password\n"'
    

    Вивід схожий на:

    username: my-app
    password: 39528$vdg7Jb
    

Приклад: Надавання операційних/тестових облікових даних Podʼам за допомогою Secret

У цьому прикладі показано Pod, який використовує Secret, що містить облікові дані операційного середовища, і ще один Pod, який використовує Secret з обліковими даними тестового середовища.

  1. Створіть Secret для облікових даних операційного середовища:

    kubectl create secret generic prod-db-secret --from-literal=username=produser --from-literal=password=Y4nys7f11
    

    Вивід схожий на:

    secret "prod-db-secret" created
    
  2. Створіть Secret для облікових даних тестового середовища.

    kubectl create secret generic test-db-secret --from-literal=username=testuser --from-literal=password=iluvtests
    

    Вивід схожий на:

    secret "test-db-secret" created
    
  3. Створіть маніфести Podʼів:

    cat <<EOF > pod.yaml
    apiVersion: v1
    kind: List
    items:
    - kind: Pod
      apiVersion: v1
      metadata:
        name: prod-db-pod
      spec:
        containers:
        - name: prod-db-container
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: prod-db-secret
                key: password
          - name: MYSQL_DATABASE
            value: mydatabase
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: prod-db-secret
                key: username
    - kind: Pod
      apiVersion: v1
      metadata:
        name: test-db-pod
      spec:
        containers:
        - name: test-db-container
          image: mysql
          env:
          - name: MYSQL_ROOT_PASSWORD
            valueFrom:
              secretKeyRef:
                name: test-db-secret
                key: password
          - name: MYSQL_DATABASE
            value: mydatabase
          - name: MYSQL_USER
            valueFrom:
              secretKeyRef:
                name: test-db-secret
                key: username
    EOF
    
  4. Застосуйте всі ці обʼєкти на сервер API, виконавши:

    kubectl create -f pod.yaml
    

Обидва контейнери матимуть у своїх файлових системах наступні файли зі значеннями для кожного середовища контейнера:

/etc/secret-volume/username
/etc/secret-volume/password

Ви також можете подальшим спрощенням базової специфікації Podʼа використовуючи два службові облікові записи:

  1. prod-user з prod-db-secret
  2. test-user з test-db-secret

Специфікація Podʼа скорочується до:

apiVersion: v1
kind: Pod
metadata:
  name: prod-db-client-pod
  labels:
    name: prod-db-client
spec:
  serviceAccount: prod-db-client
  containers:
  - name: db-client-container
    image: myClientImage

Довідка

Що далі

  • Дізнайтеся більше про Secret.
  • Дізнайтеся про Томи.
Змінено August 22, 2024 at 6:59 PM PST: upstream sync (b7f2b32b60)