Tech story/Cloud

What is DevOps? - CI Automation

kt cloud 테크블로그 2024. 11. 13. 13:18

[kt cloud DevOps팀 이효원 님]

 

What is DevOps? - CI Automation

 

1. CI(Continuous Integration) Automation

CI, 즉 지속적 통합(Continuous Integration)은 개발자가 변경한 코드를 자주 통합하고 이를 자동으로 테스트하는 소프트웨어 개발 방법입니다.

CI 자동화는 DevOps 환경에서 소프트웨어 품질과 개발 속도를 높이기 위해 필수적인 요소입니다.

주로 빌드, 테스트, 코드 품질 검사 등을 자동화하여 코드 통합에 따른 오류를 조기에 발견하고 신속히 대응할 수 있게 합니다.

 

 

 

CI 자동화가 필요한 이유는 다음과 같습니다.

  1. 코드 충돌 감소: 팀 내 여러 개발자가 동시에 작업하면서 코드 통합 시 충돌이 발생할 수 있습니다. CI 자동화는 코드가 정기적으로 통합되면서 이러한 충돌을 초기에 탐지하여 해결할 수 있습니다.
  2. 빠른 피드백 제공: 코드 변경이 통합될 때마다 자동으로 테스트하고, 문제가 발생하면 즉시 알림을 제공하여 개발자가 신속히 문제를 수정할 수 있습니다.
  3. 소프트웨어 품질 개선: 자동화된 테스트를 통해 코드 품질을 보장하고, 각 기능이 기대한 대로 작동하는지 지속적으로 검증하여 소프트웨어의 신뢰성을 높입니다.
  4. 배포 속도 향상: 수동 빌드 및 테스트 과정 없이 자동으로 처리되어, 개발 주기가 짧아지고 릴리스 주기가 빨라집니다. 이를 통해 더 자주, 빠르게 배포할 수 있습니다.
  5. 인적 오류 감소: 사람이 수행하는 반복적인 작업을 자동화하여 실수 가능성을 줄이고, 개발자가 코드 품질에 집중할 수 있는 환경을 제공합니다.

 

2. CI Automation Tools

CI 자동화를 지원하는 도구로는 Jenkins, Gitlab CI 등이 있습니다.

kt cloud는 Github Action을 사용하여 CI를 수행하며

저장소로는 Harbor Registry, 배포 정책으로는 Helm Chart를 사용합니다.

 

Github Actions

Github Actions는 Github에서 제공하는 CI/CD 도구로, Github 저장소와 직접 연동하여 DevOps 워크플로우를 자동화할 수 있습니다.

 

  • 주요 기능
    • 자동화 워크플로우 정의: 코드 커밋, 푸시, PR 등 다양한 이벤트에 따라 워크플로우를 자동으로 실행할 수 있습니다.
    • Reusable Workflows: 반복적인 작업을 재사용 가능한 워크플로우로 구성하여 효율성을 높입니다.
    • Github 환경과의 완벽한 통합: Github 플랫폼 내에서 직접 워크플로우를 설정하고 모니터링할 수 있습니다.
    • 비용 효율성: 오픈소스 프로젝트에는 무료로 무제한 제공되며, 개인 프로젝트도 무료 사용량이 지원됩니다.
  • 장점
    • Github와의 원활한 통합: 코드 저장소, 이슈, PR과 자동으로 연동되어 워크플로우 관리가 쉽습니다.
    • 초기 설정 용이: 기본 템플릿이 제공되어 빠르게 설정할 수 있으며, 커스터마이징도 쉽습니다.
    • 액션 마켓플레이스 제공: 다양한 사용자 제작 액션을 사용하여 복잡한 작업을 간단히 설정할 수 있습니다.
  • 단점
    • 고급 커스터마이징 제한: Jenkins에 비해 복잡한 빌드 흐름은 구현하기 어렵습니다.
    • Github 종속성: Github 이외의 소스 코드 관리 시스템과는 연동이 어려운 단점이 있습니다.

 

Harbor Registry

