+5

GitOps Và Sử Dụng FluxCD: Xây dựng thư mục, cấu hình Helm charts và K8s

Lời mở đầu

Ở bài viết trước GitOps Và Sử Dụng FluxCD: Cài đặt flux và môi trường Kubernetes, chúng ta đã hoàn thành việc cài đặt FluxCD, Kubernetes.

Trong bài viết này, chúng ta sẽ đi sâu vào cách triển khai GitOps bằng cách sử dụng FluxCD kết hợp với Helm charts và Kubernetes. Qua đó, chúng ta sẽ thực hành các bước cụ thể để thiết lập, cấu hình và quản lý các ứng dụng Kubernetes một cách hiệu quả và tự động hóa cao.

Chuẩn bị

Một số tài nguyên quan trọng của Flux

GitRepository

Định nghĩa một Git repository và chỉ định các nhánh, thư mục, hoặc tag cần được đồng bộ hóa. Tài nguyên này cho phép Flux biết nơi tìm kiếm các tệp cấu hình và trạng thái mong muốn của ứng dụng hoặc hạ tầng trong Git. Nó là bước đầu tiên để kết nối một kho Git với cụm Kubernetes của bạn.

$ kubectl get GitRepository
NAME          URL                                               AGE   READY   STATUS
flux-system   https://github.com/vanquynguyen/fleet-infra.git   39h   True    stored artifact for revision 'main@sha1:cffa1731421598dbca32dac26235bf4a9d30f907'

Kustomization

Định nghĩa cách các tài nguyên Kubernetes từ Git repository nên được áp dụng hoặc đồng bộ hóa với cụm Kubernetes. Kustomization giúp quản lý và áp dụng các thay đổi từ Git repository đến cụm Kubernetes một cách có kiểm soát, cho phép bạn sử dụng Kustomize để tùy chỉnh và chồng ghép các cấu hình Kubernetes.

$ kubectl get Kustomization
NAME                AGE   READY   STATUS
apps                39h   True    Applied revision: main@sha1:cffa1731421598dbca32dac26235bf4a9d30f907
flux-system         39h   True    Applied revision: main@sha1:cffa1731421598dbca32dac26235bf4a9d30f907
infra-configs       39h   True    Applied revision: main@sha1:cffa1731421598dbca32dac26235bf4a9d30f907
infra-controllers   39h   True    Applied revision: main@sha1:cffa1731421598dbca32dac26235bf4a9d30f907

HelmRepository

Định nghĩa một Helm repository từ đó các biểu đồ Helm (Helm charts) có thể được lấy. HelmRepository cho phép Flux tìm và lấy các biểu đồ Helm từ một repository nhất định, cung cấp cơ sở để triển khai các ứng dụng phức tạp thông qua Helm.

$ kubectl get HelmRepository
NAME             URL                                                   AGE   READY   STATUS
sunasteriskrnd   https://sun-asterisk-research.github.io/helm-charts   39h   True    stored artifact: revision 'sha256:2b657112cf56d0ecff243f90b7bef1a02da23db9c5067ba4db73d23f3a3f4201'

HelmRelease

Định nghĩa việc phát hành (release) một biểu đồ Helm vào cụm Kubernetes. HelmRelease cho phép quản lý và triển khai các ứng dụng thông qua biểu đồ Helm, đảm bảo rằng các ứng dụng được cài đặt và cấu hình chính xác như mong muốn.

$ kubectl get HelmRelease
NAME       AGE    READY   STATUS
metabase   39h   True    Release reconciliation succeeded

ImageRepository

Định nghĩa một kho chứa Docker image và chỉ định các quy tắc để tìm kiếm các phiên bản Docker image mới. ImageRepository giúp Flux biết nơi tìm kiếm các Docker image để triển khai, giúp theo dõi và sử dụng các phiên bản Docker image mới nhất từ các kho chứa.

$ kubectl get ImageRepository
NAME       LAST SCAN              TAGS
metabase   2024-05-27T18:24:34Z   336

