Kubernetes Cluster'a Kullanıcı Eklemek ve Sertifika Oluşturmak

Kubernetes cluster'ına kullanıcı eklemek, ilgili cluster'a güvenli bir şekilde erişmek ve yetkileri sınırlandırmak için önemlidir. Bu makalede, Kubernetes cluster'ına bir kullanıcı eklemek için sertifikaların, csr isteğinin ve kubeconfig dosyasının nasıl oluşturulacağına dair adım adım bir kılavuz sunuyoruz.

Kubernetes cluster'a sertifika eklemek için aşağıdaki adımları sırasıyla izlemelisiniz.

1. Kullanıcı İçin Private Key ve Certificate Signing Request (CSR) Oluşturmak

Kubernetes cluster'a eklemek istediğimiz kullanıcı için öncelikle bir private key oluşturmalıyız.

openssl genrsa -out ismet.key 4096

CSR oluşturma kısmı biraz daha karmaşıktır. Oluşturulan kullanıcı için şu alanları doldurmamız gerekiyor:

  • Kullanıcı adı Common Name (CN) alanında kullanılır. Böylece API Server hangi kullanıcının geldiğini CN alanı ile tanımlamada kullanır.
  • Organisation (O) alanında ise grup adı kullanılır. Böylece, API Server kullanıcının hangi gruba ait olduğunu O alanı ile tanımlamada kullanır

Aşağıdaki konfigürasyon, developer ve devops gruplarına dahil olacak ismet kullanıcısı için bir CSR oluşturur.

openssl req -new -key ismet.key -out ismet.csr -subj "/CN=ismet/O=developer/O=devops"
💡
Eğer kullanıcının cluster admini olmasını istiyorsanız grubunu (O) system:masters olarak ayarlayabilirsiniz.

Oluşturulan csr içeriğini kontrol etmek isterseniz aşağıdaki komutu çalıştırabilirsiniz:

openssl req -text -in ismet.csr -noout -verify

Çıktıda verify OK göreceksiniz.

verify OK
Certificate Request:
    Data:
        Version: 0 (0x0)
        Subject: CN=ismet, O=developer, O=devops
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                Public-Key: (4096 bit)
***
***

2. Cluster İçin CSR İsteğini Oluşturmak ve Onaylamak

Kullanıcının CSR dosyası hazır olduğunda artık CertificateSigningRequest kubernetes resource'unu oluşturmalıyız. Böylece bu istekler cluster yöneticisi tarafında onaylanabilir hale gelecektir.

İlk olarak oluşturduğumuz csr dosyasının içeriğini base64 ile encode etmeliyiz.

cat ismet.csr | base64 | tr -d "\n"

Ardından aşağıdaki CertificateSigningRequest manifestinde, request parametresini bu encode edilmiş değer ile değiştirerek kaydediniz.

apiVersion: certificates.k8s.io/v1
kind: CertificateSigningRequest
metadata:
  name: ismet
spec:
  request: <base64 csr çıktısı>
  signerName: kubernetes.io/kube-apiserver-client
  expirationSeconds: 86400
  usages:
  - client auth

Ayrıca;

  • expirationSeconds daha uzun (ör. on gün için 864000) veya daha kısa (ör. bir saat için 3600) yapılabilir.
  • usages 'client auth' olmalıdır

manifest dosyasını ismet-csr.yaml olarak kaydedittikten sonra apply komutuyla CSR isteğini oluşturabiliriz.

kubectl apply -f ismet-csr.yaml

Artık kubectl get csr komutuyla oluşturulan CSR istekleri görebiliriz.

# kubectl get csr
NAME    AGE   SIGNERNAME                            REQUESTOR   REQUESTEDDURATION   CONDITION
ismet   2s    kubernetes.io/kube-apiserver-client   admin       24h                 Pending

Oluşturulan bu isteği kubectl certificate approve ismet komutuyla onaylayabilir veya  kubectl certificate deny ismet komutuyla reddebilirsiniz.

Bir sonraki adıma geçebilmek için ilgili isteği 24 saat içinde onaylamalı ve kubectl get csr komutuyla tekrar listeye baktığınızda Approved, Issued görmelisiniz.

# kubectl get csr
NAME    AGE   SIGNERNAME                            REQUESTOR   REQUESTEDDURATION   CONDITION
ismet   11m   kubernetes.io/kube-apiserver-client   admin       24h                 Approved,Issued
💡
Bir CSR isteğini onaylamadan önce kubectl describe csr komutu ile detaylarını dikkatlice kontrol etmek ve emin olduktan sonra onaylamak güvenlik açısından kritiktir.

3. Onaylanan CSR İsteğinden Bir Sertifika Almak

Bir önceki başlıkta cluster'ımızda CSR oluşturup onayladık ve artık bu onaylanmış sertifika isteği için kullanıcımıza bir sertifika üretmenin zamanı geldi. Sertifika nesnesi, sertifika için gerekli bilgileri içerecektir. Bu bilgiler, sertifika için etki alanı adını, sertifika için geçerlilik süresini ve sertifika için alt etki alanlarını içerecektir.

Onaylanan bir CSR nesnesinden sertifika detaylarını açığa çıkarmak için şu komutu kullanabilirsiniz:

kubectl get csr ismet -o jsonpath='{.status.certificate}'| base64 -d > ismet.crt

Artık ismet.crt isimli sertifika dosyamızla cluster'a bağlanabiliriz.

Ayrıca onaylanan bir sertikanın detaylarını aşağıdaki komutla görebilirsiniz:

