Dev Stories

DevOps엔지니어링팀의 DevOps툴 활용 노하우 소개


  • 안녕하세요, DevOps엔지니어링팀 함승우입니다.DevOps엔지니어링팀에서 사용하는 기술과, 서비스 개발팀이 원활하게 개발할 수 있도록 어떤 노력을 하고 있는지 소개드리려고 합니다!


목차

  • DevOps란?

  • DevOps엔지니어링팀은 무엇을 하나요?

  • DevOps엔지니어링팀에서 하고 있는 DevOps 툴 활용법 소개!

    • [CI] Github self-hosted runner를 VM에서 k8s로 확장하기 (Github ARC)

    • [CD] Jenkins를 코드로 구성하기 (Jenkins CasC)

    • [Integration & Monitoring] DevOps팀에서 운영하는 S/W를 모니터링하기 (Slack, Datadog)

  • 앞으로의 계획

    • SLO

    • IaC

    • Github workflow 템플릿화


DevOps란?

  • DevOpsDevelopment(개발)*와 Operations(운영)의 합성어로, 소프트웨어 개발팀과 IT 운영팀이 긴밀하게 협업하고, 프로세스를 자동화해 소프트웨어와 서비스를 더 빠르고 안정적으로 제공하기 위한 문화, 방법론, 그리고 도구의 집합을 칭해요.

    1.png


DevOps는 위처럼 SW개발 전 계획 / 개발 / 배포 / 운영의 한 싸이클을 유기적으로 동작할 수 있게 하는, 생산성과 관련된 매우 중요한 개념이에요.

그렇다면…


DevOps엔지니어링팀은 무엇을 하나요?

  • 우리 팀은 아래와 같이 넓고 깊고 많은 일을 하고 있어요.


범위
관련 기술/도구
설명
Plan
Jira / Confluence

이슈 트래커인 Jira, 정보 공유 공간인 Confluence를 직접 운영하고 있어요.

KT / 그룹사 / 협력사가 함께 사용할 수 있어요.

Code / Build
Github Enterprise & Self-hosted runner (VM, kubernetes)
개발 소스코드 관리를 위한 Github Enterprise(Cloud)와, Github Actions로 CI를 자동화 할 수 있는 인프라인 self-hosted runner를 두가지 타입(VM, kubernetes)으로 직접 운영하고 있어요.
Release / Deploy
Jenkins / ArgoCD

개발자 분들의 어플리케이션을 원활히 배포할 수 있도록 배포 환경에 알맞는 오픈소스 기반 배포툴을 제공하고 있어요.

  • VM배포 : Jenkins

  • AKS배포 : ArgoCD

위 오픈소스는 KT 안에서 원활히 쓸 수 있도록 DevOps팀에서 표준을 정하고, 직접 커스텀 해두었어요.

Cloud 인프라
Azure Shared Infra 영역
Azure Shared Infra 존 “devops” 구독을 직접 개발/구성하고 운영해요.
모니터링
Datadog(SaaS)
devops 구독 내 모든 리소스 및 APM, 통합AKS(ArgoCD)에 대한 메트릭과 로그를 수집해요.뿐만 아니라 Github Enterprise의 workflow 이상현상(Anomaly)을 탐지할 수 있어요.
소통, Integrations
Slack(SaaS)

기술혁신부문의 편리한 소통을 담당해요.

여러 툴간 Integration이 가능해서 확장이 용이하다는 장점이 있으며, Datadog의 알림을 Slack으로 받고있어요.

그 외 CI/CD 검토 요청
Azure 서비스
여러 부서에서 요청하는 Github-Azure간 연동이나 CI/CD 구성을 검토하고, 이를 KT Azure 환경에서 사용할 수 있게 표준화 하고 있어요.

DevOps의 범위가 넓은 만큼 사용하고 있는 기술과 도구도 다양한데요, 이중에 DevOps엔지니어링팀에서 활용하고 있는 약간 깊지만 재밌는 기술을 아래에서 소개할게요.


DevOps엔지니어링팀에서 하고 있는 DevOps 툴 활용법 소개!


1. Github self-hosted runner를 VM에서 k8s로 확장하기 (Github ARC)

처음 self-hosted runner를 구성할때, 언어 환경별 VM을 구성했어요. (maven, gradle, python, node-npm 총 4대)

