Các thăm dò sự sống trong Kubernetes có thể nguy hiểm

Ghi chú. bản dịch.: Kỹ sư trưởng của Zalando, Henning Jacobs, đã nhiều lần nhận thấy vấn đề của người dùng Kubernetes trong việc hiểu mục đích của các đầu dò hoạt động (và mức độ sẵn sàng) cũng như cách sử dụng đúng cách của chúng. Vì vậy, anh ấy đã thu thập những suy nghĩ của mình trong tờ ghi chú đầy sức mạnh này, tờ ghi chú này cuối cùng sẽ trở thành một phần tài liệu của K8.

Các thăm dò sự sống trong Kubernetes có thể nguy hiểm

Kiểm tra sức khỏe, được biết đến trong Kubernetes là thăm dò sự sống (tức là, theo nghĩa đen, “các bài kiểm tra khả năng tồn tại” - bản dịch gần đúng), có thể khá nguy hiểm. Tôi khuyên bạn nên tránh chúng nếu có thể: ngoại lệ duy nhất là khi chúng thực sự cần thiết và bạn hoàn toàn nhận thức được các chi tiết cụ thể cũng như hậu quả của việc sử dụng chúng. Ấn phẩm này sẽ nói về việc kiểm tra tính khả thi và tính sẵn sàng, đồng thời cũng sẽ cho bạn biết trong trường hợp nào và bạn không nên sử dụng chúng.

Đồng nghiệp Sandor của tôi gần đây đã chia sẻ trên Twitter những lỗi phổ biến nhất mà anh ấy gặp phải, bao gồm cả những lỗi liên quan đến việc sử dụng các thăm dò mức độ sẵn sàng/sự sống:

Các thăm dò sự sống trong Kubernetes có thể nguy hiểm

Cấu hình không chính xác livenessProbe có thể làm trầm trọng thêm các tình huống tải cao (tắt quả cầu tuyết + thời gian khởi động ứng dụng/container có thể kéo dài) và dẫn đến các hậu quả tiêu cực khác như giảm sự phụ thuộc (Xem thêm bài viết gần đây của tôi về việc giới hạn số lượng yêu cầu trong tổ hợp K3s+ACME). Thậm chí còn tệ hơn khi kết hợp thăm dò độ sống với kiểm tra tình trạng, là cơ sở dữ liệu bên ngoài: một lỗi DB duy nhất sẽ khởi động lại tất cả các vùng chứa của bạn!

Thông điệp chung "Đừng sử dụng máy thăm dò sự sống" trong trường hợp này, nó không giúp được gì nhiều, vì vậy hãy xem việc kiểm tra tính sẵn sàng và sự sống động dùng để làm gì.

Lưu ý: Hầu hết thử nghiệm bên dưới ban đầu được đưa vào tài liệu dành cho nhà phát triển nội bộ của Zalando.

Kiểm tra mức độ sẵn sàng và sự sống động

Kubernetes cung cấp hai cơ chế quan trọng được gọi là đầu dò sự sống và đầu dò sẵn sàng. Chúng định kỳ thực hiện một số hành động—chẳng hạn như gửi yêu cầu HTTP, mở kết nối TCP hoặc thực thi lệnh trong vùng chứa—để xác nhận rằng ứng dụng đang hoạt động như mong đợi.

Sử dụng Kubernetes thăm dò sẵn sàngđể hiểu khi nào container sẵn sàng chấp nhận lưu lượng truy cập. Một nhóm được coi là sẵn sàng để sử dụng nếu tất cả các thùng chứa của nó đã sẵn sàng. Một công dụng của cơ chế này là kiểm soát nhóm nào được sử dụng làm phụ trợ cho các dịch vụ Kubernetes (và đặc biệt là Ingress).

Đầu dò sinh động giúp Kubernetes hiểu khi nào cần khởi động lại vùng chứa. Ví dụ: việc kiểm tra như vậy cho phép bạn chặn sự bế tắc khi ứng dụng bị kẹt ở một nơi. Việc khởi động lại vùng chứa ở trạng thái này giúp khởi động ứng dụng mặc dù có lỗi nhưng cũng có thể dẫn đến lỗi xếp tầng (xem bên dưới).

Nếu bạn cố gắng triển khai một bản cập nhật ứng dụng không vượt qua được các bước kiểm tra tính sẵn sàng/hoạt động, thì quá trình triển khai bản cập nhật đó sẽ bị đình trệ do Kubernetes chờ trạng thái Ready từ tất cả các nhóm.

Ví dụ

Dưới đây là ví dụ về thăm dò mức độ sẵn sàng kiểm tra đường dẫn /health qua HTTP với cài đặt mặc định (khoảng thời gian: 10 giây, thời gian chờ: 1 giây, ngưỡng thành công: 1, ngưỡng thất bại: 3):

