Mencipta penjadual kube tambahan dengan set peraturan penjadualan tersuai

Mencipta penjadual kube tambahan dengan set peraturan penjadualan tersuai

Penjadual Kube ialah komponen penting Kubernetes, yang bertanggungjawab untuk menjadualkan pod merentas nod mengikut dasar yang ditetapkan. Selalunya, semasa pengendalian gugusan Kubernetes, kita tidak perlu memikirkan dasar yang digunakan untuk menjadualkan pod, kerana set dasar penjadual kube lalai sesuai untuk kebanyakan tugas harian. Walau bagaimanapun, terdapat situasi apabila penting bagi kami untuk memperhalusi proses memperuntukkan pod, dan terdapat dua cara untuk menyelesaikan tugas ini:

  1. Buat penjadual kube dengan set peraturan tersuai
  2. Tulis penjadual anda sendiri dan ajar ia berfungsi dengan permintaan pelayan API

Dalam artikel ini, saya akan menerangkan pelaksanaan perkara pertama untuk menyelesaikan masalah penjadualan perapian yang tidak sekata pada salah satu projek kami.

Pengenalan ringkas tentang cara kube-scheduler berfungsi

Perlu diperhatikan terutamanya fakta bahawa kube-scheduler tidak bertanggungjawab untuk menjadualkan pod secara langsung - ia hanya bertanggungjawab untuk menentukan nod untuk meletakkan pod. Dalam erti kata lain, hasil kerja kube-scheduler ialah nama nod, yang ia kembalikan kepada pelayan API untuk permintaan penjadualan, dan di situlah kerjanya berakhir.

Pertama, kube-scheduler menyusun senarai nod yang pod boleh dijadualkan mengikut dasar predikat. Seterusnya, setiap nod daripada senarai ini menerima bilangan mata tertentu mengikut dasar keutamaan. Akibatnya, nod dengan bilangan mata maksimum dipilih. Jika terdapat nod yang mempunyai skor maksimum yang sama, satu rawak dipilih. Senarai dan perihalan dasar predikat (penapisan) dan keutamaan (pemarkahan) boleh didapati dalam dokumentasi.

Penerangan mengenai badan bermasalah

Walaupun sejumlah besar kluster Kubernetes berbeza dikekalkan di Nixys, kami mula-mula menghadapi masalah penjadualan pod baru-baru ini, apabila salah satu projek kami perlu menjalankan sejumlah besar tugas berkala (~100 entiti CronJob). Untuk memudahkan penerangan masalah sebanyak mungkin, kami akan mengambil sebagai contoh satu perkhidmatan mikro, di mana tugas cron dilancarkan sekali seminit, menghasilkan sedikit beban pada CPU. Untuk menjalankan tugas cron, tiga nod dengan ciri yang sama sekali telah diperuntukkan (24 vCPU pada setiap satu).

Pada masa yang sama, adalah mustahil untuk menyatakan dengan tepat berapa lama CronJob akan mengambil masa untuk dilaksanakan, kerana volum data input sentiasa berubah. Secara purata, semasa operasi biasa kube-scheduler, setiap nod menjalankan 3-4 contoh kerja, yang menghasilkan ~20-30% daripada beban pada CPU setiap nod:

Mencipta penjadual kube tambahan dengan set peraturan penjadualan tersuai

Masalahnya sendiri ialah kadangkala pod tugas cron berhenti dijadualkan pada salah satu daripada tiga nod. Iaitu, pada satu ketika, tiada satu pod dirancang untuk salah satu nod, manakala pada dua nod yang lain 6-8 salinan tugas sedang dijalankan, menghasilkan ~40-60% daripada beban CPU:

Mencipta penjadual kube tambahan dengan set peraturan penjadualan tersuai

Masalah itu berulang dengan kekerapan rawak mutlak dan kadangkala dikaitkan dengan saat versi baharu kod dilancarkan.