VM으로 runner를 꾸리게 되면, 구성은 편리하지만 하나의 VM에 하나의 workflow만 실행된다는 단점이 있어요.(1:1 매칭)

즉, 모든 VM이 사용중이면 그 이후에 들어오는 workflow는 대기열에 남게되어 CI 빌드 타임이 늘어나요.

이러한 병목을 없애기 위해 병렬적으로 처리하기 용이한 kubernetes 형태로 Runner를 확대하기로 했고, 아래와 같은 구조로 개선했어요.


구분
VM
kubernetes (ARC)
구조
  • Self-hosted runner 서비스:
    Rocky 리눅스에 서비스 프로세스 형태로 동작해요.

  • Actions Runner Controller(ARC): 
    Kubernetes 오퍼레이터로, Runner 관련 리소스(Listener, RunnerSet 등)를 관리하는 컨트롤러에요.

  • Listener Pod:
    GitHub Actions 서비스와 장기 연결(long polling)로 대기하며, 실행할 Job이 생기면 Runner Pod 생성을 스케쥴링해요.

  • Runner Pod:
    실제로 GitHub Actions의 workflow job을 받아 실행하는 일회성 Pod이며, workflow의 동작 범위에요.

특징
Runner 구성이 단순하고 편리함
pod 단위로 병렬 빌드가 가능하고, 노드풀에 오토스케일링 적용
최대 workflow 실행 갯수
VM 1대당 1개. 동시 빌드 최대 4개까지 가능
워커노드 1대당 최대 9개. 동시 빌드 최대 45개까지 가능



이해하기 쉽게, Runner 타입별 확장성에 초점을 맞춰 그림으로 설명드릴게요.


  • VM Runner

2.png


만약 모든 VM에서 workflow가 실행중이고, 추가 workflow 요청이 들어온다면, 앞선 VM의 동작이 끝날때까지 대기 상태에 들어가게돼요. (스케쥴 되지 않고 대기중이라고 해서, queued 라고 해요)

업무 시간대나 특정 VM에 많은 요청이 몰리면, 그만큼 빌드가 늦어지는 병목이 발생하게 되는거에요.



  • K8S Runner

3.png

그에 반해 kubernetes형 Runner는, Pod로 동작하기 때문에 설정된 최대 갯수만큼 pod를 스케쥴할 수 있고, 만약 node가 부족하다면 오토스케일링되어 확장성있게 요청을 처리할 수 있어요.



현재는 위 2가지 타입의 러너를 모두 사용할 수 있고, 선호도/환경에 맞게 유동적으로 사용하실 수 있어요!

