87
June 16, 2024, 1:42 p.m.
Передача секретов с помощью Ansible в кластер kubernetes
Задача: составить плейбук для передчи серкретов в определенные namespace из текстов или файлов
Для реализации задачи потребуется определить структуру переменных:
Для текстовых значений
SECRETS:
DOCUMENTSERVER:
values:
- {name: JWT_SECRET, value: dfskldsjfdsjf, namespace: ds-ns, state: present}
EMAIL:
values:
- {name: EMAIL-DB-USER, value: superuser, namespace: email-ns, state: present}
- {name: EMAIL-DB-PASSWORD, value: dsfkdsjkf, namespace: email-ns, state: present}
где:
DOCUMENTSERVER
илиEMAIL
- удобные названия, чтобы не путаться если проектов много;values
- служебный параметр;name
- имя секрета, которое будет преобразовано в нижний регистр, а “_” будут заменены на “-“;value
- содержимое секрета;namespace
- пространство имён куда будет помещён секрте;state
- может принимать в себяtrue
илиfalse
в зависимости от значения секрет будет либо, удалён, либо создан.
Для файлов, по аналогии с кодом выше
SECRETS_FILE:
EMAIL:
values:
- {name: cert.pem, path: cert.pem, namespace: email-ns, state: present}
- {name: key.pem, path: key.pem, namespace: email-ns, state: present}
Плейбуки
Для текстовых секретов
- name: Ensure Kubernetes namespace exists
kubernetes.core.k8s:
kubeconfig: "~/.kube/config"
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ item.1.namespace }}"
loop: "{{ lookup('subelements', SECRETS, 'values', wantlist=True) }}"
when: item.1.namespace is defined and item.1.namespace | length > 0
- name: Create Kubernetes secrets
kubernetes.core.k8s:
kubeconfig: "~/.kube/config"
state: "{{ item.1.state }}"
namespace: "{{ item.1.namespace }}"
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ item.1.name | lower | replace('_', '-') }}-secret"
namespace: "{{ item.1.namespace }}"
type: Opaque
data:
prod: "{{ item.1.value | b64encode }}"
loop: "{{ lookup('subelements', SECRETS, 'values', wantlist=True) }}"
when: item.1.value is defined and item.1.value | length > 0
Для файловых секретов
Нужно обратить внимание на путь, где должны находиться секреты.
- name: Ensure Kubernetes namespace exists
kubernetes.core.k8s:
kubeconfig: "~/.kube/config"
state: present
definition:
apiVersion: v1
kind: Namespace
metadata:
name: "{{ item.1.namespace }}"
loop: "{{ lookup('subelements', SECRETS_FILE, 'values', wantlist=True) }}"
when: item.1.path is defined and item.1.path | length > 0
- name: Create Kubernetes secrets from files
kubernetes.core.k8s:
kubeconfig: "~/.kube/config"
state: "{{ item.1.state }}"
namespace: "{{ item.1.namespace }}"
definition:
apiVersion: v1
kind: Secret
metadata:
name: "{{ item.1.name | lower | replace('_', '-') }}-secret"
namespace: "{{ item.1.namespace }}"
type: Opaque
data:
prod: "{{ lookup('template', './files/secrets/' + item.1.path) | b64encode }}"
loop: "{{ lookup('subelements', SECRETS_FILE, 'values', wantlist=True) }}"
when: item.1.path is defined and item.1.path | length > 0
Подключение секрета в Deployment
# ========== ENVS =============
env:
- name: TZ
value: "Europe/Moscow"
- name: EMAIL_DB_DRIVER
value: "pgsql"
- name: EMAIL_DB_USER
valueFrom:
secretKeyRef:
name: email-db-user-secret
key: prod
# ====== VOLUME MOUNTS =======
volumeMounts:
- name: cert-secret-volume
mountPath: /mnt/SSL/cert.pem
subPath: cert.pem
readOnly: true
- name: key-secret-volume
mountPath: /mnt/SSL/key.pem
subPath: key.pem
readOnly: true
# ======== VOLUMES ==========
volumes:
- name: cert-secret-volume
secret:
secretName: cert.pem-secret
items:
- key: prod
path: cert.pem
- name: key-secret-volume
secret:
secretName: key.pem-secret
items:
- key: prod
path: key.pem