werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Ngày 27 tháng 2019 tại sảnh chính của hội nghị DevOpsConf XNUMX, được tổ chức như một phần của lễ hội RIT++ 2019, như một phần của phần “Phân phối liên tục”, một báo cáo đã được đưa ra “werf - công cụ của chúng tôi dành cho CI/CD trong Kubernetes”. Nó nói về những các vấn đề và thách thức mà mọi người phải đối mặt khi triển khai Kubernetes, cũng như về những sắc thái có thể không được chú ý ngay lập tức. Phân tích các giải pháp khả thi, chúng tôi chỉ ra cách triển khai điều này trong công cụ Nguồn mở người sói.

Kể từ khi trình bày, tiện ích của chúng tôi (trước đây gọi là dapp) đã đạt được cột mốc lịch sử 1000 sao trên GitHub — chúng tôi hy vọng rằng cộng đồng người dùng ngày càng tăng của nó sẽ giúp cuộc sống của nhiều kỹ sư DevOps trở nên dễ dàng hơn.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Vì vậy, hãy giới thiệu video báo cáo (~47 phút, nhiều thông tin hơn bài viết) và đoạn trích chính từ nó ở dạng văn bản. Đi!

Cung cấp mã cho Kubernetes

Cuộc nói chuyện sẽ không còn về werf nữa mà là về CI/CD trong Kubernetes, ngụ ý rằng phần mềm của chúng tôi được đóng gói trong các vùng chứa Docker (Tôi đã nói về điều này trong báo cáo năm 2016)và K8 sẽ được sử dụng để chạy nó trong sản xuất (thêm về điều này trong 2017 năm).

Quá trình phân phối trong Kubernetes trông như thế nào?

  • Có một kho lưu trữ Git với mã và hướng dẫn xây dựng nó. Ứng dụng được tích hợp vào hình ảnh Docker và được xuất bản trong Docker Register.
  • Kho lưu trữ tương tự cũng chứa hướng dẫn về cách triển khai và chạy ứng dụng. Ở giai đoạn triển khai, các hướng dẫn này được gửi đến Kubernetes, Kubernetes sẽ nhận được hình ảnh mong muốn từ sổ đăng ký và khởi chạy nó.
  • Ngoài ra, thường có các bài kiểm tra. Một số điều này có thể được thực hiện khi xuất bản một hình ảnh. Bạn cũng có thể (theo các hướng dẫn tương tự) triển khai một bản sao của ứng dụng (trong một vùng tên K8s riêng biệt hoặc một cụm riêng biệt) và chạy thử nghiệm ở đó.
  • Cuối cùng, bạn cần một hệ thống CI nhận các sự kiện từ Git (hoặc các lần nhấp vào nút) và gọi tất cả các giai đoạn được chỉ định: xây dựng, xuất bản, triển khai, kiểm tra.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Có một vài lưu ý quan trọng ở đây:

  1. Bởi vì chúng tôi có cơ sở hạ tầng bất biến (cơ sở hạ tầng bất biến), hình ảnh ứng dụng được sử dụng ở tất cả các giai đoạn (dàn dựng, sản xuất, v.v.), phải có một. Tôi đã nói về điều này chi tiết hơn và có ví dụ. đây.
  2. Bởi vì chúng tôi tuân theo cơ sở hạ tầng như cách tiếp cận mã (IAC), mã ứng dụng, hướng dẫn lắp ráp và khởi chạy nó phải là chính xác trong một kho lưu trữ. Để biết thêm thông tin về điều này, xem cùng một báo cáo.
  3. Chuỗi giao hàng (vận chuyển) chúng ta thường thấy nó như thế này: ứng dụng đã được lắp ráp, thử nghiệm, phát hành (giai đoạn phát hành) và thế là xong - việc giao hàng đã diễn ra. Nhưng trên thực tế, người dùng sẽ nhận được những gì bạn đã triển khai, không sau đó là khi bạn chuyển nó đi sản xuất, và khi anh ấy có thể đến đó và quá trình sản xuất này đã thành công. Vì vậy tôi tin rằng chuỗi giao hàng đã kết thúc chỉ ở giai đoạn vận hành (chạy), hay chính xác hơn là ngay cả tại thời điểm mã đã bị xóa khỏi sản xuất (thay thế bằng mã mới).

