paint-brush
Thực hành CI/CD: Quy trình triển khai liên tục đơn giản nhưng đầy đủ chức năng [Phần 2]từ tác giả@j04n
537 lượt đọc
537 lượt đọc

Thực hành CI/CD: Quy trình triển khai liên tục đơn giản nhưng đầy đủ chức năng [Phần 2]

từ tác giả Joan Flotats14m2023/10/10
Read on Terminal Reader

dài quá đọc không nổi

Việc triển khai thủ công không dễ xảy ra lỗi. Hơn nữa, chúng bao gồm một loạt các nhiệm vụ lặp đi lặp lại và phức tạp. Bài viết này khám phá tính năng tự động hóa các quy trình triển khai của bạn để chuyển đổi chúng thành các quy trình triển khai liên tục bằng FluxCD, Flagger và Grafana.
featured image - Thực hành CI/CD: Quy trình triển khai liên tục đơn giản nhưng đầy đủ chức năng [Phần 2]
Joan Flotats HackerNoon profile picture
0-item
1-item


Việc triển khai thủ công không dễ xảy ra lỗi. Hơn nữa, chúng bao gồm một loạt các nhiệm vụ lặp đi lặp lại và phức tạp. Các nhóm phát triển lo ngại về sự phức tạp của việc triển khai một phiên bản mới của ứng dụng và những vấn đề đau đầu mà nó mang lại. Đôi khi, việc triển khai một ứng dụng đòi hỏi các kỹ năng nâng cao về nền tảng. Đó là một quá trình tẻ nhạt để gỡ lỗi các vấn đề triển khai.


FluxCD giúp bạn giảm bớt công sức dành cho các công việc thủ công và lặp đi lặp lại. Nó cũng giảm thiểu các lỗi triển khai và tương tác của con người. Nó cung cấp các công cụ để theo dõi và cập nhật trạng thái triển khai của bạn bằng cách sử dụng các tệp khai báo, giúp quá trình triển khai và gỡ lỗi trở nên dễ dàng hơn cho nhóm phát triển của bạn.


Bài viết này khám phá tính năng tự động hóa các quy trình triển khai của bạn để chuyển đổi chúng thành các quy trình triển khai liên tục bằng FluxCD , FlaggerGrafana .


Hãy xem bài viết đầu tiên để tìm hiểu thêm về cách liên tục phân phối ứng dụng:

Thực hành CI/CD: Quy trình tích hợp liên tục đơn giản nhưng đầy đủ chức năng [Phần 1] .



Giới thiệu

Sử dụng KinDTerraform để thiết lập cụm Kubernetes. Trước hết, tạo cụm và xuất cấu hình Kubernetes để đặt nhà cung cấp Kubernetes:


 $ kind create cluster --name develop $ kind export kubeconfig --name develop --kubeconfig kubeconfig


Tạo kho lưu trữ GitHub mới và mã thông báo của nhà phát triển có quyền đối với kho lưu trữ, Terrafom yêu cầu nó để thiết lập FluxCD. Khởi tạo Terraform và áp dụng các thay đổi:


 $ terraform init $ terraform apply -var="github_owner=owner_name" -var="github_repository=repo_name" # Introduce your GitHub token


Khi Terraform hoàn tất quá trình cài đặt, bạn sẽ chạy FluxCD trong cụm KinD và một thư mục mới có tên cụm trong kho lưu trữ của bạn.


địa hình

Dưới mui xe, Terraform cài đặt MetalLB và định cấu hình dải IP. Bạn có thể đọc thêm về cấu hình MetalLB ở phần đầu bài viết :


 resource "helm_release" "metallb" { name = "metallb" repository = "https://metallb.github.io/metallb" chart = "metallb" } data "docker_network" "kind" { name = "kind" } resource "kubectl_manifest" "kind-address-pool" { yaml_body = yamlencode({ "apiVersion" : "metallb.io/v1beta1", "kind" : "IPAddressPool", "metadata" : { "name" : "kind-address-pool" }, "spec" : { "addresses" : [replace(tolist(data.docker_network.kind.ipam_config)[0].subnet, ".0.0/16", ".255.0/24")] } }) depends_on = [helm_release.metallb] } resource "kubectl_manifest" "kind-advertisement" { yaml_body = <<YAML apiVersion: metallb.io/v1beta1 kind: L2Advertisement metadata: name: kind-advertisement YAML depends_on = [helm_release.metallb] }


