Kubernetes Scheduling (Zamanlama) 19/20

Merhaba arkadaşlar, yavaş yavaş Kubernetes Eğitim Serimizi sonlandırıyoruz. Umarım bu süre içerisinde size faydalı olabilmişimdir. Sizlere birşeyler katabilmek, sorularınıza cevap verebilmek benim için çok önemli, eğer kafanıza takılan bir sorun veya bir konu var ise ilgili konuya yorum atabilirsiniz.

Bu bölümde arkadaşlar scheduling (zamanlama) konusunu öğreneceğiz. Bu bölümle birlikte;

  • kube-scheduler zamanlayıcısının nasıl programlandığını öğrenecek,
  • pod zamanlayıcısını kullanmak için label’ları kullanabilecek,
  • taint ve toleration’ları yapılandırabilecek,
  • podAffinity ve podAntiAffinity nesnelerini kullanabilecek,
  • birden fazla scheduler’ın nasıl çalıştığını anlayabileceksiniz.

kube-scheduler

Bir kubernetes’in konuşlandırılması ne kadar büyük ve çeşitli olursa scheduler yönetimi kadar önemli olabilir. kube-scheduler hangi node’ların topolojiye duyarlı bir algoritma kullanarak bir pod çalıştıracağını belirler.

Kullanıcılar, daha yüksek öncelikli bir pod’un korunmasına izin verecek bir pod önceliği belirleyebilir. Düşük öncelikli pod’ların çıkarılması, daha yüksek pod’ların planlanmasına izin verecektir.

Scheduler, cluster’ınızdaki node’ları izler, bunları bir tahmin cluster’ına göre filtreler, ardından her bir pod’un hangi node’da zamanlanacağını belirlemek için öncelikli işlevler kulanır. Varsayılan olarak scheduler kararı node ve pod’lardaki label’ların kullanılmasıyla etkilenebilir.

Filtrelemeler (Predicates)

Scheduler, uygun node’ları bulmak için bir dizi filtreden geçer ve tahminde bulunur. Ardından öncelikli işlevleri kullanarak her bir node’u sıralar. Pod’u dağıtmak için en yüksek dereceye sahip node seçilir.

filtrelemeSiralamalari= []string{CheckNodeConditionPred,
GeneralPred, HostNamePred, PodFitsHostPortsPred,
MatchNodeSelectorPred, PodFitsResourcesPred, NoDiskConflictPred,
PodToleratesNodeTaintsPred, PodToleratesNodeNoExecuteTaintsPred,
CheckNodeLabelPresencePred, checkServiceAffinityPred,
MaxEBSVolumeCountPred, MaxGCEPDVolumeCountPred,
MaxAzureDiskVolumeCountPred, CheckVolumeBindingPred,
NoVolumeZoneConflictPred, CheckNodeMemoryPressurePred,
CheckNodeDiskPressurePred, MatchInterPodAffinityPred}

PodFitsHost veya NoDiskConflict gibi filtreler, belirli ve yapılandırılabilr bir sırada değerlendirilir. Bu şekilde bir node, yeni bir pod’un konuşlandırılması için en az miktarda kontrol içerir; eğer node uygun durumda değilse, bir node’u gereksiz kontrollerde dışlamak faydalı olabilir.

Öncelikler (Priorities)

Öncelikler kaynakların kullanımını ayarlamak için kullanılan fonksiyonlardır. Pod ve node benzeşimi, mevcut çalışan podların sayısına göre node’ları sıralayan SelectorSpreadPriority ayarıan göre yapılandırılmadığı sürece, en az pod içeren node’u seçecektir. Bu pod’ları cluster’a yaymanın temel bir yoludur.

Özel cluster ihtiyaçları için diğer önceliler kullanılabilir. ImageLocalityPriorityMap, önceden container image’ları indirmiş olan node’ları tercih eder. Toplam image boyutu, en yüksek önceliğe sahip olanlarla karşılaştırılır ancak kullanıalcak image’i kontrol etmez.

Zamanlama Politikaları (Scheduling Policies)

Varsayılan olarak scheduler bir dizi tahmin ve öncelik içerir; ancak, bunlar bir scheduler politika dosyası aracılığıyla değiştirilebilir.

Kısa bir versiyon aşağıda verilmiştir;

"kind" : "Policy",
"apiVersion" : "v1",
"predicates" : [
        {"name" : "MatchNodeSelector", "order": 6},
        {"name" : "PodFitsHostPorts", "order": 2},
        {"name" : "PodFitsResources", "order": 3},       
        {"name" : "NoDiskConflict", "order": 4},
        {"name" : "PodToleratesNodeTaints", "order": 5},
        {"name" : "PodFitsHost", "order": 1}
        ],