라벨 설정 방법은 다음 가이드를 참고해주세요. (https://wiki.dspace.kt.co.kr/pages/viewpage.action?pageId=392969990)


2. Jenkins를 코드로 구성하기 (Jenkins CasC)

VM 배포에 꼭 필요한 Jenkins라는 오픈 소스를 DevOps엔지니어링팀에서 표준을 정하고, KT 내부에서 원활히 쓸 수 있도록 커스텀해서 서비스팀에 제공하고 있어요.

크고 작은 수정사항이 생길 때마다 마스터 이미지가 변경되어야하는데요, 이 때 어떤식으로 관리하는지 소개드리려고해요.


  • Jenkins란?

4.png


Jenkins

전세계적으로 많이 사용하는 CI/CD 자동화 오픈소스 프로젝트에요. Java 기반으로 구성되어있고, 약 2,000개의 플러그인을 서로 조합하여 활용할 수 있어요.

“Job”이라는 단위로 파이프라인 스크립트를 사용해 여러 명령어를 자동화 할 수 있어요.


  • JCasC란?

Configuration as Code 의 약어로, Jenkins 플러그인 중 하나에요. Jenkins 내부 구성을 yaml 기반 코드로 구성/설정/관리 할 수 있다는게 특징이에요.

이렇게 구성하면 아래와 같은 멋진 장점이 있어요.


  1. 완전한 자동화 및 일관성 보장

Jenkins 서버의 설정(플러그인, 인증, job, credentials 등)을 코드로 정의해, 신규 서버 구축이나 재설치 시에도 동일한 환경을 자동으로 재현할 수 있어요.

수동 설정 과정에서 발생하는 실수와 환경 불일치를 방지할 수 있어요.

  1. GitOps 및 버전 관리 용이

설정 파일을 Git 등 버전 관리 시스템에 저장할 수 있어, 변경 이력 추적과 롤백이 쉬워요.

팀원 간 협업 및 코드 리뷰가 가능해져 운영 안정성이 향상돼요.

  1. 수동 작업 최소화 및 운영 효율화

UI를 통한 반복적이고 번거로운 수동 설정 작업을 줄이고, 코드 기반으로 대규모 환경도 효율적으로 운영할 수 있어요.

Jenkins 관리의 표준화와 문서화가 가능해요.


그러면 JCasC를 어떻게 구현할까요? (아래 펼치기 참고)

  1. configurations.yaml 파일

Jenkins를 yaml로 설정하는 코드에요.
Python
# JCasC configurations.yaml 예시

jenkins:
  systemMessage: |
    <h2>Jenkins 자동화 구성 (JCasC)</h2>
    <ul>
      <li>문의: devops@example.com</li>
      <li>매주 일요일 23:45 점검</li>
    </ul>
  numExecutors: 4
  remotingSecurity:
    enabled: true
    slaveAgentPort: 0
  globalNodeProperties:
    - envVars:
        env:
          - key: JAVA_HOME
            value: /usr/lib/jvm/java-17-openjdk
          - key: TZ
            value: Asia/Seoul
  securityRealm:
    local:
      allowsSignup: false
      users:
        - id: "admin"
          password: "${JENKINS_ADMIN_PASSWORD}"
        - id: "devuser"
          password: "${JENKINS_DEV_PASSWORD}"
  authorizationStrategy:
    loggedInUsersCanDoAnything:
      allowAnonymousRead: false
  crumbIssuer:
    standard:
      excludeClientIPFromCrumb: false
  unclassified:
    location:
      url: http://localhost:8080
  views:
    - all:
        name: "전체 빌드"
    - list:
        name: "주요 파이프라인"
        jobNames:
          - "example-pipeline"
  updateCenter:
    sites:
      - id: "default"
        url: "https://updates.jenkins.io/update-center.json"
​
12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849


  1. pipeline.yaml 파일

Jenkins가 서비스되면 바로 배포할 수 있도록 사전에 파이프라인 Job을 구성해 둘 수 있어요. 주로 시스템, 환경, 계정 등 설정을 담당해요.
Python
​# JCasC pipeline.yaml 예시

jobs:
  - script: >
      pipelineJob('example-pipeline') {
        definition {
          cps {
            script("""
              pipeline {
                agent any
                stages {
                  stage('Build') {
                    steps {
                      echo 'Building...'
                    }
                  }
                  stage('Test') {
                    steps {
                      echo 'Testing...'
                    }
                  }
                  stage('Deploy') {
                    steps {
                      echo 'Deploying...'
                    }
                  }
                }
              }
            """)
            sandbox(true)
          }
        }
      }
123456789101112131415161718192021222324252627282930313233
  1. plugins.txt 파일

Jenkins에 심어둘 플러그인을 지정해요. 플러그인 리스트는 https://plugins.jenkins.io/ 에서 확인할 수 있어요.
Python
# JCasC plugins.txt 예시
configuration-as-code:latest
git:latest
workflow-aggregator:latest
matrix-auth:latest
credentials:latest
...
1
2
3
4
5
6
7
  1. Dockerfile

Jenkins 이미지를 어떻게 Docker 이미지로 만들지 정의하는 파일이에요. 여러 설정과 구성, yaml 파일을 Jenkins 컨테이너 이미지 안에 이식하는 작업을 해요.
Python
# JCasC Dockerfile 예시

FROM jenkins/jenkins:lts

# 플러그인 설치
COPY plugins.txt /usr/share/jenkins/ref/plugins.txt
RUN /usr/local/bin/install-plugins.sh < /usr/share/jenkins/ref/plugins.txt

# JCasC 및 파이프라인 Job 설정 복사
COPY configuration.yaml /var/jenkins_home/casc_configs/configuration.yaml
COPY pipeline.yaml /var/jenkins_home/casc_configs/pipeline.yaml

# JCasC 환경변수 지정
ENV CASC_JENKINS_CONFIG="/var/jenkins_home/casc_configs"

# Setup Wizard 비활성화
ENV JAVA_OPTS -Djenkins.install.runSetupWizard=false

# Jenkins 기동 시 pipeline.yaml의 Job 정의를 반영하는 스크립트 추가
COPY init-jobs.groovy /usr/share/jenkins/ref/init.groovy.d/init-jobs.groovy​
1234567891011121314151617181920

쉽게 요약해서,


1 & 2 & 3 파일을 4. Dockerfile에 더하면, Jenkins 이미지를 코드&컨테이너로 관리할 수 있어ub에 올려서 관리하면, 이력 추적과 변경사항, 코드리뷰, 그리고 Runner를 통한 CI 자동화까지 적용할 수 있어요.

성된 KT 표준 Jenkins 이미지는, 골든이미지로 Azure 컴퓨팅 갤러리에 업로드되어 서비스 팀이 VM을 설치하자마자 바로 사용할 수 있게 전달됩니다!

5.png



3. DevOps팀에서 직접 운영하는 S/W를 모니터링하기 (Slack, Datadog)

Azure Shared Infra 존에는 저희팀이 운영하는 devops 구독에 아래와 같은 여러 상용 서비스가 24/7 동작하고 있어요.

대표적으로,

  • Github self-hosted-runner (VM, kubernetes)

  • Nexus Repository : runner로 CI 작업시 외부 라이브러리를 가져올 수 있어요.

  • Squid Proxy : Azure → Github 으로 요청하기 위한 proxy에요.


위 서비스 안정성을 확보하기 위해 DevOps엔지니어링 팀은 Datadog을 사용하고 있고, 대표적으로 구성해둔 Slack 채널과 알람을 소개할게요.



6.png

Datadog-Slack 알림 채널 구성 예시


여러 알림을 Slack에서부터 빠르게 파악할 수 있게 주요 서비스를 채널로 구분해두었어요.

서비스 채널은 APM과 하드웨어 리소스 메트릭을 감지하고, workflows 채널은 Github workflow의 동작 지연 이벤트를 감지해서 오래 걸리는 CI 파이프라인을 DevOps팀에서 바로 확인할 수 있어요.


  • Nexus Repository 모니터


    7.png

    위 모니터에서 Nexus 상태에 문제가 발생하면, 아래와 같이 알림 받고 있어요. 서비스 On/Off 상태 뿐만 아니라 메트릭 정보도 받아볼 수 있어요.


8.png


Nexus 서비스 상태 Slack 알람
9.png

Nexus Memory 사용량 메트릭 Slack 알람


  • Github workflow 동작 지연 감지 모니터
    Github self-hosted runner에서 발생하는 로그를 파싱해서, 어떤 workflow가 어떤 Runner에서 지연되고 있는지 감지할 수 있어요.


10.png

workflow 지연 알림이 발생하면,

11.png

담당자가 원인을 확인하고 조치한걸,

12.png
Slack으로 알 수 있어요

  • Github workflow 상태 수집 모니터또한 Github Enterprise의 로그를 수집/정제해서 아래처럼 workflow 상태별 통계를 확인해볼 수도 있어요.
13.png



TO-BE

  • SLO (Service Level Objective, 서비스 수준 목표)SLO를 수립해 Azure 환경 CI/CD의 서비스 안정성을 확보할 계획이에요. Datadog & Slack으로 모니터링을 강화해, KT에서 개발하는 모든 SW개발자/엔지니어 분들이 원활하게 빌드배포 할 수 있도록 튼튼한 DevOps 생태계를 만들고 싶어요.

  • IaC (Infrastructure as Code)저희 팀에서 직접 설치하는 배포툴을 IaC에 적용해서, 기술지원에 걸리는 시간을 아주 짧게 단축시킬 계획이에요. CI/CD 관련 허들을 낮추기 위해 노력하고 있답니다!

  • Github workflow 템플릿화가이드에서 복사/붙여넣기 하는 workflow가 아닌, 개발자가 변수만 넣으면 바로 사용할 수 있는 workflow 템플릿을 개발할거에요. 보다 편리하게 파이프라인을 구성할 수 있을거에요.



앞으로의 DevOps엔지니어링팀을 응원하고, 기대해주세요!

함승우

KT DevOps엔지니어링팀에서 Azure CI/CD와 Github Enterprise 를 담당하고 있습니다.

IT/DevOps와 관련된 재밌는 이야기를 작성하는 것을 즐겨합니다.