Sau đó, nó cài đặt Biểu đồ hỗ trợ FLuxCD và định cấu hình kho GitHub để sử dụng FluxCD:


 resource "helm_release" "flux" { repository = "https://fluxcd-community.github.io/helm-charts" chart = "flux2" name = "flux2" namespace = "flux-system" create_namespace = true version = "2.9.2" } resource "tls_private_key" "flux" { depends_on = [helm_release.flux] algorithm = "ECDSA" ecdsa_curve = "P256" } resource "github_repository_deploy_key" "flux" { depends_on = [tls_private_key.flux] title = "Flux" repository = var.github_repository key = tls_private_key.flux.public_key_openssh read_only = "false" } resource "flux_bootstrap_git" "this" { depends_on = [github_repository_deploy_key.flux] path = "clusters/develop" }


Đề xuất móc cam kết trước:

  1. Terraform ( https://github.com/antonbabenko/pre-commit-terraform ):
    • TFSec: Phân tích tĩnh cho Terraform để phát hiện các cấu hình sai tiềm ẩn
    • TFLint: Trình kiểm tra định dạng tĩnh cho Terraform
  2. Phát hiện bí mật ( https://github.com/Yelp/ detect-secrets): Ngăn chặn các bí mật mới xâm nhập vào cơ sở mã.


FluxCD

FluxCD là một công cụ GitOps để duy trì cụm Kubernetes với các thay đổi kiểm soát nguồn mới nhất (như kho lưu trữ Git). Flux tự động hóa việc triển khai mã mới.


Khi Flux đang chạy trong cụm, hãy xem nó hoạt động như thế nào. Chúng tôi sẽ triển khai ingress-nginx với tư cách là nhà cung cấp ingress. Flux không thực thi cấu trúc thư mục dự án. Bạn có thể định cấu hình nó theo ý muốn hoặc làm theo tiêu chuẩn ưa thích của bạn.


Tạo một thư mục có tên base bên trong thư mục có tên là cơ sở hạ tầng . Thư mục cơ sở có cấu hình cơ sở hạ tầng cơ bản cho tất cả các cụm của bạn. Tiếp theo, tạo thư mục có tên ingress-nginx . Sử dụng tên không gian tên làm tên thư mục.


 --- apiVersion: v1 kind: Namespace metadata: name: ingress-ngnix --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: ingress-nginx spec: interval: 2h url: https://kubernetes.github.io/ingress-nginx --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: ingress-nginx spec: interval: 15m chart: spec: chart: ingress-nginx version: 4.7.1 sourceRef: kind: HelmRepository name: ingress-nginx interval: 15m --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: ingress-ngnix resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Sử dụng nhiều tệp để xác định đối tượng của bạn: helmrelease.yaml , helmrepository.yaml , namespace.yaml , kustomization.yaml , v.v.


Kustomization đọc và xử lý các tài nguyên để áp dụng chúng. Cuối cùng nhưng không kém phần quan trọng, bạn cần tạo đối tượng Kustomization để đồng bộ hóa cấu hình cụm của mình. Tạo tệp YAML có tên là cơ sở hạ tầng.yaml bên trong thư mục cluster/cluster_name :


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-base namespace: flux-system spec: interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/base prune: true wait: true


Sau khi cam kết và đẩy các thay đổi của bạn vào kho lưu trữ, Flux sẽ điều chỉnh trạng thái cụm để cài đặt Biểu đồ Helm ingress-nginx.


Người gắn cờ

Flagger là nhà điều hành Kubernetes cung cấp dần dần ứng dụng của bạn bằng cách sử dụng triển khai xanh lam/xanh lục, phát hành canary hoặc thử nghiệm A/B.


Bạn có thể sử dụng thư mục cơ sở để cài đặt ngăn xếp của mình vào tất cả các cụm hoặc sử dụng một thư mục khác để tùy chỉnh cài đặt của bạn tùy thuộc vào cụm. Ví dụ: chúng tôi chỉ muốn cài đặt Flagger vào cụm phát triển.


Tạo một thư mục mới bằng tên cụm của bạn bên trong thư mục cơ sở hạ tầng . Sau đó, tạo một tệp có tên i nfrastructure.yaml vào cluster/cluster_name của bạn:


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: infra-cluster-name namespace: flux-system spec: dependsOn: - name: infra-base interval: 1h retryInterval: 1m timeout: 5m sourceRef: kind: GitRepository name: flux-system path: ./infrastructure/cluster_name prune: true


FluxCD sẽ đồng bộ hóa trạng thái cụm sau khi áp dụng Kustomization cơ sở hạ tầng. Cài đặt Flagger, tạo tệp YAML sau trong thư mục cơ sở hạ tầng/cluster_name/flagger-system :


 --- apiVersion: v1 kind: Namespace metadata: name: flagger-system --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: flagger spec: interval: 1h url: https://flagger.app --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger spec: interval: 1h install: crds: CreateReplace upgrade: crds: CreateReplace chart: spec: chart: flagger version: 1.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: flagger-loadtester spec: interval: 1h chart: spec: chart: loadtester version: 0.xx interval: 6h sourceRef: kind: HelmRepository name: flagger --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: flagger-system resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Triển khai liên tục

Để xây dựng quy trình triển khai liên tục ứng dụng Podinfo , hãy tạo tệp YAML cài đặt vào apps/cluster_name/podinfo *:*


 --- apiVersion: v1 kind: Namespace metadata: name: podinfo --- apiVersion: source.toolkit.fluxcd.io/v1beta2 kind: HelmRepository metadata: name: podinfo spec: interval: 5m url: https://stefanprodan.github.io/podinfo --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3 values: ingress: enabled: true className: nginx hpa: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Bạn có thể sử dụng tập lệnh Python của máy chủ cập nhật để cập nhật máy chủ môi trường cục bộ của mình, như được giải thích trong phần đầu tiên của bài viết .


Sau đó, tạo tệp Kustomization vào thư mục cluster/cluster_name để đồng bộ hóa ứng dụng của bạn:


 --- apiVersion: kustomize.toolkit.fluxcd.io/v1 kind: Kustomization metadata: name: apps namespace: flux-system spec: interval: 10m0s dependsOn: - name: infra-cluster-name sourceRef: kind: GitRepository name: flux-system path: ./apps/cluster_name prune: true wait: true timeout: 5m0s


Tiếp theo, chúng ta có thể định cấu hình FluxCD để tự động cập nhật phiên bản Biểu đồ Helm hình ảnh Podinfo. Để định cấu hình tự động cập nhật hình ảnh, chúng tôi cần tạo kho lưu trữ hình ảnh để quét thẻ hình ảnh mới, chính sách cập nhật hình ảnh để xác định mẫu phiên bản cần cập nhật và tự động cập nhật hình ảnh để định cấu hình kho lưu trữ nhằm thúc đẩy thay đổi.


 --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImageRepository metadata: name: podinfo-chart spec: image: ghcr.io/stefanprodan/charts/podinfo interval: 5m --- apiVersion: image.toolkit.fluxcd.io/v1beta2 kind: ImagePolicy metadata: name: podinfo-chart spec: imageRepositoryRef: name: podinfo-chart policy: semver: range: 6.xx --- apiVersion: image.toolkit.fluxcd.io/v1beta1 kind: ImageUpdateAutomation metadata: name: podinfo-chart spec: interval: 30m sourceRef: kind: GitRepository name: flux-system namespace: flux-system git: checkout: ref: branch: main commit: author: email: [email protected] name: fluxcdbot messageTemplate: 'chore(develop): update podinfo chart to {{range .Updated.Images}}{{println .}}{{end}}' push: branch: main update: path: ./apps/cluster_name/podinfo strategy: Setters --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - imagepolicy.yaml - imagerepository.yaml - imageautoupdate.yaml


Cuối cùng, áp dụng chính sách cập nhật hình ảnh cho hình ảnh hoặc thẻ bạn muốn cập nhật:


 apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: podinfo spec: releaseName: podinfo chart: spec: chart: podinfo version: 6.5.0 # {"$imagepolicy": "podinfo:podinfo-chart:tag"} sourceRef: kind: HelmRepository name: podinfo interval: 50m install: remediation: retries: 3


Bất cứ khi nào Biểu đồ Podinfo có phiên bản mới trong phạm vi 6.xx, FluxCD sẽ đẩy một cam kết vào kho lưu trữ, cập nhật phiên bản hiện tại lên phiên bản mới hơn.


FluxCD. https://fluxcd.io/flux/comComponents/image


Phát hành Canary

Phát hành phiên bản ứng dụng mới cho một nhóm nhỏ người dùng để đảm bảo rằng chức năng, hiệu suất và bảo mật của ứng dụng là những thứ được mong đợi. FluxCD tự động cập nhật phiên bản Biểu đồ và cung cấp cho người dùng. Trong trường hợp bị lỗi, FluxCD sẽ tự động khôi phục phiên bản hình ảnh về phiên bản trước đó.

Người gắn cờ dần dần cung cấp phiên bản ứng dụng mới cho một nhóm nhỏ người dùng và theo dõi trạng thái ứng dụng. Nó tạo ra một triển khai mới cho các phiên bản ứng dụng mới và dần dần chuyển hướng lưu lượng truy cập đến sang triển khai mới. Nó sẽ thúc đẩy việc triển khai canary sau khi phân tích thành công các số liệu. Trong trường hợp xảy ra lỗi, Flagger sẽ xóa hoạt động triển khai mới và thiết lập lại luồng lưu lượng truy cập đến hoạt động triển khai cũ. Quá trình này giả vờ phát hiện các khiếm khuyết, sự cố và lỗi trước khi cung cấp ứng dụng cho tất cả người dùng.



Người gắn cờ. https://docs.flagger.app/tutorials/nginx-progressive-delivery


Trước tiên, hãy tạo mẫu số liệu để cho Người gắn cờ biết trạng thái ứng dụng. Chúng tôi sử dụng Prometheus để đo lường tỷ lệ thành công của yêu cầu:


 --- apiVersion: flagger.app/v1beta1 kind: MetricTemplate metadata: name: podinfo-request-success-rate spec: provider: type: prometheus address: http://loki-stack-prometheus-server.loki-stack:80 query: | 100 - sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", status!~"5.*" }[{{ interval }}] ) ) / sum( rate( http_requests_total{ app_kubernetes_io_name="podinfo", namespace="{{ namespace }}", }[{{ interval }}] ) ) * 100 --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - metrictemplate.yaml


Sau đó, xác định quá trình phát hành chim hoàng yến. Chúng tôi sử dụng nginx làm nhà cung cấp để định hình lưu lượng truy cập đến. Người gắn cờ cung cấp nhiều cách và công cụ để định cấu hình bản phát hành của bạn.


 --- apiVersion: flagger.app/v1beta1 kind: Canary metadata: name: podinfo spec: provider: nginx targetRef: apiVersion: apps/v1 kind: Deployment name: podinfo ingressRef: apiVersion: networking.k8s.io/v1 kind: Ingress name: podinfo autoscalerRef: apiVersion: autoscaling/v2beta2 kind: HorizontalPodAutoscaler name: podinfo progressDeadlineSeconds: 60 service: port: 9898 targetPort: 9898 analysis: interval: 10s threshold: 10 maxWeight: 50 stepWeight: 5 metrics: - name: podinfo-request-success-rate thresholdRange: min: 99 interval: 1m webhooks: - name: acceptance-test type: pre-rollout url: http://flagger-loadtester.flagger-system/ timeout: 30s metadata: type: bash cmd: curl -sd 'test' http://podinfo-canary.podinfo:9898/token | grep token - name: load-test url: http://flagger-loadtester.flagger-system/ timeout: 5s metadata: cmd: hey -z 1m -q 10 -c 2 http://podinfo-canary.podinfo:9898/healthz --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: podinfo resources: [...] - canary.yaml


Trình gắn cờ yêu cầu các tài liệu tham khảo về quá trình triển khai, xâm nhập và tự động chia tỷ lệ nhóm của bạn. Bất cứ khi nào Flagger phát hiện một phiên bản mới, nó sẽ mở rộng quy mô triển khai, tạo dịch vụ chính và phụ, đồng thời định cấu hình nginx để gửi lưu lượng truy cập đến dịch vụ tương ứng. Sử dụng thuộc tính maxWeight và stepWeight để định cấu hình phần trăm chuyển hướng lưu lượng truy cập tối đa và phần trăm bước tăng dần.

Kiểm tra tải ứng dụng của bạn bằng cách sử dụng móc gắn cờ. Nó có nhiều móc. Móc chấp nhận kiểm tra mức độ sẵn sàng triển khai canary và móc kiểm tra tải tạo ra lưu lượng truy cập đến liên tục.

Người gắn cờ sẽ theo dõi trạng thái phát hành canary bằng cách sử dụng chỉ số tỷ lệ thành công được xác định trước để quyết định trường hợp xúc tiến triển khai canary. Flagger kỳ vọng tỷ lệ yêu cầu thành công là 99% để thúc đẩy quá trình triển khai canary. Sử dụng thuộc tính ngưỡng để định cấu hình số lần kiểm tra số liệu không thành công tối đa trước khi khôi phục.


Giám sát

Sử dụng ngăn xếp Loki để theo dõi trạng thái của tài nguyên cụm bằng Grafana + Loki + Prometheus. Cài đặt ngăn xếp Loki bằng cách tạo tệp YAML sau trong thư mục cơ sở hạ tầng/cluster_name/loki-stack :


 --- apiVersion: v1 kind: Namespace metadata: name: loki-stack --- apiVersion: source.toolkit.fluxcd.io/v1beta1 kind: HelmRepository metadata: name: grafana spec: interval: 2h url: https://grafana.github.io/helm-charts --- apiVersion: helm.toolkit.fluxcd.io/v2beta1 kind: HelmRelease metadata: name: loki-stack spec: interval: 1h chart: spec: chart: loki-stack version: v2.9.11 sourceRef: kind: HelmRepository name: grafana interval: 1h values: grafana: enabled: true ingress: enabled: true annotations: kubernetes.io/ingress.class: nginx hosts: - grafana.local prometheus: enabled: true nodeExporter: enabled: true --- apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: loki-stack resources: - namespace.yaml - helmrepository.yaml - helmrelease.yaml


Quá trình cài đặt ngăn xếp Loki cho phép Grafana Ingress truy cập Grafana, Prometheus để thu thập các số liệu môi trường của bạn và Trình xuất nút để xuất các số liệu nút của bạn.


Bạn có thể sử dụng tập lệnh Python của máy chủ cập nhật để cập nhật máy chủ môi trường cục bộ của mình, như được giải thích trong phần đầu tiên của bài viết


Đăng nhập vào Grafana bằng tên người dùng và mật khẩu quản trị viên. Bạn có thể xác định mật khẩu quản trị viên bằng cách sử dụng các giá trị cài đặt. Theo mặc định, Biểu đồ tạo bí mật Kubernetes để lưu trữ mật khẩu ngẫu nhiên. Mô tả bí mật để lấy giá trị mật khẩu base64 và giải mã nó.


Bạn có thể nhập trang tổng quan yêu thích của mình bằng ID của họ hoặc sao chép JSON thô:


Grafana - Bảng điều khiển Prometheus K8s


Grafana - Bảng điều khiển Prometheus FluxCD


Grafana - Nhật ký Loki


Phần kết luận

Bài viết đầu tiên khám phá cách cung cấp một ứng dụng đã được thử nghiệm tốt. Bài viết này khám phá cách triển khai liên tục một sản phẩm có thể phân phối và theo dõi trạng thái triển khai.


FluxCD và Flagger cung cấp nhiều tính năng để liên tục kiểm tra, triển khai và theo dõi trạng thái ứng dụng của bạn. Bài viết này sử dụng một số trong số chúng, nhưng chúng tôi không thấy các tính năng webhooks và thông báo. Sử dụng các tính năng thông báo để biết thời điểm triển khai không thành công hoặc tính năng web-hook để thúc đẩy quá trình triển khai sang môi trường mới hoặc khởi chạy thử nghiệm của bạn trên các phiên bản mới. Tích hợp FluxCD cùng với các công cụ khác để làm phong phú quy trình triển khai của bạn.

Tránh triển khai thủ công. Chúng phức tạp và không dễ xảy ra lỗi. Khuyến khích các nhóm phát triển duy trì ứng dụng của họ, giúp quá trình triển khai trở nên dễ dàng hơn. Triển khai tự động giúp giảm thời gian thực hiện, vòng phản hồi và chi phí tổng thể. Các nhà phát triển có thể tập trung vào những gì thực sự quan trọng.