Kubernetes’ın her geçen gün ağırlığını hissettirmesiyle birlike geliştiricilerin de ilgisi artmakta. Bu ilgiye paralel olarak sistem yöneticileri ve güvenlik ekiplerinin de yakın takibinde. Enterprisecoding olarak destek verdiğimiz ekiplere ilk tavsiyemiz sürece küçük projelerle başlamaları. Bu sayede neyle karşı karşıya kalacakları hakkında fikir sahibi olurken alacakları riskde görece daha düşük olacaktır. Yönetilebilirlik Kubernetes ile çözümler sunarken ilk değindimiz nokta olmakta. Standartlar, otomasyonlar ve kontrol noktaları… Baştan belirlenmesi ve sıkı tutulması gereken konular. Bu konulara girdiğimizde de ekiplerin rüyaları kaçmaya başlıyor… Yönetilebilirlik…
Bu yazımızda sizlere Kubernetes yönetişimi için önemli bir adım olan OPA Gatekeeper’den bahsedeceğiz. OPA Gatekeeper, yaklaşık 8 ay önce değindimiz Open Policy Agent (OPA) üzerine inşa edilmiş bir projedir. OPA’yı kısaca hatırlatmak gerekirse, en sade şekliyle Cloud Native Computing Foundation (CNCF) destekli bir kural motoru dersek yanlış olmayacaktır. OPA Gatekeeper ise Kubernetes için politikalar belirleterek yönetişiminizi kolaylaştırabileceğiniz bir platformdur. OPA Gatekeeper ile belirlediğiniz kurum politikalarının sadece kağıt üzerinde kalmayıp gerçekten uygulanmasına zorlayabilirsiniz. Hatta bir adım daha öteye giderek bu politikaları diğer firmalar ve kurumlarla da paylaşabilirsiniz.
Kamu; tüm Kubernetes kurulumlarında uyulması gereken standartları OPA Gatekeeper kuralları haline getirip dağıtabilir. BBDK; tüm bankalarda Kubernetes için standartları belirleyerek uyulmasını sağlayabilir. Özel şirketler, tüm Kubernetes kümeleri için ortak bir standart belirleyerek uyumluluğunu kontrol edebilir. Örnekler daha da arttırılabilir…
OPA Gatekeeper, mimarisinin temelinde Admission Controller Webhook‘larını kullanmaktadır. OPA Gatekeeper, kurulumu ardından bir admission controller webhook yapılandırarak yönetimsel taleplerin kontrolüne başlar. Bu mimari aynı zamanda kontrolden geçmeyen taleplerin reddedilebilmesine de imkan sağlamaktadır. Bu sayede örneğin; bir pod oluşturulurken sahibinin etiketle belirtilmesi zorunlu tutulabilir. OPA Gatekeeper görevi yerine getirirken altta yatan OPA motoruna sadece yapılan talebi iletmekle kalmayıp aynı zamanda Kubernetes kümesinin mevcut durumunu da iletmektedir. Bu sayede politikalarda sadece talep değil küme durumu da göz önüne alınabilir hale geliyor. Örneğin; bir servis oluşturulurken küme içerisinde tekil olmasını sağlayacak label’lara sahip olmalıdır diyebilirsiniz.
OPA Gatekeeper kuralları aynı diğer Kubernetes kaynakları gibi CRD’ler üzerinden tanımlanmaktadır. Bu sayede tekrar tekrar kullanılabilir, dağıtılabilirler. Söz konusu tanımlar kısıtlama şablonları olarak geçmektedirler. Kısıtlama şablonları içinde kısıtlar için kullanılacak CRD’lere ait doğrulama bilgileri ile kısıtın çalışmasına ait akışı barındırmaktadırlar. Kısıt akışı politikaları ifade etmemiz için geliştirilmiş bir üst seviye dil olan rego ile ifade edilmektedirler. Kısıtlama şablonları sayesinde Kubernetes yöneticileri detaylı bir rego bilgisine sahip olmasalar bile hazır şablonları kullanarak kolaylıkla Kubernetes politikaları belirleyebilirler.
Kurulum
OPA Gatekeeper’ı kullanabilmek için (webhook’lara eklenen zaman aşım parametresinden dolayı) minimumda Kubernetes 1.14 olmalıdır. Her ne kadar alt dağıtımlar için kurulum sırasında doğrulama baypass edilerek OPA Gatekeeper kurulumu yapılabilse de tavsiye edilmemektedir. Kurulumu gerçekleştirecek kullanıcını küme yöneticisi yetkisine sahip olmalıdır. İki farklı şekilde kurulum yapılabilir.
İlk yöntemde github deposunda yer alan kaynak dosyası uygulanır;
kubectl apply -f https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/deploy/gatekeeper.yaml
Alternatif olarak Helm v2 kullanıyorsanız aşağıdaki şekilde helm chart olarak kurabilirsiniz;
helm repo add gatekeeper https://raw.githubusercontent.com/open-policy-agent/gatekeeper/master/charts/gatekeeper helm install gatekeeper/gatekeeper --devel
Kullanım
OPA Gatekeeper uygulayacağı politikaları Kubernetes CRD’si olarak almaktadır. Kurulum ardından yeni bir politikayı uygulamak için öncelikle politikaya ait bir kısıtlama şablonu tanımlamalısınız. Kısıtlama şablonu templates.gatekeeper.sh/v1beta1 altında ve ConstraintTemplate türünde olmalıdır. Yukarıda da belirttiğimiz gibi kısıtlama şablonları tanımladıkları CRD doğrulaması ve rego dilinde kısıt ifadesini barındırmaktadırlar. validation bölümünde verilen CRD doğrulaması sayesinde tasarıma aykırı bir kayıt oluşturulmasının da önüne geçilecektir.
Konunun netleşmesi adına bir senaryo üzerinden gitmek daha doğru olacaktır. Aşağıda tanımını bulacağınız ConstraintTemplate ile belirtilen bir Kubernetes kaynağı için yine belirtilen etiketlerin bulunması zorunlu hale getirilmekte.
Aşağıdaki komutu çalıştırın;
cat <<EOF | kubectl apply -f - apiVersion: templates.gatekeeper.sh/v1beta1 kind: ConstraintTemplate metadata: name: k8srequiredlabels spec: crd: spec: names: kind: K8sRequiredLabels listKind: K8sRequiredLabelsList plural: k8srequiredlabels singular: k8srequiredlabels validation: # 'Parameters' alanı için kullanılacak şema openAPIV3Schema: properties: labels: type: array items: string targets: - target: admission.k8s.gatekeeper.sh rego: | package k8srequiredlabels violation[{"msg": msg, "details": {"missing_labels": missing}}] { provided := {label | input.review.object.metadata.labels[label]} required := {label | label := input.parameters.labels[_]} missing := required - provided count(missing) > 0 msg := sprintf("you must provide labels: %v", [missing]) } EOF
Kısıtlama tanımı olduktan sonra artık elinizde bir şablon var. Öte yandan bu şablon bir aksiyon almayacak, sadece bir tanım olarak kalacaktır. Bu şablonu kullanmak için yapbozun eksik parçalarının yer alacağı kısıt oluşturmalısınız.
Kısıtlama şablonumuzu inceleyelim; 10-13. satırlar arasında OPA Gatekeeper’a K8sRequiredLabels adıyla yeni bir CRD hakkında bilgi vermekte. Bizim oluşturduğumuz bu yeni CRD türü yine kısıt kontrollünde kullanılmak üzere 16-20. satırlar arasında tanımlandığı şekliyle labels parametresi alacaktır. 24-32. satırlar arasında kısıt doğrulamasına dair rego ifadesi belirtilmekte. Bu rego ifadesi kontrolü istenen CRD içerisindeki etiketleri inceleyerek içerisinde zorunlu tutulan etiketin olup olmadına bakmaktadır. Zorunlu etiketin bulunamaması durumunda “you must provide labels: … ” ifadesi ile hata vererek işlemin gerçekleştirilmesini engellemektedir.
Bu detaylar ardından artık kısıtı oluşturabiliriz. Aşağıdaki komutu çalıştırarak kısıtın oluşturun;
cat <<EOF | kubectl apply -f - apiVersion: constraints.gatekeeper.sh/v1beta1 kind: K8sRequiredLabels metadata: name: ns-enterprisecoding-etiketi-olmali spec: match: kinds: - apiGroups: [""] kinds: ["Namespace"] parameters: labels: ["enterprisecoding"] EOF
Oluşturulması ardından, ns-enterprisecoding-etiketi-olmali adındaki kısıtımız tüm namespace CRD’lerinde devreye girerek işletilecek. Parametre olarak verilen değer kullanılarak oluşturulan tüm namespace’lerde enterprisecoding etiketinin olup olmadığı kontrol edilecektir. Kontrol etmek adına aşağıdaki komutu çalıştırılabilir;
kubectl create ns enterprisecoding-test
Komutun çalıştırılması ardından, gerekli etiketler olmadığı için create komutu OPA Gatekeeper tarafından aşağıdaki mesajla hata verip namespace’in oluşturulması engellenecektir;
Error from server ([denied by ns-enterprisecoding-etiketi-olmali] you must provide labels: {“enterprisecoding”}): admission webhook “validation.gatekeeper.sh” denied the request: [denied by ns-enterprisecoding-etiketi-olmali] you must provide labels: {“enterprisecoding”}

Namespace’i bu defa aşağıdaki şekilde etiket vererek oluşturabiliriz;
cat <<EOF | kubectl apply -f - apiVersion: v1 kind: Namespace metadata: name: enterprisecoding-test labels: enterprisecoding: rocks EOF