Kinh nghiệm của chúng tôi trong việc phát triển trình điều khiển CSI trong Kubernetes cho Yandex.Cloud

Kinh nghiệm của chúng tôi trong việc phát triển trình điều khiển CSI trong Kubernetes cho Yandex.Cloud

Chúng tôi vui mừng thông báo rằng Flant đang mở rộng đóng góp của mình cho các công cụ Nguồn mở cho Kubernetes bằng cách phát hành phiên bản alpha của trình điều khiển CSI (Giao diện lưu trữ container) cho Yandex.Cloud.

Nhưng trước khi chuyển sang chi tiết triển khai, hãy trả lời câu hỏi tại sao điều này lại cần thiết khi Yandex đã có dịch vụ Dịch vụ được quản lý dành cho Kubernetes.

Giới thiệu

Tại sao thế này?

Trong công ty của chúng tôi, ngay từ khi bắt đầu sử dụng Kubernetes trong sản xuất (tức là trong vài năm nay), chúng tôi đã phát triển công cụ của riêng mình (deckhouse), nhân tiện, chúng tôi cũng có kế hoạch sớm cung cấp công cụ này dưới dạng dự án Nguồn mở . Với sự trợ giúp của nó, chúng tôi định cấu hình và định cấu hình thống nhất tất cả các cụm của mình và hiện đã có hơn 100 cụm trong số đó, trên nhiều cấu hình phần cứng và trong tất cả các dịch vụ đám mây có sẵn.

Các cụm sử dụng deckhouse có tất cả các thành phần cần thiết cho hoạt động: bộ cân bằng, giám sát bằng biểu đồ, số liệu và cảnh báo thuận tiện, xác thực người dùng thông qua các nhà cung cấp bên ngoài để truy cập vào tất cả các bảng thông tin, v.v. Sẽ chẳng ích gì khi cài đặt một cụm “được tăng cường” như vậy trong một giải pháp được quản lý, vì điều này thường là không thể hoặc sẽ dẫn đến việc phải vô hiệu hóa một nửa số thành phần.

NB: Đây là kinh nghiệm của chúng tôi và nó khá cụ thể. Chúng tôi không hề gợi ý rằng mọi người nên tự mình triển khai các cụm Kubernetes thay vì sử dụng các giải pháp làm sẵn. Nhân tiện, chúng tôi không có kinh nghiệm thực tế trong việc vận hành Kubernetes từ Yandex và chúng tôi sẽ không đưa ra bất kỳ đánh giá nào về dịch vụ này trong bài viết này.

Nó là gì và dành cho ai?

Vì vậy, chúng ta đã nói về cách tiếp cận hiện đại để lưu trữ trong Kubernetes: CSI hoạt động như thế nào? и cộng đồng đã đến như thế nào đến cách tiếp cận này.

Hiện tại, nhiều nhà cung cấp dịch vụ đám mây lớn đã phát triển trình điều khiển để sử dụng đĩa đám mây của họ làm Ổ đĩa liên tục trong Kubernetes. Nếu nhà cung cấp không có trình điều khiển như vậy nhưng tất cả các chức năng cần thiết đều được cung cấp thông qua API, thì không có gì ngăn cản bạn tự triển khai trình điều khiển. Đây là những gì đã xảy ra với Yandex.Cloud.

Chúng tôi lấy làm cơ sở để phát triển Trình điều khiển CSI cho đám mây DigitalOcean và một vài ý tưởng từ trình điều khiển cho GCP, vì sự tương tác với API của những đám mây này (Google và Yandex) có một số điểm tương đồng. Đặc biệt, API và GCP, Và Yandex trả lại một đối tượng Operation để theo dõi trạng thái của các hoạt động chạy trong thời gian dài (ví dụ: tạo đĩa mới). Để tương tác với API Yandex.Cloud, hãy sử dụng SDK Yandex.Cloud Go.

Kết quả công việc đã làm được xuất bản trên GitHub và có thể hữu ích cho những người vì lý do nào đó sử dụng cài đặt Kubernetes của riêng họ trên máy ảo Yandex.Cloud (nhưng không phải cụm được quản lý tạo sẵn) và muốn sử dụng (đặt hàng) đĩa thông qua CSI.

Thực hiện

Các tính năng chính

