background

Azure Kubernetes Service Püf Noktaları — 1

Azure Kubernetes Service Püf Noktaları — 1

Azure Kubernetes Service (AKS) container orchestration konusunda de-facto hale gelmiş Kubernetes aracının Azure tarafından yönetilen servisine verilen isim. Bu makalede AKS kurulumu ve kullanımı sırasında dikkat edilmesi gereken püf noktalara, Microsoft’un kendi kaynaklarından ve yaşanmış tecrübelerden edindiğim bilgilerle değinmeye çalışacağım.

1. Bölüm — Cluster İzolasyonu ve Yetki Yönetimi

Genelde şirketler uygulamalarını cloud üzerine taşırken pilot olarak seçtikleri uygulamayı düşünürler ve platformları ona göre dizayn ederler. Fakat hem cloud genelinde hem de AKS özelinde uygulamalarınızı taşırken birden fazla uygulamanızın cloud’a taşınacağını varsayıp, bu uygulamaların fiziksel veya mantıksal olarak nasıl ayrılacağını hesaba katmanız gerekir.

Benzer şekilde, aynı uygulamada çalışan onlarca farklı takım, her takımın Dev-Test-Prod ortamları olacaktır. AKS’de bu ayrımları yapmak için aşağıdaki özellikleri kullanabilirsiniz:

  • Scheduling: Bir pod’un hangi node’da çalışacağı, hangi node’da çalışmayacağı, hangi pod ile aynı node’da olup olmayacağı gibi özel scheduling kuralları için node selectors, taints, tolerations, affinities kullanabilirsiniz.
  • Networking: NetworkPolicytipindeki kaynaklarla hangi pod’a hangi pod’dan erişileceği kontrol edilebilir.

  • kind: NetworkPolicy
    apiVersion: networking.k8s.io/v1
    metadata:
    name: backend-policy
    spec:
    podSelector:
    matchLabels:
    app: backend
    ingress:
    - from:
    - podSelector:
    matchLabels:
    app: frontend

  • Authentication ve authorization: Authentication için Azure Active Directory önerilir. Kendi Active Directory’nizi Azure AD ile eşleyerek yetkileri kendi AD kullanıcılarınız üzerinden yapabilirsiniz. Hangi kullanıcıların hangi namespace’lere erişeceği, kimlerin cluster’da admin rolünde olacağı gibi authorization konuları ise RBAC ile yönetilebilir. Pod’ların Azure kaynaklarına erişimleri ise Pod Identities ve secret tipli kaynaklarla yönetilir.
  • Container güvenliği için imaj tarama araçları, runtime açıklarını izleme araçları kullanılır.

Peki cluster izolasyonunu nasıl ve ne durumda yapacağız?

AKS üzerinde farklı takımların birlikte ve izole şekilde çalışması için aynı cluster üzerinde farklı namespace’lerde çalışmaları önerilir. Bu yapı mantıksal izolasyona örnektir.

Aynı uygulamanın Dev, Test, Prod ortamları içinse en azından Prod, Non-Prod ayrımının fiziksel olarak yapılması, yani en az iki ayrı cluster bulundurulması önerilir. Bu şekilde test ortamındaki bir kod veya konfigürasyon ayarının Prod uygulamalarını etkileme ihtimali en aza indirilir.

Farklı uygulamalarınız var ve hepsini AKS üzerine almak istiyorsunuz diyelim. Bu durumda uygulamalarınızın kaynak tüketimi, cluster’ınızın büyüklüğü, Disaster Recovery ihtiyacı, veri hassaslığı gibi konuları göz önüne alarak aynı cluster’da veya farklı cluster’da çalıştırabilirsiniz.

Makalenin geri kalanında yukarıdaki başlıklara biraz daha detaylı değineceğiz.

Temel Scheduler Özellikleri

  • RBAC ve Azure AD yardımıyla farklı takımları farklı namespace’lere ayırdınız diyelim. Bir takımın veya kullanıcının yazdığı hatalı bir kodun cluster’daki tüm kaynakları kullanmasını engellemek için namespace kaynaklarını sınırlamanız gerekir. Bunun için ResourceQuota ve LimitRange kullanımı önerilir. Kaynak yönetiminin nasıl yapılacağı için aşağıdaki makaleye göz atabilirsiniz.
    Kubernetes’te Kaynak Yönetimi
  • Bakım veya cluster upgrade gibi durumlarda AKS node’larınızı tek tek boşaltır, yani upgrade edeceği node’daki pod’ları tek tek öldürür ve farklı bir node’da ayağa kaldırır. Uygulamanızın bu durumdan en az etkilenmesi için Pod disruption budgetlarını kullanabilirsiniz: Cluster upgrade, hardware error, VM silinmesi gibi durumlarda minimum pod sayısını belirlemek için PodDisruptionBudget tipinde resource kullanılır:


    apiVersion: policy/v1beta1
    kind: PodDisruptionBudget
    metadata:
    name: nginx-pdb
    spec:
    minAvailable: 3
    selector:
    matchLabels:
    app: nginx-frontend

  • Yukarıda namespace’lerin kaynak yönetiminin ResourceQuota ve LimitRange ile yapılması gerektiğinden bahsetmiştik. ResourceQuota pod’larınızın limit ve request tanımları olmadan ayağa kalkmasına izin vermez. Fakat ya ResourceQuota tanımlanmadıysa? Bu tanımların eksik olup olmadığını kontrol etmek için Azure ekibinin geliştirdiği kube-advisor kullanımı önerilir.

