0
0
Lập trình
Admin Team
Admin Teamtechmely

Khám Phá Pods: Bí Quyết Kubernetes Cho DevOps

Đăng vào 7 tháng trước

• 13 phút đọc

Khám Phá Pods: Bí Quyết Kubernetes Cho DevOps

Giới thiệu

Nếu bạn đã từng triển khai bất kỳ ứng dụng nào trên Kubernetes, chắc chắn bạn đã chạm đến Pods. Hầu hết mọi người coi chúng như một hộp chứa các container, khởi động chúng, kiểm tra trạng thái và tiếp tục công việc. Nhưng thực tế, Pods còn nhiều điều thú vị hơn thế. Chúng chứa đựng nhiều tính năng vượt xa việc “chỉ chạy ứng dụng”.

Bên dưới bề ngoài đơn giản là các mẫu, probes, policies và công cụ gỡ lỗi có thể khiến hạ tầng của bạn trở nên trơn tru hoặc trở thành cơn ác mộng khi mọi thứ đi sai. Trong bài viết này, chúng ta sẽ khám phá tiềm năng thực sự của Pods, từ sidecars và init containers đến ephemeral containers và tối ưu hóa tài nguyên. Dù bạn đang khắc phục sự cố dịch vụ không ổn định, tối ưu hóa hiệu suất cụm hay đơn giản chỉ là tò mò về những gì mà các chuyên gia làm khác biệt, bài viết này dành cho bạn.

Hãy cùng đào sâu và nâng cao kỹ năng Pod của bạn từ cơ bản đến nâng cao.

Pods: Nhiều hơn một Container

Hầu hết các lập trình viên nghĩ rằng một Pod chỉ là một lớp vỏ quanh một container. Nó chạy ứng dụng của bạn, có thể khởi động lại khi có sự cố, và đó là tất cả. Tuy nhiên, Pods là đơn vị triển khai nhỏ nhất trong Kubernetes và có thể chứa nhiều container chia sẻ mạng, lưu trữ và vòng đời.

Về cơ bản, một Pod có thể chứa một container, là điều mà hầu hết mọi người sử dụng. Nhưng Kubernetes thiết kế Pods để hỗ trợ nhiều container chạy song song. Những container này làm việc như một đội, chia sẻ IP và các volume đã gắn. Điều này khiến Pods trở nên lý tưởng cho việc chạy các quy trình trợ giúp như thu thập log hay biến đổi dữ liệu bên cạnh ứng dụng chính.

Tiếp theo là init containers. Đây là những container được chạy trước khi ứng dụng chính bắt đầu. Chúng xử lý các tác vụ thiết lập như kéo các tệp cấu hình, kiểm tra phụ thuộc dịch vụ hoặc thực hiện di trú cơ sở dữ liệu. Bạn không cần phải lập trình điều này trong ứng dụng của mình nữa; init containers giúp mọi thứ trở nên mô-đun và dễ quản lý hơn.

Cuối cùng, có khái niệm về shared context. Mỗi container trong một Pod có thể giao tiếp với nhau thông qua localhost và tất cả đều chia sẻ các volume đã gắn. Điều này mở ra cơ hội cho các mẫu thiết kế như sidecars và adapters (mà chúng ta sẽ tìm hiểu sau).

Vì vậy, lần tới khi bạn tạo một Pod, hãy đặt câu hỏi: liệu nó có cần chỉ là một container, hay tôi có thể kiến trúc một cái gì đó gọn gàng hơn bằng cách phân chia trách nhiệm bên trong Pod?

Chính Sách Khởi Động, Probes và Tại Sao Ứng Dụng Của Bạn Liên Tục Bị Khởi Động

Bạn triển khai một ứng dụng. Nó chạy tốt trên máy của bạn. Bạn gửi nó lên Kubernetes. Sau đó, đột nhiên, Pod của bạn liên tục khởi động lại, log không có ý nghĩa gì và pager của bạn reo vào những giờ không thể tưởng tượng nổi. Nghe quen thuộc chứ?

Hãy cùng phân tích lý do tại sao điều này xảy ra và cách Kubernetes thực sự đang cố gắng giúp bạn.

Mỗi Pod đi kèm với một chính sách khởi động lại. Theo mặc định, nó được cài đặt để luôn luôn khởi động lại container nếu nó bị hỏng. Điều này rất tốt cho tính bền bỉ nhưng có thể trở thành một vòng lặp im lặng nếu ứng dụng của bạn liên tục thất bại ngay sau khởi động. Bạn thậm chí sẽ không nhận ra nếu không kiểm tra nhật ký sự kiện hoặc số liệu.

