Gắn thẻ dựa trên nội dung trong trình thu thập werf: tại sao và hoạt động như thế nào?

Gắn thẻ dựa trên nội dung trong trình thu thập werf: tại sao và hoạt động như thế nào?

người sói là tiện ích GitOps CLI mã nguồn mở của chúng tôi để xây dựng và phân phối ứng dụng cho Kubernetes. TRONG phát hành v1.1 một tính năng mới đã được giới thiệu trong trình thu thập hình ảnh: gắn thẻ hình ảnh theo nội dung hoặc gắn thẻ dựa trên nội dung. Cho đến thời điểm hiện tại, sơ đồ gắn thẻ điển hình trong werf liên quan đến việc gắn thẻ hình ảnh Docker bằng thẻ Git, nhánh Git hoặc cam kết Git. Nhưng tất cả các kế hoạch này đều có những nhược điểm đã được giải quyết hoàn toàn bằng chiến lược gắn thẻ mới. Thông tin chi tiết về nó và lý do tại sao nó lại tốt như vậy vẫn chưa được tiết lộ.

Triển khai một bộ vi dịch vụ từ một kho lưu trữ Git

Một tình huống thường xảy ra khi một ứng dụng được chia thành nhiều dịch vụ độc lập ít nhiều. Việc phát hành các dịch vụ này có thể diễn ra độc lập: một hoặc nhiều dịch vụ có thể được phát hành cùng một lúc, trong khi các dịch vụ còn lại phải tiếp tục hoạt động mà không có bất kỳ thay đổi nào. Nhưng từ quan điểm lưu trữ mã và quản lý dự án, sẽ thuận tiện hơn nếu giữ các dịch vụ ứng dụng đó trong một kho lưu trữ duy nhất.

Có những tình huống khi các dịch vụ thực sự độc lập và không liên kết với một ứng dụng nào. Trong trường hợp này, chúng sẽ được đặt trong các dự án riêng biệt và việc phát hành chúng sẽ được thực hiện thông qua các quy trình CI/CD riêng biệt trong mỗi dự án.

Tuy nhiên, trên thực tế, các nhà phát triển thường chia một ứng dụng thành nhiều vi dịch vụ, nhưng việc tạo một kho lưu trữ và dự án riêng cho từng dịch vụ... rõ ràng là một việc quá mức cần thiết. Tình huống này sẽ được thảo luận thêm: một số dịch vụ vi mô như vậy được đặt trong một kho lưu trữ dự án duy nhất và việc phát hành diễn ra thông qua một quy trình duy nhất trong CI/CD.

Gắn thẻ theo nhánh Git và thẻ Git

Giả sử chiến lược gắn thẻ phổ biến nhất được sử dụng - thẻ hoặc nhánh. Đối với các nhánh Git, hình ảnh được gắn thẻ với tên của nhánh, mỗi nhánh chỉ có một hình ảnh được xuất bản theo tên của nhánh đó. Đối với thẻ Git, hình ảnh được gắn thẻ theo tên thẻ.

Khi thẻ Git mới được tạo—ví dụ: khi phiên bản mới được phát hành—thẻ Docker mới sẽ được tạo cho tất cả hình ảnh dự án trong Sổ đăng ký Docker:

  • myregistry.org/myproject/frontend:v1.1.10
  • myregistry.org/myproject/myservice1:v1.1.10
  • myregistry.org/myproject/myservice2:v1.1.10
  • myregistry.org/myproject/myservice3:v1.1.10
  • myregistry.org/myproject/myservice4:v1.1.10
  • myregistry.org/myproject/myservice5:v1.1.10
  • myregistry.org/myproject/database:v1.1.10

Những tên hình ảnh mới này được chuyển qua các mẫu Helm đến cấu hình Kubernetes. Khi bắt đầu triển khai bằng lệnh werf deploy trường đang được cập nhật image trong bảng kê khai tài nguyên Kubernetes và khởi động lại các tài nguyên tương ứng do tên hình ảnh đã thay đổi.

vấn đề: trong trường hợp trên thực tế, nội dung của hình ảnh không thay đổi kể từ lần triển khai trước (thẻ Git), mà chỉ có thẻ Docker của nó, điều này sẽ xảy ra thêm khởi động lại ứng dụng này và do đó, có thể xảy ra một số thời gian ngừng hoạt động. Mặc dù không có lý do thực sự để thực hiện việc khởi động lại này.

