k8s

Native K8s + Jenkins, Ansible (1)

자바바라 2025. 2. 11. 21:43

기본 전제 조건:

  • Kubernetes 클러스터 (예: minikube, kind, managed Kubernetes 서비스)
  • Jenkins 설치 (Kubernetes 플러그인을 사용하여 Kubernetes 클러스터 내에 설치 권장)
  • Ansible 설치 (Jenkins 서버 또는 별도의 서버에 설치)
  • kubectl, ssh, git 등 필요한 도구 설치
  • Jenkins와 Ansible 간의 인증 설정 (예: SSH 키)

시나리오 1: Kubernetes 애플리케이션 빌드, 테스트 및 배포

개요:
소스 코드 변경 시 Jenkins가 트리거되어 애플리케이션을 빌드, 테스트하고, Docker 이미지를 생성하여 Kubernetes 클러스터에 배포합니다. Ansible은 Kubernetes 매니페스트 (YAML 파일)를 관리하고 배포를 자동화합니다.

단계:

  1. 소스 코드 변경 감지 (Jenkins):
    • Jenkinsfile (Declarative Pipeline) 예시:
      pipeline {
          agent any
          triggers {
              gitHub(credentialsId: 'github-credentials', triggerOnPush: true)
          }
          stages {
              stage('Checkout') {
                  steps {
                      git branch: 'main', url: 'https://github.com/your-repo/your-app.git'
                  }
              }
          }
      }
       
  2. 빌드 (Jenkins):
    • Jenkinsfile 예시:
      stage('Build') {
          steps {
              sh 'mvn clean package' // Maven 빌드 예시
          }
      }
       
  3. 테스트 (Jenkins):
    • Jenkinsfile 예시:
      stage('Test') {
          steps {
              sh 'mvn test' // JUnit 테스트 예시
          }
      }
       
  4. Docker 이미지 빌드 및 Push (Jenkins):
    • Jenkinsfile 예시:
      stage('Docker Build & Push') {
          steps {
              script {
                  docker.build("your-dockerhub-username/your-app:${env.BUILD_NUMBER}").push()
              }
          }
      }
       
  5. Kubernetes 매니페스트 업데이트 (Ansible):
    • Ansible Playbook (deploy.yml) 예시:
      - hosts: localhost
        tasks:
          - name: Update image tag in Kubernetes deployment
            replace:
              path: k8s/deployment.yaml
              regexp: 'image: your-dockerhub-username/your-app:.*'
              replace: "image: your-dockerhub-username/your-app:${BUILD_NUMBER}"
       
    • Jenkinsfile에서 Ansible 실행:
      stage('Update Manifest') {
        steps{
          ansiblePlaybook(
            playbook: 'deploy.yml',
            inventory: 'localhost,' // single host comma-separated.
          )
        }
      }
       
  6. Kubernetes 배포 (Ansible 또는 kubectl):
    • Ansible 사용:
      - hosts: localhost # 또는 Kubernetes 마스터 노드
        tasks:
          - name: Deploy to Kubernetes
            k8s:
              state: present
              src: k8s/
       
    • kubectl 사용 (Jenkinsfile):
      stage('Deploy') {
          steps {
              sh 'kubectl apply -f k8s/'
          }
      }
      Use code with caution.Groovy

시나리오 2: Kubernetes 인프라 프로비저닝 (Terraform + Ansible)

개요:
Terraform을 사용하여 Kubernetes 클러스터 (예: AWS EKS, GCP GKE, Azure AKS)를 프로비저닝하고, Ansible을 사용하여 클러스터 구성 (예: 노드 레이블, 네트워크 정책)을 관리합니다. Jenkins는 이 과정을 자동화합니다.

단계:

  1. Terraform 코드 실행 (Jenkins):
    • Jenkinsfile 예시:
      stage('Terraform Apply') {
          steps {
              sh 'terraform init'
              sh 'terraform apply -auto-approve'
          }
      }
       
  2. Kubernetes 클러스터 정보 가져오기 (Jenkins):
    • Terraform output을 사용하여 kubeconfig 파일 경로 등을 Jenkins 환경 변수로 설정합니다.
  3. Ansible Playbook 실행 (Jenkins):
    • Ansible Playbook (configure_cluster.yml) 예시:
      - hosts: all # 또는 특정 노드 그룹
        become: true # 필요한 경우 sudo 권한 사용
        tasks:
          - name: Add node labels
            k8s:
              kind: Node
              name: "{{ inventory_hostname }}"
              merge_type: strategic
              resource_definition:
                metadata:
                  labels:
                    node-type: worker
       
    • Jenkinsfile:
      stage('Configure Cluster') {
        steps {
            ansiblePlaybook(
                playbook: 'configure_cluster.yml',
                inventory: 'dynamic_inventory.py', // 동적 인벤토리 사용 (예: AWS, GCP)
                extraVars: [
                    kubeconfig: "${KUBECONFIG_PATH}"  // Terraform output에서 가져온 kubeconfig
                ]
            )
          }
      }
       

시나리오 3: Kubernetes 리소스 관리 (Helm + Ansible)

개요:
Helm을 사용하여 Kubernetes 애플리케이션 (차트)을 패키징하고, Ansible을 사용하여 Helm 차트 배포 및 관리를 자동화합니다. Jenkins는 이 파이프라인을 트리거하고 실행합니다.

단계:

  1. Helm 차트 패키징 (Jenkins):
    • Jenkinsfile:
      stage('Helm Package') {
          steps {
              sh 'helm package ./my-chart'
          }
      }
       
  2. Helm 차트 저장소에 업로드 (Jenkins):
    • (선택 사항) ChartMuseum 또는 다른 Helm 저장소를 사용하는 경우, Jenkins에서 차트를 업로드합니다.
  3. Ansible Playbook 실행 (Jenkins):
    • Ansible Playbook (deploy_chart.yml) 예시:
      - hosts: localhost
        tasks:
          - name: Deploy Helm chart
            helm:
              name: my-app
              chart: ./my-chart-0.1.0.tgz # 패키징된 차트 경로
              state: present
       

Jenkinsfile:

stage('Helm Deploy') {
      steps{
        ansiblePlaybook(
          playbook: 'deploy_chart.yml',
          inventory: 'localhost,',
        )
      }
    }

 


시나리오 4: Kubernetes 클러스터 업그레이드

개요:
Ansible을 사용하여 Kubernetes 클러스터 (컨트롤 플레인 및 워커 노드)를 업그레이드합니다. Jenkins는 업그레이드 프로세스를 자동화하고 롤백 기능을 제공합니다.