Tiếp theo là các liveness, readiness, và startup probes - bộ ba thánh thiện giúp giữ cho Pods của bạn khỏe mạnh và cụm của bạn ổn định.

  • Liveness probe cho Kubernetes biết ứng dụng của bạn có đang sống hay không. Nếu nó thất bại, Kubernetes sẽ giết và khởi động lại container.
  • Readiness probe cho biết liệu ứng dụng của bạn đã sẵn sàng phục vụ lưu lượng không. Cho đến khi nó vượt qua, không có lưu lượng nào được gửi đến.
  • Startup probe rất hoàn hảo cho các ứng dụng khởi động chậm. Nó ngăn chặn các kiểm tra liveness khởi động quá sớm và giết chết một container chỉ cần thêm thời gian để khởi động.

Khi những probes này không được cấu hình đúng, Kubernetes có thể khởi động lại ứng dụng của bạn quá mức hoặc để nó tồn tại ngay cả khi nó bị hỏng. Đây là một hành động cân bằng nhưng khi được điều chỉnh đúng, chúng sẽ cứu bạn khỏi vô số cơn đau đầu trong sản xuất.

Probes không chỉ là các ô kiểm - chúng là hệ thống phòng thủ của bạn. Cài đặt chúng như thể bạn quan tâm đến giấc ngủ của mình.

Sidecars, Ambassadors và Adapters: Giải Thích Mẫu Pod

Đây là nơi mọi thứ bắt đầu trở nên kiến trúc.

Pods không chỉ chạy ứng dụng của bạn - chúng có thể chạy một hệ sinh thái các container làm việc cùng nhau. Kubernetes hỗ trợ một tập hợp các mẫu thiết kế container giúp phân chia chức năng thành các vai trò hợp tác bên trong một Pod. Ba mẫu phổ biến nhất là sidecars, ambassadors, và adapters.

Hãy bắt đầu với sidecar pattern. Hãy nghĩ về nó như một sidecar của xe máy - nó được gắn vào ứng dụng chính của bạn và di chuyển cùng nó. Một sidecar container có thể xử lý logging, proxying, tải lại cấu hình, hoặc đồng bộ hóa bí mật. Một ví dụ điển hình là sử dụng Fluentd hoặc Filebeat để thu thập log từ ứng dụng chính và gửi chúng đến nơi khác.

Tiếp theo là ambassador pattern. Mẫu này hơi khác một chút. Một ambassador container hoạt động như một proxy mà ứng dụng chính của bạn giao tiếp, và ambassador xử lý các giao tiếp bên ngoài. Điều này có thể giúp với các vấn đề như TLS termination, dịch vụ dịch, hoặc thậm chí phát hiện dịch vụ. Ứng dụng của bạn chỉ cần giao tiếp với localhost, và ambassador sẽ xử lý mọi thứ rắc rối.

Cuối cùng, adapter pattern. Container này nhận đầu ra của ứng dụng của bạn và chuyển đổi nó sang định dạng hoặc giao thức khác. Ví dụ, nó có thể chuyển đổi log văn bản thuần túy thành JSON có cấu trúc hoặc lấy phản hồi HTTP và phát nó như là số liệu cho một hệ thống giám sát.

Ý tưởng chính ở đây là phân tách mối quan tâm. Thay vì gộp tất cả vào container chính của bạn, các mẫu cấp Pod này cho phép bạn phân chia chức năng một cách rõ ràng, dễ gỡ lỗi hơn và tái sử dụng các thành phần giữa các dịch vụ.

Khi bạn bắt đầu suy nghĩ theo các mẫu, Pods trở thành thứ gì đó nhiều hơn là chỉ là một nơi để chứa các container - chúng trở thành các hệ thống mạnh mẽ.

Ephemeral Containers và Gỡ Lỗi Trong Sản Xuất

Hãy thực tế: dù bạn có bao nhiêu bảng điều khiển hay bao nhiêu log bạn gửi, sẽ có lúc mọi thứ bị hỏng và cách duy nhất để tìm ra là nhảy vào Pod đang chạy và kiểm tra.

Đây là lúc ephemeral containers xuất hiện. Chúng là một loại container đặc biệt mà bạn có thể chèn vào một Pod đang chạy sau khi nó đã khởi động. Hãy nghĩ về chúng như là cánh cửa khẩn cấp để gỡ lỗi mà không làm gián đoạn ứng dụng thực tế.