"priorities" : [
        {"name" : "LeastRequestedPriority", "weight" : 1},
        {"name" : "BalancedResourceAllocation", "weight" : 1},
        {"name" : "ServiceSpreadingPriority", "weight" : 2},
        {"name" : "EqualPriority", "weight" : 1}
        ],
"hardPodAffinitySymmetricWeight" : 10
}

Genellikle –policy-config-file parametresi kullanılarak bir zamanlayıcı yapılandırılır ve –scheduler-name parametresini kullanarak bu zamanlayıcı için bir ad tanımlarsınız.

Birden fazla zamanlayıcı ile pod ayırmada çatışma olabilir. Her pod hangi zamanlayıcının kullanılması gerektiğini bildirmelidir. Ancak, ayrı zamanlayıcılıar bir node’un kullanılabilir kaynaklar nedeniyle uygun olduğunu belirler ve her ikisi de dağıtılmaya çalışılır, bu da kaynağın artık bulunmamasına neden olur ve bir çatışma ortaya çıkar.

Mevcut çözüm yerel kubelet’lerin pod’ları yeniden atama için zamanlayıcıya döndürmesi içindir. Sonunda bir pod başarılı olacak ve diğeri başka bir yerde zamanlanmış olacak.

Pod Yapılandırmaları

Çoğu zamanlama kararı, pod yapılandırmalarının bir parçası olarak alınabilir. Bir pod belirtimi, zamanlamayı bildiren birkaç alan içerir;

  • nodeName
  • nodeSelector
  • affinity
  • schedulerName
  • tolerations

nodeName ve nodeSelector seçenekleri bir pod’un tek bir node’a veya belirli label’lara sahip bir node gurubuna atanmasına izin verir.

Afinity ve anti-affinity zamanlayıcı tarafından hangi node’un kullanılmasını gerektirmek veya tercih etmek için kullanılabilir.

Bir toleration, bir pod’un taint’ini görmezden gelmesine ve diğer şartların karşılandığı varsayılarak zamanlanmasına izin verir.

Bu seçenlerden hiçbiri cluster’ın gereksinimlerini karşılamıyorsa, özel bir zamanlayıcı dağıtabilirsiniz. Her pod daha sonra hangi programın kullanılacağını seçmek için bir schedulerName özelliği içerir.

Node’a Label Belirleme

Bir pod belirtiminde nodeSelector alanı, bir veya daha fazla key-value çifti kullanılarak bir node’u hedeflemenin kolay bir yolunu sunar. Örneğin;

....
spec:
  containers:
  - name: redis
    image: redis
  nodeSelector:
    net: fast

nodeSelector öğesinin ayarlanması zamanlayıcıya, pod’u label’larla eşleşen bir node’a yerleştirmesini söyler. Listelenen tüm selector’lerin yerine getirilmesi gerekir, ancak node’da daha fazla label bulunabilir. Eşlenen label’larda bir node bulunana kadar pod beklemede (pending) kalacaktır.

Affinity/anti-affinity kullanımı her özelliği nodeSelector olarak ifade edebilmelidir. Affinity kararlı hale geldiğinde, plan nodeSelector öğesinin kullanımdan kaldırılmasıdır.

Pod Affinity Kuralları

Çoklu iletişim kurabilen veya veri paylaşabilen pod’lar birlikte bulunmaları durumunda en iyi şekilde çalışabilir. bu bir affinity biçimi olur. Daha fazla hataya dayanıklılık için pod’ların olabildiğince ayrı olmasını ve bunun anti-affinity olmasını isteyebilirsiniz. Bu ayarlar zaten çalışan pod’ların label’larını temel olarak zamanlayıcı tarafından kullanılır. Sonuç olarak zamanlayıcı her node’u sorgulamalı ve çalışan pod label’larını izlemelidir. Birkaç yüz node’dan oluşan büyük cluster’lar önemli performans kaybı görebilir. Pod affinity kuralları In, NotIn, Exists ve DoesNotExist operatörlerini kullanır.

Affinity ve podAffinity ayarlarının bir örneği aşağıda görülebilir. Bu aynı zamanda pod başladığında eşleşmesi gereken belirli bir label gerektirir ancak label daha sonra kaldırılırsa gerekli olmaz.

....
spec:
  affinity:
    podAffinity:  
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: security
            operator: In
            values: - S1
        topologyKey: failure-domain.beta.kubernetes.io/zone

