Tạo một bộ lập lịch kube bổ sung với bộ quy tắc lập lịch tùy chỉnh

Tạo một bộ lập lịch kube bổ sung với bộ quy tắc lập lịch tùy chỉnh

Kube-scheduler là một thành phần không thể thiếu của Kubernetes, chịu trách nhiệm lên lịch cho các nhóm trên các nút theo các chính sách được chỉ định. Thông thường, trong quá trình vận hành cụm Kubernetes, chúng ta không phải suy nghĩ về việc chính sách nào được sử dụng để lên lịch cho các nhóm, vì bộ chính sách của bộ lập lịch kube-scan mặc định phù hợp với hầu hết các tác vụ hàng ngày. Tuy nhiên, có những tình huống mà chúng ta cần tinh chỉnh quá trình phân bổ nhóm và có hai cách để hoàn thành nhiệm vụ này:

  1. Tạo bộ lập lịch kube với bộ quy tắc tùy chỉnh
  2. Viết lịch trình của riêng bạn và hướng dẫn nó hoạt động với các yêu cầu máy chủ API

Trong bài viết này, tôi sẽ mô tả việc thực hiện điểm đầu tiên để giải quyết vấn đề lập kế hoạch lò sưởi không đồng đều trong một trong các dự án của chúng tôi.

Giới thiệu ngắn gọn về cách hoạt động của kube-scheduler

Điều đặc biệt cần lưu ý là thực tế là kube-scheduler không chịu trách nhiệm lên lịch trực tiếp cho các nhóm - nó chỉ chịu trách nhiệm xác định nút để đặt nhóm trên đó. Nói cách khác, kết quả công việc của kube-scheduler là tên của nút, nút này sẽ trả về máy chủ API để gửi yêu cầu lập lịch và đó là nơi công việc của nút kết thúc.

Đầu tiên, kube-scheduler biên soạn một danh sách các nút mà trên đó nhóm có thể được lên lịch theo các chính sách vị từ. Tiếp theo, mỗi nút trong danh sách này sẽ nhận được một số điểm nhất định theo chính sách ưu tiên. Kết quả là nút có số điểm tối đa sẽ được chọn. Nếu có các nút có cùng điểm tối đa thì một nút ngẫu nhiên sẽ được chọn. Bạn có thể tìm thấy danh sách và mô tả các chính sách vị từ (lọc) và ưu tiên (cho điểm) trong tài liệu.

Mô tả nội dung vấn đề

Mặc dù số lượng lớn các cụm Kubernetes khác nhau đang được duy trì tại Nixys, nhưng lần đầu tiên chúng tôi gặp phải vấn đề về lập lịch nhóm chỉ gần đây, khi một trong các dự án của chúng tôi cần chạy một số lượng lớn nhiệm vụ định kỳ (~100 thực thể CronJob). Để đơn giản hóa việc mô tả vấn đề nhiều nhất có thể, chúng ta sẽ lấy một microservice làm ví dụ, trong đó một tác vụ cron được khởi chạy mỗi phút một lần, tạo ra một số tải cho CPU. Để chạy tác vụ cron, ba nút có đặc điểm hoàn toàn giống nhau đã được phân bổ (24 vCPU trên mỗi nút).

Đồng thời, không thể nói chính xác CronJob sẽ mất bao lâu để thực thi, vì khối lượng dữ liệu đầu vào liên tục thay đổi. Trung bình, trong quá trình hoạt động bình thường của bộ lập lịch kube, mỗi nút chạy 3-4 phiên bản công việc, tạo ra ~20-30% tải cho CPU của mỗi nút:

Tạo một bộ lập lịch kube bổ sung với bộ quy tắc lập lịch tùy chỉnh

Bản thân vấn đề là đôi khi các nhóm tác vụ cron đã ngừng được lên lịch trên một trong ba nút. Nghĩa là, tại một số thời điểm, không một nhóm nào được lên kế hoạch cho một trong các nút, trong khi trên hai nút còn lại, 6-8 bản sao của tác vụ đang chạy, tạo ra ~40-60% tải CPU:

Tạo một bộ lập lịch kube bổ sung với bộ quy tắc lập lịch tùy chỉnh

Sự cố tái diễn với tần suất hoàn toàn ngẫu nhiên và đôi khi tương quan với thời điểm phiên bản mã mới được triển khai.

Bằng cách tăng mức ghi nhật ký của bộ lập lịch kube lên cấp 10 (-v=10), chúng tôi bắt đầu ghi lại số điểm mà mỗi nút đạt được trong quá trình đánh giá. Trong quá trình lập kế hoạch thông thường, thông tin sau có thể được nhìn thấy trong nhật ký:

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

Những thứ kia. đánh giá dựa trên thông tin thu được từ nhật ký, mỗi nút đạt được số điểm cuối cùng bằng nhau và một nút ngẫu nhiên được chọn để lập kế hoạch. Tại thời điểm lập kế hoạch có vấn đề, nhật ký trông như thế này:

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

Từ đó có thể thấy rằng một trong các nút ghi được ít điểm cuối cùng hơn các nút khác và do đó việc lập kế hoạch chỉ được thực hiện đối với hai nút ghi được số điểm tối đa. Vì vậy, chúng tôi chắc chắn tin rằng vấn đề nằm chính xác ở việc sắp xếp lịch trình của các nhóm.

Chúng tôi đã thấy rõ thuật toán tiếp theo để giải quyết vấn đề - phân tích nhật ký, hiểu mức độ ưu tiên mà nút không ghi điểm và nếu cần, hãy điều chỉnh các chính sách của bộ lập lịch kube mặc định. Tuy nhiên, ở đây chúng ta phải đối mặt với hai khó khăn đáng kể:

  1. Ở mức ghi nhật ký tối đa (10), điểm chỉ đạt được đối với một số mức độ ưu tiên sẽ được phản ánh. Trong đoạn trích nhật ký ở trên, bạn có thể thấy rằng đối với tất cả các ưu tiên được phản ánh trong nhật ký, các nút đạt cùng số điểm trong lập kế hoạch bình thường và lập kế hoạch có vấn đề, nhưng kết quả cuối cùng trong trường hợp lập kế hoạch có vấn đề là khác nhau. Do đó, chúng tôi có thể kết luận rằng đối với một số mức độ ưu tiên, việc tính điểm xảy ra “đằng sau” và chúng tôi không có cách nào để hiểu nút nào không nhận được điểm ưu tiên. Chúng tôi đã mô tả vấn đề này một cách chi tiết trong vấn đề Kho lưu trữ Kubernetes trên Github. Tại thời điểm viết bài, đã nhận được phản hồi từ các nhà phát triển rằng hỗ trợ ghi nhật ký sẽ được thêm vào trong các bản cập nhật Kubernetes v1.15,1.16, 1.17 và XNUMX.
  2. Không có cách nào dễ dàng để hiểu bộ chính sách cụ thể nào mà kube-scheduler hiện đang làm việc. Vâng, trong tài liệu danh sách này được liệt kê nhưng không chứa thông tin về trọng số cụ thể được chỉ định cho từng chính sách ưu tiên. Bạn chỉ có thể xem trọng số hoặc chỉnh sửa chính sách của bộ lập lịch kube mặc định trong mã nguồn.

Điều đáng lưu ý là một khi chúng tôi có thể ghi lại rằng một nút không nhận được điểm theo chính sách ImageLocalityPriority, chính sách này sẽ thưởng điểm cho một nút nếu nút đó đã có hình ảnh cần thiết để chạy ứng dụng. Nghĩa là, tại thời điểm phiên bản mới của ứng dụng được triển khai, tác vụ cron được quản lý để chạy trên hai nút, tải hình ảnh mới từ sổ đăng ký docker xuống chúng và do đó hai nút nhận được điểm cuối cùng cao hơn so với nút thứ ba. .

Như tôi đã viết ở trên, trong nhật ký, chúng tôi không thấy thông tin về việc đánh giá chính sách ImageLocalityPriority, vì vậy để kiểm tra giả định của mình, chúng tôi đã đổ hình ảnh có phiên bản mới của ứng dụng vào nút thứ ba, sau đó việc lập lịch hoạt động chính xác . Chính vì chính sách ImageLocalityPriority mà vấn đề lập kế hoạch được quan sát khá hiếm khi xảy ra; thường thì nó được liên kết với một thứ khác. Do chúng tôi không thể gỡ lỗi hoàn toàn từng chính sách trong danh sách ưu tiên của bộ lập lịch kube mặc định, nên chúng tôi cần quản lý linh hoạt các chính sách lập lịch nhóm.

Báo cáo sự cố

Chúng tôi muốn giải pháp cho vấn đề càng cụ thể càng tốt, nghĩa là các thực thể chính của Kubernetes (ở đây ý chúng tôi là bộ lập lịch kube mặc định) sẽ không thay đổi. Chúng tôi không muốn giải quyết vấn đề ở nơi này và tạo ra vấn đề ở nơi khác. Vì vậy, chúng tôi đã đi đến hai lựa chọn để giải quyết vấn đề, đã được thông báo trong phần giới thiệu bài viết - tạo một bộ lập lịch bổ sung hoặc viết bộ lập lịch của riêng bạn. Yêu cầu chính để lập lịch các tác vụ cron là phân phối tải đồng đều trên ba nút. Yêu cầu này có thể được đáp ứng bằng các chính sách lập lịch kube hiện có, vì vậy để giải quyết vấn đề của chúng ta, bạn không cần phải viết trình lập lịch trình của riêng mình.

Hướng dẫn tạo và triển khai bộ lập lịch kube bổ sung được mô tả trong tài liệu. Tuy nhiên, đối với chúng tôi, có vẻ như thực thể Triển khai không đủ để đảm bảo khả năng chịu lỗi khi vận hành một dịch vụ quan trọng như kube-scheduler, vì vậy chúng tôi đã quyết định triển khai một kube-scheduler mới dưới dạng Static Pod, sẽ được giám sát trực tiếp của Kubelet. Vì vậy, chúng tôi có các yêu cầu sau đối với bộ lập lịch kube mới:

  1. Dịch vụ phải được triển khai dưới dạng Static Pod trên tất cả các cụm chính
  2. Phải cung cấp khả năng chịu lỗi trong trường hợp nhóm hoạt động có bộ lập lịch kube không khả dụng
  3. Ưu tiên chính khi lập kế hoạch phải là số lượng tài nguyên có sẵn trên nút (LeastRequestedPriority)

Giải pháp thực hiện

Điều đáng lưu ý ngay là chúng tôi sẽ thực hiện tất cả công việc trong Kubernetes v1.14.7, bởi vì Đây là phiên bản đã được sử dụng trong dự án. Hãy bắt đầu bằng cách viết một bản tuyên ngôn cho bộ lập lịch kube mới của chúng ta. Hãy lấy bảng kê khai mặc định (/etc/kubernetes/manifests/kube-scheduler.yaml) làm cơ sở và đưa nó về dạng sau:

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

Nói ngắn gọn về những thay đổi chính:

  1. Đã thay đổi tên của nhóm và vùng chứa thành kube-scheduler-cron
  2. Chỉ định việc sử dụng cổng 10151 và 10159 làm tùy chọn đã được xác định hostNetwork: true và chúng tôi không thể sử dụng các cổng giống như bộ lập lịch kube mặc định (10251 và 10259)
  3. Sử dụng tham số --config, chúng tôi đã chỉ định tệp cấu hình mà dịch vụ sẽ được khởi động
  4. Đã định cấu hình gắn tệp cấu hình ( Scheduler-custom.conf ) và tệp chính sách lập lịch ( Scheduler-custom-policy-config.json ) từ máy chủ

Đừng quên rằng kube-scheduler của chúng ta sẽ cần các quyền tương tự như quyền mặc định. Chỉnh sửa vai trò cụm của nó:

kubectl edit clusterrole system:kube-scheduler

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

Bây giờ hãy nói về những gì nên có trong tệp cấu hình và tệp chính sách lập lịch:

  • Tệp cấu hình (lịch trình-custom.conf)
    Để có được cấu hình kube-scheduler mặc định, bạn phải sử dụng tham số --write-config-to của tài liệu. Chúng tôi sẽ đặt cấu hình kết quả vào tệp /etc/kubernetes/scheduler-custom.conf và giảm nó thành dạng sau:

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"

Nói ngắn gọn về những thay đổi chính:

  1. Chúng ta đặt SchedulerName thành tên của dịch vụ kube-scheduler-cron.
  2. Trong tham số lockObjectName bạn cũng cần đặt tên dịch vụ của chúng tôi và đảm bảo rằng tham số leaderElect được đặt thành true (nếu bạn có một nút chính, bạn có thể đặt nó thành false).
  3. Đã chỉ định đường dẫn đến tệp có mô tả về chính sách lập lịch trong tham số algorithmSource.

Cần xem xét kỹ hơn điểm thứ hai, nơi chúng ta chỉnh sửa các tham số cho khóa leaderElection. Để đảm bảo khả năng chịu lỗi, chúng tôi đã kích hoạt (leaderElect) quy trình chọn người dẫn đầu (chính) giữa các nhóm của bộ lập lịch kube của chúng tôi bằng cách sử dụng một điểm cuối duy nhất cho chúng (resourceLock) có tên là kube-scheduler-cron (lockObjectName) trong không gian tên kube-system (lockObjectNamespace). Bạn có thể tìm thấy cách Kubernetes đảm bảo tính sẵn sàng cao của các thành phần chính (bao gồm cả bộ lập lịch kube) trong Bài viết.

  • Tệp chính sách lập lịch trình (scheduler-custom-policy-config.json)
    Như tôi đã viết trước đó, chúng ta có thể tìm ra những chính sách cụ thể nào mà bộ lập lịch kube mặc định hoạt động chỉ bằng cách phân tích mã của nó. Nghĩa là, chúng tôi không thể lấy tệp có chính sách lập lịch cho bộ lập lịch kube mặc định giống như tệp cấu hình. Hãy mô tả các chính sách lập lịch mà chúng ta quan tâm trong tệp /etc/kubernetes/scheduler-custom-policy-config.json như sau:

{
  "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
}

Do đó, kube-scheduler trước tiên sẽ biên dịch danh sách các nút mà nhóm có thể được lên lịch theo chính sách GeneralPredicates (bao gồm một tập hợp các chính sách PodFitsResources, PodFitsHostPorts, HostName và MatchNodeSelector). Và sau đó mỗi nút được đánh giá theo bộ chính sách trong mảng ưu tiên. Để đáp ứng các điều kiện của nhiệm vụ, chúng tôi cho rằng một bộ chính sách như vậy sẽ là giải pháp tối ưu. Hãy để tôi nhắc bạn rằng một bộ chính sách với mô tả chi tiết có sẵn trong tài liệu. Để hoàn thành nhiệm vụ của mình, bạn chỉ cần thay đổi bộ chính sách được sử dụng và gán trọng số phù hợp cho chúng.

Hãy gọi tệp kê khai của kube-scheduler mới mà chúng ta đã tạo ở đầu chương là kube-scheduler-custom.yaml và đặt nó vào đường dẫn sau /etc/kubernetes/manifests trên ba nút chính. Nếu mọi thứ được thực hiện chính xác, Kubelet sẽ khởi chạy một nhóm trên mỗi nút và trong nhật ký của bộ lập lịch kube mới, chúng ta sẽ thấy thông tin cho thấy tệp chính sách của chúng ta đã được áp dụng thành công:

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:{}]'

Bây giờ tất cả những gì còn lại là chỉ ra trong thông số kỹ thuật của CronJob rằng tất cả các yêu cầu lên lịch cho nhóm của nó phải được xử lý bởi bộ lập lịch kube mới của chúng tôi:

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

Kết luận

Cuối cùng, chúng tôi đã có thêm một bộ lập lịch kube với một bộ chính sách lập lịch duy nhất, công việc của nó được giám sát trực tiếp bởi kubelet. Ngoài ra, chúng tôi đã thiết lập cuộc bầu cử người lãnh đạo mới giữa các nhóm của bộ lập lịch kube của chúng tôi trong trường hợp người lãnh đạo cũ không thể tham gia vì lý do nào đó.

Các ứng dụng và dịch vụ thông thường tiếp tục được lên lịch thông qua bộ lập lịch kube mặc định và tất cả các tác vụ cron đã được chuyển hoàn toàn sang tác vụ mới. Tải do tác vụ cron tạo ra hiện được phân bổ đều trên tất cả các nút. Xem xét rằng hầu hết các tác vụ cron được thực thi trên cùng các nút với các ứng dụng chính của dự án, điều này đã giảm đáng kể nguy cơ di chuyển các nhóm do thiếu tài nguyên. Sau khi giới thiệu bộ lập lịch kube bổ sung, các vấn đề về lập lịch không đồng đều cho các tác vụ cron không còn phát sinh nữa.

Cũng đọc các bài viết khác trên blog của chúng tôi:

Nguồn: www.habr.com

Thêm một lời nhận xét