Khác với các container chính trong một Pod, ephemeral containers không tự động chạy và không khởi động lại nếu chúng bị hỏng. Mục đích của chúng hoàn toàn là để kiểm tra và chẩn đoán. Bạn khởi động một cái, chạy các công cụ của bạn, và khi bạn xong, nó biến mất như một ninja gỡ lỗi.

Giả sử ứng dụng của bạn bị hỏng một cách bí ẩn và log không cung cấp thông tin gì nhiều. Thay vì khởi động lại Pod và có nguy cơ làm mọi thứ tồi tệ hơn, bạn có thể chèn một ephemeral container với các công cụ như strace, curl, netstat hoặc thậm chí chỉ là bash. Nó đưa bạn vào không gian tên, mạng và bối cảnh volume của Pod mà không làm gián đoạn các container đang chạy ở đó.

Tất nhiên, tính năng này chỉ có sẵn nếu cụm của bạn cho phép và quyền hạn đúng đã được thiết lập. Nhưng một khi được thiết lập, nó thực sự là một cứu tinh. Nó có thể cứu lấy sự tỉnh táo của bạn, thời gian hoạt động và cuối tuần của bạn.

Vì vậy, lần sau khi ai đó hỏi làm thế nào để gỡ lỗi một Pod đang sống mà không có thời gian chết, bạn có thể nói: có một container cho điều đó.

Pod Presets, Overhead và Tại Sao Các Node Của Bạn La Lên

Bạn đã bao giờ triển khai vài chục Pods và chứng kiến cụm của bạn ngừng hoạt động như thể nó vừa hết RAM khi cố mở một bảng tính? Đó thường không phải là do Kubernetes tồi tệ - mà là do bạn (hoặc ai đó trong nhóm bạn) không quản lý đúng resource requests, limits, và overhead.

Hãy bắt đầu với những điều cơ bản. Mỗi container trong một Pod có thể (và nên) khai báo bao nhiêu CPU và bộ nhớ mà nó yêu cầu và bao nhiêu mà nó được phép sử dụng. Kubernetes sử dụng yêu cầu để lập lịch cho Pods và giới hạn để giới hạn chúng. Nếu bỏ qua việc thiết lập này, Pods của bạn sẽ trở thành những kẻ ăn bám trên cụm, lấy bất cứ thứ gì chúng muốn, bất cứ khi nào chúng muốn.

Điều này trở nên tồi tệ hơn khi mọi người sao chép và dán YAML từ Stack Overflow mà không hiểu 500Mi hoặc 250m có nghĩa là gì. Các Pods yêu cầu quá nhiều thì không được lập lịch. Các Pods yêu cầu quá ít thì bị đuổi. Nếu bạn vượt quá số lượng node của mình, mọi thứ sẽ chậm lại hoặc sập theo những cách kỳ quặc, khó gỡ lỗi.

Bây giờ hãy nói về Pod overhead. Mỗi Pod thêm một số tài nguyên cần thiết - nghĩ đến việc thiết lập mạng, cách ly thời gian chạy, và các volume đã gắn. Overhead này không lớn cho mỗi Pod, nhưng tích lũy nhanh ở quy mô lớn. Nếu bạn đang chạy hàng trăm Pods nhỏ với lưu lượng tối thiểu, chi phí ẩn này có thể tiêu tốn khả năng của node mà bạn không nhận ra.

Giải pháp là Pod presets. Chúng giống như các macro của Kubernetes cho phép bạn áp dụng cấu hình tài nguyên tiêu chuẩn (hoặc nhãn, biến môi trường, v.v.) cho tất cả các Pods một cách tự động. Chúng đặc biệt hữu ích trong các tổ chức lớn để ngăn chặn các nhóm cấu hình sai tài nguyên, vì hãy đối mặt với nó - không phải ai cũng đọc tài liệu.

Và sau đó có các lớp Quality of Service (QoS). Kubernetes sử dụng chúng để phân loại mức độ quan trọng của một Pod khi đến lúc đuổi bỏ thứ gì đó. Các Pods có tài nguyên được đảm bảo được giữ an toàn. Các Pods có khả năng bùng nổ thì tạm ổn. Các Pods tốt nhất nỗ lực là những người đầu tiên bị đuổi khi áp lực đến.