Hãy quay lại sơ đồ phân phối ở trên trong Kubernetes: nó không chỉ được phát minh bởi chúng tôi mà còn bởi tất cả những người giải quyết vấn đề này theo đúng nghĩa đen. Trên thực tế, mẫu này hiện được gọi là GitOps (bạn có thể đọc thêm về thuật ngữ này và ý tưởng đằng sau nó đây). Chúng ta hãy xem xét các giai đoạn của kế hoạch.

Xây dựng sân khấu

Có vẻ như bạn có thể nói về việc xây dựng Docker image vào năm 2019, khi mọi người đều biết cách viết Dockerfiles và chạy docker build?.. Dưới đây là những sắc thái mà tôi muốn chú ý đến:

  1. Trọng lượng hình ảnh quan trọng, vì vậy hãy sử dụng nhiều giai đoạnchỉ để lại trong hình ảnh ứng dụng thực sự cần thiết cho hoạt động.
  2. Số lớp phải được giảm thiểu bằng cách kết hợp các chuỗi RUN-lệnh theo ý nghĩa.
  3. Tuy nhiên, điều này gây thêm vấn đề gỡ lỗi, vì khi lắp ráp gặp sự cố, bạn phải tìm đúng lệnh từ chuỗi gây ra sự cố.
  4. Tốc độ lắp ráp quan trọng vì chúng tôi muốn nhanh chóng triển khai các thay đổi và xem kết quả. Ví dụ: bạn không muốn xây dựng lại các phần phụ thuộc trong thư viện ngôn ngữ mỗi khi bạn xây dựng một ứng dụng.
  5. Thông thường từ một kho Git bạn cần nhiều hình ảnh, có thể được giải quyết bằng một tập hợp Dockerfiles (hoặc các giai đoạn được đặt tên trong một tệp) và tập lệnh Bash với tập hợp tuần tự của chúng.

Đây chỉ là phần nổi của tảng băng trôi mà mọi người đều phải đối mặt. Nhưng có những vấn đề khác, đặc biệt:

  1. Thông thường ở giai đoạn lắp ráp chúng ta cần một cái gì đó gắn kết (ví dụ: lưu trữ kết quả của lệnh như apt trong thư mục của bên thứ ba).
  2. Chúng tôi muốn Có khả năng thay vì viết bằng shell.
  3. Chúng tôi muốn xây dựng không có Docker (tại sao chúng ta cần một máy ảo bổ sung để định cấu hình mọi thứ cho việc này, khi chúng ta đã có cụm Kubernetes để có thể chạy các container?).
  4. Lắp ráp song song, có thể được hiểu theo nhiều cách khác nhau: các lệnh khác nhau từ Dockerfile (nếu sử dụng nhiều giai đoạn), một số cam kết của cùng một kho lưu trữ, một số Dockerfile.
  5. lắp ráp phân phối: Chúng tôi muốn thu thập những thứ "phù du" bởi vì bộ đệm của họ biến mất, điều đó có nghĩa là nó cần được lưu trữ ở một nơi riêng biệt.
  6. Cuối cùng tôi đặt tên cho đỉnh cao của ham muốn tự động: Sẽ là lý tưởng nếu bạn đi đến kho lưu trữ, gõ một số lệnh và lấy một hình ảnh tạo sẵn, được tập hợp với sự hiểu biết về cách thức và những gì cần làm một cách chính xác. Tuy nhiên, cá nhân tôi không chắc chắn rằng tất cả các sắc thái có thể được đoán trước theo cách này.

Và đây là các dự án:

  • đám đông/bộ công cụ xây dựng — một công cụ xây dựng từ Docker Inc (đã được tích hợp vào các phiên bản hiện tại của Docker), đang cố gắng giải quyết tất cả những vấn đề này;
  • kaniko — một công cụ xây dựng của Google cho phép bạn xây dựng mà không cần Docker;
  • Buildpacks.io — Nỗ lực của CNCF nhằm tạo ra phép thuật tự động và đặc biệt là một giải pháp thú vị với tính năng rebase cho các lớp;
  • và hàng loạt tiện ích khác như xây dựng, công cụ chính hãng/img...

