구성 및 동작 과정
- Helm 을 통해 Job을 생성한다.
- Job은 빌드 번호에 해당하는 디렉터리의 파일을 배포 폴더로 Sync 를 맞춰준다.
Helm 구성
- Front 소스 배포용 Helm 차트 구조
- Helm 상세 내용
- job.yaml
apiVersion: batch/v1 kind: Job metadata: name: {{ .Release.Name }} namespace: {{ .Values.namespace }} spec: ttlSecondsAfterFinished: 0 // 1회성 실행을 위한 설정 template: spec: containers: - name: {{ .Release.Name }}-container image: {{ .Values.image }} command: {{ .Values.command }} envFrom: - secretRef: name: {{ .Values.envSecretName }} args: - "--endpoint-url=https://{{ .Values.storage.endpoint }}" restartPolicy: {{ .Values.restartPolicy }} imagePullSecrets: - name: {{ .Values.imagePullSecretName }} backoffLimit: {{ .Values.backoffLimit }}
- index.yaml
apiVersion: v1 entries: fastapi: - apiVersion: v2 appVersion: "1.0" created: "2023-11-21T16:39:53.6250541+09:00" description: A Helm chart for deploying project digest: b212cc1ff670a1e2b2d50a03b7703afc21031655564e2090e1b74066336ccc7d name: fastapi type: application urls: - https://storage.com/bucket-name/front-chart/fastapi-0.1.0.tgz version: 0.1.0 generated: "2023-11-21T16:39:53.6244422+09:00"
- job.yaml
HelmBuild
Releases · helm/helm
The Kubernetes Package Manager. Contribute to helm/helm development by creating an account on GitHub.
github.com
- Helm 환경 변수 추가