Dengan meningkatkan tahap pengelogan penjadual kube ke tahap 10 (-v=10), kami mula merekodkan bilangan mata yang diperoleh setiap nod semasa proses penilaian. Semasa operasi perancangan biasa, maklumat berikut boleh dilihat dalam log:

resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node03: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1387 millicores 4161694720 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node02: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1347 millicores 4444810240 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node03: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1387 millicores 4161694720 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node01: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1687 millicores 4790840320 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node02: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1347 millicores 4444810240 memory bytes, score 9
resource_allocation.go:78] cronjob-1574828880-mn7m4 -> Node01: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1687 millicores 4790840320 memory bytes, score 9
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: NodeAffinityPriority, Score: (0)                                                                                       
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node01: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: TaintTolerationPriority, Score: (10)                                                                                   
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node02: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node01: SelectorSpreadPriority, Score: (10)                                                                                                        
interpod_affinity.go:237] cronjob-1574828880-mn7m4 -> Node03: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node02: SelectorSpreadPriority, Score: (10)                                                                                                        
selector_spreading.go:146] cronjob-1574828880-mn7m4 -> Node03: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node01: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node02: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574828880-mn7m4_project-stage -> Node03: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:781] Host Node01 => Score 100043                                                                                                                                                                        
generic_scheduler.go:781] Host Node02 => Score 100043                                                                                                                                                                        
generic_scheduler.go:781] Host Node03 => Score 100043

Itu. berdasarkan maklumat yang diperoleh daripada log, setiap nod mendapat jumlah mata akhir yang sama dan satu rawak dipilih untuk perancangan. Pada masa perancangan bermasalah, log kelihatan seperti ini:

resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1587 millicores 4581125120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1087 millicores 3532549120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node02: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1587 millicores 4581125120 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: BalancedResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 987 millicores 3322833920 memory bytes, score 9
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node01: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 987 millicores 3322833920 memory bytes, score 9 
resource_allocation.go:78] cronjob-1574211360-bzfkr -> Node03: LeastResourceAllocation, capacity 23900 millicores 67167186944 memory bytes, total request 1087 millicores 3532549120 memory bytes, score 9
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node03: InterPodAffinityPriority, Score: (0)                                                                                                        
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node02: InterPodAffinityPriority, Score: (0)                                                                                                        
interpod_affinity.go:237] cronjob-1574211360-bzfkr -> Node01: InterPodAffinityPriority, Score: (0)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node03: SelectorSpreadPriority, Score: (10)                                                                                                        
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node02: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: TaintTolerationPriority, Score: (10)                                                                                   
selector_spreading.go:146] cronjob-1574211360-bzfkr -> Node01: SelectorSpreadPriority, Score: (10)                                                                                                        
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node03: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: TaintTolerationPriority, Score: (10)                                                                                   
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node02: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: NodeAffinityPriority, Score: (0)                                                                                       
generic_scheduler.go:726] cronjob-1574211360-bzfkr_project-stage -> Node01: SelectorSpreadPriority, Score: (10)                                                                                    
generic_scheduler.go:781] Host Node03 => Score 100041                                                                                                                                                                        
generic_scheduler.go:781] Host Node02 => Score 100041                                                                                                                                                                        
generic_scheduler.go:781] Host Node01 => Score 100038

Dari mana dapat dilihat bahawa salah satu nod mendapat mata akhir yang lebih sedikit daripada yang lain, dan oleh itu perancangan dijalankan hanya untuk dua nod yang mendapat markah maksimum. Oleh itu, kami pasti yakin bahawa masalahnya terletak pada penjadualan pod.