단계:

  1. (선택 사항) 업그레이드 전 백업 (Jenkins, Ansible):
    • etcd 스냅샷, Persistent Volume 백업 등.
  2. Ansible Playbook 실행 (Jenkins):
    • Ansible Playbook (upgrade_cluster.yml)은 다음 작업을 수행할 수 있습니다.
      • 컨트롤 플레인 노드 업그레이드 (kubeadm upgrade 사용)
      • 워커 노드 드레이닝 (drain) 및 업그레이드
      • 업그레이드 후 노드 언코든 (uncordon)
      • 롤백 기능 (예: 이전 버전으로 복원)
    • Jenkinsfile:
    stage('Upgrade Cluster') {
        steps {
            ansiblePlaybook(
              playbook: 'upgrade_cluster.yml',
              inventory: 'k8s_cluster_inventory.ini' // 정적 또는 동적 인벤토리
              extraVars: [
                  kubernetes_version: "1.27.0" // 업그레이드할 버전
              ]
            )
        }
      }
      ```
     
  3. 업그레이드 후 검증 (Jenkins, Ansible):
    • 클러스터 상태 확인, 애플리케이션 정상 작동 여부 확인.

시나리오 5: Kubernetes 애플리케이션 롤링 업데이트

개요:
새 버전의 애플리케이션 이미지가 생성되면, Ansible을 사용하여 Kubernetes Deployment의 롤링 업데이트를 수행합니다. Jenkins는 이 과정을 자동화하고 롤백 기능을 제공합니다.

단계:

  1. 새 이미지 태그 감지 (Jenkins):
    • Docker Hub webhook, 레지스트리 이벤트 등을 사용하여 새 이미지 태그를 감지합니다.
  2. Ansible Playbook 실행 (Jenkins):
    • Ansible Playbook (rolling_update.yml) 예시:
      - hosts: localhost
        tasks:
          - name: Perform rolling update
            k8s:
              kind: Deployment
              name: my-app
              namespace: default
              definition:
                spec:
                  template:
                    spec:
                      containers:
                      - name: my-app-container
                        image: "your-dockerhub-username/your-app:${NEW_IMAGE_TAG}"
       
    • Jenkinsfile:
      groovy stage('Rolling Update') { steps { script { env.NEW_IMAGE_TAG = sh(returnStdout: true, script: 'get_new_image_tag.sh').trim() // 새 이미지 태그 가져오기 } ansiblePlaybook( playbook: 'rolling_update.yml', inventory: 'localhost,', extraVars: [ new_image_tag: "${env.NEW_IMAGE_TAG}" ] ) } }
  3. 업데이트 후 검증 (Jenkins, Ansible):
    • 새 버전의 애플리케이션 정상 작동 여부 확인, 롤아웃 상태 확인 (kubectl rollout status).
    • 필요한 경우 롤백 수행 (kubectl rollout undo).

참고 사항:

  • 위 명령어 예시는 기본적인 형태이며, 실제 환경에 맞게 수정해야 합니다.
  • Ansible의 k8s 모듈은 kubectl을 내부적으로 사용하므로, kubectl이 올바르게 설정되어 있어야 합니다.
  • Jenkins와 Ansible 간의 인증은 SSH 키, API 토큰 등 다양한 방법을 사용할 수 있습니다.
  • 동적 인벤토리 (Dynamic Inventory)를 사용하면 클라우드 환경 (AWS, GCP, Azure)의 리소스를 Ansible에서 쉽게 관리할 수 있습니다.
  • 에러 처리, 롤백 전략, 알림 (Slack, email) 등을 Jenkins 파이프라인에 추가하여 안정성을 높일 수 있습니다.
  • Secret 관리를 위해 HashiCorp Vault, Kubernetes Secrets 등을 사용하는 것이 좋습니다.

 

 

 

 

기본 전제 조건:

  • Kubernetes 클러스터 (Minikube, Kind, EKS, GKE, AKS 등) 구축 및 kubectl 설정
  • Jenkins 설치 및 Kubernetes 플러그인 설정
  • Ansible 설치 및 Kubernetes 모듈(k8s) 설치
  • Jenkins와 Ansible 서버 간 SSH 통신 설정 (선택 사항, 인증 방법에 따라 다름)

시나리오 1: Kubernetes Deployment 업데이트 (Rolling Update)

개요: 새로운 버전의 애플리케이션 이미지를 빌드하고, Kubernetes Deployment를 통해 Rolling Update 방식으로 배포합니다.

단계:

  1. Jenkins:
    • 소스 코드 변경 감지 (Git, SVN 등)
    • 새로운 애플리케이션 이미지 빌드 (Docker)
      docker build -t my-app:$BUILD_NUMBER .
      docker push my-registry/my-app:$BUILD_NUMBER
       
    • Ansible Playbook 실행 (Kubernetes 클러스터에 배포)
  2. Ansible Playbook (deploy.yml):
    • kubectl apply -f deploy.yml 대신 Ansible k8s 모듈을 사용합니다.
      - hosts: localhost # Jenkins 서버에서 실행
        become: false # sudo 권한 필요 없음
        tasks:
          - name: Update Kubernetes Deployment
            k8s:
              state: present
              definition:
                apiVersion: apps/v1
                kind: Deployment
                metadata:
                  name: my-app
                spec:
                  replicas: 3
                  selector:
                    matchLabels:
                      app: my-app
                  template:
                    metadata:
                      labels:
                        app: my-app
                    spec:
                      containers:
                        - name: my-app
                          image: "my-registry/my-app:{{ lookup('env', 'BUILD_NUMBER') }}" # Jenkins 변수 사용
                          ports:
                            - containerPort: 8080
       
  3. Jenkins:
    • 배포 성공 여부 확인 및 알림 (Slack, Email 등)

시나리오 2: Kubernetes 리소스 생성 및 관리 (ConfigMap, Secret)

개요: 애플리케이션 설정 (ConfigMap) 및 민감 정보 (Secret)를 Kubernetes 리소스로 생성하고 관리합니다.

단계:

  1. Jenkins:
    • 설정 파일 변경 감지 (Git, 별도 저장소 등)
    • Ansible Playbook 실행 (ConfigMap, Secret 생성/업데이트)
  2. Ansible Playbook (config.yml):
    - hosts: localhost
      become: false
      tasks:
        - name: Create/Update ConfigMap
          k8s:
            state: present
            definition:
              apiVersion: v1
              kind: ConfigMap
              metadata:
                name: my-app-config
              data:
                app.properties: |
                  key1=value1
                  key2=value2
        - name: Create/Update Secret
          k8s:
            state: present
            definition:
              apiVersion: v1
              kind: Secret
              metadata:
                name: my-app-secret
              type: Opaque
              stringData: # stringData를 사용하면 base64 인코딩 불필요
                db_password: mysecretpassword
     
  3. Jenkins:
    • 리소스 생성/업데이트 성공 여부 확인

시나리오 3: Kubernetes Namespace 생성 및 관리

개요: 개발, 테스트, 스테이징 등 환경별로 Kubernetes Namespace를 생성하고 관리합니다.

단계:

  1. Jenkins:
    • 환경 변수 (예: ENVIRONMENT=dev) 설정
    • Ansible Playbook 실행 (Namespace 생성/삭제)
  2. Ansible Playbook (namespace.yml):
    - hosts: localhost
      become: false
      tasks:
        - name: Create/Update Namespace
          k8s:
            state: present # 또는 absent (삭제)
            definition:
              apiVersion: v1
              kind: Namespace
              metadata:
                name: "{{ lookup('env', 'ENVIRONMENT') }}" # Jenkins 환경 변수 사용
     
  3. Jenkins:
    • Namespace 생성/삭제 성공 여부 확인

시나리오 4: Kubernetes CronJob을 이용한 배치 작업 실행

개요: 정해진 시간에 특정 작업을 수행하는 Kubernetes CronJob을 생성하고 관리합니다.

단계:

  1. Jenkins:
    • CronJob 스케줄 변경 감지 (Git, 설정 파일 등)
    • Ansible Playbook 실행 (CronJob 생성/업데이트)
  2. Ansible Playbook (cronjob.yml):
    - hosts: localhost
      become: false
      tasks:
        - name: Create/Update CronJob
          k8s:
            state: present
            definition:
              apiVersion: batch/v1
              kind: CronJob
              metadata:
                name: my-batch-job
              spec:
                schedule: "0 0 * * *" # 매일 자정에 실행
                jobTemplate:
                  spec:
                    template:
                      spec:
                        containers:
                        - name: my-batch-container
                          image: my-batch-image:latest
                          command: ["/bin/sh", "-c", "my-batch-script.sh"]
                        restartPolicy: OnFailure
     
  3. Jenkins:
    • CronJob 생성/업데이트 성공 여부 확인

시나리오 5: Kubernetes Ingress를 이용한 외부 접근 설정

개요: 외부에서 애플리케이션에 접근할 수 있도록 Kubernetes Ingress를 설정하고 관리합니다. (Ingress Controller 필요)

단계:

  1. Jenkins:
    • Ingress 설정 변경 감지 (Git, 설정 파일 등)
    • Ansible Playbook 실행 (Ingress 생성/업데이트)
  2. Ansible Playbook (ingress.yml):
    - hosts: localhost
      become: false
      tasks:
        - name: Create/Update Ingress
          k8s:
            state: present
            definition:
              apiVersion: networking.k8s.io/v1
              kind: Ingress
              metadata:
                name: my-app-ingress
                annotations:
                   kubernetes.io/ingress.class: "nginx" # 사용하는 Ingress Controller에 따라 변경
              spec:
                rules:
                - host: my-app.example.com
                  http:
                    paths:
                    - path: /
                      pathType: Prefix
                      backend:
                        service:
                          name: my-app-service # Deployment에 연결된 Service 이름
                          port:
                            number: 80
     
  3. Jenkins:
    • Ingress 생성/업데이트 성공 여부 확인

참고:

  • 위 예시들은 기본적인 형태이며, 실제 환경에서는 더 복잡한 설정과 로직이 필요할 수 있습니다.
  • Ansible Vault를 사용하여 민감 정보를 암호화하여 관리하는 것을 권장합니다.
  • Jenkins Pipeline (Declarative 또는 Scripted)을 사용하여 CI/CD 과정을 더욱 세밀하게 제어할 수 있습니다.
  • kubectl 명령어를 직접 사용하는 대신 Ansible의 k8s 모듈을 활용하여 Kubernetes 리소스를 관리하면,멱등성을 보장하고, 코드 재사용성을 높일 수 있습니다.
  • Jenkins와 Ansible의 역할을 분리하여, Jenkins는 빌드 및 테스트, Ansible은 배포 및 인프라 관리를 담당하도록 구성하는 것이 좋습니다.
  • 각 명령어들은 예시이며, 실제 환경과 필요에 맞게 수정해서 사용해야 합니다.

시나리오 2: Kubernetes ConfigMap/Secret 업데이트

 

개요: 애플리케이션 설정 (ConfigMap) 또는 민감 정보 (Secret)를 업데이트하고, 변경 사항을 애플리케이션에 적용합니다.

단계:

  1. Jenkins:
    • 설정 파일 변경: (예: 환경 변수, 데이터베이스 연결 정보 등)
    • ConfigMap/Secret 생성 또는 업데이트:
    • Ansible yaml에서 template 모듈을 사용하여 변수 치환 후, Kubernetes 모듈(k8s)로 생성/업데이트
  2. Ansible:
    - name: Update ConfigMap
      k8s:
        state: present
        src: configmap.yaml  #또는 template
    
    - name: Update Secret
      k8s:
        state: present
        src: secret.yaml  #또는 template
    
    - name: restart deployment to apply changes
      community.kubernetes.k8s_rollback:
        kind: Deployment
        name: my-app

시나리오 3: Kubernetes 리소스 (Pod, Service, Ingress 등) 관리

개요: Jenkins와 Ansible을 사용하여 Kubernetes 리소스를 생성, 삭제, 업데이트하는 작업을 자동화합니다. (예: 임시 테스트 환경 구축, 리소스 정리 등)

단계:

  1. Jenkins:
    • 작업 트리거: (예: 스케줄링, 사용자 요청 등)
    • Ansible playbook 실행: (필요한 파라미터 전달)
  2. Ansible:
    - name: Create a namespace
      k8s:
        name: test-environment
        api_version: v1
        kind: Namespace
        state: present
    
    - name: Create a deployment
      k8s:
        state: present
        src: deployment.yaml
    
    - name: Create a service
      k8s:
        state: present
        src: service.yaml
    - name: Delete resources
      k8s:
        state: absent
        src: "{{ item }}"
      with_items:
        - deployment.yaml
        - service.yaml
     

시나리오 4: Kubernetes 클러스터 상태 확인 및 알림

개요: Jenkins와 Ansible을 사용하여 Kubernetes 클러스터의 상태 (Node 상태, Pod 상태, 리소스 사용량 등)를 주기적으로 확인하고, 문제가 발생하면 알림을 보냅니다.

단계:

  1. Jenkins:
    • 주기적인 작업 실행: (예: Cron 스케줄러 사용)
    • Ansible playbook 실행:
  2. Ansible:
    - name: Get node status
      k8s_info:
        kind: Node
      register: node_status
    
    - name: Check node conditions
      fail:
        msg: "Node {{ item.metadata.name }} is not ready!"
      when: item.status.conditions | selectattr('type', 'equalto', 'Ready') | map(attribute='status') | first != 'True'
      loop: "{{ node_status.resources }}"
    
    # Pod 상태, 리소스 사용량 등 추가 확인
    
    - name: Send notification (if any issues)
      # ... (Slack, Email 등 알림 전송 로직) ...
      when: ... # 문제 발생 조건 ...
      community.general.slack:
        token: "{{ slack_token }}"
        channel: "{{ slack_channel }}"
        msg: "Kubernetes cluster issue detected!"
     

시나리오 5: Kubernetes 기반 애플리케이션 테스트 자동화

개요: Jenkins와 Ansible을 사용하여 Kubernetes 환경에서 애플리케이션 테스트 (단위 테스트, 통합 테스트, E2E 테스트 등)를 자동화합니다.

단계:

  1. Jenkins:
    • 소스 코드 체크아웃 및 빌드: (시나리오 1과 유사)
    • 테스트 환경 구축: (Ansible playbook 실행, 필요한 Kubernetes 리소스 생성)
    • 테스트 실행: (테스트 프레임워크에 맞는 명령어 실행, 예: pytest, npm test)
    • 테스트 결과 수집 및 보고:
    • 테스트 환경 정리: (Ansible playbook 실행, 임시 리소스 삭제)
  2. Ansible (테스트 환경 구축/정리):
    - name: Create test namespace
       k8s:
         name: test-environment
         api_version: v1
         kind: Namespace
         state: present
    - name: Create deployment for Test
      k8s:
          state: present
          src: test_deployment.yaml
    
     - name: clean up Test resources
       k8s:
         state: absent
         src: "{{ item }}"
       with_items:
         - test_deployment.yaml
         - test-environment/namespace.yaml
     
  3. 테스트 실행(Jenkins)
    # Pod 내에서 테스트 실행(kubectl exec)
    kubectl exec -it -n <namespace> <pod-name> -- <test command>
     

참고:

  • 위 명령어들은 예시이며, 실제 환경과 요구사항에 맞게 수정해야 합니다.
  • Ansible의 k8s 모듈은 Kubernetes API와 직접 통신하므로, 다양한 리소스를 관리하고 제어할 수 있습니다.
  • Jenkins Pipeline (Declarative 또는 Scripted)을 사용하여 CI/CD 워크플로우를 더욱 체계적으로 구성할 수 있습니다.
  • 보안을 위해 Jenkins 자격 증명 (Credentials)을 사용하여 Kubernetes 클러스터 인증 정보를 안전하게 관리해야 합니다. (Kubernetes 플러그인, HashiCorp Vault 등 활용)
  • Ansible vault를 사용하여 민감정보를 암호화하여 관리합니다.

 

기본 전제:

  • Jenkins, Ansible은 이미 설치 및 설정되어 있고, Kubernetes 클러스터와 연동되어 있습니다.
  • Jenkins에는 Kubernetes 플러그인이 설치되어 있고, 필요한 자격 증명(Credentials)이 구성되어 있습니다.
  • Ansible은 k8s 모듈을 사용하여 Kubernetes API와 통신할 수 있습니다.

시나리오 1: 애플리케이션 배포 자동화 (Deployment 업데이트)

개요: 소스 코드 변경 시 자동으로 빌드, Docker 이미지 생성, Kubernetes Deployment 업데이트를 수행합니다.

Jenkins Pipeline (Declarative):

pipeline {
    agent any
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your/repo.git'
            }
        }
        stage('Build') {
            steps {
                sh 'mvn clean package' // 예: Maven 빌드
            }
        }
        stage('Docker Build & Push') {
            steps {
                script {
                    docker.build("your-registry/your-image:${env.BUILD_TAG}")
                    docker.withRegistry('https://your-registry', 'your-registry-credentials') {
                        docker.image("your-registry/your-image:${env.BUILD_TAG}").push()
                    }
                }
            }
        }
        stage('Deploy to Kubernetes') {
            steps {
                // Ansible playbook 호출 (k8s 모듈 사용)
                ansiblePlaybook(
                    playbook: 'deploy.yaml',
                    inventory: 'inventory.ini', // Ansible inventory 파일 (Kubernetes 클러스터 정보)
                    credentialsId: 'your-kubeconfig-credentials' // Kubernetes 자격 증명
                )
            }
        }
    }
}
 

Ansible (deploy.yaml):

- name: Deploy Application
  hosts: localhost  # Kubernetes API 서버와 통신하므로 localhost
  connection: local  # 로컬 연결 사용
  tasks:
    - name: Update Deployment
      k8s:
        state: present
        src: deployment.yaml # 또는 template 모듈을 사용하여 이미지 태그 동적 변경
      register: deployment_result

    - name: print result
      debug:
        var: deployment_result
 

핵심 명령어:

  • git: 소스 코드 체크아웃
  • mvn clean package: 빌드 (예시)
  • docker build, docker push: Docker 이미지 빌드 및 푸시
  • ansiblePlaybook: Jenkins에서 Ansible playbook 실행
  • k8s: Ansible 모듈로 Kubernetes 리소스 관리 (Deployment 업데이트)

시나리오 2: ConfigMap/Secret 업데이트

개요: 애플리케이션 설정 (ConfigMap) 또는 비밀 정보 (Secret)를 업데이트하고, Deployment를 재시작하여 변경 사항을 적용합니다.

Jenkins Pipeline:

pipeline {
  agent any
  stages {
      stage('update config and restart'){
        steps{
            ansiblePlaybook(
            playbook: 'config_update.yaml',
            inventory: 'inventory.ini',
            credentialsId: 'your-kubeconfig-credentials'
            )
        }
    }
  }
}
 

Ansible (config_update.yaml):

- name: Update ConfigMap/Secret and Restart Deployment
  hosts: localhost
  connection: local
  tasks:
    - name: Update ConfigMap
      k8s:
        state: present
        src: configmap.yaml # 또는 template 모듈 사용

    - name: Update Secret
      k8s:
        state: present
        src: secret.yaml # 또는 template 모듈 사용
        # base64 encoding이 필요한 경우 to_yaml | b64encode 필터 사용

    - name: Restart Deployment
      community.kubernetes.k8s_rollback: # 또는 k8s 모듈로 rollout restart 수행
          kind: Deployment
          name: your-app-deployment
 

핵심 명령어:

  • k8s: ConfigMap/Secret 생성 또는 업데이트
  • community.kubernetes.k8s_rollback: Deployment 재시작(롤백을 이용한 재시작) 또는
  • kubectl rollout restart deployment/your-app-deployment (Jenkins에서 sh를 통해 실행)

시나리오 3: 임시 환경 생성 및 삭제

개요: 테스트 또는 개발을 위한 임시 환경 (Namespace, Deployment, Service 등)을 생성하고, 작업 완료 후 삭제합니다.

Jenkins Pipeline:

pipeline {
    agent any
    stages {
        stage('Create Environment') {
            steps {
                ansiblePlaybook(
                    playbook: 'create_env.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'your-kubeconfig-credentials'
                )
            }
        }
        stage('Run Tests') {
            steps {
                // ... 테스트 실행 ...
                sh 'kubectl exec -it -n test-env <pod-name> -- <test-command>'
            }
        }
        stage('Destroy Environment') {
            steps {
                ansiblePlaybook(
                    playbook: 'destroy_env.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'your-kubeconfig-credentials'
                )
            }
        }
    }
}
 

Ansible (create_env.yaml):

- name: Create Test Environment
  hosts: localhost
  connection: local
  tasks:
    - name: Create Namespace
      k8s:
        state: present
        name: test-env
        api_version: v1
        kind: Namespace

    - name: Create Deployment
      k8s:
        state: present
        src: test-deployment.yaml

    - name: Create Service
      k8s:
        state: present
        src: test-service.yaml
 

Ansible (destroy_env.yaml):

- name: Destroy Test Environment
  hosts: localhost
  connection: local
  tasks:
    - name: Delete Deployment
      k8s:
        state: absent
        src: test-deployment.yaml

    - name: Delete Service
      k8s:
        state: absent
        src: test-service.yaml

    - name: Delete Namespace
      k8s:
        state: absent
        name: test-env
        api_version: v1
        kind: Namespace
 

핵심 명령어:

  • k8s: Namespace, Deployment, Service 생성 및 삭제

시나리오 4: 클러스터 상태 모니터링 및 알림

개요: Kubernetes 클러스터의 상태 (Node, Pod 등)를 주기적으로 확인하고, 문제가 발생하면 알림을 보냅니다.

Jenkins Pipeline:

pipeline {
    agent any
    triggers {
        cron('H/15 * * * *') // 예: 15분마다 실행
    }
    stages {
        stage('Monitor Cluster') {
            steps {
                ansiblePlaybook(
                    playbook: 'monitor_cluster.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'your-kubeconfig-credentials'
                )
            }
        }
    }
}
 

Ansible (monitor_cluster.yaml):

- name: Monitor Kubernetes Cluster
  hosts: localhost
  connection: local
  tasks:
    - name: Get Node Status
      k8s_info:
        kind: Node
      register: node_status

    - name: Check Node Conditions
      fail:
        msg: "Node {{ item.metadata.name }} is not ready!"
      when: item.status.conditions | selectattr('type', 'equalto', 'Ready') | map(attribute='status') | first != 'True'
      loop: "{{ node_status.resources }}"
      #ignore_errors: true # fail 모듈에서 에러 무시 (필요한 경우)

    - name: Get Pod Status (예: 특정 Namespace)
      k8s_info:
        kind: Pod
        namespace: your-namespace
      register: pod_status

    - name: check pod is running
      fail:
        msg: "pod {{ item.metadata.name }} is not running"
      when: item.status.phase != "Running"
      loop: "{{ pod_status.resources }}"

    - name: Send Notification (Slack 예시)
      community.general.slack:
        token: "{{ slack_token }}"  # Jenkins Credentials 사용 권장
        channel: "{{ slack_channel }}"
        msg: "Kubernetes cluster issue detected!"
      when: not ansible_failed_result is skipped # 조건: 이전 task 중 실패가 있는 경우
 

핵심 명령어:

  • k8s_info: Kubernetes 리소스 정보 가져오기 (Node, Pod 등)
  • fail: 조건에 따라 작업 실패 처리
  • community.general.slack: Slack 알림 전송 (다른 알림 모듈 사용 가능)
  • when: 조건부 실행

시나리오 5: 롤링 업데이트 및 롤백

개요: 새로운 버전의 애플리케이션을 롤링 업데이트 방식으로 배포하고, 문제가 발생하면 이전 버전으로 롤백합니다.

Jenkins Pipeline:

pipeline {
  agent any
  stages {
    stage('rolling update'){
      steps{
        ansiblePlaybook(
          playbook: "rolling_update.yaml",
          inventory: 'inventory.ini',
          credentialsId: 'your-kubeconfig-credentials'
        )
      }
    }
  }
}
 

Ansible (rolling_update.yaml):

- name: Perform Rolling Update
  hosts: localhost
  connection: local
  tasks:
    - name: Update Deployment (Rolling Update)
      k8s:
        state: present
        src: deployment.yaml # 새 이미지 태그를 포함하는 deployment 파일
        strategy:
          type: RollingUpdate # 롤링 업데이트 전략 명시 (생략 시 기본값)
          rollingUpdate:
            maxSurge: 25%       # 최대 추가 Pod 수 (기본값)
            maxUnavailable: 25% # 최대 사용 불가 Pod 수 (기본값)

    # (선택 사항) 롤백
    - name: Rollback Deployment (if needed)
      k8s:
        state: present
        src: old-deployment.yaml # 이전 버전 deployment 파일
      when: ... # 롤백 조건 (예: 테스트 실패, 모니터링 지표 이상 등)
      # 또는 k8s_rollback 모듈 사용
 

핵심 명령어:

  • k8s: strategy.type: RollingUpdate 설정으로 롤링 업데이트 수행
  • when: rollback 조건 설정
  • k8s_rollback: 롤백

핵심 요약:

  • Jenkins Pipeline을 사용하여 CI/CD 워크플로우를 정의합니다.
  • Ansible playbook을 호출하여 Kubernetes 리소스를 관리합니다. (k8s, k8s_info, k8s_rollback 등 모듈 사용)
  • Jenkins Credentials를 사용하여 Kubernetes 클러스터 및 기타 서비스 (Docker registry, Slack 등) 인증 정보를 안전하게 관리합니다.
  • Ansible의 when 조건을 사용하여 조건부 실행 (예: 롤백, 알림)을 구현합니다.
  • 필요에 따라 Ansible의 template 모듈을 사용하여 설정 파일 (deployment.yaml, configmap.yaml 등)을 동적으로 생성합니다.

이 핵심 시나리오들을 바탕으로, 필요에 따라 세부 단계를 추가하거나 수정하여 실제 환경에 맞는 CI/CD 파이프라인을 구축할 수 있습니다.

 


 

기본 전제:

  • Jenkins, Ansible, kubectl 설치 및 설정 완료
  • Jenkins에 Kubernetes 플러그인 및 필요한 자격 증명(Credentials) 구성
  • Ansible에서 k8s 모듈 사용 가능

시나리오 1: 애플리케이션 배포 및 롤링 업데이트

개요:

  1. 코드 변경 감지: Jenkins가 Git 저장소의 코드 변경을 감지합니다.
  2. 빌드 및 테스트: 코드를 빌드하고, 단위/통합 테스트를 실행합니다.
  3. Docker 이미지 생성 및 푸시: 새로운 Docker 이미지를 빌드하고, 이미지 저장소(Registry)에 푸시합니다.
  4. Kubernetes 배포: Ansible Playbook을 사용하여 Kubernetes Deployment를 생성하거나 업데이트합니다 (롤링 업데이트 전략 사용).
  5. (선택 사항) 롤백: 배포 중 문제 발생 시, 이전 버전으로 롤백합니다.

Jenkins Pipeline (Declarative):

pipeline {
    agent any
    triggers {
        git 'https://github.com/your/repo.git' // 또는 SCM Trigger 사용
    }
    stages {
        stage('Build & Test') {
            steps {
                sh 'mvn clean install' // 예시: Maven
                // ... 테스트 실행 ...
            }
        }
        stage('Docker Build & Push') {
            steps {
                script {
                    def imageName = "your-registry/your-image:${env.BUILD_TAG}"
                    docker.build(imageName)
                    docker.withRegistry('https://your-registry', 'registry-credentials') {
                        docker.image(imageName).push()
                    }
                }
            }
        }
        stage('Deploy') {
            steps {
                ansiblePlaybook(
                    playbook: 'deploy.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
        // (선택 사항) Rollback Stage
    }
    post {
        failure {
            // 롤백 로직 (Ansible Playbook 호출 등)
        }
    }
}
 

Ansible Playbook (deploy.yaml):

- name: Deploy Application
  hosts: localhost
  connection: local
  tasks:
    - name: Create or Update Deployment
      k8s:
        state: present
        src: deployment.yaml  # 또는 template 모듈 사용
        strategy:
          type: RollingUpdate
          rollingUpdate:
            maxSurge: 1
            maxUnavailable: 0 # 무중단 배포를 위한 설정 예시
 

핵심 명령어:

  • git: 코드 변경 감지 (Jenkins Trigger)
  • sh 'mvn clean install': 빌드 및 테스트 (예시)
  • docker build, docker push: Docker 이미지 관리
  • ansiblePlaybook: Ansible Playbook 호출 (Jenkins)
  • k8s: Kubernetes 리소스 관리 (Ansible)
    • state: present: 리소스 생성 또는 업데이트
    • strategy: RollingUpdate: 롤링 업데이트 전략 설정

시나리오 2: 애플리케이션 스케일링 (Auto Scaling)

개요:

  1. 모니터링: Jenkins가 애플리케이션의 메트릭 (CPU 사용량, 메모리 사용량 등)을 모니터링합니다. (Prometheus, Grafana 등 연동)
  2. 스케일링 조건 확인: 메트릭이 임계값을 초과하거나 미달하는지 확인합니다.
  3. Ansible Playbook 실행: 스케일링 조건을 만족하면, Ansible Playbook을 실행하여 Kubernetes Horizontal Pod Autoscaler (HPA)를 생성하거나 업데이트합니다. 또는 직접 replica 개수를 조정합니다.
  4. (선택 사항) 스케일 다운: 부하 감소 시 스케일 다운

Jenkins Pipeline:

pipeline {
    agent any
    triggers {
        cron('*/5 * * * *') // 5분마다 실행 (예시)
    }
    stages {
        stage('Check Metrics') {
            steps {
                // 메트릭 확인 로직 (Prometheus 쿼리 등)
                // 임계값 초과/미달 여부 판단 -> 변수 설정 (scaleUp, scaleDown)
                script{
                    env.SCALE_UP = sh(returnStdout: true, script: '...').trim() // true or false
                }

            }
        }
        stage('Scale Up') {
           when {
                expression { env.SCALE_UP == 'true' }
            }
            steps {
                ansiblePlaybook(
                    playbook: 'scale_up.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
        // Scale Down Stage (when 조건: scaleDown == 'true')
    }
}
 

Ansible Playbook (scale_up.yaml - HPA 사용):

- name: Scale Up Application (HPA)
  hosts: localhost
  connection: local
  tasks:
    - name: Create or Update HPA
      k8s:
        state: present
        src: hpa.yaml # HPA 설정 파일
 

Ansible Playbook (scale_up.yaml - 직접 replica 조정):

- name: direct scale deployment
  hosts: localhost
  connection: local
  tasks:
    - name: scale up
      community.kubernetes.k8s_scale:
        kind: Deployment
        name: <deployment name>
        namespace: <namespace>
        replicas: 5
 

핵심 명령어:

  • cron: 주기적인 작업 실행 (Jenkins Trigger)
  • script: Jenkins에서 Groovy 스크립트 실행 (메트릭 확인, 변수 설정)
  • when: 조건부 Stage 실행 (Jenkins)
  • ansiblePlaybook: Ansible Playbook 호출
  • k8s: HPA 생성 또는 업데이트 (Ansible)
  • community.kubernetes.k8s_scale : replica 개수 조정

시나리오 3: Kubernetes 리소스 백업 및 복원

개요:

  1. 주기적인 백업: Jenkins가 주기적으로 (또는 이벤트 기반으로) Ansible Playbook을 실행합니다.
  2. Ansible Playbook:
    • k8s_info 모듈을 사용하여 백업할 리소스(Deployment, Service, ConfigMap, PersistentVolumeClaim 등) 정보를 가져옵니다.
    • 리소스 정보를 YAML 파일로 저장합니다. (또는 Velero, Kopia 등 백업 도구 사용)
    • 백업 파일을 저장소(S3, NFS 등)에 업로드합니다.
  3. (선택 사항) 복원: 필요 시, 백업 파일을 사용하여 Kubernetes 리소스를 복원합니다.

Jenkins Pipeline:

pipeline {
    agent any
    triggers {
        cron('0 0 * * *') // 매일 자정에 실행 (예시)
    }
    stages {
        stage('Backup') {
            steps {
                ansiblePlaybook(
                    playbook: 'backup.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
        // (선택 사항) Restore Stage
    }
}
 

Ansible Playbook (backup.yaml):

- name: Backup Kubernetes Resources
  hosts: localhost
  connection: local
  tasks:
    - name: Get Deployment Info
      k8s_info:
        kind: Deployment
        namespace: your-namespace
      register: deployments

    - name: Save Deployment YAML
      copy:
        content: "{{ item | to_nice_yaml }}"
        dest: "/backup/{{ item.metadata.name }}-{{ lookup('pipe', 'date +%Y%m%d%H%M%S') }}.yaml"
      loop: "{{ deployments.resources }}"

    # 다른 리소스 (Service, ConfigMap, PVC 등)에 대해서도 동일하게 처리

    - name: Upload Backup Files
      # ... (S3, NFS 등에 업로드하는 로직) ...
      # 예: aws_s3 모듈 사용
      aws_s3:
        bucket: your-backup-bucket
        object: "/kubernetes/{{ lookup('pipe', 'date +%Y%m%d') }}/{{ item | basename }}"
        src: "{{ item }}"
        mode: put
      with_fileglob:
        - "/backup/*.yaml"
 

Ansible Playbook (restore.yaml - 예시):

- name: Restore Resources
  hosts: localhost
  connection: local
  tasks:
  - name: restore deployment
    k8s:
      state: present
      src: /path/to/your/backup/file.yaml
 

핵심 명령어:

  • cron: 주기적인 작업 실행 (Jenkins Trigger)
  • ansiblePlaybook: Ansible Playbook 호출
  • k8s_info: Kubernetes 리소스 정보 가져오기 (Ansible)
  • copy: 리소스 정보를 YAML 파일로 저장 (Ansible)
  • aws_s3 (또는 다른 스토리지 관련 모듈): 백업 파일 업로드 (Ansible)
  • k8s: state: present, src: 복원 (Ansible, 복원 시)

참고:

  • 위 예시들은 기본적인 흐름을 보여주기 위한 것이며, 실제 환경에 맞게 수정해야 합니다.
  • 보안을 위해 Jenkins Credentials를 적극적으로 활용하고, Ansible Playbook에서 민감한 정보는 암호화(Ansible Vault)하여 관리하는 것이 좋습니다.
  • 복잡한 백업/복원 시나리오의 경우, Velero 또는 Kopia와 같은 전문적인 Kubernetes 백업 도구를 사용하는 것을 고려해 보세요.
  • 스케일링의 경우, 단순히 HPA를 사용하는 것 외에도, Cluster Autoscaler와 연동하여 Node 자체를 스케일링하는 것도 고려할 수 있습니다.
  • 롤백의 경우 k8s_rollback 모듈을 사용하는 것 외에, 이전 버전 deployment.yaml파일을 보관하고 있다가 사용하는 방식을 고려할 수도 있습니다.

이 시나리오들을 기반으로, Kubernetes 환경에서 필요한 다양한 자동화 작업을 Jenkins Pipeline과 Ansible Playbook을 결합하여 효율적으로 수행할 수 있습니다.

 


 

시나리오 11: Kubernetes Namespace 관리 자동화

개요:

  • 목적: 개발팀, 프로젝트, 환경(dev, staging, prod) 별로 Namespace를 자동으로 생성/삭제하고, 필요한 설정(ResourceQuota, LimitRange, NetworkPolicy 등)을 적용합니다.
  • Jenkins: 사용자 입력(파라미터) 또는 외부 이벤트(Git webhook 등)를 받아 Namespace 생성/삭제 작업을 트리거합니다.
  • Ansible: k8s 모듈을 사용하여 Namespace 및 관련 리소스를 생성/삭제/관리합니다.

Jenkins Pipeline:

pipeline {
    agent any
    parameters {
        string(name: 'NAMESPACE', defaultValue: 'dev-team-a', description: 'Namespace to create/delete')
        choice(name: 'ACTION', choices: ['create', 'delete'], description: 'Action to perform')
    }
    stages {
        stage('Manage Namespace') {
            steps {
                ansiblePlaybook(
                    playbook: "${params.ACTION}_namespace.yaml", // create_namespace.yaml 또는 delete_namespace.yaml
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials',
                    extraVars: [namespace: params.NAMESPACE] // Ansible에 변수 전달
                )
            }
        }
    }
}
 

Ansible (create_namespace.yaml):

- name: Create Namespace
  hosts: localhost
  connection: local
  vars:
    namespace: "{{ namespace }}" # Jenkins에서 전달받은 변수
  tasks:
    - name: Create Namespace
      k8s:
        state: present
        name: "{{ namespace }}"
        api_version: v1
        kind: Namespace

    - name: Create ResourceQuota (optional)
      k8s:
        state: present
        src: "{{ namespace }}-resourcequota.yaml" # 또는 template

    - name: create network policy(optional)
      k8s:
        state: present
        src: "{{ namespace }}-netpol.yaml"
 

Ansible (delete_namespace.yaml):

- name: Delete Namespace
  hosts: localhost
  connection: local
  vars:
    namespace: "{{ namespace }}"
  tasks:
    - name: Delete Namespace
      k8s:
        state: absent
        name: "{{ namespace }}"
        api_version: v1
        kind: Namespace
 

핵심 명령어:

  • parameters: Jenkins Pipeline 파라미터 정의
  • ansiblePlaybook: extraVars를 사용하여 Ansible에 변수 전달
  • k8s: Namespace 및 관련 리소스 관리 (state: present, state: absent)

시나리오 12: CI/CD 파이프라인에서 Kubernetes Job 실행

개요:

  • 목적: 데이터베이스 마이그레이션, 배치 처리, 일회성 작업 등 Kubernetes Job을 사용하여 CI/CD 파이프라인의 일부로 실행합니다.
  • Jenkins: 빌드, 테스트 후 Job 실행을 트리거하고, Job의 성공/실패 여부를 확인합니다.
  • Ansible: k8s 모듈을 사용하여 Job을 생성하고, 상태를 추적합니다.

Jenkins Pipeline:

pipeline {
    agent any
    stages {
        stage('Run Database Migration') {
            steps {
                ansiblePlaybook(
                    playbook: 'run_db_migration.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
    }
}
 

Ansible (run_db_migration.yaml):

- name: Run Database Migration Job
  hosts: localhost
  connection: local
  tasks:
    - name: Create Job
      k8s:
        state: present
        src: db-migration-job.yaml # Job 정의 YAML 파일
      register: job_result

    - name: Wait for Job to complete
      k8s_info:
        kind: Job
        namespace: "{{ job_result.metadata.namespace }}"
        name: "{{ job_result.metadata.name }}"
      register: job_status
      until: job_status.resources[0].status.succeeded is defined and job_status.resources[0].status.succeeded > 0 or job_status.resources[0].status.failed is defined and  job_status.resources[0].status.failed > 0
      retries: 60 # 최대 재시도 횟수
      delay: 10   # 재시도 간격 (초)

    - name: Fail if Job failed
      fail:
        msg: "Database migration Job failed!"
      when: job_status.resources[0].status.failed is defined and job_status.resources[0].status.failed > 0
 

핵심 명령어:

  • k8s: Job 생성 (state: present)
  • k8s_info: Job 상태 추적
  • until, retries, delay: 조건이 만족될 때까지 반복 (Job 완료 대기)
  • fail: Job 실패 시 파이프라인 실패 처리

시나리오 13: Helm Chart 배포 자동화

개요:

  • 목적: Helm Chart를 사용하여 애플리케이션 및 관련 리소스를 패키징하고, Jenkins를 통해 배포/업데이트/롤백을 자동화합니다.
  • Jenkins: Helm CLI를 사용하여 Chart를 배포/관리합니다. (Ansible의 helm 모듈 사용 가능)
  • Helm: 애플리케이션 배포 및 관리를 위한 패키지 매니저

Jenkins Pipeline:

pipeline {
    agent any
    stages {
        stage('Deploy with Helm') {
            steps {
                script{
                    // helm repo add, update 등 (필요한 경우)
                    sh 'helm repo add stable https://charts.helm.sh/stable'
                    sh 'helm repo update'
                    sh 'helm upgrade --install my-release stable/nginx-ingress -f values.yaml --namespace my-namespace --create-namespace'
                }

            }
        }
           stage('Rollback (if needed)') {
                when {
                   expression { /* 롤백 조건 */ }
                }
                steps {
                    sh 'helm rollback my-release <REVISION>'
                }
            }
    }
}
 

핵심 명령어:

  • sh 'helm ...': Helm CLI 명령어 실행 (Jenkins)
    • helm repo add: Helm repository 추가
    • helm repo update: Helm repository 업데이트
    • helm upgrade --install: Chart 설치 또는 업그레이드
    • helm rollback: 이전 버전으로 롤백
  • Ansible helm 모듈 사용 예시
- name: install helm chart
  community.kubernetes.helm:
    name: my-release
    chart_ref: stable/nginx-ingress
    release_namespace: my-namespace
    create_namespace: true
    values_files:
     - values.yaml

 


시나리오 14: Istio/Linkerd (Service Mesh)를 사용한 트래픽 관리

개요:

  • 목적: Istio 또는 Linkerd와 같은 Service Mesh를 사용하여 트래픽 관리(카나리 배포, A/B 테스트, 트래픽 미러링 등)를 자동화합니다.
  • Jenkins: Istio/Linkerd CLI (istioctl, linkerd) 또는 Kubernetes API를 통해 VirtualService, DestinationRule 등 Service Mesh 리소스를 관리합니다.
  • Ansible: k8s 모듈 또는 Service Mesh 관련 모듈을 사용하여 리소스를 생성/업데이트합니다.

Jenkins Pipeline (Istio 예시):

pipeline {
    agent any
    stages {
        stage('Deploy Canary') {
            steps {
            script{
                sh 'istioctl install --set profile=demo -y' # istio 설치 예시, 이미 설치되어 있다면 생략
                sh 'kubectl label namespace default istio-injection=enabled' # istio sidecar 자동 주입 설정 예시, 이미 설정되어 있다면 생략.
                sh 'kubectl apply -f virtual-service-canary.yaml' # istio virtual service 설정
                // ... 트래픽 비율 조정 ...
            }
            }
        }
    }
}
 

Ansible (Istio 예시):

- name: Deploy Canary with Istio
  hosts: localhost
  connection: local
  tasks:
    - name: Create VirtualService
      k8s:
        state: present
        src: virtual-service-canary.yaml # VirtualService 정의 YAML
    - name: create destination rule
      k8s:
          state: present
          src: destination-rule-canary.yaml
 

핵심 명령어:

  • istioctl (Istio CLI) 또는 linkerd (Linkerd CLI)
  • kubectl apply: Istio/Linkerd 리소스 배포
  • k8s: Service Mesh 리소스 관리 (Ansible)

시나리오 15: Jenkins Agent (Pod) 동적 프로비저닝

개요:

  • 목적: Kubernetes 플러그인을 사용하여 Jenkins 빌드 작업에 필요한 Agent(Pod)를 동적으로 생성하고, 작업 완료 후 자동으로 삭제합니다.
  • Jenkins: Kubernetes 플러그인 설정 (Pod Template, Container Template 등)
  • Kubernetes: Jenkins Master가 요청하는 Pod를 생성/삭제

Jenkins Pipeline (Declarative, Kubernetes 플러그인 사용):

pipeline {
    agent {
        kubernetes { // Kubernetes 플러그인 사용
            label 'my-jenkins-agent'
            yaml """
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: jnlp
    image: jenkins/inbound-agent:latest
    args: ['\$(JENKINS_SECRET)', '\$(JENKINS_NAME)']
  - name: maven
    image: maven:3.8.1-adoptopenjdk-11
    command: ['cat']
    tty: true

"""
        }
    }
    stages {
        stage('Build') {
            steps {
                container('maven') { // 'maven' 컨테이너에서 실행
                    sh 'mvn clean package'
                }
            }
        }
    }
}
 

핵심 설정:

  • agent { kubernetes ... }: Kubernetes 플러그인을 사용하여 Agent 정의
    • label: Agent를 식별하는 레이블
    • yaml: Pod Template 정의 (여러 컨테이너 정의 가능)
  • container('container-name'): 특정 컨테이너 내에서 steps 실행

 

시나리오 16: 지능형 배포 및 자동 롤백 (with Prometheus & Grafana)

개요:

  1. 기본 배포 자동화: 이전 시나리오와 같이 코드 변경 감지, 빌드, 테스트, Docker 이미지 생성, Kubernetes Deployment 업데이트를 수행합니다.
  2. Prometheus & Grafana 연동:
    • Jenkins는 배포 후 Prometheus 쿼리를 통해 애플리케이션의 핵심 지표(응답 시간, 에러율, 리소스 사용량 등)를 모니터링합니다.
    • Grafana 대시보드를 통해 실시간으로 지표를 시각화하고, 이상 징후를 감지합니다.
  3. 지능형 롤백:
    • Prometheus 쿼리 결과, 특정 지표가 임계값을 초과하면(예: 에러율 급증, 응답 시간 지연) Jenkins가 자동으로 이전 버전으로 롤백을 수행합니다.
    • 롤백 후에는 슬랙(Slack) 등으로 알림을 보내고, 관련 Grafana 대시보드 링크를 제공합니다.

Jenkins Pipeline:

pipeline {
    agent any
    // ... (이전 시나리오의 빌드, 테스트, Docker 이미지 생성 단계) ...

    stages {
        stage('Deploy') {
            steps {
                ansiblePlaybook(
                    playbook: 'deploy.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
        stage('Monitor & Rollback') {
            steps {
                script {
                    // Prometheus 쿼리 (예: 에러율 확인)
                    def errorRate = sh(returnStdout: true, script: """
                        curl -s "http://prometheus:9090/api/v1/query?query=sum(rate(http_requests_total{status=~'5..',job='your-app'}[5m])) / sum(rate(http_requests_total{job='your-app'}[5m]))" | jq '.data.result[0].value[1]'
                    """).trim().toDouble()

                    // 임계값 초과 여부 확인
                    if (errorRate > 0.05) { // 5% 초과 시
                        // 자동 롤백 (Ansible Playbook 호출)
                        ansiblePlaybook(
                            playbook: 'rollback.yaml',
                            inventory: 'inventory.ini',
                            credentialsId: 'kubeconfig-credentials'
                        )

                        // 슬랙 알림 (Grafana 대시보드 링크 포함)
                        slackSend(
                            channel: '#your-channel',
                            color: 'danger',
                            message: "Automatic rollback triggered! Error rate: ${errorRate}. See Grafana dashboard: [your-grafana-dashboard-link]"
                        )
                        error("Automatic rollback triggered due to high error rate!") // 파이프라인 실패 처리

                    } else {
                        echo "Deployment successful. Error rate: ${errorRate}"
                    }
                }
            }
        }
    }
}
 

Ansible (rollback.yaml):

- name: Rollback Deployment
  hosts: localhost
  connection: local
  tasks:
    - name: Rollback to previous revision
      community.kubernetes.k8s_rollback: # 또는 k8s 모듈 + 이전 deployment.yaml 사용
        kind: Deployment
        name: your-app-deployment
 

핵심 요소:

  • sh 'curl ...': Prometheus 쿼리 실행 (Jenkins)
  • jq: JSON 응답 파싱 (Prometheus 쿼리 결과)
  • if (condition) { ... }: 조건부 로직 (임계값 비교)
  • ansiblePlaybook: 자동 롤백 (Ansible Playbook 호출)
  • slackSend: 슬랙 알림 (Jenkins)
  • error(...): 파이프라인 실패 처리

시나리오 17: 다중 클러스터 배포 및 관리 (with Argo CD)

개요:

  • Argo CD 도입: GitOps 기반의 지속적 배포(CD) 도구인 Argo CD를 사용하여 여러 Kubernetes 클러스터(개발, 스테이징, 프로덕션 등)에 애플리케이션을 배포하고 관리합니다.
  • Jenkins 역할:
    • CI 파이프라인 (빌드, 테스트, Docker 이미지 생성)을 실행합니다.
    • Argo CD Application CR (Custom Resource)을 생성/업데이트하여 배포를 트리거합니다. (또는 Argo CD API/CLI 사용)
    • Argo CD Application의 상태를 모니터링하고, 배포 성공/실패 여부를 확인합니다.
  • Argo CD 역할:
    • Git 저장소에 정의된 애플리케이션 구성(YAML, Helm Chart, Kustomize 등)을 감시합니다.
    • 변경 사항이 발생하면, 대상 클러스터에 자동으로 동기화(배포)합니다.
    • 배포 상태 및 리소스 상태를 시각화하고 관리합니다.

Jenkins Pipeline:

pipeline {
    agent any
    // ... (CI 파이프라인: 빌드, 테스트, Docker 이미지 생성) ...

    stages {
        stage('Deploy with Argo CD') {
            steps {
                script {
                    // Argo CD Application CR 생성/업데이트 (kubectl 사용)
                    sh """
                        kubectl apply -f argocd-application.yaml -n argocd
                    """

                    // 또는 Argo CD CLI 사용
                    // sh "argocd app create your-app --repo <git-repo> --path <path> --dest-server <cluster-url> --dest-namespace <namespace> --revision <git-branch/tag>"
                   // sh 'argocd app sync <your-app>'
                    // Argo CD Application 상태 확인
                    def appStatus = sh(returnStdout: true, script: "argocd app get your-app -o json | jq '.status.sync.status'").trim()

                    if (appStatus != '"Synced"') {
                        error("Argo CD Application sync failed!")
                    }
                }
            }
        }
    }
}
 

Argo CD Application CR (argocd-application.yaml):

apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
  name: your-app
  namespace: argocd
spec:
  project: default
  source:
    repoURL: 'https://github.com/your/repo.git' # Git 저장소 URL
    targetRevision: HEAD # 또는 특정 브랜치/태그
    path: k8s/ # 애플리케이션 구성 파일 경로 (YAML, Helm Chart 등)
  destination:
    server: 'https://kubernetes.default.svc' # 대상 클러스터 (또는 외부 클러스터)
    namespace: your-app-namespace
  syncPolicy:
    automated:
      prune: true # 리소스 삭제 허용
      selfHeal: true # 자동 복구
 

핵심 요소:

  • kubectl apply: Argo CD Application CR 생성/업데이트
  • argocd app create/sync/get: Argo CD CLI 명령어 (선택 사항)
  • jq: JSON 응답 파싱 (Argo CD Application 상태 확인)
  • Argo CD Application CR: GitOps 기반 배포 설정

시나리오 18: 보안 강화된 CI/CD 파이프라인 (with Trivy, OPA/Gatekeeper)

개요:

  1. 컨테이너 이미지 취약점 스캔 (Trivy):
    • Jenkins는 Docker 이미지 빌드 후, Trivy를 사용하여 이미지의 취약점을 스캔합니다.
    • 발견된 취약점이 특정 심각도(Severity) 이상이면, 빌드를 실패시키고 알림을 보냅니다.
  2. Kubernetes 리소스 정책 검사 (OPA/Gatekeeper):
    • Open Policy Agent (OPA) 또는 Gatekeeper를 사용하여 Kubernetes 리소스(Deployment, Service, Ingress 등)에 대한 정책을 정의합니다.
    • Jenkins는 배포 전에 Ansible Playbook 또는 kubectl을 통해 OPA/Gatekeeper 정책을 적용하고, 정책 위반 여부를 확인합니다.
    • 정책 위반 시, 배포를 중단하고 알림을 보냅니다.

Jenkins Pipeline:

pipeline {
    agent any
    // ... (빌드, Docker 이미지 생성) ...

    stages {
        stage('Security Scan') {
            steps {
                script {
                    // Trivy를 사용한 이미지 스캔
                    def imageName = "your-registry/your-image:${env.BUILD_TAG}"
                    sh "trivy image --severity CRITICAL,HIGH --exit-code 1 ${imageName}"

                    // OPA/Gatekeeper 정책 검사 (예시: Gatekeeper)
                    sh """
                        kubectl apply -f gatekeeper-constraints.yaml # 제약 조건 템플릿 및 제약 조건 적용
                        kubectl get constrainttemplates # 제약 조건 템플릿 확인
                        kubectl get k8srequiredlabels # 제약 조건 확인 (예: 레이블 필수 제약 조건)

                        # 정책 위반 시뮬레이션 (테스트)
                        # kubectl apply -f invalid-deployment.yaml
                    """
                }
            }

            post{
               failure{
                 slackSend(
                    channel: '#your-channel',
                    color: 'danger',
                    message: "Security Scan failed!! check vulnerability or policy violation."
                )
               }
            }
        }

        stage('Deploy') {
            when{
                expression{
                    // 이전 단계 성공시에만 실행
                    currentBuild.result == null || currentBuild.result == 'SUCCESS'
                }
            }
            steps {
                ansiblePlaybook(
                    playbook: 'deploy.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
    }
}
 

Gatekeeper Constraints (gatekeeper-constraints.yaml - 예시):

# ConstraintTemplate (레이블 필수)
apiVersion: templates.gatekeeper.sh/v1
kind: ConstraintTemplate
metadata:
  name: k8srequiredlabels
spec:
  crd:
    spec:
      names:
        kind: K8sRequiredLabels
      validation:
        # Schema for the `parameters` field
        openAPIV3Schema:
          properties:
            labels:
              type: array
              items:
                type: string
  targets:
    - target: "admission.k8s.gatekeeper.sh"
      rego: |
        package k8srequiredlabels

        violation[{"msg": msg, "details": {"missing_labels": missing}}] {
          provided := {label | input.review.object.metadata.labels[label]}
          required := {label | label := input.parameters.labels[_]}
          missing := required - provided
          count(missing) > 0
          msg := sprintf("you must provide labels: %v", [missing])
        }
---
# Constraint (특정 리소스에 제약 조건 적용)
apiVersion: constraints.gatekeeper.sh/v1beta1
kind: K8sRequiredLabels
metadata:
  name: ns-must-have-gk
spec:
  match:
    kinds:
      - apiGroups: [""]
        kinds: ["Namespace"]
  parameters:
    labels: ["gatekeeper"]
 

핵심 요소:

  • trivy image: 컨테이너 이미지 취약점 스캔
  • kubectl apply: OPA/Gatekeeper 정책 (ConstraintTemplate, Constraint) 적용
  • kubectl get constrainttemplates/k8srequiredlabels: 정책 확인
  • when: 이전 단계 성공시에만 다음 단계 실행
  • post - failure: 실패 시 알림

 

시나리오 19: 멀티 리전/멀티 클러스터 배포 및 재해 복구 (DR) 자동화

목표:

  • 애플리케이션을 여러 리전(Region) 또는 여러 Kubernetes 클러스터에 배포하여 고가용성(High Availability) 및 재해 복구(Disaster Recovery) 능력을 확보합니다.
  • 장애 발생 시, 자동으로 트래픽을 다른 리전/클러스터로 전환하고, 필요한 경우 데이터베이스 복구 등을 수행합니다.

사용하는 도구 및 환경:

  • Jenkins: CI/CD 파이프라인 오케스트레이션
  • Ansible: Kubernetes 리소스 관리, 클러스터 간 동기화
  • Argo CD: GitOps 기반 다중 클러스터 배포 (선택 사항)
  • Kubernetes: 멀티 클러스터 구성 (Federation v2, KubeFed, 또는 자체 구성)
  • DNS 서비스: (예: AWS Route 53, Google Cloud DNS) 트래픽 라우팅
  • 데이터베이스: (예: PostgreSQL, MySQL) 클러스터 간 복제 구성 (Master-Slave, Multi-Master)
  • 모니터링: Prometheus, Grafana (클러스터 및 애플리케이션 상태 모니터링)

요구사항:

  • 여러 리전에 Kubernetes 클러스터 구축 (또는 여러 클러스터 구성)
  • 클러스터 간 네트워크 연결 구성 (VPN, Direct Connect 등)
  • 데이터베이스 복제 구성 및 자동 Failover 설정
  • DNS 서비스 설정 및 Health Check 구성

단계별 구현 방법:

  1. CI 파이프라인 (Jenkins):
    • 코드 변경 감지, 빌드, 테스트, Docker 이미지 생성 및 푸시
    • Ansible Playbook을 호출하여 각 리전/클러스터에 배포 (또는 Argo CD Application 업데이트)
  2. 배포 (Ansible/Argo CD):
    • Ansible:
      • k8s 모듈을 사용하여 각 클러스터에 Deployment, Service, Ingress 등 리소스 생성/업데이트
      • delegate_to를 사용하여 각 클러스터에 대한 작업을 원격으로 실행
      • include_role 또는 import_playbook을 사용하여 클러스터별 설정을 모듈화
    • Argo CD (선택 사항):
      • Git 저장소에 각 클러스터별 애플리케이션 구성(YAML, Helm Chart)을 정의
      • Argo CD Application CR을 사용하여 각 클러스터에 배포
  3. 트래픽 라우팅 (DNS):
    • DNS 서비스(Route 53, Cloud DNS 등)에 각 클러스터의 Ingress/Load Balancer 엔드포인트를 등록
    • Health Check를 구성하여 비정상 클러스터로의 트래픽 라우팅 방지
    • Weighted Round Robin, Geolocation Routing 등 다양한 라우팅 정책 설정
  4. 장애 감지 및 자동 Failover (Jenkins, Ansible, 모니터링):
    • Jenkins: Prometheus 쿼리를 통해 각 클러스터 및 애플리케이션의 상태를 주기적으로 확인
    • 모니터링: Prometheus Alertmanager를 사용하여 임계값 초과 시 알림 발생
    • Ansible:
      • 장애 발생 시, DNS 레코드를 업데이트하여 트래픽을 정상 클러스터로 전환
      • 필요한 경우, 데이터베이스 Failover 수행 (pg_ctl promote 등)
      • failover 모듈 또는 postgresql_replication 모듈 사용 (PostgreSQL 예시)
  5. 복구 (Ansible):
    • 장애가 복구되면, Ansible을 사용하여 DNS 레코드 복원, 데이터베이스 동기화 등을 수행

Jenkins Pipeline (예시):

pipeline {
    agent any
    // ... (CI 파이프라인) ...

    stages {
        stage('Deploy to Multiple Clusters') {
            steps {
                ansiblePlaybook(
                    playbook: 'deploy_multi_cluster.yaml',
                    inventory: 'inventory.ini', // 각 클러스터 정보 포함
                    credentialsId: 'kubeconfig-credentials'
                )
            }
        }
        stage('Monitor & Failover') {
            steps {
                script {
                    // 각 클러스터 상태 확인 (Prometheus 쿼리)
                    // ...

                    // 장애 발생 시
                    if (cluster1Status == 'DOWN') {
                        // Ansible Playbook 호출 (failover.yaml)
                        // ...
                    }
                }
            }
        }
    }
}
 

Ansible (deploy_multi_cluster.yaml - 예시):

- name: Deploy to Multiple Clusters
  hosts: all # inventory 파일에서 각 클러스터 그룹 정의
  gather_facts: false # 각 클러스터에서 facts 수집 안 함
  tasks:
    - name: Deploy to {{ inventory_hostname }} # 현재 호스트(클러스터) 이름
      include_role:
        name: deploy_app
      vars:
        kubeconfig: "{{ lookup('env', 'KUBECONFIG_' + inventory_hostname) }}" # 각 클러스터별 kubeconfig
      delegate_to: localhost # 로컬에서 k8s 모듈 실행
 

Ansible (deploy_app role - 예시):

# roles/deploy_app/tasks/main.yaml
- name: Create/Update Deployment
  k8s:
    state: present
    src: deployment.yaml
    kubeconfig: "{{ kubeconfig }}" # 변수로 전달받은 kubeconfig 사용
  # ... (Service, Ingress 등) ...
 

Ansible (failover.yaml - 예시):

- name: Failover
  hosts: localhost # DNS 서비스 및 DB 관리 호스트
  connection: local
  tasks:
    - name: Update DNS Records (Route 53 예시)
      community.aws.route53:
        state: present
        zone: your-domain.com
        record: app.your-domain.com
        type: A
        value: "{{ healthy_cluster_ip }}" # 정상 클러스터 IP
        ttl: 60

    - name: Promote Standby Database (PostgreSQL 예시)
      become: true
      become_user: postgres
      command: pg_ctl promote -D /var/lib/postgresql/data # 또는 failover 모듈 사용
      when: database_role == 'standby' # 현재 역할이 standby인 경우에만
 

고려 사항:

  • 클러스터 간 통신: 보안 (TLS), 성능, 복잡성 등을 고려하여 적절한 통신 방식 선택 (VPN, Direct Connect, Service Mesh 등)
  • 데이터베이스 복제: 동기/비동기 복제, 복제 지연, 데이터 정합성 등을 고려
  • DNS TTL: 장애 복구 시간(RTO)과 DNS 캐싱 영향을 고려하여 적절한 TTL 설정
  • 모니터링: 각 클러스터 및 애플리케이션에 대한 상세한 모니터링 구성 (메트릭, 로그, 트레이싱)
  • 테스트: 정기적인 장애 복구 훈련(Chaos Engineering)을 통해 시스템의 복원력 검증

시나리오 20: Kubernetes 기반 머신러닝 모델 서빙 및 자동 업데이트

목표:

  • 머신러닝 모델을 Kubernetes 환경에서 서빙하고, 새로운 모델이 학습될 때마다 자동으로 업데이트합니다.
  • 모델 서빙 성능(응답 시간, 처리량)을 모니터링하고, 필요에 따라 스케일링합니다.
  • A/B 테스트 또는 카나리 배포를 통해 새로운 모델의 성능을 검증합니다.

사용하는 도구 및 환경:

  • Jenkins: CI/CD 파이프라인
  • Ansible: Kubernetes 리소스 관리
  • Kubernetes: 모델 서빙 환경
  • MLflow/Seldon Core/KServe: 모델 서빙 프레임워크
  • Prometheus/Grafana: 모니터링
  • Istio/Linkerd: 트래픽 관리 (A/B 테스트, 카나리 배포) (선택 사항)
  • 데이터 저장소: (예: S3, GCS, MinIO) 학습된 모델 저장

요구사항:

  • 머신러닝 모델 학습 파이프라인 구축 (별도 시스템 또는 Kubernetes Job)
  • 모델 서빙 프레임워크 선택 및 구성
  • 모델 저장소 설정
  • 모니터링 시스템 구축

단계별 구현 방법:

  1. 모델 학습 (별도 시스템/Kubernetes Job):
    • 데이터 수집, 전처리, 모델 학습, 평가, 모델 저장(S3, GCS 등)
    • MLflow를 사용하여 모델 버전 관리 및 추적 (선택 사항)
  2. CI 파이프라인 (Jenkins):
    • 새로운 모델 학습 완료 이벤트 감지 (Webhook, 주기적 확인 등)
    • 모델 서빙 이미지 빌드 (모델 포함) 및 푸시
    • Ansible Playbook을 호출하여 모델 서빙 배포/업데이트
  3. 모델 서빙 배포 (Ansible):
    • Seldon Core/KServe:
      • SeldonDeployment 또는 InferenceService CR (Custom Resource)을 사용하여 모델 서빙 배포
      • k8s 모듈 또는 kubectl 사용
      • 새로운 모델 버전으로 업데이트 (롤링 업데이트)
      • 필요에 따라 HPA (Horizontal Pod Autoscaler) 설정
    • MLflow (Serving):
      • mlflow deployments create 명령어를 사용하여 Kubernetes에 배포 (또는 REST API 사용)
  4. 모니터링 (Prometheus/Grafana):
    • 모델 서빙 프레임워크에서 제공하는 메트릭(응답 시간, 처리량, 에러율 등)을 Prometheus로 수집
    • Grafana 대시보드를 통해 실시간으로 성능 모니터링
  5. A/B 테스트 또는 카나리 배포 (Istio/Linkerd - 선택 사항):
    • Service Mesh (Istio/Linkerd)를 사용하여 트래픽 일부를 새로운 모델 버전으로 라우팅
    • 성능 비교 후, 점진적으로 트래픽 비율 조정

Jenkins Pipeline (예시):

pipeline {
    agent any
    // ... (모델 학습 완료 이벤트 감지) ...

    stages {
        stage('Build Model Serving Image') {
            steps {
                // ... (Docker 이미지 빌드 및 푸시) ...
            }
        }
        stage('Deploy Model') {
            steps {
                ansiblePlaybook(
                    playbook: 'deploy_model.yaml',
                    inventory: 'inventory.ini',
                    credentialsId: 'kubeconfig-credentials',
                    extraVars: [model_version: 'v2'] // 새로운 모델 버전 전달
                )
            }
        }
    }
}
 

Ansible (deploy_model.yaml - Seldon Core 예시):

- name: Deploy ML Model (Seldon Core)
  hosts: localhost
  connection: local
  tasks:
    - name: Create/Update SeldonDeployment
      k8s:
        state: present
        src: seldon-deployment.yaml # SeldonDeployment CR 정의
        # 또는 k8s_raw 모듈 사용
        # definition: "{{ lookup('template', 'seldon-deployment.yaml.j2') | from_yaml }}"
 

SeldonDeployment CR (seldon-deployment.yaml - 예시):

apiVersion: machinelearning.seldon.io/v1
kind: SeldonDeployment
metadata:
  name: your-model
spec:
  predictors:
    - componentSpecs:
      - spec:
          containers:
          - image: your-registry/model-serving-image:{{ model_version }} # Jenkins에서 전달받은 버전
            name: classifier
      graph:
        children: []
        endpoint:
          type: REST
        name: classifier
        type: MODEL
      name: default
      replicas: 1
 

고려 사항:

  • 모델 서빙 프레임워크 선택: 요구사항(성능, 확장성, 기능), 모델 유형, 개발 편의성 등을 고려
  • 모델 버전 관리: MLflow, DVC 등 모델 버전 관리 도구 사용
  • A/B 테스트/카나리 배포: Istio, Linkerd, Flagger 등 적절한 도구 선택 및 구성
  • 모니터링: 상세한 성능 지표 수집 및 시각화, 알림 설정
  • 보안: 모델 서빙 API 인증/인가, 네트워크 정책 설정

시나리오 21: Kubernetes 이벤트 기반 자동화 (with Argo Events & Ansible)

목표:

  • Kubernetes 클러스터 내에서 발생하는 다양한 이벤트(Pod 생성/삭제, ConfigMap 변경, HPA 스케일링 등)에 실시간으로 대응하는 자동화 작업을 수행합니다.
  • Argo Events를 사용하여 이벤트 소스(Event Source)를 정의하고, 이벤트 발생 시 Ansible Playbook을 트리거합니다.

사용하는 도구 및 환경:

  • Argo Events: Kubernetes 이벤트 기반 워크플로우 자동화 프레임워크
  • Ansible: 이벤트 핸들링 작업 수행
  • Kubernetes: 이벤트 발생 환경
  • Webhook (선택 사항): 외부 시스템(GitHub, GitLab, Docker Hub 등)의 이벤트 수신
  • Event Source: 이벤트 발생 소스. 여기서는 k8s 이벤트를 예시로 들지만, webhook, kafka, S3등 다양한 소스 선택 가능

요구사항:

  • Argo Events 설치 및 구성
  • 이벤트 소스 정의 (예: Kubernetes API, Webhook)
  • 이벤트 필터링 및 변환 규칙 정의
  • Ansible Playbook 작성 (이벤트 처리 로직)

단계별 구현 방법:

  1. Argo Events 설치:
    kubectl create namespace argo-events
    kubectl apply -n argo-events -f https://raw.githubusercontent.com/argoproj/argo-events/stable/manifests/install.yaml
     
  2. EventSource 정의 (Kubernetes API 예시):
    apiVersion: argoproj.io/v1alpha1
    kind: EventSource
    metadata:
      name: k8s-events
    spec:
      serviceAccountName: argo-events-sa # 필요한 경우 service account 생성
      kubernetes: {}  # 모든 리소스에 대한 이벤트
     
  3. Sensor 정의 (Ansible Playbook 트리거):
apiVersion: argoproj.io/v1alpha1
kind: Sensor
metadata:
  name: k8s-events-sensor
spec:
  template:
    serviceAccountName: argo-events-sa
  dependencies:
    - name: k8s-events-dep
      eventSourceName: k8s-events
      eventName: kubernetes
  triggers:
    - template:
        name: ansible-trigger
        k8s:
          group: ""
          version: v1
          resource: pods # 임시 pod 생성하여 ansible 실행
          operation: create
          source:
            resource:
              apiVersion: v1
              kind: Pod
              metadata:
                generateName: ansible-runner-
                namespace: argo-events
              spec:
                containers:
                  - name: ansible-runner
                    image: your-ansible-image # Ansible 포함된 이미지
                    command: [ "ansible-playbook" ]
                    args: [ "-i", "inventory.ini", "handle_event.yaml" ] # Ansible playbook 실행
                    env:
                      - name: EVENT_PAYLOAD #k8s event 내용을 환경변수로 전달
                        value: "{{ toJson .event }}"
                restartPolicy: Never
 
*   `dependencies`: 어떤 EventSource의 어떤 이벤트를 감시할지 지정
*   `triggers`: 이벤트 발생 시 어떤 작업을 수행할지 지정 (여기서는 Ansible Playbook 실행)
    * 임시 pod를 생성하여 ansible playbook 실행
    * `env`를 통해 event 내용을 ansible playbook으로 전달
    * inventory.ini 파일이 필요합니다.
 
  1. Ansible Playbook (handle_event.yaml):
    - name: Handle Kubernetes Event
      hosts: localhost  # 또는 원격 호스트
      connection: local
      tasks:
          - name: Print event
            debug:
              msg: "{{ lookup('env', 'EVENT_PAYLOAD') | from_json }}" #전달받은 event 내용 출력
    # 이벤트 처리 로직 (예: 특정 레이블을 가진 Pod 생성 시 알림)
          - name: Send notification on new labeled pod
            community.general.slack: # 슬랙 알림
              token: "{{ slack_token }}"
              channel: "#k8s-events"
              msg: "New pod '{{ event_data.metadata.name }}' created with label 'app=my-app'"
            vars:
              event_data: "{{ lookup('env', 'EVENT_PAYLOAD') | from_json }}" # 환경 변수에서 이벤트 데이터 가져오기
            when:
              - event_data.kind == "Pod"
              - event_data.type == "ADDED"
              - "'app' in event_data.metadata.labels"
              - event_data.metadata.labels.app == 'my-app'
     

고려 사항:

  • 이벤트 필터링: EventSource 또는 Sensor에서 필요한 이벤트만 필터링 (리소스 종류, 레이블, 네임스페이스 등)
  • 이벤트 변환: Sensor에서 이벤트를 변환하여 Ansible Playbook에 전달 (JSONPath, jq 등 사용)
  • 멱등성(Idempotency): Ansible Playbook이 여러 번 실행되어도 동일한 결과를 보장하도록 작성
  • 에러 처리: 이벤트 처리 실패 시 재시도, 알림 등 적절한 에러 처리 로직 추가
  • 보안: Argo Events, Ansible, Kubernetes API 간 통신 보안 강화 (TLS, RBAC 등)

시나리오 22: 하이브리드 클라우드 환경에서 애플리케이션 배포 및 오토스케일링

목표:

  • 온프레미스 Kubernetes 클러스터와 퍼블릭 클라우드(AWS, GCP, Azure 등) Kubernetes 클러스터를 통합하여 하이브리드 클라우드 환경을 구축합니다.
  • 애플리케이션을 하이브리드 클라우드 환경에 배포하고, 부하에 따라 자동으로 리소스를 스케일링합니다. (온프레미스 리소스 우선 사용, 부족 시 클라우드 리소스 활용)
  • 클라우드 버스팅(Cloud Bursting)을 구현하여 온프레미스 리소스가 포화 상태일 때 클라우드 리소스를 활용하고, 부하 감소 시 다시 온프레미스로 축소합니다.

사용하는 도구 및 환경:

  • Jenkins: CI/CD 파이프라인
  • Ansible: 클러스터 간 리소스 관리 및 오케스트레이션
  • Kubernetes: 온프레미스 및 퍼블릭 클라우드 클러스터
  • Cluster API: 클러스터 생성 및 관리 (선택 사항)
  • KubeFed/Federation v2: 멀티 클러스터 관리 (선택 사항)
  • Horizontal Pod Autoscaler (HPA): Pod 스케일링
  • Cluster Autoscaler: Node 스케일링 (온프레미스/클라우드)
  • Prometheus/Grafana: 모니터링
  • VPN/Direct Connect/Cloud Interconnect: 온프레미스와 클라우드 간 네트워크 연결

요구사항:

  • 온프레미스 Kubernetes 클러스터 구축
  • 퍼블릭 클라우드 Kubernetes 클러스터 구축 (또는 관리형 Kubernetes 서비스 사용)
  • 온프레미스와 클라우드 간 네트워크 연결 구성
  • Cluster Autoscaler 설정 (온프레미스 및 클라우드)
  • HPA 설정 (metrics-server 설치 등)
  • 모니터링 시스템 구축

단계별 구현 방법:

  1. 클러스터 구축 및 연결:
    • 온프레미스 Kubernetes 클러스터 구축 (kubeadm, k3s 등)
    • 퍼블릭 클라우드 Kubernetes 클러스터 구축 (EKS, GKE, AKS 등) 또는 Cluster API 사용
    • VPN, Direct Connect, Cloud Interconnect 등을 사용하여 온프레미스와 클라우드 간 네트워크 연결
  2. CI/CD 파이프라인 (Jenkins):
    • 코드 변경 감지, 빌드, 테스트, Docker 이미지 생성 및 푸시
    • Ansible Playbook을 호출하여 애플리케이션을 온프레미스 클러스터에 우선 배포
  3. 배포 (Ansible):
    • k8s 모듈을 사용하여 Deployment, Service, HPA 등 리소스 생성
    • delegate_to를 사용하여 온프레미스 클러스터에 작업 위임
  4. 오토스케일링:
    • HPA: 애플리케이션 부하(CPU, 메모리 등)에 따라 Pod 개수 자동 조정
    • Cluster Autoscaler:
      • 온프레미스: Pod가 Pending 상태(리소스 부족)가 되면, 온프레미스 클러스터에 Node 추가
      • 클라우드: Pod가 Pending 상태이고 온프레미스 리소스가 부족하면, 클라우드 클러스터에 Node 추가
      • Node utilization이 낮으면 Node 제거 (온프레미스/클라우드)
  5. 클라우드 버스팅 (Jenkins, Ansible):
    • Jenkins: Prometheus 쿼리를 통해 온프레미스 클러스터의 리소스 사용량(CPU, 메모리) 및 Pending Pod 개수 확인
    • Ansible:
      • 온프레미스 리소스가 포화 상태이고 Pending Pod가 있으면, 클라우드 클러스터에 추가 Deployment 생성 (또는 HPA 설정 변경)
      • 부하 감소 시, 클라우드 클러스터의 Deployment 축소 또는 삭제
  6. 모니터링
    • Prometheus와 Grafana를 사용하여 클러스터 및 Pod 상태를 확인

Jenkins Pipeline (예시):

pipeline {
    agent any
    // ... (CI 파이프라인) ...

    stages {
        stage('Deploy to On-Premise') {
            steps {
                ansiblePlaybook(
                    playbook: 'deploy_onpremise.yaml',
                    inventory: 'inventory.ini', // 온프레미스 클러스터 정보
                    credentialsId: 'kubeconfig-onpremise'
                )
            }
        }
        stage('Check On-Premise Resource & Cloud Bursting') {
            steps {
                script {
                    // 온프레미스 리소스 사용량 확인 (Prometheus 쿼리)
                    // ...

                    // Pending Pod 개수 확인 (kubectl 사용)
                    def pendingPods = sh(returnStdout: true, script: "kubectl get pods -n your-namespace --field-selector=status.phase=Pending | wc -l").trim().toInteger()

                    // 클라우드 버스팅 조건 확인
                    if (pendingPods > 0 && onPremiseCpuUsage > 0.8) { // 예시
                        // Ansible Playbook 호출 (cloud_bursting.yaml)
                        ansiblePlaybook(
                            playbook: 'cloud_bursting.yaml',
                            inventory: 'inventory.ini', // 클라우드 클러스터 정보
                            credentialsId: 'kubeconfig-cloud'
                        )
                    }
                }
            }
        }
    }
}
 

Ansible (deploy_onpremise.yaml - 예시):

- name: Deploy to On-Premise Cluster
  hosts: onpremise-cluster # inventory 파일에서 정의
  tasks:
    - name: Create/Update Deployment
      k8s:
        state: present
        src: deployment.yaml # HPA 설정 포함
      # ... (Service 등) ...
 

Ansible (cloud_bursting.yaml - 예시):

- name: Cloud Bursting
  hosts: cloud-cluster # inventory 파일에서 정의
  tasks:
    - name: Create/Update Deployment in Cloud
      k8s:
        state: present
        src: cloud-deployment.yaml # 클라우드용 Deployment 정의 (replicas 조정)
      # 또는 HPA 설정 변경
    - name: scale up cloud deployment
      community.kubernetes.k8s_scale:
        kind: Deployment
        name: <deployment name>
        namespace: <namespace>
        replicas: 5 # 적절한 replica 개수 설정
 

고려 사항:

  • 네트워크 연결: 온프레미스와 클라우드 간 안전하고 빠른 네트워크 연결 구성 (VPN, Direct Connect, Cloud Interconnect)
  • 클러스터 관리: Cluster API를 사용하여 클러스터 생성 및 관리 자동화 (선택 사항)
  • 멀티 클러스터 관리: KubeFed/Federation v2를 사용하여 여러 클러스터 관리 (선택 사항)
  • 오토스케일링: HPA, Cluster Autoscaler 설정 최적화, 사용자 정의 메트릭 사용 (Custom Metrics API)
  • 비용 최적화: 클라우드 리소스 사용량 최소화, 예약 인스턴스(Reserved Instances) 활용
  • 데이터 동기화: 온프레미스와 클라우드 간 데이터 동기화 (필요한 경우)
  • Stateful application 고려사항: statefulset 사용 및 적절한 persistent volume 설정