Kubernetes External Secret Operator

External Secret Operator, kubernetes uygulamalarımız içerisinde kullandığımız, kullanacağımız secret’ ları harici bir secret management aracından kubernetes secret’ ları içerisine almak için kullanılan bir kubernetes operatörüdür.

Bunlar(external secret provider); Aws Secret Manager, Azure Key Vault, Hashicorp Vault, Google Secrets Manager vb olabilir.

External Secret Operator birçok secret management aracına, yazılımına, api’ ler ile bağlanır ve bu araçlarla senkron bir şekilde çalışabilir.

Image 3

Kubernetes External Secret Operatör çalışma stratejisi;

ESO(External Secret Operator)’ da önemli 3 adet resources mevcut bunlar;

SecretStore: Namespace bazlı secret store, adından da anlaşılacağı gibi namespace e özgü external secret deposu.

ClusterSecretStore: Tüm namespace’ lerden erişilebilen SecretStore olarak tanımlayabiliriz.

ExternalSecret: Yapılandırmaları baz alarak, hangi secret’ ların alınıp, cluster içinde hangi secret’ ların oluşturulacağını belirler.

Şimdi External Secret Operatör’ ün kurulumunu yapıp, Hashicorp Vault ile entegrasyonunu tamamlayalım. Bir örnek external secret’ ı alıp cluster’ a getirelim.

Bunun için şöyle ilerleyeceğiz;

Kubernetes External Secret Operatör’ ü kuracağız, SecretStore oluşturacağız, İstediğimiz ExternalSecret konfigürasyonunu oluşturup Vault’ tan secret’ ı getireceğiz.

Öncelikle bir önceki makalemi takip ederek vaul kurulumunu yapabilirsiniz. Buraya tıklayarak makaleye ulaşabilirsiniz.

ESO kurulumu;

ESO’ yu helm ile kubernetes cluster’ ımıza hızlıca kuralım;

helm repo add external-secrets-operator https://charts.external-secrets.io/
helm install my-external-secrets external-secrets-operator/external-secrets --version 0.9.18

Kurulum sonrasında pod’ larımızın running state’ e geçtiğini görebiliriz, vault running state e geçmediyse unseal yapmanız gerekebilir.

Image 4 1024x131

Şimdi bir SecretStore oluşturalım.SecretStore için aşağıdaki yaml dosyasını kullanabilirsiniz, token base64 kodlanmış olarak giriliyor, normalde token’ ı kubernetes ortamınızda secret olarak tanımlayıp daha güvenli bir şekilde saklayıp kullanabilirsiniz, örnek olması sebebiyle ben base64 ile kodlayıp direk yazdım. Aşağıdaki komutu kullanarak kodlayıp yazabilirsiniz vault token’ ınızı.

echo -n "s.R3c3MyS3cRe7T0ken" | base64

apiVersion: external-secrets.io/v1beta1
kind: SecretStore 
metadata:
  name: secret-store-vault
  namespace: default
spec:
  provider:
    vault:
      server: "http://10.105.202.36:8200"
      version: "v2"
      auth:
        tokenSecretRef:
          name: "vault-token"
          key: "token"
---
apiVersion: v1
kind: Secret
metadata:
  name: vault-token
  namespace: default
type: Opaque
data:
  token: "aHZzLklCVVFQMmN3NTAxQ2ZHeVNjM1ppc0lnUQ=="

secretstore.yaml dosyanızı oluşturup çalıştırdığınızda kubectl get secretstore komutu ile secretstore’ unuzun validation durumunu kontrol edebilirsiniz, herşey yolundaysa aşağıdaki gibi bir çıktı almanız gerekmektedir.

Image 5

Herşey yolunda gözüktüğüne göre şimdi vault üzerinde hızlıca bir kv tanımlayıp bir test yapalım;

vault pod’ una exec olup, bir kv engine oluşturup, test secretlarımızı girelim.

/ $ vault secrets enable -path=secret kv-v2

Success! Enabled the kv-v2 secrets engine at: secret/
/ $
/ $ vault kv put secret/devwebapp/config username='mada' password='vault'
======== Secret Path ========
secret/data/devwebapp/config

======= Metadata =======
Key                Value
---                -----
created_time       2024-05-19T16:11:58.553506094Z
custom_metadata    <nil>
deletion_time      n/a
destroyed          false
version            1

Secret’ larımızı da oluşturduğumuza göre şimdi externalsecret.yaml dosyamızı oluşturup, secret’ lara erişebilecek hale geldiğimiz senaryoya geçelim. yaml dosyasını çalıştırdıktan sonra kubectl get externalsecret komutu ile synced çıktısını almayı bekliyoruz.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: external-secret
spec:
  refreshInterval: "15s"
  secretStoreRef:
    name: secret-store-vault
    kind: SecretStore
  target:
    name: vault-external-secret
    creationPolicy: Owner
  data:
    - secretKey: my-username
      remoteRef:
        key: secret/devwebapp/config
        property: username
    - secretKey: my-password
      remoteRef:
        key: secret/devwebapp/config
        property: password
Image 7

Şimdiki durumu kısaca özetleyelim, sistemde kubernetes external secret operatörümüz var, vault var, secretstore oluşturduk, store ‘umuz vault ile haberleşebiliyor root_token ile, bir de externalsecret oluşturduk, içerisinde kv engine üzerinde oluşturduğumuz secretlar mevcut ve state’ i sync!

Bir deployment üzerinden externalsecret’ ımızı referans göstererek secret’ lara erişelim.

Dikkat etmemiz gereken nokta: target: vault-external-secret olarak tanımlamıştık. Şimdi nginx.yaml dosyamızı oluşturup çalıştıralım.

apiVersion: apps/v1
kind: Deployment
metadata:
  name: "nginx-app"
  labels:
    app: "nginx-app"
spec:
  replicas: 1
  selector:
    matchLabels:
      app: "nginx-app"
  template:
    metadata:
      labels:
        app: "nginx-app"
    spec:
      containers:
      - name: "nginx-app"
        image: "nginx"
        imagePullPolicy: Always
        ports:
        - containerPort: 80
        envFrom:
        - secretRef:
            name: vault-external-secret

Pod’ umuz running state’ e geçtikten sonra exec olup env yazıp bakalım, secret’ ların gelmiş olmasını bekliyoruz.

kubectl exec -it nginx-app-589cb9c6b4-4cnlf /bin/bash
kubectl exec [POD] [COMMAND] is DEPRECATED and will be removed in a future version. Use kubectl exec [POD] -- [COMMAND] instead.
root@nginx-app-589cb9c6b4-4cnlf:/# env
my-password=vault
my-username=mada
KUBERNETES_SERVICE_PORT_HTTPS=443

Görüldüğü üzere externalsecret üzerinden my-password ve my-username’i aldık. Planladığımız noktaya ulaşmış olduk.

Faydalı Olması Dileklerimle,

Yorum bırakın

E-posta adresiniz yayınlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir