Jenkins와 Kubernetes로 효율적인 CI/CD 환경 비용 절감과 성능 최적화 구축하기

궁금하면 500원·2024년 10월 16일

데브옵스

목록 보기
9/37

Jenkins와 Kubernetes로 효율적인 CI/CD 환경 구축하기 🚀

오늘은 Jenkins와 Kubernetes를 활용해 비용 효율적이고, 자원을 최적화하는 CI/CD 환경 구축 방법을 알아보겠습니다.

이 아티클을 통해 백엔드 개발자가 어떻게 Jenkins와 Kubernetes의 통합을 활용하여 CI/CD 파이프라인을 개선하고, 비용을 절감할 수 있는지 배울 수 있습니다.

💡 Jenkins와 Kubernetes의 기본 개념

Jenkins는 소프트웨어 개발의 빌드, 테스트, 배포 과정을 자동화하는 오픈소스 도구입니다. 이 도구를 통해 지속적 통합(CI) 및 지속적 배포(CD) 파이프라인을 구축할 수 있습니다.

반면, Kubernetes는 컨테이너화된 애플리케이션을 관리하고, 확장 및 자원 할당을 자동으로 처리하는 플랫폼입니다.

Kubernetes의 유연한 리소스 관리와 자동화된 확장 기능은 CI/CD 환경에서 큰 강점을 제공합니다.

🛠️ 기존 Jenkins 구조의 문제점

기존의 Jenkins와 Kubernetes 통합 환경에서 몇 가지 문제가 발생하곤 했습니다.

주로 고정된 Kubernetes 노드를 사용해 Jenkins 에이전트를 운영했기 때문에, 자원의 낭비와 비용 증가가 심각한 문제로 지적되었습니다.

여기서 발생한 주요 문제들을 짚어보겠습니다.

문제 상황 1: 에이전트 수 (Static Agent Allocation)

Jenkins는 기본적으로 작업을 처리하기 위해 고정된 에이전트를 사용하는데, 이 경우 에이전트 수를 동적으로 조정할 수 없어 자원이 낭비되거나 부족해질 수 있습니다.

Kubernetes와 통합된 Jenkins 환경에서는 이 문제를 해결할 수 있습니다.

해결책: Jenkins Kubernetes Plugin 사용

Jenkins Kubernetes Plugin을 사용하면 Jenkins 에이전트가 Kubernetes Pod에서 동적으로 생성되고, 필요할 때마다 삭제됩니다.

이를 통해 작업의 수요에 맞게 자동으로 에이전트 수를 조절할 수 있습니다.

apiVersion: batch/v1
kind: Job
metadata:
  name: jenkins-agent
spec:
  template:
    spec:
      containers:
        - name: jenkins-agent
          image: jenkins/inbound-agent:latest
          imagePullPolicy: Always
          volumeMounts:
            - mountPath: /home/jenkins/agent
              name: agent-volume
      restartPolicy: Never
  volumes:
    - name: agent-volume
      emptyDir: {}

이 YAML 파일은 Kubernetes에서 Jenkins 에이전트를 위한 Pod를 동적으로 생성하는 설정을 보여줍니다.

이를 통해 에이전트를 유동적으로 배치할 수 있습니다.

문제 상황 2: 리소스 관리 (Resource Waste)

고정된 인스턴스를 사용하게 되면, 리소스를 효율적으로 사용하지 못하게 됩니다.
Kubernetes와 Jenkins의 통합을 통해 이 문제를 해결할 수 있습니다.

해결책: Pod 리소스 요청 및 제한 설정

Kubernetes는 각 Pod에 대해 리소스 요청 및 제한을 설정할 수 있습니다.

이를 통해 각 Jenkins 에이전트가 필요한 리소스를 최소화하고, 동시에 리소스를 낭비하지 않도록 할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
    - name: jenkins-agent
      image: jenkins/inbound-agent:latest
      resources:
        requests:
          memory: "512Mi"
          cpu: "500m"
        limits:
          memory: "1Gi"
          cpu: "1"

위 코드에서 requests는 해당 Pod가 최소한으로 요구하는 리소스이고, limits는 Pod가 사용할 수 있는 최대 리소스입니다.

이를 통해 리소스 낭비를 줄일 수 있습니다.

문제 상황 3: 작업 실행의 집중 (Load Balancing)

모든 작업이 동일한 인스턴스에서 실행되면 특정 인스턴스에 과부하가 걸리거나 대기 시간이 길어질 수 있습니다.

해결책: Kubernetes Horizontal Pod Autoscaling (HPA)

Kubernetes에서 Horizontal Pod Autoscaling을 사용하면 부하에 따라 자동으로 Pod 수를 조정할 수 있습니다.

이를 통해 Jenkins 작업이 분산되고, 리소스 활용을 최적화할 수 있습니다.

apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
  name: jenkins-agent-hpa
  namespace: default
