Container Orchestration/Kubernetes

Flux란? / Flux + Kustomize

Somaz 2023. 10. 16. 21:02
728x90
반응형

Overview

이번 포스팅에서는 GitOps 도구 중 하나인 Flux에 대해 소개하고, Flux + Kustomize를 통합하여 Kubernetes 리소스를 어떻게 자동으로 관리하고 배포할 수 있는지를 실습과 함께 다뤄보겠다.

 

기존에는 ArgoCD를 중심으로 GitOps를 구성한 경험이 있다면, Flux는 또 다른 방식의 GitOps 흐름을 경험해볼 수 있는 좋은 선택이다. 특히 CLI 기반의 심플한 설치와 설정, 그리고 Kustomize와의 강력한 통합 덕분에 YAML 중심의 인프라 운영에 매우 적합하다.

 

이번 실습에서는 Nginx 리소스를 base, overlay 구조로 구성하고, 이를 Flux를 통해 Git에서 감지하여 자동으로 Kubernetes에 반영하는 과정까지 확인한다.

 

Git 저장소에 커밋만 하면 자동으로 리소스가 클러스터에 적용되는 GitOps 흐름이 어떻게 구현되는지 직접 확인할 수 있었다.

 

 

출처 : https://www.devopsschool.com/blog/how-to-implement-gitops-using-flux/

 

 

 

 


 

 

Flux란?

Flux는 CNCF Graduated Project 중 하나인 Weaveworks에 의해 개발된 GitOps 워크플로를 구현하는 도구로, 쿠버네티스 클러스터와 연동하여 작동한다. 현재 Flux v2 가 최신 버전이다.

 

 

GitOps란?

GitOps는 2017년에 위브웍스(Weaveworks Inc.)에서 처음 사용한 용어로 프로젝트에 DevOps의 실천 방법 중 하나이다.

클라우드 네이티브 애플리케이션을 대상으로 한 지속적 배포(Continuous Deployment)에 초점을 두고 있다.

단어로 알 수 있듯이 애플리케이션의 배포와 운영에 관련된 모든 요소들을 코드화하여 Git에서 관리(Operation) 한다는 것을 뜻한다.

 

 

 

Flux 다른 GitOps 도구와의 통합

Flux는 Kubernetes에 대한 GitOps 도구로, 여러 다른 도구와 통합할 수 있다. 다양한 GitOps 도구 중 특히 Flux와 잘 어울리는 몇가지 도구와의 조합을 아래에 제시한다.

 

  1. `ArgoCD + Flux`
    • ArgoCD는 Kubernetes를 위한 또 다른 GitOps 도구이다.
    • Flux는 자동화 및 구성 관리에 뛰어나고, ArgoCD는 시각화 및 UI/UX에 탁월하다.
  2. `Helm + Flux`
    • Helm은 패키지 매니저로 차트(Chart) 형식을 사용하여 Kubernetes 리소스를 패키징한다.
    • Flux v2에는 Helm Controller가 포함되어 있어, Helm 차트를 GitOps 방식으로 관리할 수 있다.
  3. `Flagger + Flux`
    • Flagger는 Kubernetes를 위한 PD(Progressvie Deployment) 도구이다.
    • Flux와 통합하여 GitOps 워크플로우 내에서 자동화된 카나리 배포나 블루-그린 배포를 구현할 수 있다.
  4. `SOPS + Flux`
    • SOPS는 Mozila에서 개발한 비밀 정보 암호화 도구이다.
    • Flux와 함께 사용하면 Git 내에서 Kubernetes Secret을 안전하게 관리할 수 있다.
  5. `Linkerd + Flux`
    • Linkerd는 서비스 메시(Service Mesh) 솔루션이다.
    • Flux와 함께 사용하여 GitOps 워크플로우 내에서 서비스 간 통신을 보안하고 최적화 할 수 있다.

 

 

 

 

 

 


 

 

 

 

Flux v1

  • 어플리케이션의 배포와 관련된 코드를 Git 리포지토리와 동기화한다.
  • 새로운 커밋이나 이미지 업데이트를 감지하면 자동으로 Kubernetes 클러스터에 변경사항을 배포한다.

 

 