Harbor는 클라우드 네이티브 애플리케이션을 위한 오픈소스 컨테이너 이미지 레지스트리로,

보안 관리와 성능 최적화를 지원하여 컨테이너 이미지를 안전하고 효율적으로 관리할 수 있습니다.

특히, 엔터프라이즈급 이미지 관리 기능과 통합된 보안 검사, 복제 기능을 제공합니다.

 

 

  • 주요 기능
    • 프로젝트 기반 이미지 관리: 조직 단위의 프로젝트 구성을 통해 권한 관리와 접근 제어가 가능합니다.
    • 보안 검사 및 정책 적용: 이미지 취약성 스캔, 서명, 정책 관리 기능을 제공하여 안전한 이미지를 보장합니다.
    • 멀티 클라우드 레지스트리 복제: 여러 지역에 걸쳐 이미지 복제를 지원하여 분산 환경에서 효율적인 이미지 배포가 가능합니다.
    • SSO 및 LDAP 지원: SSO 및 LDAP 기반 인증을 통해 조직 내 사용자 및 계정 관리가 용이합니다.
  • 장점
    • 강력한 보안 기능: 이미지 취약성 검사 및 서명을 통해 보안성을 확보할 수 있습니다.
    • 프로젝트 기반 관리: 프로젝트별 권한 설정과 관리가 가능하여 조직적인 이미지 관리를 지원합니다.
    • 클라우드 네이티브 환경 최적화: 여러 클라우드와 온프레미스 간 이미지를 쉽게 관리할 수 있습니다.
  • 단점
    • 설치 및 초기 설정의 복잡성: 초기 설정과 구성이 다소 복잡할 수 있어 관리 인력이 필요합니다.
    • 고급 기능 사용 시 높은 학습 곡선: 보안 정책이나 복제 설정 등의 고급 기능은 학습이 필요할 수 있습니다.

 

Helm Chart

Helm은 Kubernetes 애플리케이션을 쉽고 효율적으로 배포하기 위한 패키지 관리 도구로,

애플리케이션 및 관련 리소스를 템플릿화하여 손쉽게 배포할 수 있게 해줍니다.

Helm Chart는 Kubernetes의 "애플리케이션 템플릿" 역할을 하며, 배포 프로세스를 간소화합니다.

 

  • 주요 기능:
    • 패키지화된 배포 구성(Chart): 애플리케이션을 Helm Chart로 패키지하여 반복적으로 배포할 수 있습니다.
    • 버전 관리 및 롤백: 애플리케이션의 버전 관리가 가능하며 필요 시 간편하게 이전 버전으로 롤백할 수 있습니다.
    • Chart Repository 지원: 중앙 또는 자체 Chart Repository를 통해 여러 애플리케이션을 관리할 수 있습니다.
    • 커스터마이징 가능: 사용자 정의 값을 통해 배포 구성을 유연하게 변경할 수 있습니다.
  • 장점:
    • Kubernetes 환경 최적화: 복잡한 Kubernetes 리소스 구성을 쉽게 관리할 수 있어 DevOps 워크플로우에 유용합니다.
    • 편리한 버전 관리: 여러 버전의 애플리케이션을 관리하고 쉽게 롤백할 수 있습니다.
    • Reusable Chart: 반복 가능한 Chart로 배포 과정을 단순화할 수 있습니다.
  • 단점:
    • 템플릿 복잡성: 대규모 애플리케이션에서는 템플릿 구성이 복잡해질 수 있습니다.
    • Chart 유지보수 필요: 업데이트가 잦은 경우 Chart의 지속적인 유지 관리가 필요할 수 있습니다.

 

3. 예제: 컨테이너 이미지 및 Helm Chart 버전업 자동화

배포가 되는 개발 자산을 생성하기 위해서는 여러 과정이 필요합니다.

소스코드를 작성하고, 이를 컨테이너 이미지로 변환하며, 해당 이미지를 어떠한 방식으로 배포할지 정책을 정의하는 단계가 그것입니다.

협업 과정에서 각 단계를 분리하면, 잘못된 정책으로 애플리케이션을 배포하거나