ImagePolicy

Xác định chính sách để chọn phiên bản Docker image nào từ ImageRepository nên được sử dụng. ImagePolicy giúp kiểm soát và tự động cập nhật Docker image dựa trên các chính sách cụ thể, chẳng hạn như luôn sử dụng phiên bản mới nhất hoặc phiên bản ổn định nhất.

$ kubectl get ImagePolicy
NAME       LATESTIMAGE
metabase   docker.io/metabase/metabase:v0.50.0-RC1

ImageUpdateAutomation

Định nghĩa việc tự động cập nhật các tài nguyên Kubernetes khi có Docker image mới theo ImagePolicy. ImageUpdateAutomation tự động cập nhật các tệp cấu hình trong Git repository khi có phiên bản Docker image mới, giúp duy trì sự đồng bộ và tự động hóa quy trình phát hành ứng dụng.

$ kubectl get ImageUpdateAutomation
NAME          LAST RUN
flux-system   2024-05-27T18:24:05Z

Bucket:

Định nghĩa một nguồn chứa (bucket) chẳng hạn như S3 hoặc GCS, chứa các tệp cấu hình Kubernetes. Bucket cho phép Flux sử dụng các tệp cấu hình từ các nguồn lưu trữ đối tượng, mở rộng khả năng lấy cấu hình từ nhiều nguồn khác nhau ngoài Git.

Thực hành xây dựng các tài nguyên Flux cần thiết

Yêu cầu

  • Môi trường triển khai: Kubernetes Cluster (K8s)
  • Công cụ sử dụng:
    • FluxCD: Tự động hóa triển khai và quản lý trạng thái ứng dụng.
    • Helm Chart: Sử dụng Helm chart để quản lý các bản phát hành ứng dụng trong Kubernetes.
  • Ứng dụng triển khai:
    • Metabase: Một công cụ phân tích dữ liệu mã nguồn mở.
    • Ingress-nginx: Cài đặt Ingress NGINX để cho phép bạn quản lý các luồng lưu lượng truy cập từ internet hoặc các nguồn khác và định tuyến chúng đến các dịch vụ hoặc ứng dụng cụ thể bên trong cụm Kubernetes.
    • Cert-manager: Cấu hình Cert-manager để tự động hóa việc quản lý và cấp phát chứng chỉ SSL/TLS.

Xây dựng cấu trúc thư mục

Một repo FluxCD có thể xây dựng những thư mục chính như sau:

└── apps
└── clusters
└── infrastructure
└── script

apps

  • Thư mục apps chứa các tệp cấu hình liên quan đến các ứng dụng sẽ được triển khai trong Kubernetes cluster.
  • Trong thư mục này, bạn có thể tổ chức các ứng dụng theo thư mục con riêng biệt cho từng ứng dụng hoặc nhóm ứng dụng.
  • Mỗi thư mục con có thể chứa các tệp Helm chart, Kustomize, hoặc các manifest YAML để định nghĩa cách triển khai ứng dụng.

Trong apps tại thư mục con base chúng ta xây dựng các ImageRepository, Kustomization, HelmReleaseHelmRepository

./apps/
└── base
    └── metabase
        ├── imagerepository.yaml
        └── kustomization.yaml
        └── namespace.yaml
        └── release.yaml
        └── repository.yaml
 └── production
    └── metabase
        ├── kustomization.yaml
        └── metabase-values.yaml
└── staging
    └── metabase
        ├── kustomization.yaml
        └── metabase-values.yaml

Với việc xây dựng thư mục base này, dễ dàng tái sử dụng cấu hình chung tại các môi trường stagingproduction. Cùng theo dõi bên dưới.

Đầu tiên tạo 1 HelmRepository khai báo helm repo, ở ứng dụng metabase mình sử dụng chart của organization sun-asterisk-research (Bên org này họ publish rất nhiều Open source hay ho). Có thể sử dụng Helm HTTP/S repositoryHelm OCI repository, ở file này hiện tại mình đang dùng Helm HTTP/S repository. Để sử dụng Helm OCI repository bạn chỉ cần thêm type: "oci" và url đổi thành OCI registry với url oci://ghcr.io/sun-asterisk-research/helm-charts