Algoritma selanjutnya untuk menyelesaikan masalah adalah jelas kepada kami - menganalisis log, faham dengan keutamaan apa yang nod tidak mendapat mata dan, jika perlu, laraskan dasar penjadual kube lalai. Walau bagaimanapun, di sini kita berhadapan dengan dua kesukaran yang ketara:

  1. Pada tahap pembalakan maksimum (10), mata yang diperoleh hanya untuk beberapa keutamaan ditunjukkan. Dalam petikan log di atas, anda dapat melihat bahawa untuk semua keutamaan yang ditunjukkan dalam log, nod menjaringkan bilangan mata yang sama dalam penjadualan biasa dan masalah, tetapi keputusan akhir dalam kes perancangan masalah adalah berbeza. Oleh itu, kita boleh membuat kesimpulan bahawa untuk beberapa keutamaan, pemarkahan berlaku "di belakang tabir", dan kita tidak mempunyai cara untuk memahami keutamaan yang mana nod tidak mendapat mata. Kami menerangkan masalah ini secara terperinci dalam isu Repositori Kubernetes pada Github. Pada masa penulisan, maklum balas diterima daripada pembangun bahawa sokongan pengelogan akan ditambah dalam kemas kini Kubernetes v1.15,1.16, 1.17 dan XNUMX.
  2. Tidak ada cara mudah untuk memahami set kube-scheduler dasar tertentu yang sedang digunakan. Ya, dalam dokumentasi senarai ini disenaraikan, tetapi ia tidak mengandungi maklumat tentang pemberat khusus yang diberikan kepada setiap dasar keutamaan. Anda boleh melihat pemberat atau mengedit dasar penjadual kube lalai sahaja dalam sumber.

Perlu diingat bahawa sebaik sahaja kami dapat merekodkan bahawa nod tidak menerima mata mengikut dasar ImageLocalityPriority, yang memberikan mata kepada nod jika ia sudah mempunyai imej yang diperlukan untuk menjalankan aplikasi. Iaitu, pada masa versi baharu aplikasi itu dilancarkan, tugas cron berjaya dijalankan pada dua nod, memuat turun imej baharu daripada pendaftaran docker kepada mereka, dan dengan itu dua nod menerima skor akhir yang lebih tinggi berbanding dengan yang ketiga .

Seperti yang saya tulis di atas, dalam log kami tidak melihat maklumat tentang penilaian dasar ImageLocalityPriority, jadi untuk menyemak andaian kami, kami membuang imej dengan versi baharu aplikasi ke nod ketiga, selepas itu penjadualan berfungsi dengan betul . Justru kerana dasar ImageLocalityPriority, masalah penjadualan diperhatikan agak jarang; lebih kerap ia dikaitkan dengan sesuatu yang lain. Disebabkan fakta bahawa kami tidak dapat menyahpepijat sepenuhnya setiap dasar dalam senarai keutamaan penjadual kube lalai, kami memerlukan pengurusan fleksibel dasar penjadualan pod.

Pernyataan masalah

Kami mahu penyelesaian kepada masalah itu sespesifik mungkin, iaitu entiti utama Kubernetes (di sini kami maksudkan penjadual kube lalai) harus kekal tidak berubah. Kami tidak mahu menyelesaikan masalah di satu tempat dan menciptanya di tempat lain. Oleh itu, kami sampai kepada dua pilihan untuk menyelesaikan masalah, yang diumumkan dalam pengenalan artikel - membuat penjadual tambahan atau menulis sendiri. Keperluan utama untuk menjadualkan tugas cron adalah untuk mengagihkan beban secara sama rata merentas tiga nod. Keperluan ini boleh dipenuhi oleh dasar penjadual kube sedia ada, jadi untuk menyelesaikan masalah kami tidak ada gunanya menulis penjadual anda sendiri.