Flux v2

  • Flux v1의 성공을 기반으로 만들어진 다음 세대 GitOps 도구이다.
  • Flux v2는 확장성, 다양한 워크플로, 그리고 다양한 GitOps 프로젝트와의 통합을 목표로 한다.
  • 그리고 `modular set of toolkits` 구성되어 있어 특정 사용 사례에 맞춰서 사용하기 좋다. 확장성이 뛰어나며 CRD(사용자 정의 리소스)를 통해 Kubernetes 내에서 작동한다.

 

 

 

 

 

Flux CLI 설치

다른 설치 방법은 해당 링크에서 확인하면 된다.

curl -s https://fluxcd.io/install.sh | sudo bash

 

 

Flux 설치

flux install --namespace=flux-system
✚ generating manifests
✔ manifests build completed
► installing components in flux-system namespace
CustomResourceDefinition/alerts.notification.toolkit.fluxcd.io created
CustomResourceDefinition/buckets.source.toolkit.fluxcd.io created
CustomResourceDefinition/gitrepositories.source.toolkit.fluxcd.io created
CustomResourceDefinition/helmcharts.source.toolkit.fluxcd.io created
CustomResourceDefinition/helmreleases.helm.toolkit.fluxcd.io created
CustomResourceDefinition/helmrepositories.source.toolkit.fluxcd.io created
CustomResourceDefinition/kustomizations.kustomize.toolkit.fluxcd.io created
CustomResourceDefinition/ocirepositories.source.toolkit.fluxcd.io created
CustomResourceDefinition/providers.notification.toolkit.fluxcd.io created
CustomResourceDefinition/receivers.notification.toolkit.fluxcd.io created
Namespace/flux-system configured
ResourceQuota/flux-system/critical-pods-flux-system created
ServiceAccount/flux-system/helm-controller created
ServiceAccount/flux-system/kustomize-controller created
ServiceAccount/flux-system/notification-controller created
ServiceAccount/flux-system/source-controller created
ClusterRole/crd-controller-flux-system created
ClusterRole/flux-edit-flux-system created
ClusterRole/flux-view-flux-system created
ClusterRoleBinding/cluster-reconciler-flux-system created
ClusterRoleBinding/crd-controller-flux-system created
Service/flux-system/notification-controller created
Service/flux-system/source-controller created
Service/flux-system/webhook-receiver created
Deployment/flux-system/helm-controller created
Deployment/flux-system/kustomize-controller created
Deployment/flux-system/notification-controller created
Deployment/flux-system/source-controller created
NetworkPolicy/flux-system/allow-egress created
NetworkPolicy/flux-system/allow-scraping created
NetworkPolicy/flux-system/allow-webhooks created
◎ verifying installation
✔ helm-controller: deployment ready
✔ kustomize-controller: deployment ready
✔ notification-controller: deployment ready
✔ source-controller: deployment ready
✔ install finished

 

 

 

설치 확인한다.

k get all -n flux-system
NAME                                           READY   STATUS    RESTARTS   AGE
pod/helm-controller-6c876b99cc-2wq9m           1/1     Running   0          49s
pod/kustomize-controller-544d665c65-zxf5s      1/1     Running   0          49s
pod/notification-controller-7df5d5584f-sj69m   1/1     Running   0          49s
pod/source-controller-5856c5c874-g28fr         1/1     Running   0          49s

NAME                              TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)   AGE
service/notification-controller   ClusterIP   10.233.48.74    <none>        80/TCP    50s
service/source-controller         ClusterIP   10.233.33.165   <none>        80/TCP    50s
service/webhook-receiver          ClusterIP   10.233.9.210    <none>        80/TCP    50s

NAME                                      READY   UP-TO-DATE   AVAILABLE   AGE
deployment.apps/helm-controller           1/1     1            1           49s
deployment.apps/kustomize-controller      1/1     1            1           49s
deployment.apps/notification-controller   1/1     1            1           49s
deployment.apps/source-controller         1/1     1            1           49s

NAME                                                 DESIRED   CURRENT   READY   AGE
replicaset.apps/helm-controller-6c876b99cc           1         1         1       49s
replicaset.apps/kustomize-controller-544d665c65      1         1         1       49s
replicaset.apps/notification-controller-7df5d5584f   1         1         1       49s
replicaset.apps/source-controller-5856c5c874         1         1         1       49s

 

 

Flux bootstrap github

# Create a GitHub personal access token and export it as an env var
export GITHUB_TOKEN=<my-token>

# Run bootstrap for a private repository owned by a GitHub organization
flux bootstrap github --owner=<organization> --repository=<repository name> --path=clusters/my-cluster