...và hãy xem họ có bao nhiêu ngôi sao trên GitHub. Nghĩa là, một mặt, docker build tồn tại và có thể làm điều gì đó, nhưng trên thực tế vấn đề chưa được giải quyết hoàn toàn - bằng chứng cho điều này là sự phát triển song song của các nhà sưu tập thay thế, mỗi nhà sưu tập giải quyết được một phần vấn đề.

Hội ở Werf

Vì vậy chúng tôi phải người sói (sớm hơn nổi danh như dapp) — Một tiện ích nguồn mở từ công ty Flant mà chúng tôi đã sản xuất trong nhiều năm. Mọi chuyện bắt đầu từ 5 năm trước với các tập lệnh Bash giúp tối ưu hóa việc lắp ráp Dockerfiles và trong 3 năm qua, quá trình phát triển chính thức đã được thực hiện trong khuôn khổ một dự án có kho lưu trữ Git của riêng nó (đầu tiên là trong Ruby, sau đó viết lại thành Go, đồng thời đổi tên). Những vấn đề lắp ráp nào được giải quyết trong werf?

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Các vấn đề được tô màu xanh lam đã được triển khai, quá trình xây dựng song song được thực hiện trong cùng một máy chủ và các vấn đề được đánh dấu màu vàng dự kiến ​​sẽ hoàn thành vào cuối mùa hè.

Giai đoạn xuất bản trong sổ đăng ký (xuất bản)

Chúng tôi đã quay số docker push... - điều gì có thể khó khăn khi tải hình ảnh lên sổ đăng ký? Và ở đây câu hỏi được đặt ra: “Tôi nên đặt thẻ nào vào hình ảnh?” Nó phát sinh vì lý do là chúng ta có Dòng chảy Git (hoặc chiến lược Git khác) và Kubernetes, đồng thời ngành đang cố gắng đảm bảo rằng những gì xảy ra trong Kubernetes tuân theo những gì xảy ra trong Git. Suy cho cùng, Git là nguồn sự thật duy nhất của chúng ta.

Có gì khó khăn thế này? Đảm bảo khả năng tái tạo: từ một cam kết trong Git, về bản chất là bất biến (bất biến), vào hình ảnh Docker, hình ảnh này phải được giữ nguyên.

Nó cũng quan trọng đối với chúng tôi xác định nguồn gốc, bởi vì chúng tôi muốn hiểu ứng dụng chạy trong Kubernetes được xây dựng từ cam kết nào (sau đó chúng tôi có thể thực hiện các khác biệt và những điều tương tự).

Chiến lược gắn thẻ

Cái đầu tiên thì đơn giản thẻ git. Chúng tôi có một sổ đăng ký với một hình ảnh được gắn thẻ là 1.0. Kubernetes có giai đoạn và sản xuất, nơi hình ảnh này được tải lên. Trong Git, chúng tôi thực hiện các cam kết và tại một thời điểm nào đó, chúng tôi gắn thẻ 2.0. Chúng tôi thu thập nó theo hướng dẫn từ kho lưu trữ và đặt nó vào sổ đăng ký có gắn thẻ 2.0. Chúng tôi đưa nó lên sân khấu và nếu mọi việc đều ổn thì sẽ đưa vào sản xuất.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Vấn đề với cách tiếp cận này là trước tiên chúng tôi đặt thẻ, sau đó chỉ kiểm tra và triển khai nó. Tại sao? Thứ nhất, nó đơn giản là phi logic: chúng tôi đang phát hành một phiên bản phần mềm mà chúng tôi thậm chí còn chưa thử nghiệm (chúng tôi không thể làm khác, vì để kiểm tra, chúng tôi cần phải gắn thẻ). Thứ hai, đường dẫn này không tương thích với Gitflow.