Arahan untuk mencipta dan Meletakkan penjadual kube tambahan diterangkan dalam dokumentasi. Walau bagaimanapun, kami nampaknya entiti Deployment tidak mencukupi untuk memastikan toleransi kesalahan dalam pengendalian perkhidmatan kritikal seperti kube-scheduler, jadi kami memutuskan untuk menggunakan kube-scheduler baharu sebagai Static Pod, yang akan dipantau secara langsung oleh Kubelet. Oleh itu, kami mempunyai keperluan berikut untuk penjadual kube baharu:

  1. Perkhidmatan mesti digunakan sebagai Pod Statik pada semua induk kluster
  2. Toleransi kesalahan mesti disediakan sekiranya pod aktif dengan kube-scheduler tidak tersedia
  3. Keutamaan utama semasa merancang hendaklah bilangan sumber yang tersedia pada nod (LeastRequestedPriority)

Penyelesaian pelaksanaan

Perlu diingat dengan segera bahawa kami akan menjalankan semua kerja dalam Kubernetes v1.14.7, kerana Ini adalah versi yang digunakan dalam projek. Mari mulakan dengan menulis manifesto untuk penjadual kube baharu kami. Mari kita ambil manifes lalai (/etc/kubernetes/manifests/kube-scheduler.yaml) sebagai asas dan bawanya ke borang berikut:

kind: Pod
metadata:
  labels:
    component: scheduler
    tier: control-plane
  name: kube-scheduler-cron
  namespace: kube-system
spec:
      containers:
      - command:
        - /usr/local/bin/kube-scheduler
        - --address=0.0.0.0
        - --port=10151
        - --secure-port=10159
        - --config=/etc/kubernetes/scheduler-custom.conf
        - --authentication-kubeconfig=/etc/kubernetes/scheduler.conf
        - --authorization-kubeconfig=/etc/kubernetes/scheduler.conf
        - --v=2
        image: gcr.io/google-containers/kube-scheduler:v1.14.7
        imagePullPolicy: IfNotPresent
        livenessProbe:
          failureThreshold: 8
          httpGet:
            host: 127.0.0.1
            path: /healthz
            port: 10151
            scheme: HTTP
          initialDelaySeconds: 15
          timeoutSeconds: 15
        name: kube-scheduler-cron-container
        resources:
          requests:
            cpu: '0.1'
        volumeMounts:
        - mountPath: /etc/kubernetes/scheduler.conf
          name: kube-config
          readOnly: true
        - mountPath: /etc/localtime
          name: localtime
          readOnly: true
        - mountPath: /etc/kubernetes/scheduler-custom.conf
          name: scheduler-config
          readOnly: true
        - mountPath: /etc/kubernetes/scheduler-custom-policy-config.json
          name: policy-config
          readOnly: true
      hostNetwork: true
      priorityClassName: system-cluster-critical
      volumes:
      - hostPath:
          path: /etc/kubernetes/scheduler.conf
          type: FileOrCreate
        name: kube-config
      - hostPath:
          path: /etc/localtime
        name: localtime
      - hostPath:
          path: /etc/kubernetes/scheduler-custom.conf
          type: FileOrCreate
        name: scheduler-config
      - hostPath:
          path: /etc/kubernetes/scheduler-custom-policy-config.json
          type: FileOrCreate
        name: policy-config

Secara ringkas tentang perubahan utama:

  1. Menukar nama pod dan bekas kepada kube-scheduler-cron
  2. Menentukan penggunaan port 10151 dan 10159 sebagai pilihan ditakrifkan hostNetwork: true dan kami tidak boleh menggunakan port yang sama seperti kube-scheduler lalai (10251 dan 10259)
  3. Menggunakan parameter --config, kami menentukan fail konfigurasi yang mana perkhidmatan harus dimulakan
  4. Pemasangan konfigurasi fail konfigurasi (scheduler-custom.conf) dan fail dasar penjadualan (scheduler-custom-policy-config.json) daripada hos

Jangan lupa bahawa penjadual kube kami memerlukan hak yang serupa dengan hak lalai. Edit peranan klusternya:

kubectl edit clusterrole system:kube-scheduler

...
   resourceNames:
    - kube-scheduler
    - kube-scheduler-cron
...