Do đó, với sơ đồ gắn thẻ hiện tại, cần phải rào một số kho lưu trữ Git riêng biệt và vấn đề nảy sinh trong việc tổ chức triển khai một số kho lưu trữ này. Nói chung, sơ đồ như vậy tỏ ra quá tải và phức tạp. Tốt hơn là kết hợp nhiều dịch vụ vào một kho lưu trữ duy nhất và tạo các thẻ Docker để không phải khởi động lại không cần thiết.

Gắn thẻ bằng cam kết Git

werf cũng có chiến lược gắn thẻ liên quan đến cam kết Git.

Git-commit là mã định danh cho nội dung của kho Git và phụ thuộc vào lịch sử chỉnh sửa của các tệp trong kho Git, do đó, có vẻ hợp lý khi sử dụng nó để gắn thẻ hình ảnh trong Docker Register.

Tuy nhiên, gắn thẻ theo cam kết Git có nhược điểm tương tự như gắn thẻ theo nhánh Git hoặc thẻ Git:

  • Một cam kết trống có thể được tạo mà không thay đổi bất kỳ tệp nào, nhưng thẻ Docker của hình ảnh sẽ bị thay đổi.
  • Một cam kết hợp nhất có thể được tạo mà không thay đổi các tệp, nhưng thẻ Docker của hình ảnh sẽ bị thay đổi.
  • Một cam kết có thể được thực hiện để thay đổi những tệp trong Git chưa được nhập vào hình ảnh và thẻ Docker của hình ảnh sẽ được thay đổi lại.

Gắn thẻ tên nhánh Git không phản ánh phiên bản hình ảnh

Có một vấn đề khác liên quan đến chiến lược gắn thẻ cho các nhánh Git.

Việc gắn thẻ theo tên nhánh hoạt động miễn là các cam kết trên nhánh đó được thu thập tuần tự theo thứ tự thời gian.

Nếu trong sơ đồ hiện tại, người dùng bắt đầu xây dựng lại một cam kết cũ được liên kết với một nhánh nhất định thì werf sẽ viết lại hình ảnh bằng thẻ Docker tương ứng với phiên bản hình ảnh mới được tạo cho cam kết cũ. Việc triển khai sử dụng thẻ này kể từ bây giờ có nguy cơ lấy một phiên bản hình ảnh khác khi khởi động lại nhóm, do đó ứng dụng của chúng tôi sẽ mất kết nối với hệ thống CI và không được đồng bộ hóa.

Ngoài ra, với việc đẩy liên tiếp vào một nhánh với khoảng thời gian ngắn giữa chúng, cam kết cũ có thể được biên dịch muộn hơn phiên bản mới hơn: phiên bản cũ của hình ảnh sẽ ghi đè lên phiên bản mới bằng thẻ nhánh Git. Những vấn đề như vậy có thể được giải quyết bằng hệ thống CI/CD (ví dụ: trong GitLab CI, quy trình sau này được khởi chạy cho một loạt cam kết). Tuy nhiên, không phải tất cả các hệ thống đều hỗ trợ điều này và phải có cách đáng tin cậy hơn để ngăn chặn sự cố cơ bản như vậy.

Gắn thẻ dựa trên nội dung là gì?

Vậy, gắn thẻ dựa trên nội dung là gì – gắn thẻ hình ảnh theo nội dung.

Để tạo thẻ Docker, không phải sử dụng các nguyên hàm Git (nhánh Git, thẻ Git...) mà là tổng kiểm tra được liên kết với:

  • nội dung của hình ảnh. Thẻ ID hình ảnh phản ánh nội dung của nó. Khi xây dựng phiên bản mới, mã nhận dạng này sẽ không thay đổi nếu các file trong ảnh không thay đổi;
  • lịch sử tạo hình ảnh này trong Git. Hình ảnh được liên kết với các nhánh Git khác nhau và lịch sử xây dựng khác nhau thông qua werf sẽ có các thẻ ID khác nhau.

Thẻ định danh như vậy được gọi là hình ảnh chữ ký sân khấu.

Mỗi hình ảnh bao gồm một tập hợp các giai đoạn: from, before-install, git-archive, install, imports-after-install, before-setup, ... git-latest-patch vân vân. Mỗi giai đoạn có một mã định danh phản ánh nội dung của nó - chữ ký sân khấu (chữ ký sân khấu).

Hình ảnh cuối cùng, bao gồm các giai đoạn này, được gắn thẻ cái gọi là chữ ký của tập hợp các giai đoạn này - giai đoạn chữ ký, - mang tính khái quát cho tất cả các giai đoạn của hình ảnh.