잘못된 버전의 컨테이너 이미지로 버전 업을 수행하는 등 심각한 장애를 초래할 수 있습니다.

 

 

따라서 kt cloud에서는 Github Action을 활용하여 일련의 과정을 하나의 파이프라인으로 구성합니다.

소스코드 커밋이 발생하면 이를 자동으로 Build, 컨테이너 이미지화 하며

이 때 이미지의 Tag 정보를 가져와 Helm Chart App Version 정보를 업데이트하고 패키징 함으로써

소스코드와 컨테이너 이미지, Helm Chart 세 종류의 개발 자산이 하나의 단위로 유지합니다.

 

Github REST API

소스코드 자산을 보관하는 Repository에서 빌드 및 컨테이너 이미지화를 수행하고

이 때 이미지의 Tag 정보를 Helm Chart 자산을 보관하는 Repository로 공유하기 위해서는

Github REST API가 필요합니다.

 

GitHub REST API는 GitHub의 기능을 외부 애플리케이션이나 스크립트에서 활용할 수 있도록 제공하는 인터페이스입니다.

RESTful 방식의 API를 통해 GitHub 저장소, 이슈, 풀 리퀘스트, 커밋 등을 관리할 수 있으며,

이를 통해 GitHub에서 이루어지는 다양한 작업을 자동화하고 확장할 수 있습니다.

주로 DevOps 파이프라인이나 커스텀 애플리케이션에서 GitHub REST API를 사용하여 코드 저장소와 관련된 작업을 자동으로 수행하거나 통합된 워크플로우를 구축할 수 있습니다.

 

GitHub REST API는 다양한 Endpoint를 제공하므로 이를 기반으로 여러 기능을 구현할 수 있습니다.

- 저장소 관리

  • 저장소 생성 및 삭제: 새로운 저장소를 만들거나 기존 저장소를 삭제할 수 있습니다.
  • 저장소 정보 조회: 저장소의 메타데이터(이름, 설명, 언어 등)나 파일 목록을 조회할 수 있습니다.
  • 포크 및 브랜치 관리: 저장소를 포크하거나 새로운 브랜치를 생성하고 관리할 수 있습니다.

- 이슈 및 PR 관리

  • 이슈 생성 및 업데이트: 이슈를 자동으로 생성하거나 상태를 업데이트하는 데 유용합니다.
  • 이슈 코멘트 추가: 팀원 간 협업을 위해 자동으로 코멘트를 추가하여 정보를 전달할 수 있습니다.
  • PR(풀 리퀘스트) 생성 및 리뷰: 코드 리뷰 자동화를 통해 PR 상태 변경, 머지 등의 작업을 수행할 수 있습니다.

- 사용자 및 권한 관리

  • 사용자 정보 조회: 특정 사용자 정보나 팔로워 목록을 조회할 수 있습니다.
  • 팀 및 권한 관리: 조직 내 팀 및 멤버에 대한 권한을 설정하고 변경할 수 있습니다.

- 커밋 및 파일 관리

  • 커밋 조회 및 비교: 특정 커밋의 내용을 확인하거나 두 커밋 간의 차이를 비교할 수 있습니다.
  • 파일 생성, 업데이트, 삭제: 저장소 내 파일을 자동으로 관리하여, 특정 이벤트에 따라 파일을 변경할 수 있습니다.

GitHub REST API를 사용하려면 먼저 인증이 필요합니다.

GitHub 개인 액세스 토큰(Personal Access Token)을 생성함으로써 API 요청을 인증할 수 있습니다.

 

  1. 토큰 생성: GitHub 계정 설정에서 "Developer Settings" > "Personal Access Tokens" > "Generate new token" 메뉴로 이동합니다.
  2. 권한 설정: 토큰에 부여할 권한을 선택합니다. 예를 들어, 저장소 읽기/쓰기, 이슈 관리 등의 권한을 설정할 수 있습니다.
  3. 토큰 저장: 생성된 토큰은 한 번만 확인할 수 있으므로, 안전하게 저장합니다.