Bildirilen kod parçasında pod, security label’ı ve S1 değeri olan bir pod çalıştıran bir node’da zamanlanabilir. Bu gereklilik karşılanmazsa pod bekleme (pending) durumunda kalır.

PodAffinity’de benzer şekilde belirli bir label’ı olan bir node’dan kaçınmayı sağlar. Bu durumda zamanlayıcı bir security anahtarına S2 değerine ayarlanmış bir node’dan kaçınmayı tercih edecektir. Örnek aşağıda yer almaktadır.

....
podAntiAffinity:
  preferredDuringSchedulingIgnoredDuringExecution:
  - weight: 100
    podAffinityTerm:
      labelSelector:
        matchExpressions:
        - key: security
          operator: In
          values:
          - S2
      topologyKey: kubernetes.io/hostname

Node Affinity Kuralları

Pod Affinity/Anti-Affinity diğer pod’larla ilgiliylen nodeAffinity node label’larını temel olan pod zamanlayıcısına izin verir. Zamanlayıcı diğer pod’lara değil node’ların label’larına bakacaktır. Bu çok sayıda node’da olsa bile cluster üzerinde daha az performans etkisi yaratmalıdır.

Örnek kullanım aşağıda verilmiştir.

....
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/colo-tx-name
            operator: In
            values:
            - tx-aus
            - tx-dal
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: disk-speed
            operator: In
            values:
            - fast
            - quick 

Birinci nodeAffinity kuralı iki olası değerden birine sahip olan bir node gerektirir: tx-aus, tx-dal.

İkinci kural fast veya quick bir değere sahip bir disk-speed anahtarına sahip düğümlere weight (öncelik) değeri verir. Pod bazı düğümlerde zamanlanacaktır. Her durumda bu sadece belirli bir label’ı tercih eder.

Taints

Belirli bir taint’e sahip bir node, bu taint’e toleration olmadıkça pod’ların oluşumunu red edecektir. Bir taint key=value parçası olarak ifade edilir.

Kullanılan key=value (anahtar=değer) herhangi bir dize olabilir ve bu pod’ların herhangi bir ihtiyaca bağlı olmadan node’larda çalışmasını engelleme esnekliği sağlar. Bir pod’un mevcut bir toleration’ı yoksa zamanlayıcı taint olarak işaret edilmiş node’u dikkate almayacaktır.

Pod zamanlayıcıyı tetiklemesi için üç yol vardır.

  • NoSchedule: Zamanlayıcı, toleratin olmadıkça node’da bir pod zamanlamaz. Mevcut pod’lar toleration gözetmeksizin çalışmaya devam eder.
  • PreferNoSchedule: Zamanlayıcı, taint olmadığı sürece bu pod’da zamanlama yapmasına engel olacaktır. Mevcut pod’lar etkilenmez.
  • NoExecute: Bu değer mevcut pod’ların node içerisinden boşaltılmasına ve gelecekte pod’ların burada zamanlanmamasına neden olur. Mevcut bir pod’da toleration olduğu zaman devam eder.

Tolerations

Bir node’daki toleration’ların ayarlaması, taint’e sahip pod’ları zamanlamak için kullanılır. Bu node’u kullanan pod’ları engellemenin kolay bir yolunu sağlar. Sadece belirli bir toleration’ı olanlar zamanlanacaktır.

tolerations:
- key: "server"
  operator: "Equal"
  value: "ap-east"
  effect: "NoExecute"
  tolerationSeconds: 3600

Yukarıdaki örnekte, pod NoExecute olarak işaretlendikten sonra 3600 saniye boyunca server anahtarına sahip ve ap-east değeri içeren(Equal burada tetikleniyor) yerde kalacaktır. Süre bittiğinde pod çıkarılacaktır.

Kubernetes cluster’ı içerisinde kube-scheduler’ın çalışma mantığını öğrendik, bir pod’u bir node’dan nasıl sakındıracağımızı veya ona nasıl bağlı kılacağımızı öğrendik. Bir sonraki yazımda burada teorisini vermiş olduğum zamanlama(scheduler) bölümünün laboratuvarına buradan ulaşabilirsiniz. Sevgiler saygılar!!

Umarım bu yazı sizin için bilgilendirici olmuştur. Yazıyla ilgili bir sorunuz, görüşünüz veya isteğiniz varsa alt kısımda bulunan yorumlardan veya mail adresimden iletişime geçebilirsiniz. Bu yazının başkaları içinde bilgilendirici olduğunu düşünüyorsanız sosyal olun ve sosyal medyada paylaşın! Okuduğunuz için teşekkürler !!!!

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir