1
2
Production Kubernetes Online Study (=PKOS)는 쿠버네티스 실무 실습 스터디입니다.
CloudNet@ Gasida(가시다)님이 진행하시며, 책 "24단계 실습으로 정복하는 쿠버네티스"을 기반으로 진행하고 있습니다.

3주차 시간에는 Gitlab 과 ArgoCD를 배포하여 Gitops 시스템을 구축하였다. 이번 블로그 글에서는 GitOPS 시스템에 대한 실습 내용들을 정리하고 공유하고자 한다.

GitOps는 GIt을 진실의 원천(SSOT, Single Source of Truth) 으로 사용하는 인프라와 애플리케이션 배포 관리 방식이다. 진실의 원천이라는 말은 Git에서만 소스를 관리할 수 있게 하여 단일 진실 원천을 구현한다는 말이다. 쿠버네티스에서는 GItOps를 ArgoCD를 이용하여 깃 저장소에 있는 소스를 정의된 클러스터 환경에 자동으로 반영시켜 준다.

GitOps 시스템을 구축하면 얻을 수 있는 이점은 다음과 같다.

  1. 버전 관리: Git을 사용하므로 인프라 및 애플리케이션의 모든 변경 사항이 추적되고 버전이 관리된다. 이를 통해 문제 발생 시 이전 상태로 쉽게 되돌릴 수 있다.
  2. 디커플링: 코드와 인프라를 분리함으로써 개발자와 운영팀 간의 협업이 쉬워진다.
  3. 자동화: 변경 사항이 자동으로 적용되므로 수동 인프라 관리 작업이 줄어들고, 실수를 방지할 수 있다.
  4. 보안: Git 저장소에 접근 권한을 제어함으로써 인프라 변경에 대한 보안을 강화할 수 있다.
  5. 신속한 피드백 루프: 문제가 발생하면 소스 코드에 대한 변경을 통해 빠르게 해결하고 적용할 수 있다.

이점만 존재하는 것은 아니다, 단점도 존재한다.

  1. 학습 곡선: GitOps 및 관련 도구를 사용하려면 Git, 선언적 인프라 도구 및 오케스트레이션 플랫폼에 대한 지식이 필요하다.
  2. 복잡성: GitOps를 사용하면 초기 설정과 관리가 복잡할 수 있다. 적절한 도구와 프로세스를 구축하고 유지 관리하는 데 시간과 노력이 필요할 수 있다.
  3. 높은 의존성: GitOps는 Git 저장소에 대한 높은 의존성을 가지며, 저장소 접근이 불가능한 경우 인프라 변경이 제한될 수 있다.

간단하게 예제 시나리오를 구성하여 GitOps 시스템을 구축하고자 한다. 먼저 쿠버네티스 환경에 Gitlab과 ArgoCD를 배포할 것이고, 관리 대상을 지난 시간에 배운 Harbor 배포 차트로 지정할 것이다.

Gitlab 배포

Gitlab은 소스 원격 저장소이다. 흔히 쓰는 깃허브로 생각하면 이해가 빠르다. Gitlab의 차별점은 사설(공식문서에는 offline이라 칭함) 깃랩을 구축할 수 있다는 점인데 직접 헬름 차트를 구성하여 배포하겠다.

깃랩 차트는 다음과 같이 불러올 수 있다.

1
2
3
helm repo add gitlab https://charts.gitlab.io/
helm repo update
helm fetch gitlab/gitlab --untar --version 6.8.1

깃랩 차트에 부가 옵션이 많다.. 공식 문서를 참고하자. 다음은 필자가 차트를 보고 간략히 정리한 내용이다.

  • 유료 버전 무료 제공 : 쿠버네티스에서 오프라인 깃랩 설치시 enterprise edtion (유료, 이하 EE라 칭함) 을 무료로 사용할 수 있다. 이유를 찾아보니 고객 유치 전략이라 한다. EE 사용시 고급 보안, 인증, 권한 관리, 진행률 보고, 고급 CI/CD 기능, 멀티 프로젝트 파이프라인 등의 고급 기능을 제공한다.
  • 스토리지 관련 가용성 제공 : Gitlab 자체적으로 도커 레지스트리를 제공할 수 있다. 또한,레지스트리 이미지 및 깃랩 페이지, 등의 데이터등에 대한 저장소 스토리지로 Minio 를 사용한다. 앞선 블로그 글에서 harbor 레지스트리에 대한 고가용성 구축을 다루었는데, 깃랩에서는 자동으로 연동해주는 것 같다.
  • 네트워크 최적화 기능 제공 : gitlab 서버(Gitlay)에 대한 로드밸런싱(Prafect) 기능을 제공하며, Workhorse라는 컴포넌트를 통해 중앙 프록시 및 파일 처리를 관리한다.
  • 보안 : Oauth, 인증 및 권한 관리(gitlab shell) 을 제공한다.
  • Observability 제공 : 그라파나 연동 기능, Tracing 기능을 제공한다.
  • CI / CD 제공 : gitlab-runner 라는 컴포넌트를 통해 CI / CD 기능을 제공한다.

뭐지..? 단순히 깃 저장소를 확장하여 대부분의 addon를 자동으로 연계시켜 제공하다니, 심지어 고가용성, 최적화에 대한 구성도 자동으로 제공해준다. 기능별로 세세히 보고 싶은 마음이 굴뚝같지만, 이번 블로그글에서는 gitops 시스템 대한 내용만 다룬다. 차트에서 다음과 같은 부분을 수정하였다.

values-gitops.yaml

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
global:
  hosts:
    domain: {도메인 입력}

  ingress: 
    configureCertmanager: false
    provider: aws
    class: alb
    annotations: 
      alb.ingress.kubernetes.io/scheme: internet-facing
      alb.ingress.kubernetes.io/target-type: ip
      alb.ingress.kubernetes.io/listen-ports: '[{"HTTPS":443}, {"HTTP":80}]'
      alb.ingress.kubernetes.io/certificate-arn: {ACM arn 입력}
      alb.ingress.kubernetes.io/success-codes: 200-399
      alb.ingress.kubernetes.io/group.name: "gitlab"
    tls:
      enabled: false 

certmanager:
  install: false

nginx-ingress:
  enabled: false

prometheus:
  install: false

gitlab-runner:
  install: false

헬름 차트에서는 차트 오버라이드가 가능하다. 위의 차트에서 ACM값만 수정해서 설치를 진행하자.

1
helm install gitlab gitlab/gitlab -f values-gitops.yaml --namespace gitlab --version 6.8.4

설치 후 도메인을 통해 로그인을 진행한다. 초기 admin 계정의 아이디는 root 이며, 비밀번호는 다음의 명령어에서 확인한다.

1
2
# 웹 root 계정 암호 확인
kubectl get secrets -n gitlab gitlab-gitlab-initial-root-password --template={{.data.password}} | base64 -d ;echo

gitlab-login.png

접속하면 깃랩 프로젝트 화면이 보인다. 이어서 PKOS 스터디에서 진행한 실습 내용을 테스트하겠다. 사용자 계정을 생성하여 토큰을 발급받고, 신규 프로젝트를 파일을 업로드해보자.

git-test.png

ArgoCD 배포

ArgoCD는 Git 리포지토리에 저장된 쿠버네티스 매니페스트와 실제 클러스터 상태를 동기화시켜주는 지속적인 배포(Continuous Delivery, CD) 툴이다. Argo CD를 사용하면 Git 리포지토리를 기반으로 인프라 구성을 코드로 관리할 수 있게 된다. 이는 단일 진실 원천(SSOT)로 자동화, 보안, 버전 관리 측면에서 유용하다.

ArgoCD 배포는 Helm 차트로 진행한다.

1
2
3
helm repo add argo https://argoproj.github.io/argo-helm
helm repo update
helm fetch argo/argo-cd --untar --version 5.19.14

ArgoCD 차트 분량도 상당하다. 아키텍처를 보니 이해가 빠른 것 같아서 먼저 공유한다.

<a href="https://blog.searce.com/argocd-gitops-continuous-delivery-approach-on-google-kubernetes-engine-2a6b3f6813c0">https://blog.searce.com/argocd-gitops-continuous-delivery-approach-on-google-kubernetes-engine-2a6b3f6813c0</a>