Tùy chọn thứ hai - cam kết git + thẻ. Nhánh chính có một thẻ 1.0; cho nó trong sổ đăng ký - một hình ảnh được triển khai vào sản xuất. Ngoài ra, cụm Kubernetes có các đường viền xem trước và dàn dựng. Tiếp theo chúng ta theo dõi Gitflow: trong nhánh chính để phát triển (develop) chúng tôi tạo ra các tính năng mới, dẫn đến cam kết với mã định danh #c1. Chúng tôi thu thập và xuất bản nó trong sổ đăng ký bằng mã định danh này (#c1). Với cùng một mã nhận dạng, chúng tôi triển khai bản xem trước. Chúng tôi làm tương tự với các cam kết #c2 и #c3.

Khi chúng tôi nhận ra rằng có đủ tính năng, chúng tôi bắt đầu ổn định mọi thứ. Tạo một nhánh trong Git release_1.1 (trên cơ sở #c3 của develop). Không cần phải thu thập bản phát hành này, bởi vì... điều này đã được thực hiện ở bước trước. Vì vậy, chúng tôi có thể chỉ cần triển khai nó để dàn dựng. Chúng tôi sửa lỗi trong #c4 và tương tự triển khai để dàn dựng. Đồng thời, sự phát triển đang diễn ra ở develop, nơi các thay đổi được thực hiện định kỳ từ release_1.1. Tại một thời điểm nào đó, chúng tôi nhận được một cam kết được biên soạn và tải lên dàn dựng, điều mà chúng tôi hài lòng (#c25).

Sau đó, chúng tôi hợp nhất (với tốc độ chuyển tiếp nhanh) nhánh phát hành (release_1.1) trong chủ. Chúng tôi đặt một thẻ có phiên bản mới trên cam kết này (1.1). Nhưng hình ảnh này đã được thu thập trong sổ đăng ký, vì vậy để không thu thập lại, chúng tôi chỉ cần thêm thẻ thứ hai vào hình ảnh hiện có (bây giờ nó có thẻ trong sổ đăng ký #c25 и 1.1). Sau đó, chúng tôi đưa nó vào sản xuất.

Có một nhược điểm là chỉ upload được 1 ảnh lên staging (#c25) và trong quá trình sản xuất, nó hơi khác (1.1), nhưng chúng tôi biết rằng về mặt vật lý, đây là những hình ảnh giống nhau từ sổ đăng ký.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Nhược điểm thực sự là không có hỗ trợ cho các cam kết hợp nhất, bạn phải thực hiện chuyển tiếp nhanh.

Chúng ta có thể tiến xa hơn và thực hiện một thủ thuật... Hãy xem ví dụ về Dockerfile đơn giản:

FROM ruby:2.3 as assets
RUN mkdir -p /app
WORKDIR /app
COPY . ./
RUN gem install bundler && bundle install
RUN bundle exec rake assets:precompile
CMD bundle exec puma -C config/puma.rb

FROM nginx:alpine
COPY --from=assets /app/public /usr/share/nginx/www/public

Hãy xây dựng một tệp từ nó theo nguyên tắc sau:

  • SHA256 khỏi số nhận dạng của hình ảnh được sử dụng (ruby:2.3 и nginx:alpine), là tổng kiểm tra nội dung của chúng;
  • tất cả các đội (RUN, CMD và như thế.);
  • SHA256 từ các tệp đã được thêm vào.

... và lấy tổng kiểm tra (lại là SHA256) từ một tệp như vậy. Cái này Chữ ký mọi thứ xác định nội dung của hình ảnh Docker.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Hãy quay lại sơ đồ và thay vì cam kết, chúng tôi sẽ sử dụng chữ ký như vậy, I E. gắn thẻ hình ảnh có chữ ký.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Bây giờ, chẳng hạn, khi cần hợp nhất các thay đổi từ bản phát hành thành bản chính, chúng ta có thể thực hiện một cam kết hợp nhất thực sự: nó sẽ có mã định danh khác, nhưng có cùng chữ ký. Với cùng một mã định danh, chúng tôi sẽ đưa hình ảnh vào sản xuất.

Điểm bất lợi là bây giờ sẽ không thể xác định loại cam kết nào đã được đẩy vào sản xuất - tổng kiểm tra chỉ hoạt động theo một hướng. Vấn đề này được giải quyết bằng một lớp bổ sung có siêu dữ liệu - Tôi sẽ cho bạn biết thêm sau.

Gắn thẻ trong werf

Trong werf, chúng tôi thậm chí còn tiến xa hơn và đang chuẩn bị thực hiện một bản dựng phân tán với bộ đệm không được lưu trữ trên một máy... Vì vậy, chúng tôi đang xây dựng hai loại hình ảnh Docker, chúng tôi gọi chúng là giai đoạn и hình ảnh.

Kho lưu trữ Git của werf lưu trữ các hướng dẫn dành riêng cho bản dựng mô tả các giai đoạn khác nhau của bản dựng (trướcCài đặt, cài đặt, dựng lên, trước khi thiết lập, thiết lập). Chúng tôi thu thập hình ảnh giai đoạn đầu tiên có chữ ký được xác định là tổng kiểm tra các bước đầu tiên. Sau đó, chúng tôi thêm mã nguồn, đối với hình ảnh giai đoạn mới, chúng tôi tính toán tổng kiểm tra của nó... Các thao tác này được lặp lại cho tất cả các giai đoạn, kết quả là chúng tôi có được một tập hợp các hình ảnh giai đoạn. Sau đó, chúng tôi tạo hình ảnh cuối cùng, trong đó cũng chứa siêu dữ liệu về nguồn gốc của nó. Và chúng tôi gắn thẻ hình ảnh này theo nhiều cách khác nhau (chi tiết sau).

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Giả sử sau đó một cam kết mới xuất hiện trong đó chỉ có mã ứng dụng được thay đổi. Chuyện gì sẽ xảy ra? Để thay đổi mã, một bản vá sẽ được tạo và hình ảnh giai đoạn mới sẽ được chuẩn bị. Chữ ký của nó sẽ được xác định là tổng kiểm tra của hình ảnh giai đoạn cũ và bản vá mới. Một hình ảnh cuối cùng mới sẽ được hình thành từ hình ảnh này. Hành vi tương tự sẽ xảy ra với những thay đổi trong các giai đoạn khác.

Do đó, hình ảnh giai đoạn là một bộ đệm có thể được lưu trữ phân tán và các hình ảnh đã được tạo từ nó sẽ được tải lên Docker Register.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Làm sạch sổ đăng ký

Chúng tôi không nói về việc xóa các lớp vẫn bị treo sau khi xóa thẻ - đây là một tính năng tiêu chuẩn của chính Docker Register. Chúng ta đang nói về một tình huống khi có rất nhiều thẻ Docker tích lũy và chúng tôi hiểu rằng chúng tôi không còn cần một số thẻ đó nữa nhưng chúng chiếm dung lượng (và/hoặc chúng tôi phải trả tiền cho nó).

Các chiến lược làm sạch là gì?

  1. Bạn không thể làm gì cả không dọn dẹp. Đôi khi, việc trả một chút tiền để có thêm không gian thực sự dễ dàng hơn là giải quyết một mớ thẻ khổng lồ. Nhưng điều này chỉ hoạt động ở một mức độ nhất định.
  2. Đặt lại hoàn toàn. Nếu bạn xóa tất cả hình ảnh và chỉ xây dựng lại những hình ảnh hiện tại trong hệ thống CI thì có thể xảy ra sự cố. Nếu vùng chứa được khởi động lại trong quá trình sản xuất, một hình ảnh mới sẽ được tải cho nó - một hình ảnh chưa được bất kỳ ai thử nghiệm. Điều này giết chết ý tưởng về cơ sở hạ tầng bất biến.
  3. Xanh lam. Một sổ đăng ký bắt đầu tràn - chúng tôi tải hình ảnh lên một sổ đăng ký khác. Vấn đề tương tự như trong phương pháp trước: bạn có thể xóa sổ đăng ký đã bắt đầu tràn vào thời điểm nào?
  4. Theo thời gian. Xóa tất cả hình ảnh cũ hơn 1 tháng? Nhưng chắc chắn sẽ có một dịch vụ suốt một tháng trời chưa được cập nhật...
  5. Thủ công xác định những gì đã có thể bị xóa.

Có hai lựa chọn thực sự khả thi: không làm sạch hoặc kết hợp xanh lam + xanh lục + thủ công. Trong trường hợp sau, chúng ta đang nói về điều sau: khi bạn hiểu rằng đã đến lúc dọn dẹp sổ đăng ký, bạn tạo một sổ đăng ký mới và thêm tất cả hình ảnh mới vào đó trong khoảng thời gian, chẳng hạn như một tháng. Và sau một tháng, hãy xem nhóm nào trong Kubernetes vẫn đang sử dụng sổ đăng ký cũ và chuyển chúng sang sổ đăng ký mới.

Chúng ta đã đến cái gì người sói? Chúng tôi thu thập:

  1. Đầu Git: tất cả các thẻ, tất cả các nhánh - giả sử rằng chúng ta cần mọi thứ được gắn thẻ trong Git trong hình ảnh (và nếu không, thì chúng ta cần xóa nó trong chính Git);
  2. tất cả các nhóm hiện được bơm vào Kubernetes;
  3. ReplicaSets cũ (được phát hành gần đây) và chúng tôi cũng có kế hoạch quét các bản phát hành Helm và chọn những hình ảnh mới nhất ở đó.

... và tạo danh sách trắng từ bộ này - danh sách các hình ảnh mà chúng tôi sẽ không xóa. Chúng tôi xóa mọi thứ khác, sau đó chúng tôi tìm thấy các hình ảnh giai đoạn mồ côi và xóa chúng.

Giai đoạn triển khai

Tính khai báo đáng tin cậy

Điểm đầu tiên mà tôi muốn thu hút sự chú ý trong quá trình triển khai là việc triển khai cấu hình tài nguyên được cập nhật, được khai báo. Tài liệu YAML ban đầu mô tả tài nguyên Kubernetes luôn rất khác so với kết quả thực sự đang chạy trong cụm. Vì Kubernetes thêm vào cấu hình:

  1. số nhận dạng;
  2. thông tin dịch vụ;
  3. nhiều giá trị mặc định;
  4. phần có trạng thái hiện tại;
  5. những thay đổi được thực hiện như một phần của webhook tuyển sinh;
  6. kết quả công việc của các bộ điều khiển khác nhau (và bộ lập lịch).

Do đó, khi cấu hình tài nguyên mới xuất hiện (mới), chúng ta không thể lấy và ghi đè cấu hình “trực tiếp” hiện tại bằng nó (sống). Để làm được điều này chúng ta sẽ phải so sánh mới với cấu hình được áp dụng lần cuối (áp dụng lần cuối) và lăn lên sống đã nhận được bản vá.

Cách tiếp cận này được gọi là hợp nhất 2 chiều. Ví dụ, nó được sử dụng trong Helm.

Cũng có hợp nhất 3 chiều, khác ở chỗ:

  • so sánh áp dụng lần cuối и mới, chúng tôi xem những gì đã bị xóa;
  • so sánh mới и sống, chúng tôi xem những gì đã được thêm vào hoặc thay đổi;
  • bản vá tóm tắt được áp dụng cho sống.

Chúng tôi triển khai hơn 1000 ứng dụng với Helm, vì vậy chúng tôi thực sự đang hợp nhất 2 chiều. Tuy nhiên, nó có một số vấn đề mà chúng tôi đã giải quyết bằng các bản vá của mình, giúp Helm hoạt động bình thường.

Trạng thái triển khai thực

Sau khi hệ thống CI của chúng tôi tạo cấu hình mới cho Kubernetes dựa trên sự kiện tiếp theo, nó sẽ truyền cấu hình đó để sử dụng (áp dụng) đến một cụm - sử dụng Helm hoặc kubectl apply. Tiếp theo, quá trình hợp nhất N-way đã được mô tả sẽ diễn ra, API Kubernetes phản hồi một cách chấp thuận với hệ thống CI và với người dùng của nó.

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Tuy nhiên, có một vấn đề lớn: rốt cuộc ứng dụng thành công không có nghĩa là triển khai thành công. Nếu Kubernetes hiểu những thay đổi nào cần áp dụng và áp dụng nó thì chúng ta vẫn không biết kết quả sẽ ra sao. Ví dụ: cập nhật và khởi động lại các nhóm ở giao diện người dùng có thể thành công nhưng không thành công ở phần phụ trợ và chúng ta sẽ nhận được các phiên bản khác nhau của hình ảnh ứng dụng đang chạy.

Để thực hiện mọi thứ một cách chính xác, sơ đồ này yêu cầu một liên kết bổ sung - một trình theo dõi đặc biệt sẽ nhận thông tin trạng thái từ API Kubernetes và truyền nó để phân tích thêm về trạng thái thực của mọi thứ. Chúng tôi đã tạo thư viện Nguồn mở trong Go - chó lập phương (xem thông báo của nó đây), giải quyết vấn đề này và được tích hợp vào werf.

Hoạt động của trình theo dõi này ở cấp độ werf được định cấu hình bằng cách sử dụng các chú thích được đặt trên Triển khai hoặc StatefulSets. Chú thích chính - fail-mode - hiểu các ý nghĩa sau:

  • IgnoreAndContinueDeployProcess — chúng tôi bỏ qua các vấn đề khi triển khai thành phần này và tiếp tục triển khai;
  • FailWholeDeployProcessImmediately — một lỗi trong thành phần này sẽ dừng quá trình triển khai;
  • HopeUntilEndOfDeployProcess — chúng tôi hy vọng rằng thành phần này sẽ hoạt động khi kết thúc quá trình triển khai.

Ví dụ: sự kết hợp giữa tài nguyên và giá trị chú thích này fail-mode:

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Khi chúng tôi triển khai lần đầu tiên, cơ sở dữ liệu (MongoDB) có thể chưa sẵn sàng - Quá trình triển khai sẽ thất bại. Nhưng bạn có thể đợi thời điểm nó bắt đầu và quá trình triển khai vẫn sẽ diễn ra.

Có thêm hai chú thích cho kubedog trong werf:

  • failures-allowed-per-replica - số lần rơi được phép đối với mỗi bản sao;
  • show-logs-until — quy định thời điểm cho đến khi werf hiển thị nhật ký (trong thiết bị xuất chuẩn) từ tất cả các nhóm đã triển khai. Mặc định là PodIsReady (để bỏ qua các tin nhắn mà chúng ta có thể không muốn khi lưu lượng truy cập bắt đầu đến nhóm), nhưng các giá trị cũng hợp lệ: ControllerIsReady и EndOfDeploy.

Chúng ta còn muốn gì nữa từ việc triển khai?

Ngoài hai điểm đã được mô tả, chúng tôi muốn:

  • để xem nhật ký - và chỉ những thứ cần thiết, chứ không phải mọi thứ liên tiếp;
  • theo dõi phát triển, bởi vì nếu công việc bị treo “âm thầm” trong vài phút, điều quan trọng là phải hiểu chuyện gì đang xảy ra ở đó;
  • quay lại tự động trong trường hợp có sự cố xảy ra (và do đó, điều quan trọng là phải biết trạng thái thực sự của quá trình triển khai). Quá trình triển khai phải mang tính nguyên tử: nó sẽ đi đến cuối hoặc mọi thứ sẽ quay trở lại trạng thái trước đó.

Kết quả

Đối với chúng tôi với tư cách là một công ty, để triển khai tất cả các sắc thái được mô tả ở các giai đoạn phân phối khác nhau (xây dựng, xuất bản, triển khai), hệ thống CI và tiện ích là đủ người sói.

Thay cho một kết luận:

werf - công cụ của chúng tôi dành cho CI / CD trong Kubernetes (báo cáo tổng quan và video)

Với sự trợ giúp của werf, chúng tôi đã đạt được tiến bộ tốt trong việc giải quyết một số lượng lớn vấn đề cho các kỹ sư DevOps và sẽ rất vui nếu cộng đồng rộng lớn hơn ít nhất đã thử tiện ích này trong thực tế. Sẽ dễ dàng hơn để đạt được một kết quả tốt cùng nhau.

Video và slide

Video màn trình diễn (~47 phút):

Trình bày báo cáo:

PS

Các báo cáo khác về Kubernetes trên blog của chúng tôi:

Nguồn: www.habr.com

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