Kubernetes External Secrets Operator Nedir?
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 Manager, HashiCorp Vault, Google Secrets Manager, Azure Key Vault, IBM Cloud Secrets Manager, CyberArk 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
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.