# часть общего описания deployment'а/стека
podTemplate:
  spec:
    containers:
    - name: my-container
      # ...
      readinessProbe:
        httpGet:
          path: /health
          port: 8080

Khuyến nghị

  1. Đối với các vi dịch vụ có điểm cuối HTTP (REST, v.v.) luôn xác định một thăm dò sẵn sàng, kiểm tra xem ứng dụng (pod) có sẵn sàng chấp nhận lưu lượng truy cập hay không.
  2. Đảm bảo thăm dò sẵn sàng bao gồm tính khả dụng của cổng máy chủ web thực tế:
    • sử dụng các cổng cho mục đích quản trị, được gọi là "quản trị viên" hoặc "quản lý" (ví dụ: 9090), cho readinessProbe, hãy đảm bảo rằng điểm cuối chỉ trả về OK nếu cổng HTTP chính (như 8080) sẵn sàng chấp nhận lưu lượng truy cập*;

      *Tôi biết ít nhất một trường hợp tại Zalando mà điều này đã không xảy ra, tức là. readinessProbe Tôi đã kiểm tra cổng “quản lý”, nhưng bản thân máy chủ không bắt đầu hoạt động do có vấn đề khi tải bộ đệm.

    • Việc gắn đầu dò sẵn sàng vào một cổng riêng có thể dẫn đến tình trạng quá tải trên cổng chính sẽ không được phản ánh trong kiểm tra tình trạng (tức là thread pool trên máy chủ đã đầy, nhưng kiểm tra tình trạng vẫn cho thấy mọi thứ đều ổn ).
  3. Đảm bảo rằng thăm dò mức độ sẵn sàng cho phép khởi tạo/di chuyển cơ sở dữ liệu;
    • Cách dễ nhất để đạt được điều này là chỉ liên hệ với máy chủ HTTP sau khi quá trình khởi tạo hoàn tất (ví dụ: di chuyển cơ sở dữ liệu từ Đường bay và như thế.); nghĩa là, thay vì thay đổi trạng thái kiểm tra tình trạng, bạn chỉ cần không khởi động máy chủ web cho đến khi quá trình di chuyển cơ sở dữ liệu hoàn tất*.

      * Bạn cũng có thể chạy di chuyển cơ sở dữ liệu từ vùng chứa init bên ngoài nhóm. Tôi vẫn là người yêu thích các ứng dụng độc lập, tức là những ứng dụng trong đó bộ chứa ứng dụng biết cách đưa cơ sở dữ liệu về trạng thái mong muốn mà không cần sự phối hợp từ bên ngoài.

  4. Sử dụng httpGet để kiểm tra mức độ sẵn sàng thông qua các điểm cuối kiểm tra tình trạng điển hình (ví dụ: /health).
  5. Hiểu các tham số kiểm tra mặc định (interval: 10s, timeout: 1s, successThreshold: 1, failureThreshold: 3):
    • các tùy chọn mặc định có nghĩa là nhóm sẽ trở thành chưa sẵn sàng sau khoảng 30 giây (3 lần kiểm tra độ tỉnh táo không thành công).
  6. Sử dụng một cổng riêng cho "quản trị viên" hoặc "quản lý" nếu ngăn xếp công nghệ (ví dụ: Java/Spring) cho phép, để tách quản lý chỉ số và tình trạng khỏi lưu lượng truy cập thông thường:
    • nhưng đừng quên điểm 2.
  7. Nếu cần, có thể sử dụng đầu dò mức độ sẵn sàng để khởi động/tải bộ đệm và trả về mã trạng thái 503 cho đến khi vùng chứa ấm lên:

