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 ✅
목차¶
- 전체 파이프라인 구조
- 사전 확인 사항
- STEP 1 — Jenkins API Token 발급
- STEP 2 — Jenkins Credential 등록
- STEP 3 — SCP DevOps Console 진입 및 도구 등록
- STEP 4 — DevOps 프로젝트 생성
- STEP 5 — Jenkins Pipeline Item 생성
- STEP 6 — Jenkinsfile 작성 및 저장
- STEP 7 — 파이프라인 수동 실행
- Helm Chart 설정 — Pod 재시작 로직
- 트러블슈팅
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 }}
⚠️
podAnnotations가 Pod 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
조치:
- Jenkins Credential
scr-auth-credential의 AccessKey/SecretKey 재확인 - SCP Console → IAM → 액세스 키 유효 여부 확인
- SCR 레지스트리 엔드포인트 정확성 확인
Issue 3: Helm upgrade 실패 (kubeconfig)¶
증상: Error: Kubernetes cluster unreachable
조치:
- Jenkins Credential
kubeconfig-ske등록 여부 확인 - SCP Console → K8S Engine → 클러스터 → kubeconfig 재다운로드 후 Credential 갱신
Issue 4: Helm upgrade 실패 (chart not found)¶
증상: Error: chart "processing-chart" not found
조치:
-
HELM_CHART변수값 확인 — 업로드된 Chart 이름과 정확히 일치해야 함 - Helm repo 또는 로컬 Chart 경로 확인
Issue 5: Pod가 재시작되지 않음¶
증상: Helm upgrade는 성공했지만 Pod의 이미지가 갱신되지 않음
체크리스트:
-
values.yaml에podAnnotations항목 존재 여부 -
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