https://blog.searce.com/argocd-gitops-continuous-delivery-approach-on-google-kubernetes-engine-2a6b3f6813c0

  1. argo-cd-server: Argo CD API 서버와 웹 UI를 제공하는 컴포넌트이다. 사용자 인증 및 권한 관리를 처리하며, 클러스터와 Git 리포지토리 간의 동기화를 관리한다.
  2. argo-cd-repo-server: Git 리포지토리와 통신하여 사용자가 관리하는 쿠버네티스 매니페스트 파일을 가져오는 컴포넌트이다. 또한, 리포지토리 내의 Helm 차트와 Kustomize 구성을 처리한다.
  3. argo-cd-application-controller: Argo CD의 핵심 컴포넌트로, 쿠버네티스 클러스터 상태와 Git 리포지토리 상태를 비교하고 동기화를 수행한다. 클러스터의 실제 상태와 원하는 상태를 일치시키는 작업을 담당한다.
  4. argo-cd-dex-server: 인증 프록시 역할을 하는 컴포넌트로, 다양한 OAuth 및 OIDC 프로바이더와 통합하여 Argo CD 인증을 처리한다.
  5. argo-cd-redis: 캐싱 및 세션 관리를 위한 Redis 데이터베이스이다. Argo CD는 Redis를 사용하여 성능 향상과 빠른 응답 시간을 제공한다.
    • Kustomize ?

      쿠버네티스 리소스 구성을 커스터마이징을 위한 도구이다. 동일한 구성을 가진 매니패스트에 수정할 부분만 추가해서 오버라이드가 가능하다.

      아래 예는 원본 베이스 앱(my-app) 에 dev, ops 환경별 필요 값을 오버라이드하는 예제이다.

      먼저 베이스가 되는 deployment를 선언하고 Kustomize 구성한다.

       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      
      # base/deployment.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-app
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: my-app
        template:
          metadata:
            labels:
              app: my-app
          spec:
            containers:
            - name: my-app
              image: my-app-image:latest
              ports:
              - containerPort: 80
      
      1
      2
      3
      4
      5
      
      # base/kustomization.yaml
      apiVersion: kustomize.config.k8s.io/v1beta1
      kind: Kustomization
      resources:
        - deployment.yaml
      

      이제 dev, Ops 환경에 대한 kustomization.yaml 파일을 생성하고 다음 내용을 추가하자.

      Dev 환경 설정

      1
      2
      3
      4
      5
      6
      7
      
      # overlays/dev/kustomization.yaml
      apiVersion: kustomize.config.k8s.io/v1beta1
      kind: Kustomization
      bases:
        - ../../base
      patchesStrategicMerge:
        - deployment-patch.yaml
      
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      
      # verlays/dev/deployment-patch.yaml 
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-app
      spec:
        replicas: 2
        template:
          spec:
            containers:
            - name: my-app
              image: my-app-image:dev
      

      Ops 환경 설정

      1
      2
      3
      4
      5
      6
      7
      
      # overlays/ops/kustomization.yaml
      apiVersion: kustomize.config.k8s.io/v1beta1
      kind: Kustomization
      bases:
        - ../../base
      patchesStrategicMerge:
        - deployment-patch.yaml
      
       1
       2
       3
       4
       5
       6
       7
       8
       9
      10
      11
      12
      
      # overlays/ops/kustomization.yaml
      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: my-app
      spec:
        replicas: 4
        template:
          spec:
            containers:
            - name: my-app
              image: my-app-image:ops
      

      눈치 챘는가? Ops와 dev의 replicas 개수와 이미지 설정만 달랐고 그 부분만 추가했다. 배포는 다음 식으로 진행한다.

      1
      
      kubectl kustomize overlays/dev | kubectl apply -f -
      

위의 컴포넌트별 차트에서 설정이 가능하다. 추가 설정은 아래 config.param 에서 오버라이드하는 것을 추천한다. 사용 예는 깃허브에 있다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
# Argo CD configuration parameters
  ## Ref: https://github.com/argoproj/argo-cd/blob/master/docs/operator-manual/argocd-cmd-params-cm.yaml
  params:
    ## Controller Properties
    # -- Number of application status processors
    controller.status.processors: 20
    # -- Number of application operation processors
    controller.operation.processors: 10
    # -- Specifies timeout between application self heal attempts
    controller.self.heal.timeout.seconds: 5
    # -- Repo server RPC call timeout seconds.
    controller.repo.server.timeout.seconds: 60