# Run bootstrap for a private repository and assign organization teams to it
flux bootstrap github --owner=<organization> --repository=<repository name> --team=<team1 slug> --team=<team2 slug> --path=clusters/my-cluster

# Run bootstrap for a private repository and assign organization teams with their access level(e.g maintain, admin) to it
flux bootstrap github --owner=<organization> --repository=<repository name> --team=<team1 slug>:<access-level> --path=clusters/my-cluster

# Run bootstrap for a public repository on a personal account
flux bootstrap github --owner=<user> --repository=<repository name> --private=false --personal=true --path=clusters/my-cluster

# Run bootstrap for a private repository hosted on GitHub Enterprise using SSH auth
flux bootstrap github --owner=<organization> --repository=<repository name> --hostname=<domain> --ssh-hostname=<domain> --path=clusters/my-cluster

# Run bootstrap for a private repository hosted on GitHub Enterprise using HTTPS auth
flux bootstrap github --owner=<organization> --repository=<repository name> --hostname=<domain> --token-auth --path=clusters/my-cluster

  # Run bootstrap for an existing repository with a branch named main
  flux bootstrap github --owner=<organization> --repository=<repository name> --branch=main --path=clusters/my-cluste

 

 

Flux github SSH 연결

# Create a secret for Flux to access the git repository:
flux create secret git flux-ssh-key \
  --url=ssh://git@github.com/somaz94/kustomize-study.git \ # github url
  --private-key-file=/home/somaz/.ssh/id_rsa_somaz94 \ # url ssh private key
  --export > flux-secret.yaml

k apply -f flux-secret.yaml -n flux-system

# Create a source from the git repository:
flux create source git nginx-source \
  --url=ssh://git@github.com/somaz94/kustomize-study.git \
  --branch=main \
  --namespace=flux-system \
  --secret-ref=flux-ssh-key \ 
  --export > git-source.yaml

kubectl apply -f git-source.yaml -n flux-system

# Check Github Repo:
k get gitrepositories.source.toolkit.fluxcd.io -n flux-system
NAME           URL                                                AGE   READY   STATUS
nginx-source   ssh://git@github.com/somaz94/kustomize-study.git   50s   True    stored artifact for revision 'main@sha1:842f85844aa1a5a92fb12b86c98ab629d6c43271'

 

 

 

GitHub Actions로 자동 Bootstrap(Auto)

GitHub Actions를 활용하면 Flux 설치, 부트스트랩, 리소스 동기화까지 자동화된 워크플로우로 처리할 수 있다.

jobs:
  flux-setup:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v3

      - name: Install Flux CLI
        run: curl -s https://fluxcd.io/install.sh | sudo bash

      - name: Bootstrap Flux
        run: |
          flux bootstrap github \
            --owner=somaz94 \
            --repository=kustomize-study \
            --branch=main \
            --path=clusters/dev \
            --personal

 

 

 

 

Flux + Kustomize 리소스 배포

자세한 내용은 아래의 Github를 참조하면 된다. `flux-nginx-deployment` 를 실습해볼 예정이다.

https://github.com/somaz94/kustomize-study

 

GitHub - somaz94/kustomize-study: kustomize-study

kustomize-study. Contribute to somaz94/kustomize-study development by creating an account on GitHub.

github.com

# Setup Kustomizations for different environments:

# Development
flux create kustomization nginx-dev-kustomization \
  --source=nginx-source \
  --path="flux-nginx-deployment/overlays/dev" \
  --prune=true \
  --interval=1m \
  --namespace=flux-system

# Production
flux create kustomization nginx-prod-kustomization \
  --source=nginx-source \
  --path="flux-nginx-deployment/overlays/prod" \
  --prune=true \
  --interval=1m \
  --namespace=flux-system

# QA
flux create kustomization nginx-qa-kustomization \
  --source=nginx-source \
  --path="flux-nginx-deployment/overlays/qa" \
  --prune=true \
  --interval=1m \
  --namespace=flux-system

 

 

 

`dev` 환경만 배포

# Deploy dev
flux create kustomization nginx-dev-kustomization \
source=n>   --source=nginx-source \
>   --path="flux-nginx-deployment/overlays/dev" \
>   --prune=true \
>   --validation=client \
>   --interval=1m \
>   --namespace=flux-system
Flag --validation has been deprecated, this arg is no longer used, all resources are validated using server-side apply dry-run
✚ generating Kustomization
► applying Kustomization
✔ Kustomization created
◎ waiting for Kustomization reconciliation
✔ Kustomization nginx-dev-kustomization is ready
✔ applied revision main@sha1:842f85844aa1a5a92fb12b86c98ab629d6c43271

