Kubernetes External Secrets Operator Nedir?
4 min read

Kubernetes External Secrets Operator Nedir?

External Secrets Operator, secret provider'lar üzerindeki secret'larınıza cluster içinden erişebilmeniz için bir abstraction sunar.
Kubernetes External Secrets Operator Nedir?
Photo by Stefan Steinbauer / Unsplash

External Secrets Operator, secret'ları external bir secret provider'dan Kubernetes secret'larına almak için kullanılan bir Kubernetes Operator'dur.

Uygulamanızın kullanacağı secret'ları saklayabilmeniz için piyasada AWS Secrets ManagerHashiCorp VaultGoogle Secrets ManagerAzure Key VaultIBM Cloud Secrets ManagerCyberArk Conjur gibi onlarca secret provider bulunuyor. Ve siz bunlardan herhangi birini kullanıyor olabilirsiniz. Fakat maaliyet, performans, optimizasyon gibi herhangi bir sebepten ötürü provider'ı değiştirmek istediğinizde bir yığın entegrasyon ve zaman/kaynak israfı gibi zorlu bir süreçle tekrar uğraşmak zorunda kalacaksınız. Üstelik çok fazla key bulundurduğunuzda, bu provider'ların limitlerine takılmanız veya AIP istek ücretleriyle karşılaşmanız da oldukça olası.

External Secrets Operator, birçok secret provider'ı API'lar aracılığıyla entegre ederek size bir abstraction sunar. Böylece, ne sebeple olursa olsun, bir secret provider değişikliği yaptığınızda tek yapmanız gereken basit birkaç config değişikliğinden öteye geçmemiş olur.

1. External Secrets Operator Nasıl Çalışır?

External Secrets Operator, Kubernetes Custom Resources extension'ı extend ederek external secret'ları nereden ve nasıl alıp, cluster içindeki secret'ları nasıl oluşturacağını belirleyen resource'ları oluşturur.

External Secrets Operator ile oluşturabileceğiniz resource'lar; SecretStore, ClusterSecretStore ve ExternalSecret resource'larıdır.

  • SecretStore, namespaced bir resource'dur ve external API'e nasıl erişebileceğimizi belirler. Vault, AWS, GCP gibi secret provider'lara erişim bilgilerini tutar.
  • ClusterSecretStore, tek bir namespace yerine tüm namespace'lerden erişilebilen bir SecretStore'dur.
  • ExternalSecret, hangi secret'ların işleneceğini ve cluster içinde hangi secret'larının oluşturulacağını belirler.

2. External Secrets Operator Kurulumu

External Secrets Operator kurulumu için Helm chart kullanabilirsiniz.

helm repo add external-secrets https://charts.external-secrets.io

helm install external-secrets \
   external-secrets/external-secrets \
    -n external-secrets \
    --create-namespace \

3. External Secrets Operator Kullanımı

Temel kavramları anladıktan WS Secret Manager ile bir örneğimizi yapalım.

3.1. SSM Secret Oluşturmak

İlk olarak örneğimizde çekmeye çalışacağımız örnek secret'ı, AWS Secret Manager tarafında oluşturalım ve adına dev/backend_credentials verelim.

{
  "backend": {"username": "dbadmin", "password": "@WftEst&esuDKU"}
}

3.2. SecretStore Oluşturmak

Oluşturduğumuz secret'ı kendi cluster'ımızda bir secret olarak oluşturabilmek için önce SecretStore'u yapılandırmamız lazım. Fakat SecretStore nesneleri namespace bazında kullanılır. Eğer siz tüm namespace'lerin aynı bağlantı bilgilerini kullanabilmesini isterseniz ClusterSecretStore nesnesi oluşturabiliriz.

apiVersion: external-secrets.io/v1beta1
kind: ClusterSecretStore
metadata:
  name: secretstore-awssm
spec:
  provider:
    aws:
      service: SecretsManager
      region: us-east-1
      auth:
        secretRef:
          accessKeyIDSecretRef:
            name: awssm-secret
            key: access-key
          secretAccessKeySecretRef:
            name: awssm-secret
            key: secret-access-key