Đối với mỗi hình ảnh từ cấu hình werf.yaml trong trường hợp chung, sẽ có chữ ký riêng và theo đó là thẻ Docker.

Chữ ký sân khấu giải quyết tất cả những vấn đề này:

  • Chống lại các cam kết Git trống.
  • Chống lại Git cam kết thay đổi các tập tin không liên quan đến hình ảnh.
  • Không dẫn đến vấn đề đại tu phiên bản hiện tại của hình ảnh khi khởi động lại các bản dựng cho các cam kết Git cũ của một nhánh.

Đây hiện là chiến lược gắn thẻ được đề xuất và là chiến lược mặc định trong werf cho tất cả các hệ thống CI.

Cách kích hoạt và sử dụng trong werf

Lệnh bây giờ có tùy chọn tương ứng werf publish: --tag-by-stages-signature=true|false

Trong hệ thống CI, chiến lược gắn thẻ được chỉ định bằng lệnh werf ci-env. Trước đây, tham số đã được xác định cho nó werf ci-env --tagging-strategy=tag-or-branch. Bây giờ, nếu bạn chỉ định werf ci-env --tagging-strategy=stages-signature hoặc không chỉ định tùy chọn này, werf sẽ sử dụng chiến lược gắn thẻ theo mặc định stages-signature. Đội werf ci-env sẽ tự động đặt các cờ cần thiết cho lệnh werf build-and-publish (hoặc werf publish), do đó không cần chỉ định tùy chọn bổ sung cho các lệnh này.

Ví dụ: lệnh:

werf publish --stages-storage :local --images-repo registry.hello.com/web/core/system --tag-by-stages-signature

...có thể tạo ra những hình ảnh sau:

  • registry.hello.com/web/core/system/backend:4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d
  • registry.hello.com/web/core/system/frontend:f44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6

Здесь 4ef339f84ca22247f01fb335bb19f46c4434014d8daa3d5d6f0e386d là dấu hiệu của các giai đoạn của hình ảnh backendf44206457e0a4c8a54655543f749799d10a9fe945896dab1c16996c6 - chữ ký của các giai đoạn hình ảnh frontend.

Khi sử dụng các chức năng đặc biệt werf_container_image и werf_container_env Không cần thay đổi bất cứ điều gì trong mẫu Helm: các chức năng này sẽ tự động tạo tên hình ảnh chính xác.

Cấu hình ví dụ trong hệ thống CI:

type multiwerf && source <(multiwerf use 1.1 beta)
type werf && source <(werf ci-env gitlab)
werf build-and-publish|deploy

Thông tin thêm về cấu hình có sẵn trong tài liệu:

trong tổng số

  • Tùy chọn mới werf publish --tag-by-stages-signature=true|false.
  • Giá trị tùy chọn mới werf ci-env --tagging-strategy=stages-signature|tag-or-branch (nếu không được chỉ định thì mặc định sẽ là stages-signature).
  • Nếu trước đây bạn đã sử dụng các tùy chọn gắn thẻ cho các cam kết Git (WERF_TAG_GIT_COMMIT hoặc tùy chọn werf publish --tag-git-commit COMMIT), thì hãy nhớ chuyển sang chiến lược gắn thẻ chữ ký giai đoạn.
  • Tốt hơn là chuyển ngay các dự án mới sang sơ đồ gắn thẻ mới.
  • Khi chuyển sang werf 1.1 thì nên chuyển dự án cũ sang sơ đồ gắn thẻ mới, nhưng cái cũ thẻ hoặc nhánh vẫn được hỗ trợ.

Gắn thẻ dựa trên nội dung giải quyết tất cả các vấn đề được đề cập trong bài viết:

  • Tên thẻ Docker chống lại các cam kết Git trống.
  • Khả năng phục hồi của tên thẻ Docker đối với Git cam kết thay đổi các tệp không liên quan đến hình ảnh.
  • Không dẫn đến vấn đề đại tu phiên bản hiện tại của hình ảnh khi khởi động lại các bản dựng cho các cam kết Git cũ cho các nhánh Git.

Sử dụng nó! Và đừng quên ghé thăm chúng tôi tại GitHubđể tạo ra một vấn đề hoặc tìm một vấn đề hiện có, đưa ra điểm cộng, tạo PR hoặc đơn giản là theo dõi sự phát triển của dự án.

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