openssl x509 -in ismet.crt -noout -text

Örnek çıktı şu şekilde olacaktır:

Certificate:
    Data:
        Version: 3 (0x2)
        Serial Number:
            6f:fa:4d:20:72:8d:e1:96:9c:0e:c0:98:8b:74:b6:11
        Signature Algorithm: sha256WithRSAEncryption
        Issuer: C = US, L = San Francisco, O = Kubernetes, CN = Kubernetes
        Validity
            Not Before: Jul 30 12:52:46 2023 GMT
            Not After : Jul 31 12:52:46 2023 GMT
        Subject: O = devops + O = developer, CN = ismet
        Subject Public Key Info:
            Public Key Algorithm: rsaEncryption
                RSA Public-Key: (4096 bit)
****
****

4. Sertifikayı Config Dosyasına Eklemek

Artık kullanıcı için gerekli ve onaylı olan sertifika ile hedef kubernetes cluster'a bağlanabiliriz. Bunun için sertifikayı oluşturduğumuz kullanıcının key ve sertifika verisiyle kendi .kube/config dosyasını oluşturması veya düzenlemesi gerekir.

İlk kez config dosyası oluşturacaksanız, aşağıdaki config içeriğini doğru verilerle güncelleyip .kube dizini altında config isimli dosya olarak koymalısınız.

apiVersion: v1
clusters:
- cluster:
    certificate-authority-data: <CA-DATA>
    server: https://<APISERVER-HOST>:<APISERVER-PORT>
  name: <CLUSTER-NAME>
contexts:
- context:
    cluster: <CLUSTER-NAME>
    user: <USER>
  name: <USER>@<CLUSTER-NAME>
kind: Config
users:
- name: <USER>
  user:
    client-certificate-data: <CLIENT-CRT-DATA>
    client-key-data: <CLIENT-KEY-DATA>
  • <APISERVER-HOST> ve <APISERVER-PORT> parametrelerini Kubernetes API Server IP adresi ve portuyla güncelleyin.
  • <CA-DATA> parametresini Kubernetes CA sertifikasının base64 encode edilmiş verisiyle güncelleyin.
  • <CLUSTER-NAME> parametresi için clusterter'ı tanıyacağınız bir isim verin.
  • <USER> parametresini sertifika oluştururken verdiğiniz CN de tanımladığınız kullanıcı adı ile güncelleyin
  • <CLIENT-CRT-DATA> parametresini oluşturduğunuz onaylı sertifikanın (ismet.crt) base64 encode edilmiş verisiyle güncelleyin.
  • <CLIENT-KEY-DATA> parametresini en başta oluşturduğunuz private key'in (ismet.key) base64 encode edilmiş verisiyle güncelleyin.
💡
Eğer siz sadece cluster'a dahil olmaya çalışan bir kullanıcıysanız, <APISERVER-HOST>, <APISERVER-PORT> ve <CA-DATA> değerlerini cluster yöneticisinden temin etmelisiniz.
💡
Bir dosya içeriğini Base64 ile encode etmek için cat <file-name> | base64 | tr -d '\n' komutunu kullanabilirsiniz.

Fakat mevcut cluster'a ilgili kullanıcıyı ekleyecekseniz ve .kube/config dosyası zaten mevcutsa, aşağıdaki komutları kullanabilirsiniz.

kubectl config set-credentials <user> \
  --client-certificate=<crt-file> \
  --client-key=<key-file> \
  --embed-certs=true
kubectl config set-context <new-context-name> \
  --cluster=<cluster-name> \
  --namespace=<namespace> \
  --user=<user>

Ve artık eklediğiniz contexti ayarladığınız kullanıcıyla kullanmaya başlayabilirsiniz.

kubectl use-context <new-context-name>

Ardından kubectl config get-contexts veya kubectl  config current-context ile eklediğiniz contexti kontrol edebilirsiniz.

# k config get-contexts
CURRENT   NAME                                       CLUSTER                                    AUTHINFO   NAMESPACE
*         ismet-context                              vke-e275324a-d1e4-4a28-b58a-0a09699468be   ismet      default
# k config current-context
ismet-context

5. Eklenen Kullanıcıyı Yetkilendirmek

Kullanıcıyı cluster'a ekledik fakat yeni kullanıcının context'ini kullanıp bir komut çalıştırdığımızda, basit bir pod listeleme işlemi dahi olsa yetki hatası aldığımızı göreceksiniz.

# k get pods
Error from server (Forbidden): pods is forbidden: User "ismet" cannot list resource "pods" in API group "" in the namespace "default"

RBAC aktif olan bir cluster'da, yeni eklenen tüm kullanıcılar Role ve ClusterRole'lere atanana kadar hiçbir yetkiye sahip değildirler. Bu sebeple eklediğiniz kulanıcıyı hangi amaç için eklemişseniz, o amaca hizmet eden Role veya ClusterRole nesnelerini oluşturup kullanıcınıza atamalısınız.


Kubernetes RBAC, Role, ClusterRole, RoleBinding ve ClusterRoleBinding nesneleri hakkında detaylı bilgi almak ve kullanıcınızı yetkilendirmek için sıradaki yazımızı okuyabilirsiniz.

Kubernetes RBAC ve Role, ClusterRole, RoleBinding ve ClusterRoleBinding Nedir?
Kubernetes RBAC, Kubernetes nesneleri üzerinde izinleri yönetmek için kullanılan bir izin sistemidir. Role, ClusterRole, RoleBinding ve ClusterRoleBinding, Kubernetes RBAC’de kullanılan dört temel kavramdır