apiVersion: source.toolkit.fluxcd.io/v1
kind: HelmRepository
metadata:
  name: sunasteriskrnd
  namespace: metabase
spec:
  interval: 5m
  url: https://sun-asterisk-research.github.io/helm-charts

Xây dựng 1 HelmRelease với các giá trị chung: Bao gồm khai báo chart, default values. Với cấu hình interval: 30m, FluxCD sẽ kiểm tra trạng thái của Helm release này cứ mỗi 30 phút một lần. Nếu có bất kỳ thay đổi nào trong cấu hình (như thay đổi trong repository hoặc giá trị được chỉ định), FluxCD sẽ thực hiện cập nhật tương ứng cho bản phát hành Helm.

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: metabase
  namespace: metabase
spec:
  releaseName: metabase
  chart:
    spec:
      chart: metabase
      sourceRef:
        kind: HelmRepository
        name: sunasteriskrnd
  interval: 30m
  install:
    remediation:
      retries: 3
  # Default values
  # https://github.com/sun-asterisk-research/helm-charts/blob/master/charts/metabase/values.yaml
  values:
    image:
      tag: latest
      pullPolicy: Always

Cũng không thể thiếu ImageRepository, metabase chart của sun-asterisk-research sử dụng image của metabase trên dockerhub docker.io/metabase/metabase

apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageRepository
metadata:
  name: metabase
  namespace: metabase
spec:
  image: docker.io/metabase/metabase
  interval: 5m0s
  accessFrom:
    namespaceSelectors:
      - matchLabels:
          kubernetes.io/metadata.name: flux-system

Tại mỗi cluster cần cấu hình thêm các giá trị của chart, ở apps/staging thì HelmRelease sẽ chỉ định chart version, helm values bao gồm image tag,...

apiVersion: helm.toolkit.fluxcd.io/v2
kind: HelmRelease
metadata:
  name: metabase
  namespace: metabase
spec:
  chart:
    spec:
      version: "1.0.3"
  test:
    enable: false
  values:
    image:
      tag: v0.44.0 # {"$imagepolicy": "flux-system:metabase:tag"}
    ingress:
      enabled: true
      ingressClassName: nginx
      hosts:
        - host: mb.staging.com

Bạn có thể dễ dàng nhìn thấy {"$imagepolicy": "<policy-namespace>:<policy-name>:tag"}. Các điểm đánh dấu này được đặt trực tiếp trong tệp YAML đích dưới dạng nhận xét. Chiến lược "Setter" đề cập đến các setter kyaml mà Flux có thể tìm và thay thế trong quá trình đồng bộ hóa, khi được hướng dẫn bởi một thành phần ImageUpdateAutomation sẽ được chia sẻ ở bên dưới.

clusters

  • Thư mục clusters chứa cấu hình cho các cụm Kubernetes khác nhau mà FluxCD sẽ quản lý.
  • Mỗi cụm Kubernetes có thể có một thư mục con riêng, chứa các tệp YAML định nghĩa namespace, policies, và các nguồn tài nguyên khác cần thiết cho cụm đó.
  • Cấu trúc này cho phép quản lý nhiều cụm Kubernetes trong cùng một repo, với các cấu hình riêng biệt cho từng cụm.
./clusters/
└── production
    └── flux-system
        ├── gotk-components.yaml
        └── gotk-sync.yaml
        └── kustomization.yaml
     └── image-automation
        ├── imagepolicy-metabase.yaml
        └── imageupdateautomation.yaml
     └── apps.yaml
     └── infrastructure.yaml
└── staging
    └── flux-system
        ├── gotk-components.yaml
        └── gotk-sync.yaml
        └── kustomization.yaml
     └── image-automation
        ├── imagepolicy-metabase.yaml
        └── imageupdateautomation.yaml
     └── apps.yaml
     └── infrastructure.yaml