# Confirm dev
k get kustomizations.kustomize.toolkit.fluxcd.io -n flux-system
NAME                      AGE   READY   STATUS
nginx-dev-kustomization   88s   True    Applied revision: main@sha1:1c8e1453893119cfab06e45880345711cd044587

 

 

 

배포 리소스 확인

k get po,svc,ingress -n dev-nginx
NAME                                    READY   STATUS    RESTARTS   AGE
pod/nginx-deployment-7f89bcdfd4-7tfln   1/1     Running   0          54s

NAME                    TYPE        CLUSTER-IP     EXTERNAL-IP   PORT(S)   AGE
service/nginx-service   ClusterIP   10.233.11.39   <none>        80/TCP    54s

NAME                                      CLASS    HOSTS                  ADDRESS        PORTS   AGE
ingress.networking.k8s.io/nginx-ingress   <none>   dev-nginx.somaz.link   10.10.100.22   80      54s

 

 

 

테스트 완료 후 리소스 삭제

# Check the created resources:
k get kustomizations.kustomize.toolkit.fluxcd.io -n flux-system


# Cleanup:

# Delete Kustomizations
k delete kustomizations.kustomize.toolkit.fluxcd.io -n flux-system nginx-dev-kustomization

# Delete Git Repository source
k delete gitrepositories.source.toolkit.fluxcd.io -n flux-system nginx-source

# Delete Secret
k delete secrets -n flux-system flux-ssh-key


# Uninstall Flux:
flux uninstall --namespace=flux-system

 

 

 

 

 


 

 

 

HelmRelease 실습

Flux는 Helm도 완벽히 지원한다. `HelmRepository, HelmRelease, HelmChart` 리소스를 정의하여 Helm 차트를 GitOps 방식으로 배포할 수 있다.

 

 

예시

flux create helmrepository bitnami \
  --url=https://charts.bitnami.com/bitnami \
  --interval=10m \
  --export > helm-repo.yaml
kubectl apply -f helm-repo.yaml -n flux-system

 

 

 

HelmRelease

apiVersion: helm.toolkit.fluxcd.io/v2beta1
kind: HelmRelease
metadata:
  name: nginx
spec:
  chart:
    spec:
      chart: nginx
      version: 10.2.0
      sourceRef:
        kind: HelmRepository
        name: bitnami
  values:
    service:
      type: ClusterIP
  • 이렇게 구성하면 Helm 기반 리소스도 Kustomize와 동일하게 자동 배포할 수 있다.

 

 

 

 

멀티 클러스터 구성

Flux는 여러 클러스터를 하나의 Git 저장소에서 관리할 수 있다. 각 클러스터에는 `flux-system` 을 개별 설치하고, Git 저장소의 `clusters/CLUSTER_NAME` 경로를 기준으로 동기화하도록 설정한다.

 

 

예시

flux bootstrap github \
  --owner=somaz94 \
  --repository=kustomize-study \
  --path=clusters/dev-cluster \
  --context=dev-context
  • 이를 통해 prod, staging, dev 클러스터를 모두 Git으로 통합 관리할 수 있다.

 

 

 

 


 

 

 

 

 

Image Update Automation (이미지 자동 업데이트)

Flux는 컨테이너 이미지 태그가 변경되었을 때 이를 자동으로 감지하고, GitOps 방식으로 Git 리포지토리에 PR을 생성하거나 직접 리소스를 업데이트해주는 기능도 제공한다. 이를 위해 사용하는 구성 요소가 바로 Image Automation Controller 이다.

 

 

예를 들어, `flux-system` 네임스페이스에 다음과 같이 설정한다.

flux create image repository nginx \
  --image=nginx \
  --interval=1m \
  --export > image-repository.yaml
kubectl apply -f image-repository.yaml -n flux-system
  • 이후, ImagePolicy 및 ImageUpdateAutomation 리소스를 정의하여 최신 태그가 감지되면 Git에 커밋을 자동 생성할 수 있다.
  • 이 기능은 CD 파이프라인을 보다 자동화하고 운영자의 개입 없이 최신 이미지를 적용할 수 있도록 돕는다.

 

 

 

Flux Notifications 연동