Vì vậy, chắc chắn rằng các node của bạn có thể la lên vì các Pods của bạn quá ồn ào, tham lam và không được quản lý. Giải pháp? Hãy hào phóng với các giới hạn, bảo thủ với yêu cầu, và đừng bao giờ quên rằng mỗi Pod tốn kém hơn chỉ là ứng dụng bên trong.

Cách Pods Thích Ứng Với Bức Tranh Lớn

Bạn đã nhìn thấy bên trong một Pod. Nhưng hiểu cách hoạt động của Pods trong cô lập không đủ. Trong một cụm Kubernetes thực sự, các Pods hiếm khi sống một mình. Chúng gần như luôn được quản lý bởi một thứ lớn hơn - thường là một controller.

Hãy phân tích điều đó với các ví dụ.

Deployments Quản Lý Pods Cho Bạn

Một Deployment xác định số lượng bản sao của Pod mà bạn muốn chạy tại mọi thời điểm.

yaml Copy
apiVersion: apps/v1
kind: Deployment
metadata:
  name: my-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: my-app
  template:
    metadata:
      labels:
        app: my-app
    spec:
      containers:
      - name: my-app
        image: my-app:latest

Điều này cho Kubernetes biết để giữ ba Pods giống hệt đang chạy. Nếu một bị hỏng, một cái khác sẽ khởi động. Bạn không cần phải tạo Pods một cách thủ công trong hầu hết các ứng dụng - bạn định nghĩa các mẫu và để Kubernetes quản lý chúng.

Pods Xuất Hiện Trong Các Controller Khác

  • DaemonSets chạy một Pod trên mỗi node (nghĩ đến các log shipper hoặc các tác nhân giám sát).
  • StatefulSets quản lý các Pods có danh tính vĩnh viễn (tuyệt vời cho cơ sở dữ liệu).
  • JobsCronJobs chạy các Pods thực hiện một tác vụ và thoát.
bash Copy
kubectl get pods
kubectl describe pod my-app-6fd79c9d87-xyz

Những công cụ này không chỉ để xem Pods - chúng rất cần thiết khi gỡ lỗi. Lệnh describe cho biết lý do tại sao một Pod có thể không khởi động: các mount thất bại, vấn đề kéo hình ảnh, probes sai, v.v.

Tại Sao Điều Đó Quan Trọng

Bạn sẽ không bao giờ quản lý Pods một cách thủ công ở quy mô lớn. Nhưng hiểu chúng, cách chúng khởi động lại, cách chúng được kiểm tra, cách chúng chia sẻ tài nguyên là điều tách biệt một kỹ sư DevOps giỏi với người chỉ nhấn nút trong UI.

Khi một ứng dụng bị hỏng, một node bị quá tải, hoặc lưu lượng tăng đột ngột vào lúc 2 giờ sáng, bạn sẽ vui mừng khi biết điều gì đang thực sự xảy ra bên trong Pod trông có vẻ vô tội đó.

Kết luận

Pods là trái tim đập của Kubernetes. Chắc chắn, chúng ta nói về Deployments, Services và Ingresses cả ngày, nhưng cuối cùng, mọi thứ đều chạy bên trong một Pod. Càng hiểu rõ cách thức hoạt động của chúng, bạn càng giỏi hơn trong việc chẩn đoán vấn đề, mở rộng ứng dụng và làm cho hạ tầng của bạn thực sự hoạt động.

Chúng ta đã đề cập đến nhiều hơn chỉ là “một container trong một lớp vỏ”. Bạn giờ đây biết cách:

  • Sử dụng init containers và các mẫu nhiều container hiệu quả
  • Cấu hình probes để giữ cho ứng dụng của bạn khỏe mạnh (và giấc ngủ của bạn không bị gián đoạn)
  • Tận dụng sidecars, ambassadors và adapters như một chuyên gia
  • Gỡ lỗi với ephemeral containers thay vì khởi động lại mọi thứ một cách hoảng loạn
  • Quản lý yêu cầu tài nguyên, giới hạn và tránh làm hỏng các node của bạn với sự tử tế
  • Thấy nơi mà Pods sống trong bức tranh lớn hơn của cụm Kubernetes

Bạn không cần phải ghi nhớ mọi thứ ở đây. Nhưng hãy đánh dấu nó, tham khảo lại và quan trọng hơn, hãy thử các khái niệm này trong một cụm thử nghiệm. Phá hỏng mọi thứ. Sửa chữa nó. Đó là cách bạn thực sự giỏi.

Liên kết hữu ích để đi sâu hơn

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào