Kubernetes pods resource management: requests vs limits

Kubernetes pods resource management: requests vs limits

Trong môi trường container orchestration, việc quản lý tài nguyên một cách hiệu quả không chỉ giúp tối ưu chi phí mà còn đảm bảo tính ổn định và hiệu suất của hệ thống. Kubernetes cung cấp hai cơ chế quan trọng để kiểm soát tài nguyên cho pods và containers: requests (yêu cầu) và limits (giới hạn). Hiểu rõ sự khác biệt và cách sử dụng chúng là chìa khóa để triển khai ứng dụng thành công trên Kubernetes.

Requests và Limits là gì?

Khi bạn định nghĩa một container trong Kubernetes pod, bạn có thể chỉ định mức tài nguyên mà container đó cần (requests) và mức tối đa mà nó được phép sử dụng (limits). Hai loại tài nguyên chính thường được cấu hình là CPU và memory (RAM), mặc dù Kubernetes cũng hỗ trợ các loại tài nguyên khác như ephemeral-storage và hugepages.

  • Requests: Là lượng tài nguyên mà Kubernetes đảm bảo sẽ có sẵn cho container. Điều này giúp kube-scheduler quyết định node nào phù hợp để đặt pod. Nếu node không đủ tài nguyên để đáp ứng tổng requests của tất cả containers, pod sẽ không được lên lịch.
  • Limits: Là ngưỡng tối đa mà container được phép sử dụng. Nếu container forsøi vượt quá limit, Linux kernel sẽ can thiệp thông qua cgroups (Control Groups) để ngăn chặn.

CPU requests và limits: Cách thức hoạt động

Đối với CPU, việc enforce limits được thực hiện thông qua CPU throttling. Khi container sử dụng lượng CPU gần đạt tới limit, kernel sẽ giới hạn thời gian CPU mà container có thể sử dụng trong mỗi khoảng thời gian (thường là 100ms). Điều này có nghĩa là:

  • CPU limit là một hard limit – container sẽ không bao giờ sử dụng vượt quá lượng CPU này được cấp phép.
  • Tuy nhiên, container vẫn có thể sử dụng nhiều hơn mức request nếu có tài nguyên dư trên node (do không có upper bound ngoài limit).
  • CPU được đo bằng đơn vị “cpu” (core), với 1 cpu = 1 CPU core. Các giá trị phân số được cho phép (ví dụ: 0.5 cpu = 500m cpu).

Memory requests và limits: Cách thức hoạt động

Đối với memory,is different. Memory limits được enforce bằng cơ chế Out of Memory (OOM) killing của Linux kernel. Khi container sử dụng memory vượt quá limit:

  • Kernel sẽ terminate container nếu hệ thống gặp memory stress (không có đủ RAM còn lại).
  • Nếu node còn nhiều memory trống, container có thể tạm thời sử dụng vượt quá limit mà không bị giết ngay lập tức.
  • Điều này khiến memory limit trở thành một reactive limit – chỉ được áp dụng khi hệ thống thực sự cần giải phóng memory.
  • Memory được đo bằng bytes, với hỗ trợ các tiền tố như Ki, Mi, Gi (binary) hoặc k, M, G (decimal).

Pod-level resource management

Từ Kubernetes v1.34 (beta), có khả năng chỉ định resource requests và limits ở mức pod (ngoài mức container này). Khi sử dụng tính năng PodLevelResources:

  • Pod-level requests/limits được áp dụng cho tổng tài nguyên của tất cả containers trong pod.
  • Containers không có explicit requests/limits sẽ chia sẻ tài nguyên còn lại trong pod sau khi trừ đi lượng tài nguyên đã được cấp cho các container có cấu hình rõ ràng.
  • Tính năng này đặc biệt hữu ích cho pods có nhiều containers (sidecar pattern) nơi việc cấu hình tài nguyên từng container riêng lẻ trở nên phức tạp.

Best practices để cấu hình requests và limits

Để tối ưu hiệu suất và chi phí, hãy tham khảo các hướng dẫn sau:

  1. Xác định request dựa trên nhuattan thực tế: Sử dụng công cụ monitoring (như Prometheus + Grafana) để đo lường mức tài nguyên trung bình và mức sử dụng cao nhất (peak) của ứng dụng trong thời gian chạy bình thường.
  2. Đặt limitcao hơn request 1.5-2 lần: Để có buffer cho các đợt tăng tải tạm thời mà không gây OOM kill hoặc throttling quá mức.
  3. Luôn đặt cả request và limit: Nếu chỉ đặt limit mà không có request, Kubernetes sẽ tự động đặt request = limit (từ v1.26), điều này có thể dẫn to việcover-allocate resources.
  4. Sử dụng ResourceQuota và LimitRange ở mức namespace: Để đặt mặc định và giới hạn tổng tài nguyên mà tất cả pods trong namespace có thể sử dụng.
  5. Giám sát và điều chỉnh định kỳ: Sử dụng metrics như container_cpu_usage_seconds_total và container_memory_usage_height để xem mức utilizations và tinh chỉnh cấu hình theo thời gian.