생성된 토큰은 이후 API 요청 시 Authorization 헤더에 포함하여 사용됩니다.

 

cURL, JavaScript 등 다양한 방법을 사용할 수 있지만 이번 예제에서는 Github Action CLI를 사용합니다.

 

 

소스코드 Repository Action

소스코드 Repository에서는 기존과 동일하게 소스코드를 기반으로 Build 및 컨테이너 이미지화를 수행합니다.

name: Helm Trigger

on:
  push:
    branches: [ "*" ]
    paths:
      - "src/**"
      - ".github/workflows/helm-trigger.yml"
  ...
jobs: 
  gradle-build:
    ...
  img-push:
    ...

 

그리고 Action Workflow 하단에 컨테이너 이미지 Tag 정보를 Helm Chart Repository로 전달하는 Job을 추가합니다.

  trigger:
    runs-on: ubuntu-latest
    steps:
      - run: gh api /repos/kt-cloud-org-example/helm/dispatches -f event_type='repo_trigger' -F "client_payload[tag]=${{ env.TAG }}"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          TAG: ${{ env.IMG_TAG }}

 

run 커맨드를 사용하여 Github API를 호출합니다.

이 때 Github API를 수신할 레파지토리와 Trigger할 Workflow 정보, 그리고 함께 전달할 파라미터를 명시합니다.

  • “/repos/kt-cloud-org-example/helm”: 이미지 Tag 정보를 수신할 Repository 명
  • “event_type='repo_trigger'“: 해당 레파지토리가 Github API를 수신했을 때 실행할 Github Action Workflow
  • "client_payload[tag]=${{ env.TAG }}": Github API에 담아서 보낼 파라미터

해당 API는 “kt-cloud-org-example/helm“ Repository 내 'repo_trigger'라는 Type을 ID로 가지는 Workflow를 실행하며

파라미터로는 기존 환경 변수 내 “TAG“ 값을 “tag“로 명명하여 전송합니다.

 

 

Helm Chart Repository Action

Helm Chart Repository에서는 Github API를 수신했을 때, Helm Chart App Version을 업데이트 하고

패키징한 Helm Chart를 Harbor Registry에 Push하는 Action Workflow를 작성합니다.

name: helm

on:
  repository_dispatch:
    types: [ repo_trigger ]

 

이 때 워크플로우 실행 방식은 “repository_dispatch“ 입니다.

repository_dispatch는 외부 시스템이나 사용자 지정 스크립트에서 GitHub Actions 워크플로우를 원격으로 시작할 수 있도록 지원하는 방식입니다.

따라서 해당 워크플로우의 Type을 지정하고 외부에서 해당 Type으로 Triggering을 하면

목적지 Repository 내 명시된 repository_dispatch Type을 가진 워크플로우가 시작됩니다.

jobs:
  update:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      packages: write
      id-token: write
      
    steps:
      - name: Client_Payload Check
        run: |
          echo "payload: ${{ toJson(github.event.client_payload) }}"

 

수신한 파라미터는 Payload를 JSON으로 전환하여 확인 가능합니다.

예제의 경우, “tag“라는 이름에 컨테이너 이미지 Tag을 값으로 매핑했으므로

{{“tag“: “$ IMG TAG“} 구조의 Payload인 것을 확인할 수 있습니다.“$ IMG TAG“} 구조의 Payload인 것을 확인할 수 있습니다.

 

      - uses: actions/checkout@v4
      
      - name: Chart AppVersion Update
        run: |
          sed -i 's/appVersion: "[0-9.]\+"/appVersion: "${{ github.event.client_payload.tag }}"/g' sddc-gateway/Chart.yaml
          cat ./sddc-gateway/Chart.yaml

 

      - uses: actions/checkout@v4
            - name: Chart AppVersion Update
        run: |
          sed -i 's/appVersion: "[0-9.]\+"/appVersion: "${{ github.event.client_payload.tag }}"/g' sddc-gateway/Chart.yaml
          cat ./sddc-gateway/Chart.yaml

 