Flux는 Notification Controller를 통해 Slack, Discord, Microsoft Teams, Webhook 등 다양한 채널로 동기화 결과나 에러 메시지를 전송할 수 있다. 실시간 알림을 통해 GitOps 배포 결과를 빠르게 파악하고 대응할 수 있다.

apiVersion: notification.toolkit.fluxcd.io/v1beta1
kind: Receiver
metadata:
  name: slack-receiver
spec:
  type: slack
  events:
    - "apply"
    - "error"
  secretRef:
    name: slack-webhook-secret
  • Slack Webhook과 연결하여 배포 성공/실패를 바로 확인할 수 있습니다. 팀 단위 운영에서는 필수 기능이다.

 

 

 

Flux + SOPS로 Secret 안전하게 관리

보안 정보를 Git에 저장해야 할 때 가장 많이 사용하는 방식이 바로 SOPS이다. Flux는 이를 기본적으로 지원한다.

  • SOPS로 암호화된 Secret을 Git에 저장
  • Flux는 Git에서 리소스를 읽고, 자동으로 복호화하여 Kubernetes에 적용
sops -e --pgp <your-key> secret.yaml > secret.enc.yaml

 

 

그리고 `kustomization.yaml` 에 다음처럼 decryption 설정을 추가해준다.

decryption:
  provider: sops
  secretRef:
    name: sops-gpg
  • GitOps 환경에서 Secret 관리는 반드시 SOPS 등 안전한 방법을 병행해야 한다.

 

 

 

 

ArgoCD와 Flux 비교 정리

항목 ArgoCD Flux
UI Web UI 제공 CLI + YAML 기반 (UI는 별도)
Sync 방식 Pull (Git → K8s) Pull (Git → K8s)
배포 단위 Application CRD Kustomization, HelmRelease
확장성 Argo Workflows 등 별도 구성 필요 Toolkit 기반, 모듈식 구성 가능
GitHub Actions 연계 간접 지원 공식 지원 및 예제 제공
SOPS 지원 SealedSecrets 등 별도 도구 기본 내장 (SOPS 내장 지원)
Helm 통합 Template 렌더링 후 배포 Helm Controller로 직접 릴리스 관리
기업 도입 UI 중심, 직관적 사용에 강점 파일 기반 자동화, SRE/DevOps에 강점

 

결론: 팀 규모나 운영 방식에 따라 선택할 수 있으며, 하이브리드 구성도 가능!

 

 

 

 

 

 

 

 


 

 

 

마무리: “YAML 중심 GitOps에 최적화된 Flux + Kustomize 조합”

Flux는 단순히 리소스를 Git으로 관리하는 수준을 넘어, 실제 클러스터와 지속적으로 동기화하고, 변경 사항이 감지되면 자동으로 이를 반영하는 GitOps 도구다.

 

특히 Flux v2는 Kustomize, Helm, SOPS, Notification Controller 등과의 모듈형 통합으로 환경별 오버레이 관리, 암호화된 Secret 처리, 알림 연동, Helm 릴리스 자동 관리 등 유연하고 확장 가능한 워크플로우를 구성할 수 있다.

 

이번 실습을 통해 알 수 있듯이, 단일 Nginx 배포 예제를 기반으로 했지만, 실무에서는 수많은 마이크로서비스를 Git 저장소 하나 또는 여러 개로 나눠 관리하고, Flux를 통해 클러스터의 상태를 자동으로 유지할 수 있다.

 

ArgoCD가 UI 기반의 GitOps 도구라면, Flux는 보다 선언적이고 파일 기반 중심의 GitOps 스타일에 잘 맞는다. 두 도구는 상호 보완적으로 사용될 수도 있으며, 팀 상황에 따라 선택하거나 병행 사용도 가능하다.

 

 

앞으로는 Flagger, Helm, SOPS, Image Automation Controller 등 Flux의 다양한 컨트롤러들을 조합한 고급 GitOps 구성도 함께 실습해볼 예정이다.

 

 

 

 

 

 

 

 

 

 

 


Reference

 

 

728x90
반응형

'Container Orchestration > Kubernetes' 카테고리의 다른 글

kind(Kubernetes in Docker)란?  (2) 2024.01.13
K3s & k3sup 이란?  (2) 2024.01.05
2. Kustomize + ArgoCD ApplicationSet  (2) 2023.10.14
1. Kustomize란?  (0) 2023.10.12
CertManager로 Let's Encrypt 인증서 발급  (2) 2023.10.03