깃허브의 사용 예에는 중요한 reSyncPreiod 설정(저장소 동기화 시간) 이 없는 것 같다. 이럴 때는 직접 차트를 확인하여 구성 값을 확인하고 config.params에 추가하자.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
# argo-cd/templates/argocd-application-controller
- command:
        - argocd-application-controller
        - --metrics-port={{ .Values.controller.containerPorts.metrics }}
        {{- if .Values.controller.metrics.applicationLabels.enabled }}
        {{- range .Values.controller.metrics.applicationLabels.labels }}
        - --metrics-application-labels
        - {{ . }}
        {{- end }}
        {{- end }}
        {{- with .Values.controller.args.statusProcessors }}
        - --status-processors
        - {{ . | quote }}
        {{- end }}
        {{- with .Values.controller.args.operationProcessors }}
        - --operation-processors
        - {{ . | quote }}
        {{- end }}
        {{- with .Values.controller.args.appResyncPeriod }} # config.params 추가
        - --app-resync
        - {{ . | quote }}
        {{- end }}
        {{- with .Values.controller.args.appHardResyncPeriod }}
        - --app-hard-resync
        - {{ . | quote }}
        {{- end }}
        {{- with .Values.controller.args.selfHealTimeout }}
        - --self-heal-timeout-seconds
        - {{ . | quote }}
        {{- end }}

실제 배포는 CLB에 externalDNS 로 진행하였다.

1
2
3
4
5
6
# values-argocd.yaml
server:
  service:
    type: LoadBalancer
    annotations:
      external-dns.alpha.kubernetes.io/hostname: argocd.<도메인 입력>

배포

1
2
kubectl create ns argocd 
helm install argocd argo/argo-cd -f values-argocd.yaml --namespace argocd --version 5.19.14

실제로 배포할 시 고려할 점은 접네트워크 대역이다. ArgoCD는 클러스터를 직접적으로 관리할 수 있기 때문이다. 실제 Devops 팀이나 Admin 사용자가 사용할 것이라 예상한다. 이를 위해 허용된 네트워크 대역에서만 로드밸런서 접근이 가능하도록 설정하는 것이 중요할 것 같다. 로드밸런스 설정 후 적절한 보안 그룹을 생성하여 접근을 제어하도록 하자.

argocd.png

초기 admin 로그인 정보는 다음의 명령어로 확인이 가능하다.

1
2
3
#비밀번호 
ARGOPW=$(kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d)
echo $ARGOPW

로그인 이후 ArgoCD에 클러스터와 깃 저장소 등록이 필요하다. ArgoCD UI 나 CLI 를 통해 확인 및 등록이 가능하다. 클러스터는 구축한 클러스터 정보가 기본으로 등록되어 있다. 향후 생산성을 위해 CLI를 통해 확인해보겠다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# 최신버전 설치
curl -sSL -o argocd-linux-amd64 https://github.com/argoproj/argo-cd/releases/latest/download/argocd-linux-amd64
install -m 555 argocd-linux-amd64 /usr/local/bin/argocd
chmod +x /usr/local/bin/argocd

# 버전 확인 
argocd version --short

# argocd 서버 로그인 
argocd login argocd.$KOPS_CLUSTER_NAME --username admin --password $ARGOPW

WARNING: server certificate had error: x509: certificate is valid for localhost, argocd-server, argocd-server.argocd, argocd-server.argocd.svc, argocd-server.argocd.svc.cluster.local, not argocd.hanhorang.link. Proceed insecurely (y/n)? y 
'admin:login' logged in successfully
Context 'argocd.hanhorang.link' updated

# argocd repo 등록 
argocd repo add https://gitlab.hanhorang.link/Horang/test-stg.git  --username horang --password PASSWORDa!
Repository 'https://gitlab.hanhorang.link/Horang/test-stg.git' added

# argocd 확인
argocd repo list 
TYPE  NAME  REPO                                               INSECURE  OCI    LFS    CREDS  STATUS      MESSAGE  PROJECT
git         https://gitlab.hanhorang.link/Horang/test-stg.git  false     false  false  true   Successful

argocd cluster list 
SERVER                          NAME        VERSION  STATUS   MESSAGE                                                  PROJECT
https://kubernetes.default.svc  in-cluster           Unknown  Cluster has no applications and is not being monitored.

GitOps 구축

구축한 Gilab, ArgoCD 를 통해서 GitOps 시스템을 구축해보겠다. gitops 정의대로 깃 저장소에 있는 헬름 차트가 쿠버네티스 환경에 실시간으로 동기화되는 지 테스트해보겠다. 사용 헬름 차트는 앞서 스토리지 테스트를 위해 구축한 minIO 를 대상으로 진행하겠다. 해당 차트는 필자의 깃허브에서 확인이 가능하다.

1
2
3
helm repo add minio https://charts.bitnami.com/bitnami
helm repo update
helm fetch minio/minio --untar --version 12.2.1