Ví dụ cấu hình thực tế

Dưới đây là ví dụ manifest cho một web application pod với 2 containers (app chính và sidecar logging):

apiVersion: v1
kind: Pod
metadata:
  name: web-app
spec:
  containers:
  - name: app
    image: myapp:latest
    resources:
      requests:
        memory: "512Mi"
        cpu: "250m"
      limits:
        memory: "1Gi"
        cpu: "500m"
  - name: log-agent
    image: fluent/fluentd:v1.14-debian-1
    resources:
      requests:
        memory: "128Mi"
        cpu: "50m"
      limits:
        memory: "256Mi"
        cpu: "100m"

Trong ví dụ này:

  • Pod tổng request: 640Mi RAM và 300m CPU
  • Pod tổng limit: 1.25Gi RAM và 600m CPU
  • Log sidecar có thể ‘mượn’ tài nguyên từ app container nếu có sẵn, nhưng sẽ không bao giờ vượt quá 256Mi RAM và 100m CPU của riêng nó.

Common mistakes to avoid

  • Setting limits too low: Dẫn đến frequent throttling (CPU) hoặc OOM kills (memory), gây ra degraded performance hoặc downtime.
  • Ignoring requests: Làmให้ scheduler không thểตัดสินใจ placement tốt, có thể dẫn đếnoverloaded nodes or resource waste。
  • Using same values for all environments: Phát triển, staging, và production thường có mức tải khác nhau – cần cấu hình tương ứng.
  • Not monitoring actual usage: Làmให้ bạn không biết cấu hình hiện tại có phù hợp không và có thể lãng phí tài nguyên hoặc gây ra vấn đề ổn định.

Kết luận

Việc hiểu đúng sự khác biệt giữa requests và limits trong Kubernetes là nền tảng để triển khai ứng dụng ổn định, hiệu quả và chi phí tối ưu. Nhờ chính xác cấu hình hai tham số này, bạn sẽ:

  • Đảm bảo các ứng dụng quan trọng luôn có đủ tài nguyên để hoạt động (nhờ requests)
  • Ngăn ngừa một ứng dụng tiêu thụ quá nhiều tài nguyên và làm ảnh hưởng đến các ứng dụng khác trên cùng node (nhờ limits)
  • Tối ưu sử dụng tài nguyên cluster và giảm chi phí vận hành
  • Dễ dàng mở rộng (scale) ứng dụng khi có nhu cầu

Kubernetes scheduler sử dụng pod requests để đặt node

So sánh cơ chế CPU throttling và OOM killing trong Kubernetes

Nguồn tham khảo

Tôi là một lập trình viên IOS. Code chính là IOS nhưng thỉnnh thoảng vẫn đá sang Android hoặc web. Mặc dù không quá thông thạo nhưng tôi sẽ chia sẻ những kiến thức mà mình đã tìm hiểu, áp dụng qua.

Bài viết liên quan

Event Sourcing và CQRS: kiến trúc sự kiện cho app thương mại

Event Sourcing và CQRS: kiến trúc sự kiện cho app thương mại Event Sourcing (ES) là một mô hình lưu trữ dữ liệu trong đó trạng thái của một thực…

Xem thêm
docker_twistlock

Docker multi-stage builds: Cách thu nhỏ image xuống 90%

Docker multi-stage builds: Cách thu nhỏ image xuống 90% Một trong những thách thức lớn nhất khi dùng Docker là image size quá lớn. Một image Python đơn giản có…

Xem thêm
Giao diện Jetpack Compose trên thiết bị Android

Jetpack Compose Kotlin: Xây dựng ứng dụng Android hiện đại

Jetpack Compose Kotlin: Xây dựng ứng dụng Android hiện đại Jetpack Compose Kotlin đang cách đẳng cách phát triển giao diện Android bằng cách thay thế XML bằng mã Kotlin…

Xem thêm
0 0 đánh giá
Article Rating
Theo dõi
Thông báo của
guest
0 Comments
Cũ nhất
Mới nhất Được bỏ phiếu nhiều nhất