Sekarang mari kita bincangkan tentang perkara yang harus terkandung dalam fail konfigurasi dan fail dasar penjadualan:

  • Fail konfigurasi (scheduler-custom.conf)
    Untuk mendapatkan konfigurasi penjadual kube lalai, anda mesti menggunakan parameter --write-config-to daripada dokumentasi. Kami akan meletakkan konfigurasi yang terhasil dalam fail /etc/kubernetes/scheduler-custom.conf dan mengurangkannya kepada bentuk berikut:

apiVersion: kubescheduler.config.k8s.io/v1alpha1
kind: KubeSchedulerConfiguration
schedulerName: kube-scheduler-cron
bindTimeoutSeconds: 600
clientConnection:
  acceptContentTypes: ""
  burst: 100
  contentType: application/vnd.kubernetes.protobuf
  kubeconfig: /etc/kubernetes/scheduler.conf
  qps: 50
disablePreemption: false
enableContentionProfiling: false
enableProfiling: false
failureDomains: kubernetes.io/hostname,failure-domain.beta.kubernetes.io/zone,failure-domain.beta.kubernetes.io/region
hardPodAffinitySymmetricWeight: 1
healthzBindAddress: 0.0.0.0:10151
leaderElection:
  leaderElect: true
  leaseDuration: 15s
  lockObjectName: kube-scheduler-cron
  lockObjectNamespace: kube-system
  renewDeadline: 10s
  resourceLock: endpoints
  retryPeriod: 2s
metricsBindAddress: 0.0.0.0:10151
percentageOfNodesToScore: 0
algorithmSource:
   policy:
     file:
       path: "/etc/kubernetes/scheduler-custom-policy-config.json"

Secara ringkas tentang perubahan utama:

  1. Kami menetapkan schedulerName kepada nama perkhidmatan kube-scheduler-cron kami.
  2. Dalam parameter lockObjectName anda juga perlu menetapkan nama perkhidmatan kami dan pastikan bahawa parameter leaderElect ditetapkan kepada benar (jika anda mempunyai satu nod induk, anda boleh menetapkannya kepada palsu).
  3. Menentukan laluan ke fail dengan perihalan dasar penjadualan dalam parameter algorithmSource.

Perlu melihat lebih dekat pada titik kedua, di mana kita mengedit parameter untuk kunci leaderElection. Untuk memastikan toleransi kesalahan, kami telah mendayakan (leaderElect) proses memilih ketua (master) antara pod penjadual kube kami menggunakan satu titik akhir untuk mereka (resourceLock) bernama kube-scheduler-cron (lockObjectName) dalam ruang nama sistem kube (lockObjectNamespace). Cara Kubernetes memastikan ketersediaan tinggi komponen utama (termasuk penjadual kube) boleh didapati dalam artikel.

  • Fail dasar penjadualan (scheduler-custom-policy-config.json)
    Seperti yang saya tulis sebelum ini, kita boleh mengetahui dasar khusus mana yang berfungsi dengan penjadual kube lalai hanya dengan menganalisis kodnya. Iaitu, kami tidak boleh mendapatkan fail dengan dasar penjadualan untuk kube-scheduler lalai dengan cara yang sama seperti fail konfigurasi. Mari kita terangkan dasar penjadualan yang kita minati dalam fail /etc/kubernetes/scheduler-custom-policy-config.json seperti berikut:

{
  "kind": "Policy",
  "apiVersion": "v1",
  "predicates": [
    {
      "name": "GeneralPredicates"
    }
  ],
  "priorities": [
    {
      "name": "ServiceSpreadingPriority",
      "weight": 1
    },
    {
      "name": "EqualPriority",
      "weight": 1
    },
    {
      "name": "LeastRequestedPriority",
      "weight": 1
    },
    {
      "name": "NodePreferAvoidPodsPriority",
      "weight": 10000
    },
    {
      "name": "NodeAffinityPriority",
      "weight": 1
    }
  ],
  "hardPodAffinitySymmetricWeight" : 10,
  "alwaysCheckAllPredicates" : false
}

