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ôi trường và công cụ đã cài đặt xong, mình cũng đã tạo xong repo: https://github.com/vanquynguyen/fleet-infra.
- Cùng ôn lại 1 số flux CLI phổ biến: https://viblo.asia/p/gitops-va-su-dung-fluxcd-tu-dong-hoa-quy-trinh-trien-khai-lien-tuc-bXP4WM9xL7G#_mot-so-flux-cli-pho-bien-10
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
, HelmRelease
và HelmRepository
./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 staging
và production
. 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 repository
và Helm 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 staging
và production
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 imagepolicy
và imageupdateautomation
đâ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