Tự host Paperless-ngx trên k3s đòi hỏi xử lý lưu trữ GitOps cẩn trọng
Một nhà phát triển chi tiết hóa những cạm bẫy khi chạy Paperless-ngx trên k3s với Flux, nhấn mạnh các yêu cầu chú thích (annotation) quan trọng cho bộ nhớ lưu trữ bền vững và các lỗi khởi tạo phổ biến.
Bài được dịch tự động từ bản gốc tiếng Anh.
Một hướng dẫn kỹ thuật gần đây trình bày quy trình tự host Paperless-ngx, một hệ thống quản lý tài liệu mã nguồn mở, trên cụm Kubernetes k3s nút đơn sử dụng các nguyên tắc GitOps. Tác giả, Dhiraj Shrotri, ghi lại các bước cấu hình cụ thể và quá trình khắc phục sự cố cần thiết để chạy ứng dụng trên máy tính mini Beelink với bộ nhớ ngoài, đồng thời nhấn mạnh những rủi ro liên quan đến việc tự động cắt tỉa (pruning) tài nguyên trong Flux.
Chuyện gì đã xảy ra
Dự án nhằm mục đích thay thế các dịch vụ quét tài liệu dựa trên đám mây bằng một giải pháp tự host riêng tư, cung cấp tính năng nhận dạng ký tự quang học (OCR) và tìm kiếm dựa trên nội dung. Stack công nghệ được lựa chọn bao gồm việc chạy Paperless-ngx trên k3s, một bản phân phối Kubernetes nhẹ, được quản lý bởi Flux cho việc triển khai liên tục theo mô hình GitOps. Thiết lập này sử dụng máy tính mini Beelink với ổ SSD bên trong cho cơ sở dữ liệu và chỉ mục tìm kiếm, trong khi một ổ cứng ngoài lưu trữ các tệp tài liệu thực tế và bản sao lưu. Kiến trúc này cho phép người dùng quét tài liệu thông qua các ứng dụng di động như Swift Paperless hoặc PaperNext, sau đó tải lên máy chủ cục bộ để xử lý.
Một phần đáng kể của hướng dẫn tập trung vào những nguy hiểm khi sử dụng prune: true trong các cấu hình Flux. Trong GitOps, cài đặt này đảm bảo rằng các tài nguyên bị xóa khỏi kho Git cũng sẽ bị xóa khỏi cụm. Mặc dù hữu ích cho việc dọn dẹp các bản triển khai, nó gây ra rủi ro nghiêm trọng cho các khối lượng lưu trữ bền vững (persistent storage volumes). Nếu một PersistentVolume Claim (PVC) vô tình bị xóa khỏi manifest Git, Flux sẽ xóa bộ nhớ lưu trữ nền tảng, dẫn đến mất dữ liệu vĩnh viễn. Để ngăn chặn điều này, tác giả đã thêm chú thích kustomize.toolkit.fluxcd.io/prune: disabled vào namespace, PVC, PersistentVolumes (PV) và StorageClass. Chỉ thị này yêu cầu Flux quản lý các tài nguyên này nhưng không bao giờ xóa chúng, ngay cả khi chúng vắng mặt trong kho Git.
Quá trình triển khai cũng bộc lộ nhiều cạm bẫy khi khởi tạo. Tác giả lưu ý rằng lệnh flux bootstrap không đẩy các commit cục bộ hiện có lên kho từ xa; nó chỉ đẩy các tệp hệ thống của chính nó. Điều này đòi hỏi một quy trình làm việc cụ thể: đẩy các thay đổi cục bộ trước, chạy bootstrap trên máy chủ, và sau đó kéo các cập nhật trở lại máy cục bộ. Ngoài ra, các lỗi xác thực nảy sinh do Flux đọc một tệp kubeconfig cũ từ lần cài đặt MicroK8s trước đó. Việc giải quyết vấn đề này đòi hỏi phải sao chép cấu hình k3s chính xác từ /etc/rancher/k3s/k3s.yaml sang vị trí chuẩn ~/.kube/config.
Chi tiết chính
- An toàn lưu trữ: Thêm chú thích
kustomize.toolkit.fluxcd.io/prune: disabledcho tất cả các tài nguyên Kubernetes liên quan đến lưu trữ để ngăn Flux xóa các khối lượng dữ liệu trong quá trình đồng bộ hóa. - Yêu cầu hệ thống tệp: Các ổ đĩa ngoài được sử dụng cho volume Kubernetes phải được định dạng dưới ext4, vì NTFS và exFAT không hỗ trợ quyền sở hữu tệp Linux mà các container yêu cầu.
- Quy trình khởi tạo: Đẩy các commit Git cục bộ trước khi chạy
flux bootstrap, sau đó kéo repository về máy cục bộ để đồng bộ hóa các tệp hệ thống mới của Flux. - Xung đột Kubeconfig: Đảm bảo Flux sử dụng tệp kubeconfig k3s chính xác nằm tại
/etc/rancher/k3s/k3s.yamlđể tránh các lỗi chứng chỉ x509 authority. - Tích hợp di động: Không có ứng dụng di động chính thức, nhưng các client cộng đồng như Swift Paperless (iOS) và PaperNext (Android/iOS) cung cấp khả năng quét và tải lên.
- Tối ưu hóa tài nguyên: Vô hiệu hóa các liên kết dịch vụ thông qua
enableServiceLinks: falsecó thể giảm thời gian khởi động và mức độ sử dụng tài nguyên trên các cụm nút đơn.
Bối cảnh
GitOps là một tập hợp các thực hành trong đó cấu hình hạ tầng và ứng dụng được quản lý thông qua các kho Git. Các công cụ như Flux giám sát những kho này và tự động áp dụng mọi thay đổi lên cụm Kubernetes. Cách tiếp cận này cung cấp kiểm soát phiên bản, dấu vết kiểm toán và khôi phục tự động cho trạng thái hạ tầng. Tuy nhiên, nó giới thiệu một mô hình "khai báo" (declarative), nơi trạng thái cụm luôn phải khớp với trạng thái Git. Nếu một đối tượng bị xóa khỏi Git, các công cụ GitOps mặc định cho rằng nó nên bị xóa khỏi cụm trừ khi được chỉ định khác đi.
Paperless-ngx là một hệ thống lưu trữ tài liệu tiếp nhận các tài liệu đã quét, thực hiện OCR để làm cho văn bản có thể tìm kiếm được, và áp dụng gắn thẻ và sắp xếp tự động. Khác với các tủ hồ sơ truyền thống hoặc hệ thống dựa trên thư mục như Nextcloud, nó tổ chức thông tin dựa trên siêu dữ liệu nội dung. Nó phụ thuộc vào một số dịch vụ backend, bao gồm PostgreSQL cho siêu dữ liệu, Redis cho caching, và Apache Tika cùng Gotenberg để xử lý các định dạng tệp khác nhau như tài liệu Word và Excel.
Tại sao điều này quan trọng
Đối với các nhóm và cá nhân quản lý phần mềm của riêng họ, giao điểm giữa các ứng dụng có trạng thái (stateful applications) và GitOps đặt ra những thách thức vận hành độc đáo. Các ứng dụng có trạng thái, chẳng hạn như hệ thống quản lý tài liệu hoặc cơ sở dữ liệu, phụ thuộc vào bộ nhớ lưu trữ bền vững tồn tại lâu hơn các instance container riêng lẻ. Các vòng lặp hòa giải tự động (automated reconciliation loops) trong các công cụ GitOps có thể vô tình phá hủy dữ liệu bền vững này nếu không có biện pháp bảo vệ phù hợp. Hiểu cách thêm chú thích cho các tài nguyên để loại trừ chúng khỏi quá trình cắt tỉa là rất quan trọng để duy trì tính toàn vẹn dữ liệu trong môi trường tự động hóa.
Hơn nữa, sự phức tạp trong việc thiết lập một môi trường tự host mạnh mẽ trên phần cứng tiêu thụ ít điện năng làm nổi bật sự đánh đổi giữa quyền kiểm soát và sự tiện lợi. Mặc dù tự host mang lại quyền riêng tư và tránh bị khóa vào nhà cung cấp (vendor lock-in), nó đòi hỏi kiến thức sâu rộng về mạng Kubernetes, lớp lưu trữ và quản lý cấu hình. Lỗi trong đường dẫn kubeconfig hoặc quyền hệ thống tệp có thể làm dừng hoàn toàn quá trình triển khai, đòi hỏi sự can thiệp thủ công, điều này đi ngược lại mục đích của tự động hóa. Trải nghiệm này nhấn mạnh nhu cầu về thử nghiệm nghiêm ngặt và tài liệu rõ ràng khi triển khai GitOps cho các workload có trạng thái.
Bạn có thể làm gì
- Kiểm toán chính sách cắt tỉa: Xem xét tất cả các manifest của Flux hoặc ArgoCD để đảm bảo rằng PersistentVolumes và Claims được bảo vệ khỏi việc xóa tự động bằng cách sử dụng các chú thích phù hợp.
- Xác minh tương thích hệ thống tệp: Trước khi gắn bộ nhớ ngoài vào các nút Kubernetes, hãy xác nhận rằng đĩa được định dạng với hệ thống tệp gốc Linux như ext4 hoặc XFS để hỗ trợ xử lý quyền hạn đúng cách.
- Chuẩn hóa đường dẫn kubeconfig: Kiểm tra các cấu hình Kubernetes xung đột trên máy chủ và đảm bảo các công cụ CI/CD và CLI cục bộ trỏ đến tệp cấu hình chính xác của cụm đang hoạt động.
- Cố định tag hình ảnh container: Tránh sử dụng tag
:latesttrong các kho GitOps sản xuất để ngăn ngừa nâng cấp ngoài ý muốn khi pod khởi động lại; thay vào đó, hãy cố định các phiên bản cụ thể và cập nhật chúng thông qua commit. - Kiểm tra khôi phục bản sao lưu: Thường xuyên xác minh rằng các bản sao lưu được lưu trên các khối lượng ngoài có thể được khôi phục và các mount volume vẫn tồn tại đúng cách sau khi khởi động lại nút.
- Vô hiệu hóa liên kết dịch vụ không cần thiết: Thêm
enableServiceLinks: falsevào spec của pod trong các cụm nút đơn để giảm chi phí tiêm biến môi trường và tăng tốc khởi tạo pod.