spec:
  scaleTargetRef:
    apiVersion: apps/v1
    kind: Deployment
    name: jenkins-agent
  minReplicas: 1
  maxReplicas: 10
  metrics:
    - type: Resource
      resource:
        name: cpu
        target:
          type: Utilization
          averageUtilization: 50

이 코드는 CPU 사용량을 기준으로 자동으로 Pod 수를 조정하는 HPA 설정입니다.

이를 통해 과부하를 방지하고, 작업을 분산시킬 수 있습니다.

문제 상황 4: DIND (Docker in Docker) 보안 문제

Docker in Docker 구조는 보안상 취약점이 있을 수 있습니다.
이 문제는 Docker가 포함된 Jenkins 에이전트를 사용할 때 발생할 수 있습니다.

해결책: Docker Socket 사용 (보안 고려)

DIND 대신 Docker socket을 공유하여 보안 문제를 해결할 수 있습니다.

Docker socket을 Pod에서 공유하여 컨테이너가 호스트 시스템의 Docker 엔진과 상호작용할 수 있게 합니다.

이렇게 하면 Docker in Docker 구조의 보안 이슈를 피할 수 있습니다.

apiVersion: v1
kind: Pod
metadata:
  name: jenkins-agent
spec:
  containers:
    - name: jenkins-agent
      image: jenkins/inbound-agent:latest
      volumeMounts:
        - mountPath: /var/run/docker.sock
          name: docker-socket
  volumes:
    - name: docker-socket
      hostPath:
        path: /var/run/docker.sock
        type: Socket

이 설정은 docker.sock을 Kubernetes Pod 내에서 사용할 수 있도록 공유합니다.

이를 통해 Docker 컨테이너가 호스트의 Docker 엔진에 접근할 수 있으며, 보안 이슈를 최소화할 수 있습니다.

🔍 문제 해결: Kubernetes Plugin 도입

이러한 문제를 해결하기 위해 Jenkins Kubernetes Plugin을 도입했습니다.
이 플러그인을 사용하면, 작업마다 새로운 포드를 생성할 수 있으며, 필요한 만큼의 리소스를 할당할 수 있습니다.
이 방식은 자원 낭비를 최소화하고, 고정된 리소스에 의존하지 않도록 해줍니다.

유동적 리소스 관리

Kubernetes의 자동 확장 기능을 통해 필요한 만큼의 자원을 동적으로 할당하고, 더 이상 필요 없는 리소스는 자동으로 해제할 수 있습니다.

효율적 작업 분배

Jenkins 작업을 Kubernetes 클러스터의 여러 포드로 분배하여 작업 집중 현상을 방지하고, 각 작업에 필요한 최소한의 리소스를 할당함으로써 효율성을 높입니다.

🚩 Spot Instance 활용

AWS Spot 인스턴스를 활용하면 비용 절감 효과를 극대화할 수 있습니다.
Spot 인스턴스는 정해진 시간 동안 사용할 수 있는 유휴 컴퓨팅 자원을 제공하는 서비스로, 정기적인 비용 절감이 가능하지만, 작업이 중단될 수 있는 위험이 있습니다.
이러한 중단 가능성에도 불구하고, 비용 효율성을 고려할 때 AWS Spot 인스턴스는 매우 유용한 선택입니다.

✅ 성과 및 비용 절감

Jenkins와 Kubernetes를 활용한 개선 작업 후, Spot 인스턴스를 사용해 총 비용을 77% 절감할 수 있었습니다.

고정 인스턴스를 사용할 때와 비교하여 사용 시간도 41% 줄어들었고, 자원 관리가 최적화되어 비용 효율성이 대폭 향상되었습니다.

이처럼 CI/CD 환경에서의 비용 절감을 위해서는 자원을 효율적으로 관리하고, 유연하게 대응하는 것이 중요합니다.

Kubernetes의 자동 확장과 Spot 인스턴스 활용을 통해 더욱 효과적인 시스템 자원 운영이 가능하다는 점을 깨달을 수 있었습니다.

결론

Jenkins와 Kubernetes의 통합을 통해 비용 효율적이고 유연한 CI/CD 환경을 구축할 수 있다는 것을 배웠습니다.

기존의 고정된 리소스 구조에서 발생하던 문제를 해결하고, 유동적 리소스 할당과 비용 절감을 통해 더 나은 성과를 이끌어낼 수 있었습니다.

AWS Spot 인스턴스를 활용한 비용 절감과 Kubernetes Plugin을 통한 리소스 최적화는 CI/CD 환경을 개선하는 중요한 전략입니다.

백엔드 개발자나 CI/CD 파이프라인을 개선하고자 하는 개발자라면 이 방법을 참고하여 실무에 적용해보세요!

profile
에러가 나도 괜찮아 — 그건 내가 배우고 있다는 증거야.

0개의 댓글