Folder flux-system được tạo ra ngay từ khi bạn thực hiện Flux bootstrap với github, nếu bạn không thay đổi flux version hay chạy lại bootstrap thì sẽ không có sự thay đổi gì.

Thiết lập Kustomization cho folder apps/stagings để cấu hình và quản lý các ứng dụng apps.

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

Thiết lập Kustomization cho folder infrastructure để cấu hình và quản lý các ứng dụng infrastructure. Ở trong demo này mình chưa phân biệt giữa các clusters stagingproduction của infrastructure giống như apps, tuy nhiên bạn cũng có thể xây dựng base chứa common config nếu cần nhé.

---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: infra-controllers
  namespace: flux-system
spec:
  interval: 1h
  retryInterval: 1m
  timeout: 5m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./infrastructure/controllers
  prune: true
  wait: true
---
apiVersion: kustomize.toolkit.fluxcd.io/v1
kind: Kustomization
metadata:
  name: infra-configs
  namespace: flux-system
spec:
  dependsOn:
    - name: infra-controllers
  interval: 1h
  retryInterval: 1m
  timeout: 5m
  sourceRef:
    kind: GitRepository
    name: flux-system
  path: ./infrastructure/configs
  prune: true
  patches:
    - patch: |
        - op: replace
          path: /spec/acme/server
          value: https://acme-staging-v02.api.letsencrypt.org/directory
      target:
        kind: ClusterIssuer
        name: letsencrypt

Trong thư mục clusters/staging/image-automation mình có config thêm imagepolicyimageupdateautomation đây là hai file khó thể thiếu vì nó giúp chúng ta duy trì sự đồng bộ và tự động hóa quy trình phát hành ứng dụng.

ImagePolicy được tạo kèm theo các chính sách, yêu cầu về semantic Versioning, pattern của các tag.

apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImagePolicy
metadata:
  name: metabase
  namespace: flux-system
spec:
  imageRepositoryRef:
    name: metabase
    namespace: metabase
  filterTags:
    pattern: '^v(?P<number>[0-9]+)'
    extract: '$number.0.0'
  policy:
    semver:
      range: ">=0"

Tạo một ImageUpdateAutomation bao gồm các thông tin cần thiết về Git, kèm theo message, tên commit được push lên repo khi Fluxcd nhận thấy có sự thay đổi từ GitRepository .

apiVersion: image.toolkit.fluxcd.io/v1beta1
kind: ImageUpdateAutomation
metadata:
  name: flux-system
  namespace: flux-system
spec:
  interval: 5m0s
  sourceRef:
    kind: GitRepository
    name: flux-system
  git:
    commit:
      author:
        name: flux-bot
        email: flux-bot@dev.test
      messageTemplate: |-
        chore: update staging images (flux image automation)
        {{ range .Updated.Images }}
        - {{ . }}
        {{- end}}
  update:
    path: ./apps/staging
    strategy: Setters

infrastructure

  • Thư mục infrastructure chứa các tệp cấu hình liên quan đến cơ sở hạ tầng của Kubernetes cluster.
  • Các tệp trong thư mục này có thể bao gồm cấu hình cho các dịch vụ cơ sở hạ tầng như Ingress NGINX, Cert-manager, lưu trữ (storage), và các thành phần khác.
  • Mục đích của thư mục này là giữ cho cấu hình hạ tầng tách biệt khỏi cấu hình ứng dụng, giúp dễ dàng quản lý và bảo trì.
./infrastructure/
└── configs
    ├── cluster-issuers.yaml
    └── kustomization.yaml
└── controllers
    ├── cert-manager.yaml
    └── ingress-nginx.yaml
    └── kustomization.yaml

script

  • Thư mục script chứa các script tự động hóa hoặc các công cụ tiện ích hỗ trợ cho việc triển khai và quản lý ứng dụng.
  • Các script này có thể bao gồm các công cụ CI/CD, script khởi tạo (bootstrap), hoặc các tiện ích khác phục vụ cho việc quản lý repo FluxCD.