Helm Package
fastapi 디렉터리가 위치한 경로로 이동 후 helm package . 명령어 실행
Helm upload
index.yaml 에 추가한 entries.fastapi.urls 경로에 package를 통해 생성된
fastapi-0.1.0.tgz 업로드
ArgoCD Manifest 구성
- Base kustomize & values
Jenkins pipeline Check Manifest stage 에서 생성 됩니다. - 환경 별 kustomize & image-patch.yaml
- kustomization.yaml
helmCharts: - name: fastapi repo: https://storage.com/bucket-name/front-chart version: 0.1.0 releaseName: object-storage-deploy-test namespace: default valuesFile: values.yaml
- values.yaml
image: container-registry/aws-cli-1.15.58 namespace: example storage: endpoint: storage-endpoint.org command: restartPolicy: OnFailure imagePullSecretName: ncpsecret backoffLimit: 4 envSecretName: awscli
- 환경 별 kustomize & image-patch.yaml
- kustomization.yaml
resources: - ../base commonLabels: app: object-storage-deploy-test namespace: example generatorOptions: disableNameSuffixHash: true patches: - path: image-patch.yaml target: kind: Job
- image-patch.yaml
-op: replace path: /spec/template/spec/containers/0/image value: container-registry/aws-cli-1.15.58 - op: replace path: /spec/template/spec/containers/0/command value: ["aws", "s3", "sync", "s3://contents/test/#166/dist", "s3://contents/test/dist"]
- image
커스텀한 aws-cli image로 s3 command line 을 이용하여 정적 리소스를 동기화 합니다. - command
sync 를 맞추는 역할로 from bucket/path 와 to bucket/path를 설정 할 수 있도록 구성했습니다
- image
- kustomization.yaml
- kustomization.yaml
K8S Secret 추가
kind: Secret
apiVersion: v1
metadata:
name: awscli
namespace: example
stringData:
AWS_ACCESS_KEY_ID: access_key
AWS_SECRET_ACCESS_KEY: secert_key
type: Opaque
Jenkins Pipeline
@Library('shared-library-teams') _ // Shared Library (Jenkins > System > Global Pipeline)
pipeline {
agent any
tools {
nodejs 'nodejs-21.2.0'
}
environment {
PATH = "/usr/local/bin:$HOME/.local/bin:$PATH" // 환경 변수 설정
ENDPOINT = "container-registry"
ENDPOINT_URL = "https://${ENDPOINT}" // 객체 스토리지 엔드포인트 URL
BUCKET_NAME = "bucket" // 버킷 이름
BUILD_NUMBER = "#${currentBuild.number}"
ROOT_DIRECTORY = "version" // Root 폴더 이름
DIRECTORY_PATH = "dist" // 업로드할 디렉토리 경로
DEPLOY_DIRECTORY = "deploy"
GIT_URL = "http://gitlab.com/project.git"
GIT_BRANCH = "main"
APP_DIR = "dev"
APP_NAME = "app-test"
LIBRARY_NAME = "aws-cli-1.15.58"
// ArgoCD Init
APP_NAMESPACE="namespace"
CONFIG_FILE_CONTENT = ""
BASE_KUSTOMIZE = ""
PROD_KUSTOMIZE = ""
ARGOCD_CREATE = ""
ARGOCD_UPDATE = ""
PROD_ENV = " "
KEY_BASE_PATH = "${ROOT_DIRECTORY}/${BUILD_NUMBER}"
STORAGE_FROM_PATH= "${KEY_BASE_PATH}"
STORAGE_TO_PATH="${DEPLOY_DIRECTORY}"
BASE_VALUE="""
image: image-endpoint/${LIBRARY_NAME}
namespace: ${APP_NAMESPACE}
storage:
endpoint: ${ENDPOINT}
command:
restartPolicy: OnFailure
imagePullSecretName: ncpsecret
backoffLimit: 4
envSecretName: awscli
"""
}
stages {
stage('Nodejs Version Check') {
steps {
sh 'node --version'
}
}
stage('Read Config File') {
steps {
// Jenkins Dashboard -> Jenkins 관리 -> Managed Files 에서 파일로 관리
configFileProvider([configFile(fileId: 'base_yaml', variable: 'CONFIG_FILE')]) {script {BASE_KUSTOMIZE = readFile("${CONFIG_FILE}")}}
configFileProvider([configFile(fileId: 'kustomize_front_yaml', variable: 'CONFIG_FILE')]) {script {MATH_KUSTOMIZE = readFile("${CONFIG_FILE}")}}
configFileProvider([configFile(fileId: 'argo_create_cdn', variable: 'CONFIG_FILE')]) {script {ARGOCD_CREATE = readFile("${CONFIG_FILE}")}}
configFileProvider([configFile(fileId: 'argo_front_update_curl_dev', variable: 'CONFIG_FILE')]) {script {ARGOCD_UPDATE = readFile("${CONFIG_FILE}")}}
script {
BASE_KUSTOMIZE = BASE_KUSTOMIZE
.replaceAll("__HELM_CHART_URL__", "${HELM_CHART_FRONT_URL}")
.replaceAll("__APP_NAME__", "${APP_NAME}")
MATH_KUSTOMIZE = MATH_KUSTOMIZE
.replaceAll('__APP_NAME__', "${APP_NAME}")
.replaceAll('__APP_NAMESPACE__', "${APP_NAMESPACE}")
ENGL_KUSTOMIZE = MATH_KUSTOMIZE
DEV_KUSTOMIZE = MATH_KUSTOMIZE
STG_KUSTOMIZE = MATH_KUSTOMIZE
ARGOCD_CREATE = ARGOCD_CREATE
.replaceAll("__ARGOCD_GIT_URL__", "${ARGOCD_GIT_URL}")
.replaceAll("__ARGOCD_GIT_TOKEN__", "${ARGOCD_GIT_TOKEN}")
.replaceAll("__ARGOCD_GIT_BRANCH__", "${ARGOCD_GIT_BRANCH}")
.replaceAll("__APP_NAME__", "${APP_NAME}")
.replaceAll("__BASE_KUSTOMIZE__", "${BASE_KUSTOMIZE}")
.replaceAll("__DEV_KUSTOMIZE__", "${DEV_KUSTOMIZE}")
.replaceAll("__STG_KUSTOMIZE__", "${STG_KUSTOMIZE}")
.replaceAll("__MATH_KUSTOMIZE__", "${MATH_KUSTOMIZE}")
.replaceAll("__ENGL_KUSTOMIZE__", "${ENGL_KUSTOMIZE}")
.replaceAll("__BASE_VALUE__", "${BASE_VALUE}")
ARGOCD_UPDATE = ARGOCD_UPDATE
.replaceAll("__ARGOCD_GIT_URL__", "${ARGOCD_GIT_URL}")
.replaceAll("__ARGOCD_GIT_TOKEN__", "${ARGOCD_GIT_TOKEN}")
.replaceAll("__ARGOCD_GIT_BRANCH__", "${ARGOCD_GIT_BRANCH}")
.replaceAll("__APP_NAME__", "${APP_NAME}")
.replaceAll("__APP_DIR__", "${APP_DIR}")
.replaceAll("__IMAGE_NAME__", "${LIBRARY_NAME}")
.replaceAll("__NCP_REGISTRY_ENDPOINT__", "${DEV_NCP_REGISTRY_ENDPOINT}")
.replaceAll("__STORAGE_FROM_BUCKET__", "${BUCKET_NAME}")
.replaceAll("__STORAGE_FROM_PATH__", "${STORAGE_FROM_PATH}")
.replaceAll("__STORAGE_TO_BUCKET__", "${BUCKET_NAME}")
.replaceAll("__STORAGE_TO_PATH__", "${STORAGE_TO_PATH}")
}
}
}
stage('Checkout') {
steps {
script{
checkout([
$class: 'GitSCM',
branches: [[name: "${GIT_BRANCH}"]],
userRemoteConfigs: [[credentialsId: 'gitlab-access-token', url: "${GIT_URL}"]]
])
}
}
post {
failure {
echo 'Repository clone failure'
}
success {
echo 'Repository clone success'
echo "${env.gitlabBranch}"
}
}
}
// python3 pip3 가 설치 되어야함
// AWS CLI 설치 여부 확인
stage('Check AWS CLI') {
steps {
script {
// AWS CLI 설치 여부 확인
def awsCLIInstallStatus = sh(script: 'command -v aws', returnStatus: true)
if (awsCLIInstallStatus == 0) {
echo "AWS CLI is already installed."
} else {
// AWS CLI 설치
echo "AWS CLI is not installed. Installing..."
sh 'pip3 install awscli==1.15.85 --user --no-cache-dir'
echo "AWS CLI installed successfully."
}
}
}
}
stage('Build') {
steps {
script {
sh """
npm install
npm run build
"""
}
}
}
// 빌드 번호로 관리 하기 및 업로드 aws cli 이용
stage('Sync') {
steps {
script {
sh "aws --profile ncp-gov --endpoint-url=${ENDPOINT_URL} s3 sync ${DIRECTORY_PATH} s3://${BUCKET_NAME}/${KEY_BASE_PATH}"
}
}
}
stage("Check Manifest") {
steps {
script {
def check_repo_response = sh(
returnStdout: true,
script: """
curl --header "PRIVATE-TOKEN: ${ARGOCD_GIT_TOKEN}" ${ARGOCD_GIT_URL}/repository/tree?path=${APP_NAME}
"""
)
echo "check_repo_response result: ${check_repo_response}"
if ( check_repo_response == "[]" ) {
echo "Repository is empty."
check_repo_response = sh(
returnStatus: true,
script: """
${ARGOCD_CREATE}
"""
)
} else {
echo "Repository is not empty."
}
echo "check_repo_response = ${check_repo_response}"
}
}
}
stage("Update Manifest") {
steps {
script {
def check_repo_response = sh(
returnStatus: true,
script: """
${ARGOCD_UPDATE}
"""
)
echo "check_repo_response = ${check_repo_response}"
}
}
}
}
post {
success {
script {
sendBuildMsg(1, APP_NAME)
}
}
}
}
ArgoCD 연동 결과

Job을 생성하며 빌드 번호에 해당하는 directory의 파일을 복사하여 배포 전용 디렉터리로 덮어 씁니다.
완료 후 job과 pod는 자동으로 삭제 됩니다.
'Cloud' 카테고리의 다른 글
[CSAP] K8S Node Init Script (1) | 2024.12.27 |
---|---|
[ArgoCD] 계정 생성 (1) | 2024.12.27 |
[Tempo] Grafana Tempo 적용기 (2) (0) | 2024.11.19 |
[Tempo] Grafana Tempo 도입 (1) (0) | 2024.11.18 |
[Kafka] CDC 도입기 (1) (0) | 2024.11.18 |
댓글