Gelişmiş Scheduler Özellikleri

  • Bir node’u yalnızca belli uygulamaların çalışması için ayırabilirsiniz. Örneğin yapay zeka uygulamalarınızın GPU kullanan node’larda çalışması gerekebilir ve diğer uygulamaların pod’larının bu pahalı node’larda çalışmasını istemezsiniz. Bunun için Node’a taint ekleyebilirsiniz. Scheduler, Bu taint’i tolerate etmeyen hiçbir pod’un bu node üzerinde ayağa kalkmasına izin vermeyecektir.

  • Örnek bir taint komutu:

    kubectl taint node aks-nodepool1 sku=gpu:NoSchedule

    Ve bu taint’i tolerate etmesini, yani o node’da çalışmasına izin vermek istediğimiz pod’un tanımı:

    kind: Pod
    apiVersion: v1
    metadata:
    name: tf-mnist
    spec:
    containers:
    - name: tf-mnist
    image: microsoft/samples-tf-mnist-demo:gpu
    tolerations:
    - key: "sku"
    operator: "Equal"
    value: "gpu"
    effect: "NoSchedule"

  • Taintler bir node’da pod’ların koşmasını engellemek için kullanılır. Node Selector ise bir pod’un hangi node’da koşacağıyla ilgilenir. Fakat Node Selector diğer pod’lar için herhangi bir kısıtlama yapmaz. Aynı örnek üzerinden ilerlersek yapay zeka için ayırdığınız node için taint yerine Node Selector kullanırsanız yapay zeka uygulamanızın pod’ları doğru node’da ayağa kalkacaktır fakat diğer uygulamalar da aynı node’u kullanabilir. Bir pod’un node selector kullanması için o node’un label’ının olması gerekir. Örneğin:

    kubectl label node aks-nodepool1 hardware:highmem

    Pod’un aynı label ile nodeSelector kullanımı:

    kind: Pod
    apiVersion: v1
    metadata:
    name: tf-mnist
    spec:
    containers:
    - name: tf-mnist
    image: microsoft/samples-tf-mnist-demo:gpu
    nodeSelector:
    hardware: highmem

  • Node Affinity’leri Node selector’ın daha esnek versiyonu gibi düşünebilirsiniz. Node affinity eğer “preferred” ifadesi kullanılıyorsa pod için tercih edilen node’u belirler. Fakat o node’da fazlasıyla pod varsa veya scheduler o tipte bir node bulamazsa pod diğer node’larda ayağa kaldırılır.


    kind: Pod
    apiVersion: v1
    metadata:
    name: tf-mnist
    spec:
    containers:
    - name: tf-mnist
    image: microsoft/samples-tf-mnist-demo:gpu
    affinity:
    nodeAffinity:
    preferredDuringSchedulingIgnoredDuringExecution:
    nodeSelectorTerms:
    - matchExpressions:
    - key: hardware
      operator: In
      values: highmem

    Not: preferredDuringSchedulingIgnoredDuringExecution kısmı nodeAffinity’nin scheduling sırasında geçerli olduğu fakat execution sırasında örneğin label değişimi olduğunda geçersiz olduğunu belirtir. Eğer bu affinity’nin katı şekilde uygulanmasını istiyorsanız preferred yerine required kullanabilirsiniz (requiredDuringSchedulingIgnoredDuringExecution)

  • Affinity ve anti-affinity ise hangi pod’ların hangi pod’larla aynı node üzerinde çalışacağını veya çalışmayacağını belirlemek için kullanılır.


    kind: Pod
    apiVersion: v1
    metadata:
    name: tf-mnist
    spec:
    containers:
    - name: tf-mnist
    image: microsoft/samples-tf-mnist-demo:gpu
    affinity:
    podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
    matchExpressions:
    - key: security
    operator: In
    values:
    - S1

Kimlik Doğrulama ve Yetkilendirme

  • Azure Active Directory ile AKS cluster’ınız içinde kimlik doğrulamayı (authentication) kolayca yönetebilirsiniz. Yetkilendirmeyi (authorization) ise ClusterRole ve Role’leri Azure AD kullanıcıları ve gruplarıyla bind ederek bu role’ler üzerinden yönetebilirsiniz.

  • ClusterRole ve Role ilişkilerine Kubernetes dünyasında verilen isim Role Based Access Control’dur (RBAC). Azure AD üzerinde tanımladığınız gruplara role binding’ler tanımlayarak yetkileri topluca yönetmek önerilen yoldur. finance-app namespace’ine tüm yetkileri veren örnek bir role tanımı:


    kind: Role
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: finance-app-full-access-role
    namespace: finance-app
    rules:
    - apiGroups: [""]
    resources: ["*"]
    verbs: ["*"]

    Bu role’ü kullanıcı gruplarıyla bind etmek için örnek bir binding tanımı:

    kind: RoleBinding
    apiVersion: rbac.authorization.k8s.io/v1
    metadata:
    name: finance-app-full-access-role-binding
    namespace: finance-app
    subjects:
    - kind: Group
    name: [UserGroupId]
    namespace: finance-app
    roleRef:
    kind: Role
    name: finance-app-full-access-role
    apiGroup: rbac.authorization.k8s.io

  • Pod identity Azure tarafından geliştirilmiş bir managed identity çözümüdür. AKS üzerindeki pod’ların Azure üzerinde yönetilen servislere (Azure Cosmos DB, Azure SQL, vb.)güvenli bir şekilde erişmesini sağlar. Henüz yalnızca Linux uygulamalarını destekliyor. AKS üzerindeki uygulamalarınız Azure servislerine ulaşması için kullanımı önerilir.

Şimdilik burada bırakalım. Bir sonraki yazıda güvenlik, image yönetimi, network ve depolama gibi konulara değineceğim.

Kaynak:

Nasıl yardımcı olabiliriz?