Lưu ý

  1. Đừng dựa vào sự phụ thuộc bên ngoài (chẳng hạn như kho dữ liệu) khi chạy thử nghiệm mức độ sẵn sàng/hoạt động - điều này có thể dẫn đến lỗi xếp tầng:
    • Ví dụ: hãy sử dụng dịch vụ REST có trạng thái với 10 nhóm tùy thuộc vào một cơ sở dữ liệu Postgres: khi việc kiểm tra phụ thuộc vào kết nối đang hoạt động với DB, tất cả 10 nhóm có thể không thành công nếu có độ trễ ở phía mạng/DB - thường là như vậy tất cả đều kết thúc tồi tệ hơn nó có thể;
    • Xin lưu ý rằng Spring Data kiểm tra kết nối cơ sở dữ liệu theo mặc định*;

      * Đây là hành vi mặc định của Spring Data Redis (ít nhất đó là lần cuối cùng tôi kiểm tra), dẫn đến lỗi “thảm khốc”: khi Redis không khả dụng trong thời gian ngắn, tất cả các nhóm đều “bị lỗi”.

    • “bên ngoài” theo nghĩa này cũng có thể có nghĩa là các nhóm khác của cùng một ứng dụng, nghĩa là lý tưởng nhất là việc kiểm tra không nên phụ thuộc vào trạng thái của các nhóm khác trong cùng một cụm để ngăn chặn sự cố xếp tầng:
      • kết quả có thể khác nhau đối với các ứng dụng có trạng thái phân tán (ví dụ: bộ nhớ đệm trong bộ nhớ trong nhóm).
  2. Không sử dụng máy thăm dò độ sống đối với nhóm (ngoại lệ là những trường hợp khi chúng thực sự cần thiết và bạn hoàn toàn nhận thức được các chi tiết cụ thể cũng như hậu quả của việc sử dụng chúng):
    • Đầu dò hoạt động có thể giúp khôi phục các vùng chứa bị treo, nhưng vì bạn có toàn quyền kiểm soát ứng dụng của mình, nên lý tưởng nhất là những thứ như quy trình bị treo và bế tắc sẽ không xảy ra: giải pháp thay thế tốt nhất là cố tình làm hỏng ứng dụng và đưa nó trở lại trạng thái ổn định trước đó;
    • thăm dò mức độ hoạt động không thành công sẽ khiến vùng chứa khởi động lại, do đó có khả năng làm trầm trọng thêm tác động của các lỗi liên quan đến khởi động: việc khởi động lại vùng chứa sẽ dẫn đến thời gian ngừng hoạt động (ít nhất là trong thời gian khởi động ứng dụng, chẳng hạn như trên 30 giây), gây ra các lỗi mới, tăng tải trọng lên các container khác và tăng khả năng hỏng hóc của chúng, v.v.;
    • kiểm tra độ sống kết hợp với sự phụ thuộc bên ngoài là sự kết hợp tồi tệ nhất có thể xảy ra, đe dọa đến lỗi xếp tầng: một chút chậm trễ ở phía cơ sở dữ liệu sẽ dẫn đến việc khởi động lại tất cả các vùng chứa của bạn!
  3. Các thông số kiểm tra sự sống động và sẵn sàng phải khác:
    • bạn có thể sử dụng thăm dò độ sống với cùng một bài kiểm tra tình trạng, nhưng ngưỡng phản hồi cao hơn (failureThreshold), ví dụ: gán trạng thái chưa sẵn sàng sau 3 lần thử và coi như thăm dò độ sống đã thất bại sau 10 lần thử;
  4. Không sử dụng kiểm tra thực thi, vì chúng có liên quan đến các vấn đề đã biết dẫn đến sự xuất hiện của các quá trình zombie:

Tóm tắt thông tin

  • Sử dụng các thăm dò mức độ sẵn sàng để xác định thời điểm nhóm sẵn sàng nhận lưu lượng truy cập.
  • Chỉ sử dụng các thăm dò độ sống khi chúng thực sự cần thiết.
  • Việc sử dụng các thăm dò mức độ sẵn sàng/sự sống không đúng cách có thể dẫn đến giảm tính khả dụng và lỗi xếp tầng.

Các thăm dò sự sống trong Kubernetes có thể nguy hiểm

Các tài liệu bổ sung về chủ đề

Cập nhật số 1 từ 2019-09-29

Giới thiệu về bộ chứa init để di chuyển cơ sở dữ liệu: Đã thêm chú thích.

EJ đã nhắc nhở tôi về PDB: một trong những vấn đề với việc kiểm tra độ sống là thiếu sự phối hợp giữa các nhóm. Kubernetes có Ngân sách gián đoạn nhóm (PDB) để hạn chế số lượng lỗi đồng thời mà ứng dụng có thể gặp phải, tuy nhiên việc kiểm tra không tính đến PDB. Lý tưởng nhất là chúng ta có thể yêu cầu K8 "Khởi động lại một nhóm nếu thử nghiệm của nó thất bại, nhưng không khởi động lại tất cả để tránh khiến mọi thứ trở nên tồi tệ hơn".

Bryan diễn đạt nó một cách hoàn hảo: “Sử dụng việc thăm dò sự sống khi bạn biết chính xác điều gì tốt nhất là tắt ứng dụng đi"(một lần nữa, đừng quá khích).

Các thăm dò sự sống trong Kubernetes có thể nguy hiểm

Cập nhật số 2 từ 2019-09-29

Về việc đọc tài liệu trước khi sử dụng: Tôi đã tạo yêu cầu tương ứng (yêu cầu tính năng) để thêm tài liệu về thăm dò độ sống.

Tái bút từ người dịch

Đọc thêm trên blog của chúng tôi:

Nguồn: www.habr.com

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