Hiện tại trình điều khiển hỗ trợ các chức năng sau:

  • Thứ tự các đĩa trong tất cả các vùng của cụm theo cấu trúc liên kết của các nút trong cụm;
  • Loại bỏ các đĩa đã đặt hàng trước đó;
  • Thay đổi kích thước ngoại tuyến cho đĩa (Yandex.Cloud không hỗ trợ tăng số đĩa được gắn vào máy ảo). Để biết thông tin về cách sửa đổi trình điều khiển để việc thay đổi kích thước dễ dàng nhất có thể, hãy xem bên dưới.

Trong tương lai, chúng tôi dự định triển khai hỗ trợ tạo và xóa ảnh chụp nhanh ổ đĩa.

Khó khăn chính và cách vượt qua nó

Việc thiếu khả năng tăng ổ đĩa trong thời gian thực trong API Yandex.Cloud là một hạn chế làm phức tạp hoạt động thay đổi kích thước cho PV (Khối lượng liên tục): trong trường hợp này, cần phải dừng nhóm ứng dụng sử dụng đĩa, và điều này có thể gây ra thời gian ngừng hoạt động của ứng dụng.

Theo Thông số kỹ thuật CSI, nếu bộ điều khiển CSI báo cáo rằng nó chỉ có thể thay đổi kích thước đĩa “ngoại tuyến” (VolumeExpansion.OFFLINE), thì quá trình tăng đĩa sẽ diễn ra như sau:

Nếu plugin chỉ có VolumeExpansion.OFFLINE khả năng mở rộng và dung lượng hiện đã được xuất bản hoặc có sẵn trên một nút sau đó ControllerExpandVolume CHỈ PHẢI được gọi sau một trong hai:

  • Plugin có bộ điều khiển PUBLISH_UNPUBLISH_VOLUME khả năng và ControllerUnpublishVolume đã được gọi thành công.

HOẶC CÁI GÌ ĐÓ KHÁC

  • Plugin KHÔNG có bộ điều khiển PUBLISH_UNPUBLISH_VOLUME khả năng, plugin có nút STAGE_UNSTAGE_VOLUME khả năng và NodeUnstageVolume đã được hoàn thành thành công.

HOẶC CÁI GÌ ĐÓ KHÁC

  • Plugin KHÔNG có bộ điều khiển PUBLISH_UNPUBLISH_VOLUME khả năng, cũng không phải nút STAGE_UNSTAGE_VOLUME khả năng và NodeUnpublishVolume đã hoàn thành thành công.

Về cơ bản, điều này có nghĩa là bạn cần tháo đĩa ra khỏi máy ảo trước khi mở rộng nó.

Tuy nhiên, thật không may thực hiện Thông số kỹ thuật CSI qua sidecar không đáp ứng các yêu cầu sau:

  • Trong thùng xe sidecar csi-attacher, chịu trách nhiệm về sự hiện diện của khoảng cách cần thiết giữa các lần gắn kết, chức năng này đơn giản là không được triển khai khi thay đổi kích thước ngoại tuyến. Một cuộc thảo luận về điều này đã được bắt đầu đây.
  • Chính xác thì thùng chứa sidecar trong bối cảnh này là gì? Bản thân plugin CSI không tương tác với API Kubernetes mà chỉ phản hồi các lệnh gọi gRPC được gửi tới nó bằng các thùng chứa sidecar. Muộn nhất đang được phát triển bởi cộng đồng Kubernetes.

Trong trường hợp của chúng tôi (plugin CSI), hoạt động tăng đĩa trông như thế này:

  1. Chúng tôi nhận được cuộc gọi gRPC ControllerExpandVolume;
  2. Chúng tôi đang cố gắng tăng đĩa trong API nhưng chúng tôi nhận được lỗi về việc không thể thực hiện thao tác do đĩa được gắn;
  3. Chúng tôi lưu trữ mã định danh đĩa trong bản đồ, trong đó chứa các đĩa cần thực hiện thao tác tăng. Dưới đây, để cho ngắn gọn, chúng ta sẽ gọi bản đồ này là volumeResizeRequired;
  4. Xóa thủ công nhóm đang sử dụng đĩa. Kubernetes sẽ khởi động lại nó. Để đĩa không có thời gian để gắn kết (ControllerPublishVolume) trước khi hoàn tất thao tác tăng khi cố gắng gắn kết, chúng tôi kiểm tra xem đĩa đã cho có còn ở trạng thái không volumeResizeRequired và trả về một lỗi;
  5. Trình điều khiển CSI cố gắng thực hiện lại thao tác thay đổi kích thước. Nếu thao tác thành công, hãy lấy đĩa ra khỏi volumeResizeRequired;
  6. Bởi vì ID đĩa bị thiếu volumeResizeRequired, ControllerPublishVolume vượt qua thành công, đĩa được gắn, nhóm khởi động.

Mọi thứ trông có vẻ đơn giản nhưng luôn có những cạm bẫy. Mở rộng đĩa bộ thay đổi kích thước bên ngoài, trong trường hợp xảy ra lỗi trong quá trình vận hành sử dụng hàng đợi với thời gian chờ tăng theo cấp số nhân lên tới 1000 giây:

func DefaultControllerRateLimiter() RateLimiter {
  return NewMaxOfRateLimiter(
  NewItemExponentialFailureRateLimiter(5*time.Millisecond, 1000*time.Second),
  // 10 qps, 100 bucket size.  This is only for retry speed and its only the overall factor (not per item)
  &BucketRateLimiter{Limiter: rate.NewLimiter(rate.Limit(10), 100)},
  )
}

Điều này định kỳ có thể dẫn đến hoạt động mở rộng ổ đĩa được kéo dài hơn 15 phút và do đó, nhóm tương ứng sẽ không khả dụng.

Tùy chọn duy nhất khá dễ dàng và không gây đau đớn cho phép chúng tôi giảm thời gian ngừng hoạt động tiềm ẩn là sử dụng phiên bản bộ thay đổi kích thước bên ngoài của chúng tôi với giới hạn thời gian chờ tối đa trong 5 giây nữa:

workqueue.NewItemExponentialFailureRateLimiter(5*time.Millisecond, 5*time.Second)

Chúng tôi không cho rằng cần phải khẩn trương bắt đầu một cuộc thảo luận và vá bộ thay đổi kích thước bên ngoài, bởi vì việc thay đổi kích thước ổ đĩa ngoại tuyến là một nhược điểm sẽ sớm biến mất khỏi tất cả các nhà cung cấp đám mây.

Làm thế nào để bắt đầu sử dụng?

Trình điều khiển được hỗ trợ trên Kubernetes phiên bản 1.15 trở lên. Để người lái xe có thể làm việc được thì phải đáp ứng các yêu cầu sau:

  • Флаг --allow-privileged đặt thành giá trị true cho máy chủ API và kubelet;
  • Đã bao gồm --feature-gates=VolumeSnapshotDataSource=true,KubeletPluginsWatcher=true,CSINodeInfo=true,CSIDriverRegistry=true cho máy chủ API và kubelet;
  • Sự lan truyền gắn kết (gắn kết nhân giống) phải được kích hoạt trên cụm. Khi sử dụng Docker, daemon phải được cấu hình để cho phép gắn kết chia sẻ.

Tất cả các bước cần thiết cho quá trình cài đặt được mô tả trong README. Quá trình cài đặt liên quan đến việc tạo các đối tượng trong Kubernetes từ các tệp kê khai.

Để trình điều khiển hoạt động, bạn sẽ cần những thứ sau:

  • Chỉ định mã định danh thư mục trong tệp kê khai (folder-id) Yandex.Cloud (xem tài liệu);
  • Để tương tác với API Yandex.Cloud, trình điều khiển CSI sử dụng tài khoản dịch vụ. Trong bảng kê khai, Bí mật phải được thông qua khóa được ủy quyền từ tài khoản dịch vụ. Trong tài liệu mô tả, cách tạo tài khoản dịch vụ và nhận chìa khóa.

Tất cả trong tất cả - cố gắng, và chúng tôi sẽ rất vui khi nhận được phản hồi và vấn đề mớinếu bạn gặp bất kỳ vấn đề!

Sự trợ giúp thêm

Do đó, chúng tôi muốn lưu ý rằng chúng tôi triển khai trình điều khiển CSI này không phải vì mong muốn có được niềm vui viết ứng dụng trong Go mà vì nhu cầu cấp thiết trong công ty. Việc duy trì việc triển khai của riêng mình có vẻ không thực tế đối với chúng tôi, vì vậy nếu Yandex thể hiện sự quan tâm và quyết định tiếp tục hỗ trợ trình điều khiển, chúng tôi sẽ sẵn lòng chuyển kho lưu trữ cho họ.

Ngoài ra, Yandex có thể có trình điều khiển CSI riêng trong cụm Kubernetes được quản lý, có thể được phát hành trong Nguồn mở. Chúng tôi cũng thấy tùy chọn phát triển này là thuận lợi - cộng đồng sẽ có thể sử dụng trình điều khiển đã được chứng minh từ nhà cung cấp dịch vụ chứ không phải từ công ty bên thứ ba.

PS

Đọ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