sách gpt4 ăn đã đi

Phân tích ngắn gọn về cơ chế trục xuất Kubelet

In lại Tác giả: qq735679552 Thời gian cập nhật: 29-09-2022 22:32:09 26 4
mua khóa gpt4 giày nike

CFSDN nhấn mạnh vào giá trị tạo ra nguồn mở và chúng tôi cam kết xây dựng nền tảng chia sẻ tài nguyên để mọi nhân viên CNTT có thể tìm thấy thế giới tuyệt vời của bạn tại đây.

Bài blog CFSDN này phân tích sơ lược về cơ chế trục xuất Kubelet được tác giả sưu tầm và biên soạn. Nếu các bạn quan tâm tới bài viết này thì nhớ like nhé.

  。

Để bảo vệ các nút, Kubelet cho phép chức năng loại bỏ các Pod trên các nút khi tài nguyên nút không đủ. Gần đây mình có nghiên cứu về cơ chế trục xuất của Kubelet và thấy có rất nhiều điều đáng học hỏi nên mình sẽ tổng hợp lại và chia sẻ với các bạn.

Cấu hình Kubelet

Chức năng trục xuất của Kubelet cần được bật trong cấu hình và ngưỡng trục xuất đã được định cấu hình. Các tham số liên quan đến việc trục xuất trong cấu hình Kubelet như sau:

  1. loại KubeletConfiguration struct { 
  2.     ... 
  3.   // Bản đồ của tên tín hiệu ĐẾN số lượng xác định ngưỡng trục xuất cứng.  ví dụ: {"bộ nhớ.có sẵn""300 dặm"}. 
  4.   Bản đồ EvictionHard[string]string 
  5.   // Bản đồ của tên tín hiệu ĐẾN số lượng xác định ngưỡng trục xuất mềm.   ví dụ: {"bộ nhớ.có sẵn""300 dặm"}. 
  6.   Bản đồ EvictionSoft[string]string 
  7.   // Bản đồ của tên tín hiệu ĐẾN số lượng xác định thời gian ân hạn  mỗi tín hiệu trục xuất nhẹ nhàng.  ví dụ: {"bộ nhớ.có sẵn""30 tuổi"}. 
  8.   Bản đồ EvictionSoftGracePeriod[string]string 
  9.   // Khoảng thời gian  mà kubelet có ĐẾN chờ trước khi chuyển đổi ngoài của tình trạng áp lực trục xuất. 
  10.   EvictionPressureTransitionPeriod metav1.Duration 
  11.   // Thời gian gia hạn tối đa được phép (TRONG giây) ĐẾN sử dụng khi vỏ kết thúc TRONG phản ứng ĐẾN ngưỡng trục xuất mềm đang được đáp ứng. 
  12.   EvictionMaxPodGracePeriod int32 
  13.   // Bản đồ của tên tín hiệu ĐẾN số lượng xác định mức thu hồi tối thiểu, mô tả mức tối thiểu 
  14.   // số lượng của một tài nguyên nhất định mà kubelet sẽ lấy lại khi thực hiện việc trục xuất pod trong khi 
  15.   // tài nguyên đó  chịu áp lực.  ví dụ: {"imagefs.có sẵn""2Gi"
  16.   Bản đồ EvictionMinimumReclaim[string]string 
  17.   ... 

Trong số đó, EvictionHard có nghĩa là trục xuất cứng. Sau khi đạt đến ngưỡng, nó sẽ bị trục xuất trực tiếp; EvictionSoft có nghĩa là trục xuất mềm, nghĩa là bạn chỉ có thể đặt khoảng thời gian trục xuất mềm. Khoảng thời gian được đặt bằng EvictionSoftGracePeriod; EvictionMinimumReclaim có nghĩa là đặt ngưỡng khả dụng tối thiểu , chẳng hạn như hình ảnh.

Các tín hiệu trục xuất có thể được thiết lập là:

  • Memory.available: node.status.capacity[memory] - node.stats.memory.workingSet, bộ nhớ khả dụng của nút
  • nodefs.available: node.stats.fs.available, dung lượng khả dụng của hệ thống file được Kubelet sử dụng
  • nodefs.inodesFree: node.stats.fs.inodesFree, số lượng inode có thể sử dụng trong hệ thống tệp được Kubelet sử dụng
  • imagefs.available: node.stats.runtime.imagefs.available, dung lượng khả dụng của hệ thống tệp được sử dụng để lưu trữ hình ảnh và các lớp có thể ghi của vùng chứa khi vùng chứa đang chạy
  • imagefs.inodesFree: node.stats.runtime.imagefs.inodesFree, dung lượng inode có thể sử dụng của hệ thống tệp được sử dụng để lưu trữ hình ảnh và các lớp có thể ghi của vùng chứa khi vùng chứa đang chạy
  • allocatableMemory.available: bộ nhớ còn trống để phân bổ Pod
  • pid.available: node.stats.rlimit.maxpid - node.stats.rlimit.curproc, PID còn lại để phân bổ Pod

Cách thức hoạt động của Trình quản lý Trục xuất

Công việc chính của Eviction Manager là ở chức năng đồng bộ hóa. Có hai nơi để kích hoạt tác vụ đồng bộ hóa. Một là tác vụ giám sát, được kích hoạt 10 giây một lần; vị trí còn lại là tác vụ thông báo được bắt đầu dựa trên tín hiệu trục xuất được người dùng định cấu hình để giám sát các sự kiện kernel.

Phân tích ngắn gọn về cơ chế trục xuất Kubelet

thông báo

Trình thông báo được khởi động bởi Trình thông báo ngưỡng trong trình quản lý trục xuất. Mỗi tín hiệu trục xuất do người dùng định cấu hình tương ứng với một Trình thông báo ngưỡng và Trình thông báo ngưỡng và trình thông báo sẽ giao tiếp qua kênh Khi trình thông báo gửi tin nhắn đến kênh, Trình thông báo ngưỡng tương ứng sẽ kích hoạt một kênh. đồng bộ hóa logic.

Trình thông báo sử dụng các nhóm của kernel Các ngưỡng bộ nhớ cho phép các tiến trình ở chế độ người dùng thiết lập thông qua sự kiện. Khi bộ nhớ.usage_in_bytes đạt đến một ngưỡng nhất định, kernel sẽ gửi thông báo đến ứng dụng. Phương pháp cụ thể là ghi " " vào cgroup.event_control.

Mã khởi tạo của trình thông báo như sau (một số mã không liên quan đã bị xóa để thuận tiện cho việc đọc). Nó chủ yếu tìm bộ mô tả tệp watchfd của bộ nhớ.usage_in_bytes và bộ mô tả tệp controlfd của cgroup.event_control để hoàn tất việc đăng ký ngưỡng bộ nhớ cgroup. .

  1. func NewCgroupNotifier(đường dẫn, chuỗi thuộc tính, ngưỡng int64) (CgroupNotifier, lỗi) { 
  2.   var watchfd, eventfd, epfd, controlfd số nguyên 
  3.  
  4.   watchfd, err = unix.Mở(fmt. Sprintf("%s/%s", đường dẫn, thuộc tính), unix.O_RDONLY|unix.O_CLOEXEC, 0) 
  5.   hoãn Unix.Đóng(xemfd) 
  6.    
  7.   controlfd, err = unix.Mở(fmt. Sprintf("%s/cgroup.event_control", đường dẫn), unix.O_WRONLY|unix.O_CLOEXEC, 0) 
  8.   hoãn Unix.Đóng(kiểm soát) 
  9.    
  10.   eventfd, lỗi = unix.Eventfd(0, unix.EFD_CLOEXEC) 
  11.   hoãn func() { 
  12.     // Đóng eventfd nếu chúng ta gặp lỗi sau đó TRONG khởi tạo 
  13.     nếu err != nil { 
  14.       hệ điều hành unix.Đóng(sự kiện) 
  15.     } 
  16.   }() 
  17.    
  18.   epfd, lỗi = unix.EpollCreate1(unix.EPOLL_CLOEXEC) 
  19.   hoãn func() { 
  20.     // Đóng epfd nếu chúng ta gặp lỗi sau này TRONG khởi tạo 
  21.     nếu err != nil { 
  22.       hệ điều hành unix.Đóng(epfd) 
  23.     } 
  24.   }() 
  25.    
  26.   cấu hình := fmt.Sprintf("%d %d %d", eventfd, watchfd, ngưỡng) 
  27.   _, err = unix.Write(controlfd, []byte(config)) 
  28.  
  29.   trở lại &linuxCgroupThông báo 
  30.     eventfd: eventfd, 
  31.     epfd: epfd, 
  32.     dừng: make(chan struct{}), 
  33.   }, không 

Trình thông báo cũng sẽ lắng nghe sự kiện trên thông qua epoll khi nó bắt đầu. Khi nó lắng nghe sự kiện được gửi bởi kernel, điều đó có nghĩa là bộ nhớ được sử dụng đã vượt quá ngưỡng và tín hiệu được gửi đến kênh.

  1. func (n *linuxCgroupNotifier) ​​Bắt đầu(eventCh chan<- struct{}) { 
  2.   lỗi := unix.EpollCtl(n.epfd, unix.EPOLL_CTL_ADD, n.eventfd, &unix.EpollEvent{ 
  3.     Fd: int32(n.eventfd), 
  4.     Sự kiện: unix.EPOLLIN, 
  5.   }) 
  6.  
  7.    { 
  8.     lựa chọn { 
  9.     trường hợp <-n.dừng lại: 
  10.       trở lại 
  11.     mặc định
  12.     } 
  13.     sự kiện, lỗi := chờ (n.epfd, n.eventfd, notifierRefreshInterval) 
  14.     nếu err != nil { 
  15.       khôn ngoan.InfoS("Trình quản lý xóa: lỗi khi chờ sự kiện memcg""lầm", lỗi) 
  16.       trở lại 
  17.     } khác nếu !event { 
  18.       // Hết thời gian TRÊN chờ đã. Cái này  dự kiến ​​nếu ngưỡng là không đã vượt qua 
  19.       Tiếp tục 
  20.     } 
  21.     // Tiêu thụ sự kiện từ sự kiệnfd 
  22.     buf := make([]byte, eventSize) 
  23.     _, lỗi = unix.Đọc(n.eventfd, buf) 
  24.     nếu err != nil { 
  25.       khôn ngoan.InfoS("Trình quản lý xóa: lỗi khi đọc sự kiện memcg""lầm", lỗi) 
  26.       trở lại 
  27.     } 
  28.     eventCh <- cấu trúc{}{} 
  29.   } 

Mỗi lần logic đồng bộ hóa được thực thi, nó sẽ xác định xem trình thông báo đã được cập nhật trong vòng 10 giây hay chưa và khởi động lại trình thông báo. Ngưỡng bộ nhớ của nhóm được tính bằng tổng bộ nhớ trừ đi ngưỡng trục xuất do người dùng đặt.

đồng bộ hóa

Đồng bộ hóa logic chính của Trình quản lý trục xuất có nhiều chi tiết, vì vậy mã nguồn sẽ không được đăng ở đây. Những nội dung chính cần sắp xếp như sau:

  1. Xây dựng hàm xếp hạng cho từng tín hiệu;
  2. Cập nhật ngưỡng và khởi động lại trình thông báo;
  3. Nhận mức sử dụng tài nguyên của nút hiện tại (thông tin nhóm) và tất cả các nhóm đang hoạt động;
  4. Đối với mỗi tín hiệu, hãy xác định xem mức sử dụng tài nguyên của nút hiện tại có đạt đến ngưỡng trục xuất hay không. Nếu không, hãy thoát khỏi chu kỳ hiện tại;
  5. Ưu tiên tất cả các tín hiệu Ưu tiên là: các tín hiệu liên quan đến bộ nhớ được loại bỏ trước;
  6. Gửi một sự kiện trục xuất tới máy chủ apiserver;
  7. Ưu tiên tất cả các nhóm đang hoạt động;
  8. Loại bỏ các nhóm theo thứ tự được sắp xếp.

Tính toán lệnh trục xuất

Thứ tự các nhóm bị loại bỏ chủ yếu phụ thuộc vào ba yếu tố:

  • Liệu mức sử dụng tài nguyên của nhóm có vượt quá yêu cầu của nhóm hay không;
  • Giá trị ưu tiên của nhóm;
  • mức sử dụng bộ nhớ của nhóm;

Thứ tự phán đoán của 3 yếu tố cũng dựa trên thứ tự đã đăng ký trong orderBy. Việc sắp xếp đa cấp của hàm orderBy ở đây cũng là một cách triển khai đáng học hỏi (sao chép bài tập về nhà) trong Kubernetes. Bạn đọc quan tâm có thể tự mình kiểm tra mã nguồn.

  1. // rankMemoryPressure sắp xếp các pod đầu vào  trục xuất TRONG phản ứng ĐẾN áp lực bộ nhớ. 
  2. // Nó xếp hạng qua liệu hoặc không việc sử dụng pod vượt quá nhu cầu của nó, sau đó qua sự ưu tiên,  
  3. // Cuối cùng qua sử dụng bộ nhớ trên yêu cầu. 
  4. hàm rankMemoryPressure(pods []*v1.Pod, số liệu thống kê statsFunc) { 
  5.   orderedBy(exceedMemoryRequests(thống kê), ưu tiên, bộ nhớ(thống kê)).Sort(pods) 

Đuổi Pod

Tiếp theo là việc thực hiện đuổi Pods. Việc trục xuất Pod của Trình quản lý trục xuất là một hành động tiêu diệt rõ ràng và gọn gàng. Việc triển khai cụ thể sẽ không được phân tích ở đây. Điều đáng chú ý là sẽ có phán quyết trước khi trục xuất. Nếu IsCriticalPod trả về đúng, nó sẽ không bị trục xuất.

  1. func (m *managerImpl) evictPod(pod *v1.Pod, gracePeriodOverride int64, evictMsg string, chú thích map[string]string) bool { 
  2.   // Nếu pod  được đánh dấu BẰNG phê bình  tĩnh ủng hộ  chú thích pod quan trọng  được kích hoạt, 
  3.   // LÀM không loại bỏ những quả như vậy. Tĩnh vỏ quả là không được nhận lại sau đó trục xuất. 
  4.   // https://github.com/kubernetes/kubernetes/issues/40573 có thêm thông tin chi tiết. 
  5.   nếu kubelettypes.IsCriticalPod(pod) { 
  6.     khôn ngoan.ErrorS(nil, "Trình quản lý trục xuất: không thể trục xuất một nhóm quan trọng""vỏ", khôn ngoan.KObj(pod)) 
  7.     trở lại SAI 
  8.   } 
  9.   // ghi lại rằng chúng ta đang loại bỏ pod 
  10.   m.recorder.AnnotatedEventf(pod, chú thích, v1.EventTypeWarning, Lý do, evictMsg) 
  11.   // cái này  một cuộc gọi chặn  nên chỉ một trở lại khi cái vỏ  các thùng chứa của nó đã bị phá hủy. 
  12.   khôn ngoan.V(3).InfoS("Đuổi pod""vỏ", thông minh.KObj(pod), "podUID"nhóm.UID "tin nhắn", loại bỏMsg) 
  13.   lỗi := m.killPodFunc(pod, ĐÚNG VẬY, &gracePeriodOverride, chức năng(trạng thái *v1.PodStatus) { 
  14.     trạng thái.Giai đoạn = v1.PodFailed 
  15.     trạng thái.Lý do = Lý do 
  16.     trạng thái.Tin nhắn = evictMsg 
  17.   }) 
  18.   nếu err != nil { 
  19.     khôn ngoan.ErrorS(err, "Người quản lý trục xuất: nhóm không thể trục xuất""vỏ", khôn ngoan.KObj(pod)) 
  20.   } khác { 
  21.     khôn ngoan.InfoS("Người quản lý trục xuất: nhóm đã được trục xuất thành công""vỏ", khôn ngoan.KObj(pod)) 
  22.   } 
  23.   trở lại ĐÚNG VẬY 

再看看 IsCriticalPod 的代码:

  1. func IsCriticalPod(pod *v1.Pod) bool { 
  2.   if IsStaticPod(pod) { 
  3.     trở lại ĐÚNG VẬY 
  4.   } 
  5.   if IsMirrorPod(pod) { 
  6.     trở lại ĐÚNG VẬY 
  7.   } 
  8.   if pod.Spec.Priority != nil && IsCriticalPodBasedOnPriority(*pod.Spec.Priority) { 
  9.     trở lại ĐÚNG VẬY 
  10.   } 
  11.   trở lại SAI 
  12.  
  13. // IsMirrorPod trả lại ĐÚNG VẬY if the passed Pod  a Mirror Pod. 
  14. func IsMirrorPod(pod *v1.Pod) bool { 
  15.   _, ok := pod.Annotations[ConfigMirrorAnnotationKey] 
  16.   trở lại ok 
  17.  
  18. // IsStaticPod trả lại ĐÚNG VẬY if the pod  Một tĩnh pod. 
  19. func IsStaticPod(pod *v1.Pod) bool { 
  20.   source, err := GetPodSource(pod) 
  21.   trở lại err == nil && source != ApiserverSource 
  22.  
  23. func IsCriticalPodBasedOnPriority(priority int32) bool { 
  24.   trở lại priority >= scheduling.SystemCriticalPriority 

从代码看,如果 Pod 是 Static、Mirror、Critical Pod 都不驱逐。其中 Static 和 Mirror 都是从 Pod 的 annotation 中判断;而 Critical 则是通过 Pod 的 Priority 值判断的,如果 Priority 为 system-cluster-critical/system-node-critical 都属于 Critical Pod.

不过这里值得注意的是,官方文档里提及 Critical Pod 是说,如果非 Static Pod 被标记为 Critical,并不完全保证不会被驱逐:https://kubernetes.io/docs/tasks/administer-cluster/guaranteed-scheduling-critical-addon-pods 。因此,很有可能是社区并没有想清楚这种情况是否要驱逐,并不排除后面会改变这段逻辑,不过也有可能是文档没有及时更新??.

Tóm tắt

本文主要分析了 Kubelet 的 Eviction Manager,包括其对 Linux CGroup 事件的监听、判断 Pod 驱逐的优先级等。了解了这些之后,我们就可以根据自身应用的重要性来设置优先级,甚至设置成 Critical Pod.

原文链接:https://mp.weixin.qq.com/s/xEE-GoYg0b6aeMHHar7qWw 。

最后此篇关于浅析 Kubelet 驱逐机制的文章就讲到这里了,如果你想了解更多关于浅析 Kubelet 驱逐机制的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

26 4 0
Đề xuất bài viết: 一篇文章带你搞懂Map接口、HashMap集合
Đề xuất bài viết: python实现A*寻路算法
Đề xuất bài viết: 后端视野学 Webpack ,文武双全?
Đề xuất bài viết: 做SEO网站优化一定要用心
qq735679552
Hồ sơ

Tôi là một lập trình viên xuất sắc, rất giỏi!

Nhận phiếu giảm giá taxi Didi miễn phí
Phiếu giảm giá taxi Didi
Chứng chỉ ICP Bắc Kinh số 000000
Hợp tác quảng cáo: 1813099741@qq.com 6ren.com
Xem sitemap của VNExpress