Sau khi thêm đầy đủ cấu hình trên staging mình có push code lên đây, thư mục production các bạn clone về và làm tương tự nha: https://github.com/vanquynguyen/fleet-infra

Mình thực hiện bootstrap lên K8s Cluster của mình: Bootstrap Flux với github

Do metabase chart của sun-asterisk-research mới chỉ hỗ trợ docker Image metabase tag v0.49.9 vậy nên ở file image-policy-metabase.yaml mình sẽ chỉnh sửa lại 1 chút: https://github.com/vanquynguyen/fleet-infra/blob/main/clusters/staging/image-automation/imagepolicy-metabase.yaml

 policy:
    semver:
      range: ">=0 <50.0.0"

Điều này cho thấy rằng không phải lúc nào cũng phụ thuộc hoàn toàn vào tự động hóa, đôi khi trong quá trình vận hành chúng ta cũng phải thường xuyên kiểm tra change-log để kịp thời cập nhật các cấu hình, cài đặt để đảm bảo ứng dụng chạy tốt.

Kiểm tra kết quả

Kiểm tra các thành phần trong FluxCD và xem trạng thái của nó. Như bên dưới chúng đều đã chạy và không có lỗi gì.

$ flux get all

NAME                     	REVISION          	SUSPENDED	READY	MESSAGE                                           
gitrepository/flux-system	main@sha1:ccc77aa6	False    	True 	stored artifact for revision 'main@sha1:ccc77aa6'	

NAME                	LATEST IMAGE                           	READY	MESSAGE                                                                    
imagepolicy/metabase	docker.io/metabase/metabase:v0.50.0-RC1	True 	Latest image tag for 'docker.io/metabase/metabase' resolved to v0.50.0-RC1	

NAME                             	LAST RUN                 	SUSPENDED	READY	MESSAGE               
imageupdateautomation/flux-system	2024-05-28T13:24:44+07:00	False    	True 	repository up-to-date	

NAME                           	REVISION          	SUSPENDED	READY  	MESSAGE                              
kustomization/flux-system      	main@sha1:ccc77aa6	False    	True   	Applied revision: main@sha1:ccc77aa6	
kustomization/infra-controllers	main@sha1:ccc77aa6	False    	True   	Applied revision: main@sha1:ccc77aa6	
kustomization/infra-configs    	main@sha1:ccc77aa6	False    	True   	Applied revision: main@sha1:ccc77aa6	
kustomization/apps              main@sha1:ccc77aa6  False    	True   	Applied revision: main@sha1:ccc77aa6  
  • Các ứng dụng được tự động deploy vào các namespace tương ứng: Bao gồm cert-manager, ingress-nginx, metabase
cert-manager
default
flux-system
ingress-nginx
kube-node-lease
kube-public
kube-system
metabase
  • Kiểm tra dưới máy local xem trang web của metabase:
kubectl port-forward svc/metabase 8000:80

  • Ứng dụng metabase được flux-bot tạo commit trên github, tự động deploy phiên bản mới nhất

Tạm kết

Chắc hẳn sau bài viết này, các bạn đã có thể tự tạo một repository FluxCD cho ứng dụng của mình. Chúng ta đã cùng nhau tìm hiểu cách cấu hình và tự động hóa quá trình cập nhật hình ảnh Docker trong một repository sử dụng FluxCD. Với kiến thức này, bạn có thể đảm bảo rằng các ứng dụng của mình luôn được cập nhật phiên bản mới nhất một cách tự động và chính xác.

Khi ứng dụng lớn lên, đòi hỏi sẽ cần cấu hình nhiều thành phần Kubernetes hơn nữa và kèm theo đó là các cơ chế bảo mật phức tạp hơn. Đừng lo, mình sẽ tiếp tục hướng dẫn các bạn trong các phần tiếp theo về cách quản lý và bảo mật các thành phần này một cách hiệu quả.

Love All ❤️


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí