Project

General

Profile

Actions

Devops pipline manual

 

SCP DevOps Console — Processing 이미지 빌드 및 Kubernetes 배포 파이프라인 매뉴얼

작성 기준: SCP 공식 기술 가이드 (DevOps Service Configuration Guide v1.1, July 2023)
환경 전제 조건: SKE(Kubernetes Engine) ✅ · SCR(Container Registry) ✅ · Jenkins(K8S Apps) ✅ · GitHub Enterprise ✅ · Helm Chart ✅


목차

  1. 전체 파이프라인 구조
  2. 사전 확인 사항
  3. STEP 1 — Jenkins API Token 발급
  4. STEP 2 — Jenkins Credential 등록
  5. STEP 3 — SCP DevOps Console 진입 및 도구 등록
  6. STEP 4 — DevOps 프로젝트 생성
  7. STEP 5 — Jenkins Pipeline Item 생성
  8. STEP 6 — Jenkinsfile 작성 및 저장
  9. STEP 7 — 파이프라인 수동 실행
  10. Helm Chart 설정 — Pod 재시작 로직
  11. 트러블슈팅

1. 전체 파이프라인 구조

[수동 실행: Jenkins "Build Now"]
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│ Stage 1: Checkout                                           │
│   scp.sample.com/project/processing  →  main 브랜치         │
└─────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│ Stage 2: Image Build                                        │
│   docker build -t <SCR>/<PROJECT>/processing:<BUILD_NO> .   │
│   └─ Dockerfile (repo root)                                 │
│      COPY app /opt/app                                      │
└─────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│ Stage 3: Image Push                                         │
│   docker push → SCP Container Registry (SCR)               │
└─────────────────────────────────────────────────────────────┘
          │
          ▼
┌─────────────────────────────────────────────────────────────┐
│ Stage 4: Helm Upgrade (Pod 재시작 포함)                      │
│   helm upgrade <release> <chart>                            │
│     --set image.tag=<BUILD_NO>          ← 이미지 갱신        │
│     --set podAnnotations.restartedAt=<timestamp>            │
│         ← Pod 강제 재시작 트리거                              │
└─────────────────────────────────────────────────────────────┘

중요: kubectl 명령 대신 helm upgrade를 사용하여 이미지 갱신 및 Pod 재시작을 처리합니다.
image.tag 값이 변경되면 Kubernetes가 자동으로 Rolling Update를 수행합니다.


2. 사전 확인 사항

파이프라인 생성 전 아래 정보를 미리 수집합니다.

항목 확인 방법 예시
SCR 엔드포인트 SCP Console → Container → Container Registry → 레지스트리 선택 → 엔드포인트 확인 registry.samsungsdscloud.com
SCR 프로젝트명 Container Registry 생성 시 지정한 이름 myproject
SCR AccessKey / SecretKey SCP Console → IAM → 액세스 키 관리 AKID... / SECRET...
Jenkins 도메인 SCP Console → Container → Kubernetes Apps → Jenkins 상세 → 도메인 확인 jenkins.devops-edu.net
GitHub Enterprise URL SCP Console → DevOps Tools → GitHub Enterprise scp.sample.com
GitHub Token GitHub Enterprise → Settings → Developer settings → Personal Access Tokens ghp_xxx...
Helm Release 이름 기 배포된 Helm release 이름 processing
Helm Chart 이름 업로드된 Chart 이름 processing-chart
K8S Namespace 애플리케이션이 배포된 Namespace processing-ns
SKE kubeconfig (Helm 실행용) SCP Console → Container → Kubernetes Engine → 클러스터 → kubeconfig 다운로드 YAML 파일

STEP 1 — Jenkins API Token 발급

Jenkins에서 DevOps Console과 연동하기 위한 API Token을 발급합니다.

1-1. Jenkins 접속

브라우저에서 Jenkins 도메인 접속:

http://jenkins.devops-edu.net  (실제 Jenkins 도메인으로 변경)

1-2. 로그인

Jenkins 생성 시 설정한 admin 계정과 비밀번호로 로그인합니다.

1-3. API Token 생성

우측 상단 [admin 계정명] 클릭
  → Configure (또는 Settings)
    → API Token 섹션
      → [Add new Token] 버튼 클릭
        → Token 이름 입력 (예: devops-console-token)
          → [Generate] 클릭
            → 생성된 Token 값 복사하여 보관

⚠️ 주의: Token은 생성 직후 한 번만 표시됩니다. 반드시 별도로 저장하세요.


STEP 2 — Jenkins Credential 등록

Jenkins Pipeline에서 사용할 인증 정보를 사전 등록합니다.

2-1. Jenkins 관리 메뉴 진입

Jenkins 대시보드 → Manage Jenkins → Credentials
  → System → Global credentials (unrestricted)
    → [Add Credentials] 클릭

2-2. GitHub Enterprise Credential 등록

필드
Kind Username with password
Username GitHub Enterprise 계정
Password GitHub Enterprise Personal Access Token
ID ghe-credential
Description SCP GitHub Enterprise

2-3. SCP Container Registry Credential 등록

필드
Kind Username with password
Username SCR AccessKey
Password SCR SecretKey
ID scr-auth-credential
Description SCP Container Registry 인증키

2-4. kubeconfig Secret File 등록 (Helm 실행용)

Helm 명령 실행을 위해 SKE kubeconfig가 필요합니다.

SCP Console → Container → Kubernetes Engine
  → 클러스터 선택 → [kubeconfig 다운로드] 버튼 클릭

다운로드한 파일을 Jenkins Credential에 등록:

필드
Kind Secret file
File 다운로드한 kubeconfig YAML 파일 업로드
ID kubeconfig-ske
Description SKE Cluster kubeconfig

STEP 3 — SCP DevOps Console 진입 및 도구 등록

3-1. DevOps Console 접속

SCP Console (https://cloud.samsungsds.com/serviceportal)
  → 좌측 메뉴: DevOps Tools
    → DevOps Service
      → [DevOps Console 이동] 또는 [DevOps Console 접속] 클릭

⚠️ DevOps Service를 신청하지 않은 경우 → [DevOps Service 신청] 먼저 진행

3-2. Jenkins CICD 도구 등록

DevOps Console 좌측 메뉴 → 도구 관리(Tool Management)CICD 도구

[도구 등록] 클릭
  → 도구 유형: Jenkins
  → 도구 이름: jenkins-processing  (임의 지정)
  → Jenkins URL: http://jenkins.devops-edu.net
  → API Token: (STEP 1에서 발급한 Token)
  → [저장] 클릭

3-3. GitHub Enterprise SCM 도구 등록

DevOps Console → 도구 관리SCM 도구

[도구 등록] 클릭
  → 도구 유형: GitHub Enterprise
  → 도구 이름: ghe-processing
  → GitHub Enterprise URL: https://scp.sample.com
  → 인증 정보: Username / Personal Access Token 입력
  → [저장] 클릭

STEP 4 — DevOps 프로젝트 생성

4-1. Tenant 생성 (최초 1회)

DevOps Console 좌측 → 테넌트 관리[테넌트 생성]

테넌트 이름: processing-tenant
설명: Processing 서비스 CI/CD
[생성] 클릭

4-2. Project Group 생성

테넌트 선택 → [프로젝트 그룹 생성]

그룹 이름: processing-group
[생성] 클릭

4-3. Project 생성

프로젝트 그룹 선택 → [새 프로젝트 생성]

기본 정보 입력

항목
프로젝트 이름 processing-cicd
설명 Processing Image Build & Deploy
배포 대상 Kubernetes
클러스터 (등록된 SKE 클러스터 선택)

⚠️ 배포 대상을 Kubernetes로 반드시 선택해야 이후 단계에서 K8S 배포 옵션이 활성화됩니다.

클러스터가 없는 경우 → 클러스터 관리 (우측 상단 9점 아이콘) → 클러스터 등록

App Template 선택

Application Templates 목록에서
→ 적합한 템플릿 선택 (Python 없을 경우 → Custom 또는 Generic 선택)
→ [다음] 클릭

Code Repository 설정

항목
SCM 도구 ghe-processing (STEP 3에서 등록)
Repository URL https://scp.sample.com/project/processing
브랜치 main

Image Registry 설정

항목
Registry 유형 SCP Container Registry
Registry (생성된 SCR 레지스트리 선택)
AccessKey SCR AccessKey
SecretKey SCR SecretKey

Build Pipeline 설정

항목
CICD 도구 jenkins-processing (STEP 3에서 등록)
Jenkins 도메인 jenkins.devops-edu.net

최종 확인 및 생성

프로젝트 요약 정보 확인
  → Code Repository, Image Registry, Build Pipeline 설정 확인
    → [프로젝트 생성] 클릭

STEP 5 — Jenkins Pipeline Item 생성

DevOps Console에서 프로젝트가 생성되면 Jenkins에 연동 설정을 합니다.

5-1. Jenkins 대시보드 접속

브라우저 → http://jenkins.devops-edu.net

5-2. 프로젝트 폴더 확인

Jenkins 대시보드에서 DevOps Console 프로젝트와 연결된 폴더가 생성되어 있는지 확인합니다.

5-3. New Item 생성

Jenkins 대시보드 → [새로운 Item] 클릭
  → Item 이름 입력: processing-deploy
  → [Pipeline] 선택
  → [OK] 클릭

5-4. Pipeline 설정

Pipeline 설정 화면에서 하단 Pipeline 섹션으로 이동:

항목 설정값
Definition Pipeline script from SCM
SCM Git
Repository URL https://scp.sample.com/project/processing
Credentials ghe-credential
Branch */main
Script Path Jenkinsfile
[저장] 클릭

STEP 6 — Jenkinsfile 작성 및 저장

GitHub Enterprise Repository root에 아래 Jenkinsfile을 생성하여 저장합니다.

6-1. 환경변수 값 확인 후 수정 필요 항목

아래 Jenkinsfile에서 < > 로 표시된 항목을 실제 값으로 변경하세요.

변수 설명 예시
REGISTRY SCR 엔드포인트 registry.samsungsdscloud.com
SCR_PROJECT SCR 프로젝트명 myproject
HELM_RELEASE Helm Release 이름 processing
HELM_CHART Helm Chart 이름 processing-chart
HELM_NAMESPACE K8S Namespace processing-ns

6-2. Jenkinsfile

pipeline {
    agent any

    // ✅ Trigger 없음 → 수동 실행 전용
    // triggers {} 블록 미포함

    environment {
        // ─── Container Registry ───────────────────────────
        REGISTRY     = "<SCR_ENDPOINT>"          // 예: registry.samsungsdscloud.com
        SCR_PROJECT  = "<SCR_PROJECT_NAME>"       // SCR 내 프로젝트명
        IMAGE_NAME   = "processing"
        IMAGE_TAG    = "${BUILD_NUMBER}"           // 빌드번호를 이미지 태그로 사용
        FULL_IMAGE   = "${REGISTRY}/${SCR_PROJECT}/${IMAGE_NAME}:${IMAGE_TAG}"

        // ─── Helm ─────────────────────────────────────────
        HELM_RELEASE   = "<HELM_RELEASE_NAME>"    // 기 배포된 Helm release 이름
        HELM_CHART     = "<HELM_CHART_NAME>"      // 업로드된 Chart 이름
        HELM_NAMESPACE = "<K8S_NAMESPACE>"        // 배포 대상 Namespace

        // ─── Jenkins Credential ID ─────────────────────────
        SCR_CREDENTIAL     = "scr-auth-credential"
        GHE_CREDENTIAL     = "ghe-credential"
        KUBECONFIG_CRED    = "kubeconfig-ske"
    }

    stages {

        // ── Stage 1: 소스 체크아웃 ──────────────────────────
        stage('Checkout') {
            steps {
                git(
                    url:           'https://scp.sample.com/project/processing',
                    branch:        'main',
                    credentialsId: "${GHE_CREDENTIAL}"
                )
            }
        }

        // ── Stage 2: 이미지 빌드 ────────────────────────────
        // Dockerfile 위치: repo root (.)
        // 핵심 명령: COPY app /opt/app
        stage('Image Build') {
            steps {
                sh """
                    echo "=== Image Build Start ==="
                    echo "Image: ${FULL_IMAGE}"
                    docker build \\
                        -t ${FULL_IMAGE} \\
                        -f Dockerfile \\
                        .
                    echo "=== Image Build Complete ==="
                """
            }
        }

        // ── Stage 3: 이미지 푸시 ────────────────────────────
        stage('Image Push') {
            steps {
                withCredentials([
                    usernamePassword(
                        credentialsId: "${SCR_CREDENTIAL}",
                        usernameVariable: 'SCR_USER',
                        passwordVariable: 'SCR_PASS'
                    )
                ]) {
                    sh """
                        echo "=== Registry Login ==="
                        docker login ${REGISTRY} \\
                            -u \${SCR_USER} \\
                            -p \${SCR_PASS}

                        echo "=== Image Push ==="
                        docker push ${FULL_IMAGE}

                        docker logout ${REGISTRY}
                        echo "=== Push Complete ==="
                    """
                }
            }
        }

        // ── Stage 4: Helm Upgrade (Pod 재시작) ───────────────
        // kubectl 미사용 → helm upgrade로 이미지 갱신 및 Pod 재시작 처리
        // image.tag 변경 → K8S Rolling Update 자동 수행
        // podAnnotations.restartedAt 변경 → 동일 태그라도 강제 재시작 보장
        stage('Helm Upgrade') {
            steps {
                withCredentials([
                    file(
                        credentialsId: "${KUBECONFIG_CRED}",
                        variable:      'KUBECONFIG'
                    )
                ]) {
                    sh """
                        echo "=== Helm Upgrade Start ==="
                        echo "Release: ${HELM_RELEASE}"
                        echo "Image: ${FULL_IMAGE}"

                        RESTART_TIME=\$(date +%s)

                        helm upgrade ${HELM_RELEASE} ${HELM_CHART} \\
                            --namespace ${HELM_NAMESPACE} \\
                            --reuse-values \\
                            --set image.repository="${REGISTRY}/${SCR_PROJECT}/${IMAGE_NAME}" \\
                            --set image.tag="${IMAGE_TAG}" \\
                            --set "podAnnotations.restartedAt=\${RESTART_TIME}" \\
                            --kubeconfig \${KUBECONFIG} \\
                            --wait \\
                            --timeout 5m

                        echo "=== Helm Upgrade Complete ==="
                        echo "=== New Image Applied: ${FULL_IMAGE} ==="
                    """
                }
            }
        }
    }

    post {
        success {
            echo "✅ Pipeline SUCCESS"
            echo "Image: ${FULL_IMAGE}"
        }
        failure {
            echo "❌ Pipeline FAILED — Build #${BUILD_NUMBER}"
        }
    }
}

6-3. Jenkinsfile Git 저장

# 로컬 또는 GitHub Enterprise 웹 UI에서 저장
git add Jenkinsfile
git commit -m "chore: add CI/CD pipeline for processing image build and deploy"
git push origin main

STEP 7 — 파이프라인 수동 실행

7-1. Jenkins Pipeline 실행

Jenkins 대시보드
  → processing-deploy (Pipeline Item) 선택
    → 좌측 메뉴 [지금 빌드 (Build Now)] 클릭

7-2. 빌드 진행 상태 확인

빌드 히스토리에서 실행 중인 빌드 번호 클릭
  → [Console Output] 클릭하여 실시간 로그 확인

정상 실행 시 로그 예시:

=== Image Build Start ===
Image: registry.samsungsdscloud.com/myproject/processing:42
...
Successfully built abc123def456
Successfully tagged registry.samsungsdscloud.com/myproject/processing:42
=== Image Build Complete ===

=== Registry Login ===
Login Succeeded
=== Image Push ===
The push refers to repository [registry.samsungsdscloud.com/myproject/processing]
42: digest: sha256:... size: ...
=== Push Complete ===

=== Helm Upgrade Start ===
Release: processing
Image: registry.samsungsdscloud.com/myproject/processing:42
Release "processing" has been upgraded. Happy Helming!
=== Helm Upgrade Complete ===
=== New Image Applied: registry.samsungsdscloud.com/myproject/processing:42 ===

7-3. Stage 별 결과 확인

Jenkins Pipeline 화면에서 Stage View로 각 단계 성공 여부를 시각적으로 확인할 수 있습니다:

[Checkout] → [Image Build] → [Image Push] → [Helm Upgrade]
   ✅              ✅              ✅              ✅

Helm Chart 설정 — Pod 재시작 로직

Pod 재시작 원리

helm upgrade에서 Pod 재시작이 발생하는 두 가지 경우:

방법 원리 설명
image.tag 변경 Deployment spec 변경 → Rolling Update 매 빌드마다 BUILD_NUMBER가 태그 → 자동 재시작
podAnnotations 변경 Pod template spec 변경 → Rolling Update 동일 태그라도 강제 재시작 보장

Helm Chart values.yaml 확인/수정

업로드된 Helm Chart의 values.yaml에 아래 항목이 있는지 확인하고, 없으면 추가합니다.

# values.yaml

image:
  repository: registry.samsungsdscloud.com/myproject/processing
  tag: latest          # 파이프라인 실행 시 --set image.tag=<BUILD_NUMBER>로 덮어씀
  pullPolicy: Always   # 항상 최신 이미지 Pull

# Pod 재시작 어노테이션 (파이프라인에서 --set으로 갱신)
podAnnotations:
  restartedAt: "0"

Deployment 템플릿 확인

Chart의 templates/deployment.yaml에서 image 및 annotations 참조 확인:

# templates/deployment.yaml 핵심 부분

metadata:
  annotations:
    {{- toYaml .Values.podAnnotations | nindent 8 }}  # ← 이 줄 필요

spec:
  template:
    metadata:
      annotations:
        {{- toYaml .Values.podAnnotations | nindent 8 }}  # ← Pod template에도 필요
    spec:
      containers:
        - name: processing
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"  # ← 이 줄 필요
          imagePullPolicy: {{ .Values.image.pullPolicy }}

⚠️ podAnnotationsPod template metadata에 적용되어야 Pod 재시작이 발생합니다.
Deployment metadata에만 있으면 재시작되지 않습니다.


트러블슈팅

Issue 1: Docker build 실패

증상: cannot connect to the Docker daemon

원인 및 조치:

  • Jenkins Pod에 Docker daemon 접근 권한 없음
  • Jenkins K8S Apps가 Docker socket을 마운트하고 있는지 확인
  • SCP Console → K8S Apps → Jenkins 상세 → Volume 설정 확인

Issue 2: SCR Push 실패 (unauthorized)

증상: unauthorized: authentication required

조치:

  1. Jenkins Credential scr-auth-credential의 AccessKey/SecretKey 재확인
  2. SCP Console → IAM → 액세스 키 유효 여부 확인
  3. SCR 레지스트리 엔드포인트 정확성 확인

Issue 3: Helm upgrade 실패 (kubeconfig)

증상: Error: Kubernetes cluster unreachable

조치:

  1. Jenkins Credential kubeconfig-ske 등록 여부 확인
  2. SCP Console → K8S Engine → 클러스터 → kubeconfig 재다운로드 후 Credential 갱신

Issue 4: Helm upgrade 실패 (chart not found)

증상: Error: chart "processing-chart" not found

조치:

  1. HELM_CHART 변수값 확인 — 업로드된 Chart 이름과 정확히 일치해야 함
  2. Helm repo 또는 로컬 Chart 경로 확인

Issue 5: Pod가 재시작되지 않음

증상: Helm upgrade는 성공했지만 Pod의 이미지가 갱신되지 않음

체크리스트:

  • values.yamlpodAnnotations 항목 존재 여부
  • templates/deployment.yaml의 Pod template metadata에 annotations 참조 여부
  • imagePullPolicy: Always 설정 여부
  • --reuse-values 옵션으로 이전 image.tag가 유지되는 경우 → --set image.tag가 정상 전달되는지 확인

참고 정보

항목 출처
SCP DevOps Service Configuration Guide v1.1 cloud.samsungsds.com (공식 PDF, July 2023)
SCP Kubernetes Engine kubeconfig 다운로드 cloud.samsungsds.com/serviceportal/knowledge/tutorials_detail/container/connect_k8sApiSvr.html
GitHub Enterprise Webhook 연동 docs.github.com/en/enterprise-server (공식 문서)
Helm upgrade 공식 레퍼런스 helm.sh/docs/helm/helm_upgrade

Updated by HAEDONG KANG about 2 months ago · 1 revisions