데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      AKS usecase : DevOps gitlab CI + ArgoCD

      broccoli 24.01.15
      3,726 8 2
      DEVOTEE 요약
      AKS 환경을 도입하여 개발자들의 서비스 배포에 드는 노력을 줄였다. CI/CD 파이프라인을 구축하고, GitLab에 소스 저장소 생성부터 ACR로의 이미지 업로드, ArgoCD를 통한 자동 배포까지의 과정을 설정하였다. 이로써 개발자는 서비스 배포에 필요한 과정을 거치지 않고, 코드 작업에만 전념할 수 있게 되었다.
      DEVOTEE 추천 블로그

      AKS 환경에서 DevOps 사례를 만들어 보자

      AKS 를 도입하고 나서 보니 개발자들의 서비스 배포에 드는 수고가 절반은 줄어든 것으로 보인다.

      기존 Azure VM 기반에서는 오토스케일링을 위해 VM 이미지 기반 배포가 요구되기 때문에 이미지 업데이트와 배포 과정에서 많은 시간이 소요되었다.

      개발자 입장에서는 중요하지 않은 업무로 효율성이 떨어졌다.

      AKS 도입 후 CI/CD 파이프라인을 구축하여 개발자의 수고를 줄일 수 있었다.

      최근 별도의 개발 프로젝트 진행을 위해 인프라 제공이 필요했는데, AKS가 있어 어려움 없이 2일 만에 제공할 수 있었다.

      CI/CD 관점으로 GitLab에 소스 저장소 생성부터 ACR로의 이미지 업로드, ArgoCD를 통한 자동 배포까지의 과정을 정리하였다


      CI환경은 Gitlab CI로 구성을 할 수 있다

      repo는 source-repo와 manifest-repo로 분리하여 구성한다. 2개의 repo를 그룹으로 관리할 수 있도록 gitlab의 subgroup 기능을 이용한다.

      image.png

      1. 개발용 그룹 생성과 repo 생성

      image.png

      2. 샘플 소스 작성

      동작을 하기 위해 간단한 spring boot 샘플 소스를 작성한다. 간단한 웹 페이지가 보이도록 src/main/resources/static/index.html에 작성한다.

      image.png

      3. gitlab-runner 생성

      1) gitlab-runner에 대한 이해 부터

      처음에는 gitlab에 있는 runner가 CI/CD 처리를 해 주는 줄 알았다.

      shared runner(공유 러너) 환경이라면 틀린 말도 아니지만 현재 우리 회사는 아래 그림처럼 shared runner를 구축하지 않았다.

      그래서 프로젝트 담당자가 gitlab-runner를 구축해야 한다.

      우선 gitlab에서 정의하는 runner와 실제 CI/CD 수행을 하는 gitlab-runner를 구분해서 이해하고 있어야 한다.

      • 정의 : gitlab-runner는 gitlab의 CI/CD 파이프라인을 구동하기 위한 agent로, 코드 변경에 따른 자동화된 테스트, 빌드, 배포 등을 수행하는 도구

      • 필요성 : gitlab에 호스팅된 프로젝트의 continuous integration/delivery를 위해 필요, 코드 변경 시 자동으로 테스트, 빌드, 배포 등을 수행할 수 있음

      image.png

      2) gitlab에 있는 runner 설정

      repo 단위로 runner를 설정할 수도 있지만, group내에 다수 repo가 존재할 상황이라 group runner를 등록하기로 했다.

      group의 Build 메뉴를 펼쳐서 'Runners' 를 클릭하면 'New group runner'를 생성할 수 있는 기능이 제공된다.

      image.png

      아래와 같이 tag를 입력하고 Create runner를 클릭하면 바로 생성이 된다.

      image.png

      Runner created. 라는 알림이 뜨고, 하단의 Go to runners page 를 클릭하면 등록된 runner를 볼 수 있다.

      image.png

      좀 전까지도 없었던 gorup runner가 등록된 걸 볼 수 있다. 현재 상태는 Online에 Never connected 이다. 아직 연결된 것 없다.

      image.png

      아직 연결 전이므로 연결이 필요하다. 실제 역할을 수행할 컴퓨팅 자원이 필요하다.

      우리 프로젝트는 aks를 사용하므로 azure kubernetes에 gitlab-runner용 pod를 생성하기로 했다.

      3) aks에 gitlab-runner 리소스 생성
      • gitlab-runner를 k8s에 생성하기 위해서는 helm 툴을 사용한다.

      • helm 툴로 리소스를 설치하기 위해서는 chart와 values.yaml 이 필요하다.

      • chart를 온라인 상으로 조회할 수 있도록 chart repo를 아래와 같이 추가한다.

      helm repo add gitlab https://charts.gitlab.io
      • values.yaml을 작성해야 한다. values.yaml에서 핵심이자 변경이 필요한 값은 gitlabUrl 과 runnerRegistrationToken 이다.(보안성을 위해 마스킹 처리)

      affinity: {}
      checkInterval: 30
      concurrent: 10
      configMaps: {}
      gitlabUrl: https://ㅇㅇㅇ    / # runner registration url
      hostAliases: []
      image:
        image: gitlab-org/gitlab-runner
        registry: registry.gitlab.com
      imagePullPolicy: IfNotPresent
      metrics:
        enabled: false
        port: 9252
        portName: metrics
        serviceMonitor:
          enabled: false
      nodeSelector: {}
      podAnnotations: {}
      podLabels: {}
      podSecurityContext:
        fsGroup: 65533
        runAsUser: 100
      priorityClassName: ""
      rbac:
        clusterWideAccess: false
        create: true
        podSecurityPolicy:
          enabled: false
          resourceNames:
            - gitlab-runner
        rules:
          - resources:
              - configmaps
              - pods
              - pods/attach
              - secrets
              - services
            verbs:
              - get
              - list
              - watch
              - create
              - patch
              - update
              - delete
          - apiGroups:
              - ""
            resources:
              - pods/exec
            verbs:
              - create
              - patch
              - delete
      resources: {}
      runnerRegistrationToken: GR13489ㅇㅇㅇ # runner registration token(마스킹 처리)
      runners:
        builds: {}
        cache: {}
        config: |
          [[runners]]
            [runners.kubernetes]
              namespace = "{{.Release.Namespace}}"
              image = "ubuntu:16.04"
        helpers: {}
        namespace: gitlab-runner
        services: {}
      secrets: []
      securityContext:
        allowPrivilegeEscalation: false
        capabilities:
          drop:
            - ALL
        privileged: false
        readOnlyRootFilesystem: false
        runAsNonRoot: true
      service:
        enabled: false
        type: ClusterIP
      sessionServer:
        enabled: false
      terminationGracePeriodSeconds: 3600
      tolerations: []
      volumeMounts: []
      volumes: []           
      • runner registration token 은 아래 그림처럼 복사해 올 수 있다.

      image.png

      • 작성이 되었으면 helm install 명령을 aks에 배포하면 된다.

      기본형) helm install gitlab-runner -f values.yaml gitlab/gitlab-runner
      
      예시) helm install --namespace gitlab-runner-exstudio gitlab-runner-exstudio -f gitlab-runner-exstudio.yaml gitlab/gitlab-runner
      • helm 으로 설치 결과를 아래와 같이 k9s로 확인해 보면 별도 프로젝트 그룹을 위한 gitlab-runner를 위한 pod생성을 확인할 수 있다.

      image.png

      • gitlab에 가서 확인해 봐야 한다. 아래와 같이 연결이 확인 된다. 이제 gitlab에서 aks에 생성한 gitlab-runner로 CI/CD를 요청할 수 있다. (현재 개발 프로젝트에서는 gitlab은 CI만 사용)

      image.png

      4. CI 파일 작성

      이제 파이프라인 수행에 대한 정의를 기록하는 CI 파일을 작성해야 한다.

      파일명은 .gitlab-ci.yml 이며, 프로젝트 루트에 두면 된다.

      핵심 내용은 빌드를 수행하는 명령어인 mvn package jib:build 이다.

      참고로 jib는 구글에서 개발한 라이브러리로 spring boot 소스를 컨테이너 이미지로 생성해서 저장소까지 push를 원스톱으로 해주어서 자동화에 매우 유용하다.

      stages:  
        - build
      
      variables:
      
      build-job:
        stage: build
        image: maven:3.8.6-openjdk-8
        before_script:
          - apt-get update && apt-get install -y curl jq
        script:
          - ACR_SERVER="ㅇㅇㅇ.azurecr.io";
            ACR_USERNAME="token-acrㅇㅇㅇ-push";
            ACR_PASSWORD="BtaWOVRbjAKJㅇㅇㅇ";
          - mvn package jib:build -Dimage.tag=$CI_COMMIT_SHORT_SHA -Dacr.server=$ACR_SERVER -Dacr.username=$ACR_USERNAME -Dacr.password=$ACR_PASSWORD
        only:
          - develop
          - /^release-.*$/
          - main
        except:
          - tags
        # when: manual  # default는 always임 
        allow_failure: false  

      5. pom.xml

      jib 빌드와 acr정의를 위해 properties, plugins, mainClass를 추가한다.(보안성을 위해 일부 내용 마스킹 처리)

      <?xml version="1.0" encoding="UTF-8"?>
      <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
               xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
       
          <modelVersion>4.0.0</modelVersion>
       
          ...
       
          <properties>
              <java.version>1.8</java.version>
              <image.tag>local</image.tag>
              <acr.server>acraopdev.azurecr.io</acr.server>
              <acr.username>token-acrㅇㅇㅇ-push</acr.username>
              <acr.password>BtaWOVRbjAKJYgㅇㅇㅇ</acr.password>
          </properties>
       
          <dependencies>
              ...
          </dependencies>
       
          <build>
              <finalName>${project.artifactId}</finalName>
              <plugins>
                  ...
       
                  <plugin>
                      <groupId>com.google.cloud.tools</groupId>
                      <artifactId>jib-maven-plugin</artifactId>
                      <version>3.3.2</version>
                      <configuration>
                          <from>
                              <image>openjdk:8-jdk-alpine</image>
                          </from>
                          <to>
                              <image>${acr.server}/${project.artifactId}</image>
                              <tags>
                                  <tag>${project.version}-${image.tag}</tag>
                              </tags>
                              <auth>
                                  <username>${acr.username}</username>
                                  <password>${acr.password}</password>
                              </auth>
                          </to>
                          <container>
                              <creationTime>USE_CURRENT_TIMESTAMP</creationTime>
                              <mainClass>com.exstudio.springbootex.SpringbootExApplication</mainClass>
                          </container>
                      </configuration>
                  </plugin>
              </plugins>
          </build>
       
      </project>

      6. 파이프라인 확인

      이제 빌드 동작을 확인할 수 있다. pom.xml을 push 하면 빌드를 자동으로 수행한다.

      image.png

      일정 시간이 소요되고 빌드 작업이 아래와 같이 성공하는 것을 확인할 수 있다.

      image.png

      정의한 버전이 ACR에 제대로 업로드 된 것을 볼 수 있다. Repositories 메뉴를 통해 springboot-ex 패키지의 버전이 0.0.1로 업로드 되어 있다.

      image.png

      7. 서비스 동작 확인

      ACR에 업로드한 컨테이너 이미지를 수동으로 aks에 배포할 수 있다.

      • 우선 aks에 배포하기 위한 manifest 파일을 작성해야 한다. Deployment와 Service를 한 파일에 작성한다.

        • 핵심 항목 : 컨테이너 이미지와 tag(위의 구성으로 보면 springboot-ex/0.0.1), namespace(exstudio)

        • 배포 명령어 : kubectl apply -f <yaml파일명>

      apiVersion: apps/v1
      kind: Deployment
      metadata:
        name: d-deploy-exstudio
        namespace: exstudio 
      spec:
        replicas: 1
        selector:
          matchLabels:
            app: d-exstudio
        template:
          metadata:
            labels:
              app: d-exstudio
          spec:
            containers:
            - name: d-exstudio
              image: acrㅇㅇㅇ.azurecr.io/springboot-ex:0.0.1
              ports:
              - containerPort: 8080
      
      ---
      
      apiVersion: v1  
      kind: Service
      metadata:
        name: d-svc-exstudio
        namespace: exstudio
      spec:
        selector: 
          app: d-exstudio
        ports:
          - port: 80
            targetPort: 8080
      • 할당한 도메인명으로 접속을 시도하니 접속을 성공한다.

        • 사전에 도메인도 할당하고, ingress 설정도 아래와 같이 미리 해 두었었다.

      apiVersion: networking.k8s.io/v1
      kind: Ingress
      metadata:
        name: d-ingress-exstudio
        namespace: exstudio
        annotations:
          nginx.ingress.kubernetes.io/ssl-redirect: "false"
          nginx.ingress.kubernetes.io/proxy-body-size: "1024m"
      spec:
        ingressClassName: nginx
        rules:
        - host: exstudio.ㅇㅇㅇ.ㅇㅇㅇ  # 일부 마스킹 처리
          http: 
            paths:
            - path: /
              pathType: Prefix
              backend:
                service:
                  name: d-svc-exstudio  # aks에 생성하는 service 엔드포인드 이름과 동일해야 한다. 
                  port:
                    number: 80


      CD 환경 구성은 ArgoCD로 가능하다

      배포도 gitlab CI 처럼 자동화가 필요하다.

      ArgoCD는 yaml 파일의 변화를 읽어서 배포를 자동으로 수행하는 Auto Sync 기능이 있다.

      1. Access 토큰 생성과 백업

      ArgoCD가 Auto Sync를 해야 할 manifest repo에서 Access 토큰을 생성한다. : Setting> Access Tokens

      image.png

      아래의 화면에서 토큰명을 입력하고, "Create project access token" 을 클릭하면 토큰이 생성된다.

      image.png

      생성한 Access token은 ArgoCD에서 manifest repo 연결에 필요한 설정 정보에 입력해야 하니 잘 백업해 두어야 한다.

      image.png

      2. ArgoCD에서 manifest repo 설정

      아래와 같이 Settings> Repositories 메뉴로 진입하여 필요 정보를 입력하고 상단의 CONNECT를 클릭하면 연결된다.

      • 백업해 두었던 gitlab Access Token이 password로 사용된다.

      image.png

      입력 정보들 중에 Repository URL과 Password가 일치하면 연결을 성공하게 된다.

      image.png

      3. App 배포

      위에서 ArgoCD에서 gitlab에 있는 manifest repository까지 연결이 완료되어 App 자동 배포를 위한 준비가 완료되었다.

      App 추가를 통해 ArgoCD를 통한 배포 설정을 완료할 수 있다.

      manifest 파일 변화를 일정 주기로 감지하는 Auto Sync를 설정하여 아래의 구성을 완료한다.

      image.png

      image.png

      아래와 같이 정상 배포가 되어 잘 동작이 된다.

      image.png


      개발에만 전념할 수 있는 DevOps 환경이 완성되었다

      개발자는 배포 걱정없이 개발 활동에 전념한다.

      구현한 소스에 대해 배포가 필요할 때는 pom.xml의 project 버전 정보까지 변경하여 commit&push를 하고, manifest에서도 동일하게 project 버전 정보를 일치화하여 commit&push만 하면 된다.

      자동화된 CI/CD가 진행되는 환경이 완성이 되었다.

      1. source commit & push

      기능 개발이 완료되면 gitlab으로 commit을 한다. 이 때 pom.xml의 project의 버전도 변경한다.

      image.png

      2. manifest의 버전 업데이트

      소스 변경에 따라 project 버전이 변경되어 acr로 업데이트된 컨테이너 이미지가 업로드 되었으므로, manifest의 배포 파일도 동일한 버전명의 tag로 일치화 시킨다.

      image.png


      정리

      이제 개발자는 코드 작업에만 전념할 수 있는 환경 제공이 가능해졌다.

      코드 변경 사항이 있으면 Gilab CI와 ArgoCD가 자동으로 애플리케이션을 빌드 후 aks에 배포하므로, 개발자가 직접 시스템 배포 작업을 수행할 필요가 없어졌다.

      AKS 인프라에서 Gitlab CI + ArgoCD 의 조합은 개발 생산성 향상과 배포 자동화를 주었다.

      AKS, Gitlab CI, ArgoCD가 있어 개발 생산성을 확보한 배포 자동화를 동작시키는 개발 환경을 하루 만에도 제공할 수 있다.

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      broccoli 님의 최신 블로그

      더보기

      DEVOTEE 추천 블로그

      동영상 기고하기