ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • ArgoCD
    네트워크 & 인프라 2022. 11. 2. 15:49

     

     

     

     

     

     

    저번에 들었던 강의 중에서 ArgoCD에 대해 들어 자세히 어떻게 동작하는지 확인하고자 유튜브 강의를 찾게 되었다.

    (직접 실습은 하지 않고 어떻게 돌아가는지 대략적인 실행방식을 학습하였다.)

     

     

    모든 글과 캡쳐는 다음의 영상을 듣고 정리하였다!🙌

    https://www.youtube.com/watch?v=MeU5_k9ssrs

     

     

     

     

     

     

     

     

     

    기존의 CI / CD

    Jenkins와 GitLab을 사용하는 대부분의 프로젝트에서는 다음과 같이 동작한다. MSA를 운영하고 있고 쿠버네티스 환경에서 동작한다고 가정하자.

    코드 버그를 수정하거나 새로운 기능으로 인해 git repo에 커밋이 발생하면 자동적으로 Jenkins등의 파이프라인으로 CI를 유발하게 된다.

     

    CI가 코드를 테스트 하고 새로 이미지를 만들고 docker repo에 push될 것이다.그런 다음 쿠버네티스 클러스터에 변경사항을 배포(CD)하기 위해서는 다음의 과정을 거치게될 것이다.

     

    1) K8s 배포 파일을 새로운 이미지로 업데이트

     

    2) 배포 파일을 쿠버네티스에 적용

     

    즉, 코드의 변경이 발생 -> CI 서버가 테스트 진행하고 도커 이미지 생성 후 repo에 push -> 쿠버네티스 파일을 업데이트 -> 쿠버네티스에 적용 -> 새로운 버전의 어플리케이션이 배포됨 의 과정을 거치게 된다.

     

    하지만 이런 CD과정에는 몇가지 문제가 있다.

     

    1. 쿠버네티스에 배포하기 위한 셋업 툴(ex) kubectl)을 설치해야 함
    2. kubectl은 쿠버네티스 클라이언트 이기 때문에 쿠버네티스와 연결하기 위한 추가적인 접근 권한(credentials)이 필요
    3. 만약 AWS와 같은 환경에 쿠버네티스를 배포한 상황이라면 클라우드 플랫폼에 대한 접근 권한(credentials)도 필요
    4. 외부 서비스에 AWS credentials와 같은 정보를 제공해야 하므로 보안상의 문제가 발생할 수 있음 (만약 50개의 어플리케이션이 있다면 50개의 어플리케이션이 모두 credentials를 가져야 한다.)
    5. 한번 쿠버네티스에 배포를 하고 나면, 배포 후 상황을 확인할 수 없음 (잘 배포되었는지, 잘 살아있는지 등)

    ArgoCD를 사용한 CD를 구현하면 위의 문제사항을 해결할 수 있다.

     

     

     

     

     

     

     

     

     

    Argo CD

    Argo CD란 CD(continuous delivery) 기능을 수행하는 tool을 말한다.

     

    Argo CD를 이용하여 CD 부분을 개선해보자. 정확이 위의 flow를 뒤집어 ArgoCD는 쿠버네티스 클러스터의 일부분으로 K8s의 manifest에 변화가 발생한다면 pull하고 적용시키는 역할을 수행한다.

     

     

     

     

     

     

     

     

    ArgoCD의 수행 과정

    ArgoCD의 수행 과정은 다음과 같다.

    1. 클러스터 안의 ArgoCD에 배포
    2. ArgoCD가 git repo를 추적
    3. ArgoCD가 모든 변화를 모니터링하고 자동적으로 적용시킴

    자세히 살펴보면 다음과 같다.

     

    먼저 사용자가 코드를 git repo에 커밋하여 CI 파이프라인을 trigger하게 되면,

     

    CI 파이프라인이 테스트를 진행하고 이미지를 빌드해서 docker repo에 push 및 K8s manifest파일을 업데이트하게 된다.

     

    그 다음 ArgoCD가 K8s manifest 파일의 변경을 감지하고 변화된 부분을 추적하여 싱크를 맞춰 배포를 진행하는 과정을 거치게 된다.

     

     

     

     

     

    참고로, git repo를 사용할 떄에는 App 소스 코드와 App 설정 파일(K8s manifest files) 및 시스템 설정파일들을 따로 구분하는 것이 좋은데 이는 소스코드와는 별개로 설정파일들을 변경할 수 있기 때문이다. 만약 소스코드와 설정파일들이 분리되지 않은 상태라면 오직 설정파일의 변경만이 발생할 때도 전체 CI 파이프라인을 구동시켜 불필요한 CI 가 작동할 수 있는데, CI 파이프라인에 복잡한 로직을 넣기보다 이를 분리해서 해결하는 것이 낫다.

     

    여기서 App configuration에서 사용되는 K8s manifest 파일은 쿠버네티스 YAML 파일, Helm Charts, Kustomize 등 K8s manifests를 생성하는 모든 템플린 파일이 될 수 있다.

     

    ArgoCD에 의해 추적되는 git repoGitOps Repository라고 부른다.

     

     

     

     

     

     

     

     

     

    ArgoCD의 장점

    이렇게 외부 DevOps 개발자들이나 CI 파이프라인에 의해 업데이트된 K8s manifests 파일의 변경을 ArgoCD가 감지하여 동기화 함으로서 ① 분리된 CI/CD 구현이 가능해졌고, 그 결과 CI/CD는 자동화하고 개발자는 개발이 집중하여 CI를 담당하고 DevOps팀이 CD에 집중하여 관심사를 분리하는 것이 가능해졌다.

     

    또한 K8s 설정파일이 코드로 git repo에 저장됨으로서 config 파일이 하나하나 local 컴퓨터로부터 적용되는 것이 아닌 ② 같은 인터페이스로 클러스터를 업데이트 하는 것이 가능해졌다.

     

     

     

     

    그럼 만약에 git repo를 통해서가 아닌 누군가가 클러스터를 인위적으로 업데이트 시킨다면 어떻게 될까?

     

    ArgoCD는 git repo 변경 감지와 함께 클러스터안에 있는 변경도 감지를 하고 있다. ArgoCD는 git repo의 설정파일들과 쿠버네티스 클러스터의 실제 상태를 계속해서 비교한다.

     

    만약 git repo상태(desired state)와 클러스터 상태(actual state)가 다를 경우에 실제 쿠버네티스 상태 2개로 복제를 하고 인위적으로 만든 쿠버네티스를 git repo 상태로 덮어버린 후 복제본을 1개로 만든다.

     

    이는 즉 ③ ArgoCD를 사용하면 항상 쿠버네티스 클러스터와 git repo상태를 동일하다는 것을 보장하는 것으로 이를 통해 클러스터의 투명성을 가지게 된다.

     

    만약 무언가 빠르게 클러스터를 업데이트 하고 싶다면 인위적으로 클러스터를 업데이트 하는 방법이 아닌, 대신 ArgoCD에게 빠르게 실행하도록 알림을 보낸다.

     

     

     

     

     

    Argo CD를 사용하게 되면 하나의 인터페이스로 통제가 가능하기 때문에 ④ 버전 변화를 관리하거나 변화를 기록하는 것, 여러개의 브런치를 통해서 PR을 보내고 merge 하는 등의 코드 리뷰를 통한 팀 협력이 용이해진다.

     

     

     

     

     

    또한 Argo CD는 ⑤ 롤백이 쉽다는 장점도 가지고 있다. 하나의 git repo를 통해서 업데이트 되기 때문에 손수 모든 업데이트를 되돌릴 필요 없이 돌아가고자 하는 특정 상태를 지정하여 명령할 수 있다.

     

    이를 통해서 만약 쿠버네티스 서버가 다운되게 된다면 설정 git repo를 통해서 또다른 서버를 동일한 상태로 복구가 가능하다.

     

     

     

     

     

     

     

    또한 ⑥ 쿠버네티스 환경 접근은 git repository 룰을 통해서 모든 사람이 아닌 관리자 톡정인만 접근하도록 할 수 있다. 만약 개발 팀이나 주니어 엔지니어가 Merge request를 보내면 특정 관리자인 시니어 엔지니어만 확인 후 merge를 진행하도록 하여 쿠버네티스 클러스터 Role이나 User 자원을 만들 필요없이 git을 통해 간접적으로 클러스터 접근을 관리할 수 있다.

     

    이를 통해서 사람이 아닌 대상에게 외부 클러스터접근 권한을 줄 필요가 없어지고 쿠버네티스 환경 밖에 클러스터 credentials를 보관하지 않도록 할 수 있다.

     

     

     

     

    ⑦ ArgoCD는 쿠버네티스의 확장 처럼 사용이 가능하다. 즉, 외부의 Jenkins가 클러스터 상태를 확인할 수 없었던 것과 달리 ArgoCD는 데이터 저장을 위해 etcd를 사용하거나, 클러스터 모니터링이나 상태 비교를 위해 쿠버네티스 controller를 사용하는 등의 쿠버네티스 기능들을 사용이 가능하여 실시간 어플리케이션 상태 업데이트가 가능하고 pod을 생성하거나 상태가 정상적인지 확인하는 작업이 가능하다.

     

     

     

     

     

     

     

     

     

    ArgoCD의 SYNC

    ArgoCD는 target 상태와 actual 상태를 동기화 한다. ArgoCD를 구성하는 방법은 다음과 같다.

    1. ArgoCD를 쿠버네티스 클러스터 안에 배포한다.
    2. 쿠버네티스 YAML 파일을 통해서 ArgoCD를 설정한다.

     

    쿠버네티스 YAML파일 설정을 통해서 어떤 git repo와 어떤 쿠버네티스 클러스터를 동기화하여 사용할 것인지 지정한다. 여기서 git repo이나 클러스터는 어떤 것이든 선택할 수 있는데, ArgoCD가 포함된 쿠버네티스 클러스터가 될 수도 있고 외부의 클러스터가 될 수도 있다. 여러개의 MSA의 경우 다른 yaml 파일을 가지도록 설정할 수도 있고 그룹으로 몇가지를 묶어 설정할 수도 있다.

     

     

     

     

     

    만약 여러개의 클러스터를 사용한다면 어떻게 될까?

     

    하나의 ArgoCD로 여러 지역의 클러스터를 구성할 수도 있다. 같은 ArgoCD 인스턴스를 가지기 때문에 클러스터들을 동시에 동기화 할 수 있다.

     

    만약 Development, staging, production와 같이 다른 성격을 가진 클러스터의 경우 (하나의 git repository를 사용하기는 하지만 모든 환경에 한번에 deploy하기는 원하지 않는 환경), 즉 development에서 먼저 테스트가 모두 성공하고 나서 staging 단계 그 후 production 단계로 배포하기를 원한다면 어떻게 될까?

     

    이런 경우에 각각의 환경에 따라 git branch를 가지고 있어 이를 활용하거나 kustomize를 이용한 오버레이를 사용할 수도 있다.

     

     

     

     

     

    ArgoCD는 쿠버네티스 환경을 위한 CD 파이프라인이기 때문에 여전히 CI파이프라인이 필요하며, ArgoCD의 대안으로는 flux, JenkinsX와 같은 쿠버네티스를 위한 GitOps CD 툴이 존재한다.

     

     

     

     

     

     

     

     

     

     

    ArgoCD 데모 확인하기

    이제 CD 파이프라인 자동화를 만드는 과정을 살펴보자.

     

    먼저 ArgoCD 데모를 위한 준비를 진행한다. Deployment 와 Service YAML 파일과 함께 Gitlab에 git repo를 만들고, docker repo에 만들어둔 도커이미지를 호스팅하고, 로컬 장비에 비어있는 minikube를 준비를 해야 한다.

    데모에 필요한 부분들은 다음의 사이트에서 확인이 가능하다

    https://gitlab.com/nanuchi/argocd-app-config

     

    Nana Janashia / argocd-app-config · GitLab

    GitLab.com

    gitlab.com

    docker repo는 다음에서 확인이 가능하다

    https://hub.docker.com/repository/docker/nanajanashia/argocd-app

     

    Docker Hub

     

    hub.docker.com

    먼저 deployment.yaml 과 service.yaml을 작성해준다.

    // deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deployment
    spec:
      selector:
        matchLabels:
          app: myapp
      replicas: 2
      template:
        metadata:
          labels:
            app: myapp
        spec:
          containers:
          - name: myapp
            image: nanajanashia/argocd-app:1.0
            ports:
            - containerPort: 8080
    // service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: myapp-service
    spec:
      selector:
        app: myapp
      ports:
      - port: 8080
        protocol: TCP
        targetPort: 8080

     

     

     

     

     

    준비가 완료되었다면, 쿠버네티스 클러스터에 ArgoCD를 설치하고 Application CRD와 함께 ArgoCD를 설정한 후 Deployment.yaml 파일을 업데이트하여 테스트를 진행한다.

     

    먼저 쿠버네티스 클러스터에 ArgoCD를 설치해보자.

    설치 과정은 다음의 사이트에서 설명이 잘 되어있다!

    https://argo-cd.readthedocs.io/en/stable/getting_started/#1-install-argo-cd

     

    Getting Started - Argo CD - Declarative GitOps CD for Kubernetes

    Getting Started Tip This guide assumes you have a grounding in the tools that Argo CD is based on. Please read understanding the basics to learn about these tools. Requirements Installed kubectl command-line tool. Have a kubeconfig file (default location i

    argo-cd.readthedocs.io

    $ kubectl create namespace argocd
    $ kubectl apply -n argocd -f https://raw.githubusercontent.com/argoproj/argo-cd/stable/manifests/core-install.yaml
    
    ## 다음의 명령어로 argocd 네임스페이스에서 실행되는 pod을 확인할 수 있다. 
    $ kubectl get pod -n argocd
    
    ## 다음의 명령어로 argocd 네임스페이스에서 실행되는 service를 확인할 수 있다. 
    $ kubectl get svc -n argocd

    이제 8080으로 들어오는 요청을 서비스로 forwarding 시켜서 ArgoCD에 접속하자.

    $ kubectl port-forward svc/argocd-server -n argocd 8080:443

    http://127.0.0.0:8080로 접속하면 ArgoCD 화면을 만날수 있고 여기서 로그인 하기위해서 사용자 이름은 admin, 비밀번호는 다음의 명령어를 통해서 얻을 수 있다.

    $ kubectl -n argocd get secret argocd-initial-admin-secret -o jsonpath="{.data.password}" | base64 -d; echo

    이제 ArgoCD를 위해서 configuration file을 만들어준다.

     

    # application.yaml
    apiVersion: argoproj.io/v1alpha1  # 새로운 ArgoCD 버전이 나오면 API버전이 바뀐다. 
    kind: Application
    metadata:
      name: myapp-argo-application
      namespace: argocd  # argocd 네임스페이스 안에 ArgoCD가 생성될 것이다.
    spec:
      project: default  # 모든 어플리케이션은 단일 프로젝트에 속하고 만약 명시해주지 않으면 default 프로젝트에 속한다.
    
      source:
        repoURL: https://gitlab.com/nanuchi/argocd-app-config.git  # git repo URL
        targetRevision: HEAD  # 마지막 commit을 향함. 
        path: dev  # dev 폴더에 설정파일이 위치하고 있다. 
      destination: 
        server: https://kubernetes.default.svc  # 쿠버네티스 API 서버의 endpoint, 여기서는 목표 클러스터가 ArgoCD가 배포된 곳과 동일(따라서 internal service에도 접근이 가능), 만약 접근하려는 클러스터가 여러개라면 external address를 사용  
        namespace: myapp  # myapp이라는 네임스페이스에 보낸다. 
    
      syncPolicy:
        syncOptions:
        - CreateNamespace=true  # 목적지 클러스터에 지정한 네임스페이스가 존재하는 것을 보장해준다. 
    
        automated:  # 자동적으로 어떤 변화든 동기화한다. 
          selfHeal: true  # 기본적으로 살아있는 클러스터에 적용된 변화는 동기화가 적용이 안되지만, 이 어노테이션을 이용해 살아있는 클러스터에도 변화를 바로 적용할 수 있음 
          prune: true  # 기본적으로 자동 동기화는 자원을 삭제하지 않지만, 이 어노테이션을 통해 자원을 삭제하도록 설정 가능

     

     

     

     

     

    ArgoCD는 git repo를 매 3분마다 확인한다. 과연 그 사이의 지연을 없애고 싶다면 어떻게 해야할까?

     

    ArgoCD에게 git webhook을 구성해서 변경사항을 바로 알려주는 방법이 있다.

     

    안전한 mechanism을 위해 기본적으로 이 모든 설정이 되어있지 않다.

     

     

     

     

     

     

     

    이제 쿠버네티스에 이 yaml 파일을 적용시켜보자.

    $ kubectl apply -f application.yaml

    이제 ArgoCD UI에 들어가면 어플리케이션이 잘 들어오고 sync되는 것을 확인할 수 있다.

     

    클릭하면 더 자세히 확인할 수 있다. 여기서 pod도 deployment.yaml에서 설정했던 myapp 이름의 2개의 replica로 잘 생성되는 것을 확인할 수 있다.

     

    • refresh : git의 마지막 코드와 실행 상태를 비교
    • SYNC : 변경 사항을 클러스터에 적용하여 타겟의 상태에도 적용

     

     

     

     

     

    이제 업데이트를 통해서 설정한대로 ArgoCD가 잘 동작하는지 확인해보자.

    deployment.yaml의 컨테이너 이미지를 다음과 같이 1.2 로 수정해주자.

    // deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: myapp-deployment
    spec:
      selector:
        matchLabels:
          app: myapp
      replicas: 2
      template:
        metadata:
          labels:
            app: myapp
        spec:
          containers:
          - name: myapp
            image: nanajanashia/argocd-app:1.2
            ports:
            - containerPort: 8080

    변경이 완료되면 ArgoCD가 위와 같이 OutOfSync로 변경을 감지하는 것을 확인할 수 있고,

     

    잠시후 Sync가 완료되면 다음과 같이 변경된 내용을 반영하는 것을 확인할 수 있다.

     

    이미지가 1.0 -> 1.2로 바뀜

     

     

     

     

     

    이번엔 kubectl 명령어를 통해서 인위적으로 클러스터 상태를 바꿔보자.

    $ kubectl edit deployment -n myapp myapp
    ## replicas를 2 -> 4로 수정
      replicas: 4 
    ## ...

    ArgoCD가 변경을 감지하고 인위적으로 변경한 사항을 감지하고 다시 되돌려 놓는다.

     

    따라서 다시 확인해봐도 변경되지 않고 replicas값이 2로 그대로 유지되는 것을 확인할 수 있다.

    $ kubectl edit deployment -n myapp myapp
    ## ...
      replicas: 2
    ## ...

     

     

     

     

    완성 ✨

     

     

     

     

     

     

     

     

     

     

Designed by Tistory.