먼저, gitlab 저장소에 헬름 차트를 PUSH한다.

gitops-test.png

다음은 ArgoCD를 통해 동기화를 진행한다. 동기화 구성은 ArgoCD CRD로 작성한다.

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: minio-helm
  namespace: argocd
  finalizers:
  - resources-finalizer.argocd.argoproj.io
spec:
  destination:
    namespace: minio
    server: https://kubernetes.default.svc
  project: default
  source:
    repoURL: https://gitlab.hanhorang.link/Horang/test-stg
    path: minio/
    targetRevision: HEAD
    helm:
      valueFiles:
      - values-minio.yaml
  syncPolicy:
    syncOptions:
    - CreateNamespace=true
  • spec.destination : 동기화 클러스터 대상을 나타낸다
  • spec.source : 깃허브 저장소를 입력한다.
  • spec. syncpolicy : 동기화 정책을 구성한다. 옵션은 공식 문서를 참고바란다. CreateNamespace=true 옵션은 대상 네임스페이스가 없으면 생성시킨다는 옵션이다.

배포 후 ArgoCD UI에서 확인하자.

1
kubectl apply -f minio-helm-argo.yaml

배포시 OutofSync 의 상태가 되는데 상단의 Sync App눌러 동기화를 진행한다.

gitops-test2.png

동기화시 옵션에 따라 세부 동작이 가능하다.

gitops-sync.png

  • PRUNE: 리포지토리에 없는 리소스를 삭제함 DRY RUN : 테스트로 실제 변경하지 않음 APPLY ONLY: 리소스 생성 및 수정만 수행하고 삭제하지 않음 FORCE : 강제 적용

  • SKIP SCHEMA VALIDATION: 리소스 매니페스트의 JSON 스키마 검증을 건너뛰는 옵션이다. 이 옵션은 매니페스트에 포함된 스키마가 유효하지 않거나 검증되지 않아도 배포를 진행하고자 할 때 사용한다. AUTO-CREATE NAMESPACE: ArgoCD가 리소스를 배포할 네임스페이스가 존재하지 않는 경우 자동으로 해당 네임스페이스를 생성하는 옵션이다. PRUNE LAST: 클러스터에 존재하지 않아야 하는 리소스를 자동으로 제거하여 깔끔한 상태를 유지할 수 있도록 돕는다. APPLY OUT OF SYNC ONLY: ArgoCD가 오직 동기화되지 않은 리소스에 대해서만 kubectl apply 명령을 실행하는 옵션이다. 이렇게 하면 이미 동기화된 리소스는 건드리지 않고, 변경된 리소스에 대해서만 업데이트를 진행한다.

    RESPECT IGNORE DIFFERENCES: ArgoCD가 리소스를 비교할 때, 무시해야 하는 차이점을 존중하도록 설정하는 옵션이다. 이렇게 하면 사용자가 지정한 특정 필드의 변경 사항을 무시하고 동기화 여부를 결정할 수 있다.

    SERVER-SIDE APPLY: ArgoCD가 서버 측에서 리소스를 적용하도록 설정하는 옵션이다. 이 옵션을 사용하면, 리소스의 변경 사항이 서버 측에서 자동으로 병합되어 관리자가 수동으로 병합할 필요가 없다. 이 방식은 클라이언트 측에서 **kubectl apply**를 사용하는 것보다 더 효율적인 리소스 관리를 가능하게 한다.

  • REPLACE : 리소스 변경시 기존 리소스를 삭제하고 새로운 리소스를 생성하여 대체한다.

    RETRY : 동기화 실패시 재시도

Sync 후 배포까지 모니터링 후 정상적으로 작동하는 것을 확인할 수 있다.

gitops3.png

ArgoCD는 기본적으로 수동적으로 Sync 작업이 필요하다. 자동으로 깃 저장소에 내용으로만 동기화시키려면 self-healing 옵션이 필요하다. App Detail의 Policy 설정에서 활성화하자.

self-healing.png

마치며

이번 글에서는 Gitlab 와 ArgoCD 차트를 분석하여 구성하였고 GitOps 시스템을 구축해보았다. 인프라 관리자 측면에서 SSOT를 구성하면 코드 구성 관리 측면에서 편리해질 것이 느껴진다. 그리고 Gitlab와 ArgoCD 메뉴얼이 잘 정리되어 있다. 확장 기능(메트릭, 알람, 보안) 필요시 메뉴얼을 참고하자!