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.

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.

Ş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.

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

Ş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,