수신한 파라미터 값으로 Helm Chart의 App Version 동기화를 수행합니다.

해당 예제는 sed를 사용하여 기존 App Version을 수신한 파라미터로 문자열 치환합니다.

      - name: Commit Push
        run: |
          git remote set-url origin https://ghp_***@github.com/kt-cloud-org-example/helm.git
          git config --global user.name "ktcloud-devops"
          git config --global user.email "ktclouddevops@gmail.com"
          git add .
          git commit -m "Helm Chart appVersion Updated to ${{ github.event.client_payload.tag }}"
          git push https://ghp_***@github.com/kt-cloud-org-example/helm.git

 

그리고 Chart.yaml 파일의 변동 사항을 Helm Chart Repository에 커밋합니다.

이 때 Runner 환경에 맞춰 Git 정보를 설정하는 과정이 필요합니다.

 

Repository 내 Helm Chart 파일 동기화가 완료되면

수정한 파일 내용을 기반으로 Helm Chart를 패키징하고 Harbor Registry에 업로드합니다.

  push:
    runs-on: 
      group: enterprise/Default
      labels: cicd-ys-ext-build-worker
    permissions:
      contents: write
      packages: write
      id-token: write
    steps:
      - uses: actions/checkout@v4

 

Runner 환경에 맞춰 Helm 플러그인을 설정하는 과정이 선행 되어야 합니다.

- name: Packaging & Pushing Helm Chart
        run: |
          curl -fsSL -o get_helm.sh https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3
          chmod 700 get_helm.sh
          ./get_helm.sh

예제에서는 Helm 설치 파일을 사용했습니다.

 

Helm Chart Museum은 Helm Chart를 관리하고 배포하는 경량의 저장소(repository)로,

Helm Chart의 버전을 관리하고 손쉽게 배포할 수 있는 환경을 제공합니다.

Chart Museum은 Kubernetes와 함께 사용되는 패키지 관리 도구 Helm의 레포지토리 기능을 간편하게 설정할 수 있도록 도와줍니다.

helm plugin install https://github.com/chartmuseum/helm-push
          helm package ./sddc-gateway

예제에서는 Helm Chart Museum 플러그인을 다운로드하고 Helm Chart 패키징을 수행합니다.

 

Helm Chart 패키징이 완료되면 Harbor Registry에 해당 Chart를 업로드합니다.

          helm registry login harbor-cicd.ktcloud.com --username robot_github_action+auth --password ***
          helm push sddc-gateway-0.1.0.tgz oci://harbor-cicd.ktcloud.com/github_action/helm

우선 Harbor 계정을 사용하여 Helm Registry에 로그인 합니다.

해당 예제에서는 개인 계정 대신 Helm Project별로 발급한 Robot Account를 사용합니다.

이후 패키징한 Helm Chart 압축 파일과 업로드 목적지인 Harbor Project를 명시함으로써 Helm Push를 수행합니다.

예제에서 목적지로 명시한 “github_action“ Harbor Project에 접속하면 방금 Push한 Helm Chart를 확인할 수 있습니다.

 

동일하게 컨테이너 이미지 Push 목적지로 명시한 Project 하위 디렉토리에서 컨테이너 이미지를 확인할 수 있습니다.

 

 

마무리

DevOps 체계가 정착되고 협업 모듈이 비대화 되면서 Human Error로 인한 장애 발생률이 급증하고는 합니다.

kt cloud는 Github Action과 API를 활용하여 CI 자동화를 구축함으로써

소스코드와 컨테이너 이미지, Helm Chart 총 세 종류의 개발 자산을 실시간 동기화 하여 관리하고 있습니다.

CI 자동화를 도입할 경우 자산 간의 충돌을 방지할 수 있는 것은 물론이고, 개발자의 중간 관리 과정을 생략함으로써 개발 효율성 또한 제고할 수 있다는 장점이 있습니다.

kt cloud의 사례를 참고해서 나만의 CI Automation 프로세스를 설계해 보세요

 

 

참고/출처