Bu manifest dosyasında secretRef parametresine AWS Secrets Manager servisine ulaşabilecek IAM kullanısının ID ve access key'ini iletmelisiniz. Bu değerleri awssm-secret isimli secret içinden geçtiğimiz gibi sizde bir secret oluşturarak değerleri verebilirsiniz.

apiVersion: v1
kind: Secret
metadata:
  name: awssm-secret
type: Opaque
stringData:
  access-key: "<access_key_id>"
  secret-access-key:  "<secret_access_key>"

Diğer bir seçenek olarak ise IAM kullanıcısı yerine role tanımlayabilirsiniz.

provider:
  aws:
    region: us-east-1
    role: arn:aws:iam::<account-id>:role/EKSRoleForExternalSecrets
    service: ParameterStore

Ve tabiki bu rol gerekli izinlere sahip olmalı:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Effect": "Allow",
            "Action": [
                "secretsmanager:GetResourcePolicy",
                "secretsmanager:GetSecretValue",
                "secretsmanager:DescribeSecret",
                "secretsmanager:ListSecretVersionIds"
            ],
            "Resource": [ "*" ]
        }
    ]
}

3.3. ExternalSecret Oluşturmak

ExternalSecret, hangi remote secret'ların (ssm, valut keyleri vs.), ne sıklıkta ve nasıl dönüştürülerek hangi kubernetes secret'ı olarak kaydedilmesi gerektiğini açıklayan nesnedir.

apiVersion: external-secrets.io/v1beta1
kind: ExternalSecret
metadata:
  name: external-secret-backend-credentials
  namespace: eso
spec:
  refreshInterval: 1m
  secretStoreRef:
    name: secretstore-awssm
    kind: SecretStore
  target:
    name: secret-backend-credentials
    creationPolicy: Owner
  data:
    - secretKey: dbUsername
      remoteRef:
        key: dev/backend_credentials
        property: backend.username 
    - secretKey: dbPassword
      remoteRef:
        key: dev/backend_credentials
        property: backend.password

Bu örnekte, secretstore-awssm SecretStore içindeki erişim bilgileri kullanılarak AWS SSM'e bağlantı sağlanır ve refreshInterval değerinde belirtilen sürede (dakikada bir), remoteRef dizisinde belirtilen key'ler okunarak target ile belirttiğimiz Kubernetes Secret'a secretKey key'leri ile eklenir.

Şimdi manifest dosyamızı çalıştıralım ve ExternalSecret nesnemizi oluşturalım.

$ kubectl create -f externalSecret.yaml
externalsecret.external-secrets.io/external-secret-backend-credentials created

Oluşturulan nesneyi kontrol ettiğimizde, eğer bir sorun yoksa SecretSynced durumunda olduğunu gözlemlemeniz gerekmektedir.

$ kubectl get es -n eso
NAME                                  STORE                             REFRESH INTERVAL   STATUS         READY
external-secret-backend-credentials   secretstore-backend-credentials   1m                 SecretSynced   True

Son olarak ise Secret'ları listelediğimizde, otomatik oluşturulan Secret nesnemizi görebiliriz.

$ kubectl get secrets -n eso
NAME                                              TYPE                                  DATA   AGE
secret-backend-credentials                        Opaque                                2      82s
💡
Eğer remote secret değerinizi güncellerseniz, kubernetes secret değerinizin güncellenmesi için refreshInterval değerinde verdiğiniz süreyi beklemeniz gerekir.

3. Özet

Örnekte de gördüğünüz gibi, External Secrets Operator sayesinde birden fazla secret provider ile bir arada çalışabilir, herhangi bir sebeple provider değiştirdiğinizde sadece SecretStore ayarlayarak geçişi tamamlayabilirsiniz.

Secret keylerin ne sürede bir sync olacağını belirterek, provider'lara çok fazla istek atılmasını engelleyebilir ve böylece API limitleri ve network ücretlerinden kurtulmuş olursunuz.