Oleh itu, kube-scheduler mula-mula menyusun senarai nod yang mana pod boleh dijadualkan mengikut dasar GeneralPredicates (yang merangkumi satu set dasar PodFitsResources, PodFitsHostPorts, HostName dan MatchNodeSelector). Dan kemudian setiap nod dinilai mengikut set dasar dalam tatasusunan keutamaan. Untuk memenuhi syarat tugas kami, kami menganggap bahawa set dasar sedemikian akan menjadi penyelesaian yang optimum. Biar saya ingatkan anda bahawa satu set dasar dengan huraian terperincinya tersedia dalam dokumentasi. Untuk menyelesaikan tugas anda, anda hanya boleh menukar set dasar yang digunakan dan memberikan pemberat yang sesuai kepada mereka.

Kami akan memanggil manifes kube-scheduler baharu, yang kami buat pada permulaan bab, kube-scheduler-custom.yaml dan meletakkannya di laluan berikut /etc/kubernetes/manifests pada tiga nod induk. Jika semuanya dilakukan dengan betul, Kubelet akan melancarkan pod pada setiap nod, dan dalam log penjadual kube baharu kami, kami akan melihat maklumat bahawa fail dasar kami telah berjaya digunakan:

Creating scheduler from configuration: {{ } [{GeneralPredicates <nil>}] [{ServiceSpreadingPriority 1 <nil>} {EqualPriority 1 <nil>} {LeastRequestedPriority 1 <nil>} {NodePreferAvoidPodsPriority 10000 <nil>} {NodeAffinityPriority 1 <nil>}] [] 10 false}
Registering predicate: GeneralPredicates
Predicate type GeneralPredicates already registered, reusing.
Registering priority: ServiceSpreadingPriority
Priority type ServiceSpreadingPriority already registered, reusing.
Registering priority: EqualPriority
Priority type EqualPriority already registered, reusing.
Registering priority: LeastRequestedPriority
Priority type LeastRequestedPriority already registered, reusing.
Registering priority: NodePreferAvoidPodsPriority
Priority type NodePreferAvoidPodsPriority already registered, reusing.
Registering priority: NodeAffinityPriority
Priority type NodeAffinityPriority already registered, reusing.
Creating scheduler with fit predicates 'map[GeneralPredicates:{}]' and priority functions 'map[EqualPriority:{} LeastRequestedPriority:{} NodeAffinityPriority:{} NodePreferAvoidPodsPriority:{} ServiceSpreadingPriority:{}]'

Kini yang tinggal hanyalah untuk menunjukkan dalam spesifikasi CronJob kami bahawa semua permintaan untuk menjadualkan podnya harus diproses oleh penjadual kube baharu kami:

...
 jobTemplate:
    spec:
      template:
        spec:
          schedulerName: kube-scheduler-cron
...

Kesimpulan

Akhirnya, kami mendapat penjadual kube tambahan dengan set dasar penjadualan yang unik, yang kerjanya dipantau terus oleh kubelet. Selain itu, kami telah menetapkan pemilihan pemimpin baharu antara pod penjadual kube kami sekiranya pemimpin lama tidak tersedia atas sebab tertentu.

Aplikasi dan perkhidmatan biasa terus dijadualkan melalui penjadual kube lalai, dan semua tugas cron telah dipindahkan sepenuhnya kepada tugasan baharu. Beban yang dibuat oleh tugas cron kini diagihkan sama rata pada semua nod. Memandangkan kebanyakan tugas cron dilaksanakan pada nod yang sama dengan aplikasi utama projek, ini telah mengurangkan dengan ketara risiko memindahkan pod kerana kekurangan sumber. Selepas memperkenalkan penjadual kube tambahan, masalah dengan penjadualan tugas cron yang tidak sekata tidak lagi timbul.

Baca juga artikel lain di blog kami:

Sumber: www.habr.com

Tambah komen