mirror of
https://github.com/cna-bootcamp/phonebill.git
synced 2025-12-06 08:06:24 +00:00
Jenkins CI/CD 파이프라인 업데이트
- Jenkinsfile 개선: SonarQube 분석, Quality Gate 추가 - 환경별 설정 파일 업데이트 (dev/staging/prod) - Kustomize base 및 overlay 파일 정리 - prod 환경 overlay 파일 추가 - 배포 스크립트 및 검증 스크립트 업데이트 - 파이프라인 가이드 문서 업데이트 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
parent
b467b84426
commit
0f054109bb
68
deployment/cicd/Jenkinsfile
vendored
68
deployment/cicd/Jenkinsfile
vendored
@ -59,6 +59,7 @@ podTemplate(
|
|||||||
],
|
],
|
||||||
volumes: [
|
volumes: [
|
||||||
emptyDirVolume(mountPath: '/home/gradle/.gradle', memory: false),
|
emptyDirVolume(mountPath: '/home/gradle/.gradle', memory: false),
|
||||||
|
emptyDirVolume(mountPath: '/root/.azure', memory: false),
|
||||||
emptyDirVolume(mountPath: '/run/podman', memory: false)
|
emptyDirVolume(mountPath: '/run/podman', memory: false)
|
||||||
]
|
]
|
||||||
) {
|
) {
|
||||||
@ -78,6 +79,7 @@ podTemplate(
|
|||||||
stage("Setup Kubernetes") {
|
stage("Setup Kubernetes") {
|
||||||
container('kubectl') {
|
container('kubectl') {
|
||||||
sh """
|
sh """
|
||||||
|
kubectl config use-context ${props.context}
|
||||||
kubectl create namespace ${props.namespace} --dry-run=client -o yaml | kubectl apply -f -
|
kubectl create namespace ${props.namespace} --dry-run=client -o yaml | kubectl apply -f -
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
@ -92,25 +94,73 @@ podTemplate(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
stage('SonarQube Analysis & Quality Gate') {
|
||||||
|
if (skipSonarQube) {
|
||||||
|
echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=${params.SKIP_SONARQUBE})"
|
||||||
|
} else {
|
||||||
|
container('gradle') {
|
||||||
|
// 각 서비스별로 개별적으로 SonarQube 분석 및 Quality Gate 확인
|
||||||
|
services.each { service ->
|
||||||
|
withSonarQubeEnv('SonarQube') {
|
||||||
|
echo "🔍 Starting SonarQube analysis for ${service}..."
|
||||||
|
|
||||||
|
// 서비스별 테스트 및 SonarQube 분석
|
||||||
|
sh """
|
||||||
|
./gradlew :${service}:test :${service}:jacocoTestReport :${service}:sonar \
|
||||||
|
-Dsonar.projectKey=phonebill-${service}-${environment} \
|
||||||
|
-Dsonar.projectName=phonebill-${service}-${environment} \
|
||||||
|
-Dsonar.java.binaries=build/classes/java/main \
|
||||||
|
-Dsonar.coverage.jacoco.xmlReportPaths=build/reports/jacoco/test/jacocoTestReport.xml \
|
||||||
|
-Dsonar.exclusions=**/config/**,**/entity/**,**/dto/**,**/*Application.class,**/exception/**
|
||||||
|
"""
|
||||||
|
|
||||||
|
echo "✅ SonarQube analysis completed for ${service}"
|
||||||
|
}
|
||||||
|
|
||||||
|
// 각 서비스별 Quality Gate 확인
|
||||||
|
timeout(time: 5, unit: 'MINUTES') {
|
||||||
|
echo "⏳ Waiting for Quality Gate result for ${service}..."
|
||||||
|
def qg = waitForQualityGate()
|
||||||
|
if (qg.status != 'OK') {
|
||||||
|
error "❌ Quality Gate failed for ${service}: ${qg.status}"
|
||||||
|
} else {
|
||||||
|
echo "✅ Quality Gate passed for ${service}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
echo "🎉 All services passed SonarQube Quality Gates!"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
stage('Build & Push Images') {
|
stage('Build & Push Images') {
|
||||||
timeout(time: 30, unit: 'MINUTES') {
|
timeout(time: 30, unit: 'MINUTES') {
|
||||||
container('podman') {
|
container('podman') {
|
||||||
withCredentials([
|
withCredentials([
|
||||||
|
usernamePassword(
|
||||||
|
credentialsId: 'imagereg-credentials',
|
||||||
|
usernameVariable: 'IMG_USERNAME',
|
||||||
|
passwordVariable: 'IMG_PASSWORD'
|
||||||
|
),
|
||||||
usernamePassword(
|
usernamePassword(
|
||||||
credentialsId: 'dockerhub-credentials',
|
credentialsId: 'dockerhub-credentials',
|
||||||
usernameVariable: 'DOCKERHUB_USERNAME',
|
usernameVariable: 'DOCKERHUB_USERNAME',
|
||||||
passwordVariable: 'DOCKERHUB_PASSWORD'
|
passwordVariable: 'DOCKERHUB_PASSWORD'
|
||||||
)
|
)
|
||||||
]) {
|
]) {
|
||||||
|
// Docker Hub 로그인 (rate limit 해결)
|
||||||
sh "podman login docker.io --username \$DOCKERHUB_USERNAME --password \$DOCKERHUB_PASSWORD"
|
sh "podman login docker.io --username \$DOCKERHUB_USERNAME --password \$DOCKERHUB_PASSWORD"
|
||||||
|
|
||||||
|
// Image Registry 로그인
|
||||||
|
sh "podman login docker.io --username \$IMG_USERNAME --password \$IMG_PASSWORD"
|
||||||
|
|
||||||
services.each { service ->
|
services.each { service ->
|
||||||
sh """
|
sh """
|
||||||
podman build \\
|
podman build \
|
||||||
--build-arg BUILD_LIB_DIR="${service}/build/libs" \\
|
--build-arg BUILD_LIB_DIR="${service}/build/libs" \
|
||||||
--build-arg ARTIFACTORY_FILE="${service}.jar" \\
|
--build-arg ARTIFACTORY_FILE="${service}.jar" \
|
||||||
-f deployment/container/Dockerfile-backend \\
|
-f deployment/container/Dockerfile-backend \
|
||||||
-t docker.io/hiondal/${service}:${environment}-${imageTag} .
|
-t docker.io/hiondal/${service}:${environment}-${imageTag} .
|
||||||
|
|
||||||
podman push docker.io/hiondal/${service}:${environment}-${imageTag}
|
podman push docker.io/hiondal/${service}:${environment}-${imageTag}
|
||||||
@ -124,7 +174,7 @@ podTemplate(
|
|||||||
stage('Update Kustomize & Deploy') {
|
stage('Update Kustomize & Deploy') {
|
||||||
container('kubectl') {
|
container('kubectl') {
|
||||||
sh """
|
sh """
|
||||||
# Kustomize 설치
|
# Kustomize 설치 (sudo 없이 사용자 디렉토리에 설치)
|
||||||
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
||||||
mkdir -p \$HOME/bin
|
mkdir -p \$HOME/bin
|
||||||
mv kustomize \$HOME/bin/
|
mv kustomize \$HOME/bin/
|
||||||
@ -133,12 +183,12 @@ podTemplate(
|
|||||||
# 환경별 디렉토리로 이동
|
# 환경별 디렉토리로 이동
|
||||||
cd deployment/cicd/kustomize/overlays/${environment}
|
cd deployment/cicd/kustomize/overlays/${environment}
|
||||||
|
|
||||||
# 서비스 목록 정의
|
# 서비스 목록 정의 (공백으로 구분)
|
||||||
services="api-gateway user-service bill-service product-service kos-mock"
|
services="api-gateway user-service bill-service product-service kos-mock"
|
||||||
|
|
||||||
# 이미지 태그 업데이트
|
# 이미지 태그 업데이트
|
||||||
for service in \$services; do
|
for service in \$services; do
|
||||||
\$HOME/bin/kustomize edit set image docker.io/hiondal/\$service:${environment}-${imageTag}
|
\$HOME/bin/kustomize edit set image docker.io/hiondal/\$service=docker.io/hiondal/\$service:${environment}-${imageTag}
|
||||||
done
|
done
|
||||||
|
|
||||||
# 매니페스트 적용
|
# 매니페스트 적용
|
||||||
@ -147,15 +197,17 @@ podTemplate(
|
|||||||
# 배포 상태 확인
|
# 배포 상태 확인
|
||||||
echo "Waiting for deployments to be ready..."
|
echo "Waiting for deployments to be ready..."
|
||||||
for service in \$services; do
|
for service in \$services; do
|
||||||
kubectl -n ${props.namespace} wait --for=condition=available deployment/\$service --timeout=300s || echo "Timeout waiting for \$service"
|
kubectl -n ${props.namespace} wait --for=condition=available deployment/\$service --timeout=300s
|
||||||
done
|
done
|
||||||
"""
|
"""
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 파이프라인 완료 로그 (Scripted Pipeline 방식)
|
||||||
stage('Pipeline Complete') {
|
stage('Pipeline Complete') {
|
||||||
echo "🧹 Pipeline completed. Pod cleanup handled by Jenkins Kubernetes Plugin."
|
echo "🧹 Pipeline completed. Pod cleanup handled by Jenkins Kubernetes Plugin."
|
||||||
|
|
||||||
|
// 성공/실패 여부 로깅
|
||||||
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
|
if (currentBuild.result == null || currentBuild.result == 'SUCCESS') {
|
||||||
echo "✅ Pipeline completed successfully!"
|
echo "✅ Pipeline completed successfully!"
|
||||||
} else {
|
} else {
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
# Dev Environment Configuration
|
# dev Environment Configuration
|
||||||
# Minikube Remote 환경 설정
|
context=minikube
|
||||||
k8s_context=minikube-remote
|
|
||||||
namespace=phonebill
|
namespace=phonebill
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
# Production Environment Configuration
|
# prod Environment Configuration
|
||||||
# Minikube Remote 환경 설정
|
context=minikube-prod
|
||||||
k8s_context=minikube-remote
|
namespace=phonebill
|
||||||
namespace=phonebill-prod
|
|
||||||
|
|||||||
@ -1,4 +1,3 @@
|
|||||||
# Staging Environment Configuration
|
# staging Environment Configuration
|
||||||
# Minikube Remote 환경 설정
|
context=minikube-staging
|
||||||
k8s_context=minikube-remote
|
namespace=phonebill
|
||||||
namespace=phonebill-staging
|
|
||||||
|
|||||||
@ -1,120 +1,115 @@
|
|||||||
# Jenkins CI/CD 파이프라인 가이드
|
# 백엔드 Jenkins CI/CD 파이프라인 가이드
|
||||||
|
|
||||||
## 개요
|
## 📋 개요
|
||||||
이 문서는 Phonebill 프로젝트의 Jenkins 기반 CI/CD 파이프라인 구축 및 운영 가이드입니다.
|
|
||||||
|
|
||||||
## 프로젝트 정보
|
이 가이드는 phonebill 프로젝트의 Jenkins + Kustomize 기반 CI/CD 파이프라인 구축 및 운영 방법을 설명합니다.
|
||||||
|
|
||||||
|
## 🔧 사전 준비사항
|
||||||
|
|
||||||
|
### 프로젝트 정보
|
||||||
| 항목 | 값 |
|
| 항목 | 값 |
|
||||||
|------|-----|
|
|------|-----|
|
||||||
| 시스템명 | phonebill |
|
| 시스템명 | phonebill |
|
||||||
|
| 서비스 목록 | api-gateway, user-service, bill-service, product-service, kos-mock |
|
||||||
| JDK 버전 | 21 |
|
| JDK 버전 | 21 |
|
||||||
| Image Registry | docker.io |
|
| Image Registry | docker.io |
|
||||||
| Image Organization | hiondal |
|
| Image Organization | hiondal |
|
||||||
| K8s Context | minikube-remote |
|
| Jenkins K8s Cloud Name | k8s |
|
||||||
|
| K8s Context Prefix | minikube |
|
||||||
| Namespace | phonebill |
|
| Namespace | phonebill |
|
||||||
|
|
||||||
### 서비스 목록
|
### Jenkins 서버 환경 구성
|
||||||
- api-gateway (포트: 8080)
|
|
||||||
- user-service (포트: 8081)
|
|
||||||
- bill-service (포트: 8082)
|
|
||||||
- product-service (포트: 8083)
|
|
||||||
- kos-mock (포트: 8084)
|
|
||||||
|
|
||||||
---
|
#### 1. 필수 플러그인 설치
|
||||||
|
|
||||||
## 1. 사전 준비사항
|
|
||||||
|
|
||||||
### 1.1 Jenkins 필수 플러그인
|
|
||||||
```
|
```
|
||||||
- Kubernetes
|
- Kubernetes
|
||||||
- Pipeline Utility Steps
|
- Pipeline Utility Steps
|
||||||
- Docker Pipeline
|
- Docker Pipeline
|
||||||
- GitHub
|
- GitHub
|
||||||
- SonarQube Scanner
|
- SonarQube Scanner
|
||||||
|
- Azure Credentials
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.2 Jenkins Credentials 등록
|
#### 2. Jenkins Credentials 등록
|
||||||
|
|
||||||
Jenkins 관리 > Credentials > Add Credentials에서 등록:
|
**Docker Hub Credentials (Rate Limit 해결용)**
|
||||||
|
|
||||||
#### Docker Hub Credentials
|
|
||||||
```
|
```
|
||||||
- Kind: Username with password
|
- Kind: Username with password
|
||||||
- ID: dockerhub-credentials
|
- ID: dockerhub-credentials
|
||||||
- Username: {DOCKERHUB_USERNAME}
|
- Username: {DOCKERHUB_USERNAME}
|
||||||
- Password: {DOCKERHUB_PASSWORD}
|
- Password: {DOCKERHUB_PASSWORD}
|
||||||
|
- 참고: Docker Hub 무료 계정 생성 (https://hub.docker.com)
|
||||||
```
|
```
|
||||||
|
|
||||||
#### SonarQube Token (선택사항)
|
**Image Registry Credentials**
|
||||||
|
```
|
||||||
|
- Kind: Username with password
|
||||||
|
- ID: imagereg-credentials
|
||||||
|
- Username: {REGISTRY_USERNAME}
|
||||||
|
- Password: {REGISTRY_PASSWORD}
|
||||||
|
```
|
||||||
|
|
||||||
|
**SonarQube Token (선택사항)**
|
||||||
```
|
```
|
||||||
- Kind: Secret text
|
- Kind: Secret text
|
||||||
- ID: sonarqube-token
|
- ID: sonarqube-token
|
||||||
- Secret: {SonarQube토큰}
|
- Secret: {SonarQube토큰}
|
||||||
```
|
```
|
||||||
|
|
||||||
### 1.3 SonarQube 설정 (선택사항)
|
## 📁 디렉토리 구조
|
||||||
Jenkins 관리 > Configure System > SonarQube servers:
|
|
||||||
```
|
|
||||||
- Name: SonarQube
|
|
||||||
- Server URL: http://{SONARQUBE_URL}
|
|
||||||
- Server authentication token: sonarqube-token (위에서 등록한 credential)
|
|
||||||
```
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 2. Kustomize 구조
|
|
||||||
|
|
||||||
### 2.1 디렉토리 구조
|
|
||||||
```
|
```
|
||||||
deployment/cicd/
|
deployment/cicd/
|
||||||
├── Jenkinsfile
|
├── Jenkinsfile # Jenkins 파이프라인 정의
|
||||||
|
├── jenkins-pipeline-guide.md # 이 가이드 문서
|
||||||
├── config/
|
├── config/
|
||||||
│ ├── deploy_env_vars_dev
|
│ ├── deploy_env_vars_dev # dev 환경 설정
|
||||||
│ ├── deploy_env_vars_staging
|
│ ├── deploy_env_vars_staging # staging 환경 설정
|
||||||
│ └── deploy_env_vars_prod
|
│ └── deploy_env_vars_prod # prod 환경 설정
|
||||||
├── scripts/
|
├── scripts/
|
||||||
│ ├── deploy.sh
|
│ ├── deploy.sh # 수동 배포 스크립트
|
||||||
│ └── validate-resources.sh
|
│ └── validate-resources.sh # 리소스 검증 스크립트
|
||||||
└── kustomize/
|
└── kustomize/
|
||||||
├── base/
|
├── base/ # 기본 Kubernetes 매니페스트
|
||||||
│ ├── kustomization.yaml
|
│ ├── kustomization.yaml
|
||||||
│ ├── common/
|
│ ├── common/
|
||||||
│ │ ├── cm-common.yaml
|
│ │ ├── cm-common.yaml
|
||||||
│ │ ├── secret-common.yaml
|
│ │ ├── secret-common.yaml
|
||||||
│ │ └── ingress.yaml
|
│ │ └── ingress.yaml
|
||||||
│ ├── api-gateway/
|
│ ├── api-gateway/
|
||||||
|
│ │ ├── deployment.yaml
|
||||||
|
│ │ ├── service.yaml
|
||||||
|
│ │ └── cm-api-gateway.yaml
|
||||||
│ ├── user-service/
|
│ ├── user-service/
|
||||||
|
│ │ ├── deployment.yaml
|
||||||
|
│ │ ├── service.yaml
|
||||||
|
│ │ ├── cm-user-service.yaml
|
||||||
|
│ │ └── secret-user-service.yaml
|
||||||
│ ├── bill-service/
|
│ ├── bill-service/
|
||||||
|
│ │ ├── deployment.yaml
|
||||||
|
│ │ ├── service.yaml
|
||||||
|
│ │ ├── cm-bill-service.yaml
|
||||||
|
│ │ └── secret-bill-service.yaml
|
||||||
│ ├── product-service/
|
│ ├── product-service/
|
||||||
|
│ │ ├── deployment.yaml
|
||||||
|
│ │ ├── service.yaml
|
||||||
|
│ │ ├── cm-product-service.yaml
|
||||||
|
│ │ └── secret-product-service.yaml
|
||||||
│ └── kos-mock/
|
│ └── kos-mock/
|
||||||
|
│ ├── deployment.yaml
|
||||||
|
│ ├── service.yaml
|
||||||
|
│ └── cm-kos-mock.yaml
|
||||||
└── overlays/
|
└── overlays/
|
||||||
├── dev/
|
├── dev/ # 개발 환경 오버레이
|
||||||
├── staging/
|
├── staging/ # 스테이징 환경 오버레이
|
||||||
└── prod/
|
└── prod/ # 운영 환경 오버레이
|
||||||
```
|
```
|
||||||
|
|
||||||
### 2.2 환경별 설정 차이
|
## 🚀 Jenkins Pipeline Job 생성
|
||||||
|
|
||||||
| 항목 | dev | staging | prod |
|
### 1. Pipeline Job 생성
|
||||||
|------|-----|---------|------|
|
1. Jenkins 웹 UI에서 **New Item** > **Pipeline** 선택
|
||||||
| Namespace | phonebill | phonebill-staging | phonebill-prod |
|
2. Pipeline script from SCM 설정:
|
||||||
| Replicas | 1 | 2 | 3 |
|
|
||||||
| CPU Requests | 256m | 512m | 1024m |
|
|
||||||
| Memory Requests | 256Mi | 512Mi | 1024Mi |
|
|
||||||
| CPU Limits | 1024m | 2048m | 4096m |
|
|
||||||
| Memory Limits | 1024Mi | 2048Mi | 4096Mi |
|
|
||||||
| DDL_AUTO | update | validate | validate |
|
|
||||||
| SHOW_SQL | true | false | false |
|
|
||||||
| SSL Redirect | false | true | true |
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 3. Jenkins Pipeline Job 생성
|
|
||||||
|
|
||||||
### 3.1 New Item > Pipeline 선택
|
|
||||||
|
|
||||||
### 3.2 Pipeline 설정
|
|
||||||
```
|
```
|
||||||
SCM: Git
|
SCM: Git
|
||||||
Repository URL: {Git저장소URL}
|
Repository URL: {Git저장소URL}
|
||||||
@ -122,54 +117,68 @@ Branch: main (또는 develop)
|
|||||||
Script Path: deployment/cicd/Jenkinsfile
|
Script Path: deployment/cicd/Jenkinsfile
|
||||||
```
|
```
|
||||||
|
|
||||||
### 3.3 Pipeline Parameters 설정
|
### 2. Pipeline Parameters 설정
|
||||||
| 파라미터 | 타입 | 기본값 | 설명 |
|
| 파라미터 | 타입 | 값 | 설명 |
|
||||||
|----------|------|--------|------|
|
|---------|------|-----|------|
|
||||||
| ENVIRONMENT | Choice | dev | 배포 환경 (dev/staging/prod) |
|
| ENVIRONMENT | Choice | dev, staging, prod | 배포 대상 환경 |
|
||||||
| SKIP_SONARQUBE | String | true | SonarQube 분석 건너뛰기 (true/false) |
|
| IMAGE_TAG | String | latest | 이미지 태그 (선택) |
|
||||||
|
| SKIP_SONARQUBE | String | true | SonarQube 분석 건너뛰기 |
|
||||||
|
|
||||||
---
|
## ⚙️ 환경별 설정
|
||||||
|
|
||||||
## 4. 파이프라인 스테이지
|
### DEV 환경
|
||||||
|
```yaml
|
||||||
|
# Replicas: 1
|
||||||
|
# Resources:
|
||||||
|
# requests: 256m CPU, 256Mi Memory
|
||||||
|
# limits: 1024m CPU, 1024Mi Memory
|
||||||
|
# DDL_AUTO: update
|
||||||
|
# HTTPS: 비활성화
|
||||||
|
```
|
||||||
|
|
||||||
### 4.1 Get Source
|
### STAGING 환경
|
||||||
- Git 저장소에서 소스 코드 체크아웃
|
```yaml
|
||||||
- 환경별 설정 파일 로드
|
# Replicas: 2
|
||||||
|
# Resources:
|
||||||
|
# requests: 512m CPU, 512Mi Memory
|
||||||
|
# limits: 2048m CPU, 2048Mi Memory
|
||||||
|
# DDL_AUTO: validate
|
||||||
|
# HTTPS: 활성화 (SSL 인증서 필요)
|
||||||
|
```
|
||||||
|
|
||||||
### 4.2 Setup Kubernetes
|
### PROD 환경
|
||||||
- Kubernetes 컨텍스트 설정
|
```yaml
|
||||||
- 네임스페이스 생성
|
# Replicas: 3
|
||||||
|
# Resources:
|
||||||
|
# requests: 1024m CPU, 1024Mi Memory
|
||||||
|
# limits: 4096m CPU, 4096Mi Memory
|
||||||
|
# DDL_AUTO: validate
|
||||||
|
# HTTPS: 활성화 (SSL 인증서 필요)
|
||||||
|
```
|
||||||
|
|
||||||
### 4.3 Build
|
## 📊 SonarQube 설정
|
||||||
- Gradle을 사용한 빌드 (테스트 제외)
|
|
||||||
- `./gradlew build -x test`
|
|
||||||
|
|
||||||
### 4.4 SonarQube Analysis & Quality Gate (선택사항)
|
### Quality Gate 설정
|
||||||
- SKIP_SONARQUBE=false일 때만 실행
|
```
|
||||||
- 각 서비스별 테스트 및 코드 품질 분석
|
Coverage: >= 80%
|
||||||
- Quality Gate 통과 확인
|
Duplicated Lines: <= 3%
|
||||||
|
Maintainability Rating: <= A
|
||||||
|
Reliability Rating: <= A
|
||||||
|
Security Rating: <= A
|
||||||
|
```
|
||||||
|
|
||||||
### 4.5 Build & Push Images
|
### 분석 제외 대상
|
||||||
- Podman을 사용한 컨테이너 이미지 빌드
|
```
|
||||||
- Docker Hub로 이미지 푸시
|
**/config/**
|
||||||
- 이미지 태그: `{환경}-{타임스탬프}`
|
**/entity/**
|
||||||
|
**/dto/**
|
||||||
|
**/*Application.class
|
||||||
|
**/exception/**
|
||||||
|
```
|
||||||
|
|
||||||
### 4.6 Update Kustomize & Deploy
|
## 🔨 수동 배포
|
||||||
- Kustomize를 사용한 이미지 태그 업데이트
|
|
||||||
- Kubernetes 매니페스트 적용
|
|
||||||
- 배포 상태 확인
|
|
||||||
|
|
||||||
---
|
### 배포 스크립트 사용
|
||||||
|
|
||||||
## 5. 배포 실행
|
|
||||||
|
|
||||||
### 5.1 Jenkins 파이프라인 실행
|
|
||||||
1. Jenkins > phonebill > Build with Parameters
|
|
||||||
2. ENVIRONMENT 선택 (dev/staging/prod)
|
|
||||||
3. SKIP_SONARQUBE 입력 (true 또는 false)
|
|
||||||
4. Build 클릭
|
|
||||||
|
|
||||||
### 5.2 수동 배포 (스크립트 사용)
|
|
||||||
```bash
|
```bash
|
||||||
# dev 환경 배포
|
# dev 환경 배포
|
||||||
./deployment/cicd/scripts/deploy.sh dev latest
|
./deployment/cicd/scripts/deploy.sh dev latest
|
||||||
@ -181,131 +190,100 @@ Script Path: deployment/cicd/Jenkinsfile
|
|||||||
./deployment/cicd/scripts/deploy.sh prod v1.0.0
|
./deployment/cicd/scripts/deploy.sh prod v1.0.0
|
||||||
```
|
```
|
||||||
|
|
||||||
### 5.3 배포 상태 확인
|
### 리소스 검증
|
||||||
```bash
|
```bash
|
||||||
# Pod 상태 확인
|
# Kustomize 리소스 검증
|
||||||
|
./deployment/cicd/scripts/validate-resources.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
## 🔄 배포 상태 확인
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# 파드 상태 확인
|
||||||
kubectl get pods -n phonebill
|
kubectl get pods -n phonebill
|
||||||
|
|
||||||
# 서비스 상태 확인
|
# 서비스 상태 확인
|
||||||
kubectl get services -n phonebill
|
kubectl get services -n phonebill
|
||||||
|
|
||||||
# Ingress 상태 확인
|
# 인그레스 확인
|
||||||
kubectl get ingress -n phonebill
|
kubectl get ingress -n phonebill
|
||||||
|
|
||||||
# 특정 Pod 로그 확인
|
# 배포 상태 상세 확인
|
||||||
kubectl logs -f deployment/api-gateway -n phonebill
|
kubectl describe deployment api-gateway -n phonebill
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
## ⏪ 롤백 방법
|
||||||
|
|
||||||
## 6. 롤백
|
### 이전 버전으로 롤백
|
||||||
|
|
||||||
### 6.1 이전 버전으로 롤백
|
|
||||||
```bash
|
```bash
|
||||||
# 특정 리비전으로 롤백
|
# 특정 리비전으로 롤백
|
||||||
kubectl rollout undo deployment/{서비스명} -n phonebill --to-revision=2
|
kubectl rollout undo deployment/{서비스명} -n phonebill --to-revision=2
|
||||||
|
|
||||||
# 롤백 상태 확인
|
# 롤백 상태 확인
|
||||||
kubectl rollout status deployment/{서비스명} -n phonebill
|
kubectl rollout status deployment/{서비스명} -n phonebill
|
||||||
|
|
||||||
# 롤백 히스토리 확인
|
|
||||||
kubectl rollout history deployment/{서비스명} -n phonebill
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### 6.2 이미지 태그 기반 롤백
|
### 이미지 태그 기반 롤백
|
||||||
```bash
|
```bash
|
||||||
cd deployment/cicd/kustomize/overlays/{환경}
|
|
||||||
|
|
||||||
# 이전 안정 버전 이미지 태그로 업데이트
|
# 이전 안정 버전 이미지 태그로 업데이트
|
||||||
kustomize edit set image docker.io/hiondal/{서비스명}:{환경}-{이전태그}
|
cd deployment/cicd/kustomize/overlays/{환경}
|
||||||
|
kustomize edit set image docker.io/hiondal/{서비스명}=docker.io/hiondal/{서비스명}:{환경}-{이전태그}
|
||||||
# 배포
|
|
||||||
kubectl apply -k .
|
kubectl apply -k .
|
||||||
```
|
```
|
||||||
|
|
||||||
---
|
## 🔍 문제 해결
|
||||||
|
|
||||||
## 7. 리소스 검증
|
### 일반적인 문제
|
||||||
|
|
||||||
### 7.1 검증 스크립트 실행
|
#### 1. 이미지 풀 실패
|
||||||
```bash
|
```bash
|
||||||
|
# ImagePullBackOff 상태 확인
|
||||||
|
kubectl describe pod {pod-name} -n phonebill
|
||||||
|
|
||||||
|
# Docker Hub 인증 확인
|
||||||
|
kubectl get secret -n phonebill
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 2. 파드 시작 실패
|
||||||
|
```bash
|
||||||
|
# 로그 확인
|
||||||
|
kubectl logs {pod-name} -n phonebill
|
||||||
|
|
||||||
|
# 이벤트 확인
|
||||||
|
kubectl get events -n phonebill --sort-by='.lastTimestamp'
|
||||||
|
```
|
||||||
|
|
||||||
|
#### 3. Kustomize 빌드 실패
|
||||||
|
```bash
|
||||||
|
# 검증 스크립트 실행
|
||||||
./deployment/cicd/scripts/validate-resources.sh
|
./deployment/cicd/scripts/validate-resources.sh
|
||||||
|
|
||||||
|
# 직접 빌드 테스트
|
||||||
|
kubectl kustomize deployment/cicd/kustomize/overlays/dev
|
||||||
```
|
```
|
||||||
|
|
||||||
### 7.2 Kustomize 빌드 테스트
|
### Jenkins 파이프라인 문제
|
||||||
```bash
|
|
||||||
# Base 빌드 테스트
|
|
||||||
kubectl kustomize deployment/cicd/kustomize/base/
|
|
||||||
|
|
||||||
# 환경별 빌드 테스트
|
#### 1. Pod 정리가 안 되는 경우
|
||||||
kubectl kustomize deployment/cicd/kustomize/overlays/dev/
|
- `podRetention: never()` 설정 확인
|
||||||
kubectl kustomize deployment/cicd/kustomize/overlays/staging/
|
- `terminationGracePeriodSeconds: 3` 설정 확인
|
||||||
kubectl kustomize deployment/cicd/kustomize/overlays/prod/
|
- Jenkins Kubernetes Plugin 버전 확인
|
||||||
```
|
|
||||||
|
|
||||||
---
|
#### 2. 변수 치환 오류
|
||||||
|
- `${variable}` 사용 (Groovy 문자열 보간)
|
||||||
|
- `\${variable}` 사용 금지 (bash 이스케이프)
|
||||||
|
|
||||||
## 8. SonarQube 설정 (선택사항)
|
## 📝 체크리스트
|
||||||
|
|
||||||
### 8.1 Quality Gate 권장 설정
|
### 배포 전 확인
|
||||||
```
|
- [ ] 환경 변수 파일 설정 완료
|
||||||
Coverage: >= 80%
|
|
||||||
Duplicated Lines: <= 3%
|
|
||||||
Maintainability Rating: <= A
|
|
||||||
Reliability Rating: <= A
|
|
||||||
Security Rating: <= A
|
|
||||||
```
|
|
||||||
|
|
||||||
### 8.2 SonarQube 프로젝트 생성
|
|
||||||
각 서비스별로 다음 형식의 프로젝트 키로 생성:
|
|
||||||
- `phonebill-user-service-dev`
|
|
||||||
- `phonebill-user-service-staging`
|
|
||||||
- `phonebill-user-service-prod`
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 9. 트러블슈팅
|
|
||||||
|
|
||||||
### 9.1 이미지 푸시 실패
|
|
||||||
- Docker Hub 인증 정보 확인
|
|
||||||
- Rate Limit 확인 (무료 계정 제한)
|
|
||||||
|
|
||||||
### 9.2 배포 실패
|
|
||||||
```bash
|
|
||||||
# Pod 이벤트 확인
|
|
||||||
kubectl describe pod {POD_NAME} -n phonebill
|
|
||||||
|
|
||||||
# Pod 로그 확인
|
|
||||||
kubectl logs {POD_NAME} -n phonebill
|
|
||||||
```
|
|
||||||
|
|
||||||
### 9.3 Kustomize 빌드 실패
|
|
||||||
- 리소스 파일 존재 여부 확인
|
|
||||||
- YAML 문법 검증
|
|
||||||
- `kubectl kustomize` 명령으로 디버깅
|
|
||||||
|
|
||||||
### 9.4 SonarQube 연결 실패
|
|
||||||
- SonarQube 서버 URL 확인
|
|
||||||
- 인증 토큰 유효성 확인
|
|
||||||
- 네트워크 연결 확인
|
|
||||||
|
|
||||||
---
|
|
||||||
|
|
||||||
## 10. 체크리스트
|
|
||||||
|
|
||||||
### 사전 준비
|
|
||||||
- [ ] Jenkins 필수 플러그인 설치 완료
|
|
||||||
- [ ] Docker Hub Credentials 등록 완료
|
|
||||||
- [ ] SonarQube Token 등록 완료 (선택)
|
|
||||||
- [ ] Kubernetes 컨텍스트 설정 완료
|
- [ ] Kubernetes 컨텍스트 설정 완료
|
||||||
|
- [ ] 이미지 레지스트리 인증 설정
|
||||||
|
- [ ] 네임스페이스 생성 완료
|
||||||
|
- [ ] 백킹 서비스(DB, Redis) 준비 완료
|
||||||
|
|
||||||
### 배포 전
|
### 배포 후 확인
|
||||||
- [ ] 리소스 검증 스크립트 실행 완료
|
- [ ] 모든 파드 Running 상태 확인
|
||||||
- [ ] 환경별 설정 파일 확인 완료
|
- [ ] 서비스 엔드포인트 정상 응답
|
||||||
- [ ] Kustomize 빌드 테스트 완료
|
- [ ] 로그에 에러 없음
|
||||||
|
- [ ] 헬스체크 정상 통과
|
||||||
### 배포 후
|
|
||||||
- [ ] Pod 상태 확인 (Running)
|
|
||||||
- [ ] 서비스 엔드포인트 확인
|
|
||||||
- [ ] Ingress 접근 테스트
|
|
||||||
- [ ] 로그 이상 여부 확인
|
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: api-gateway-config
|
name: cm-api-gateway
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: api-gateway
|
app: api-gateway
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: api-gateway
|
name: api-gateway
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: api-gateway
|
app: api-gateway
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
@ -25,11 +24,11 @@ spec:
|
|||||||
name: http
|
name: http
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: api-gateway-config
|
name: cm-api-gateway
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: "256m"
|
cpu: "256m"
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: api-gateway
|
name: api-gateway
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: api-gateway
|
app: api-gateway
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service-config
|
name: cm-bill-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service
|
name: bill-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
@ -25,13 +24,13 @@ spec:
|
|||||||
name: http
|
name: http
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: bill-service-config
|
name: cm-bill-service
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: "256m"
|
cpu: "256m"
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service
|
name: bill-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
data:
|
data:
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: networking.k8s.io/v1
|
|||||||
kind: Ingress
|
kind: Ingress
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-ingress
|
name: phonebill-ingress
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
annotations:
|
annotations:
|
||||||
@ -10,6 +9,7 @@ metadata:
|
|||||||
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
|
nginx.ingress.kubernetes.io/proxy-read-timeout: "60"
|
||||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
|
||||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
||||||
|
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
rules:
|
rules:
|
||||||
|
|||||||
@ -1,13 +1,10 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
# JWT Secret (최소 256비트 이상, HS256 알고리즘용)
|
|
||||||
JWT_SECRET: "EK1ZV7vROOXREXbYe/BCISdQq0Yklk9JtoA2v88ux1DBDc0bDGiRRxHeDSb7GHkDP9IUYHMVsBi4/1rS4OhfRg=="
|
JWT_SECRET: "EK1ZV7vROOXREXbYe/BCISdQq0Yklk9JtoA2v88ux1DBDc0bDGiRRxHeDSb7GHkDP9IUYHMVsBi4/1rS4OhfRg=="
|
||||||
# Redis 비밀번호 (비밀번호 없는 경우 빈 값)
|
|
||||||
REDIS_PASSWORD: "P@ssw0rd$"
|
REDIS_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: kos-mock-config
|
name: cm-kos-mock
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: kos-mock
|
app: kos-mock
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: kos-mock
|
name: kos-mock
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: kos-mock
|
app: kos-mock
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
@ -25,11 +24,11 @@ spec:
|
|||||||
name: http
|
name: http
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: kos-mock-config
|
name: cm-kos-mock
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: "256m"
|
cpu: "256m"
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: kos-mock
|
name: kos-mock
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: kos-mock
|
app: kos-mock
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service-config
|
name: cm-product-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service
|
name: product-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
@ -25,13 +24,13 @@ spec:
|
|||||||
name: http
|
name: http
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: product-service-config
|
name: cm-product-service
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: "256m"
|
cpu: "256m"
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service
|
name: product-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service-config
|
name: cm-user-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: apps/v1
|
|||||||
kind: Deployment
|
kind: Deployment
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service
|
name: user-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
@ -25,13 +24,13 @@ spec:
|
|||||||
name: http
|
name: http
|
||||||
envFrom:
|
envFrom:
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- configMapRef:
|
- configMapRef:
|
||||||
name: user-service-config
|
name: cm-user-service
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- secretRef:
|
- secretRef:
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
resources:
|
resources:
|
||||||
requests:
|
requests:
|
||||||
cpu: "256m"
|
cpu: "256m"
|
||||||
|
|||||||
@ -1,8 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -2,7 +2,6 @@ apiVersion: v1
|
|||||||
kind: Service
|
kind: Service
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service
|
name: user-service
|
||||||
|
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
data:
|
data:
|
||||||
|
|||||||
@ -7,21 +7,18 @@ resources:
|
|||||||
- ../../base
|
- ../../base
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
# Common patches
|
|
||||||
- path: cm-common-patch.yaml
|
- path: cm-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- path: secret-common-patch.yaml
|
- path: secret-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- path: ingress-patch.yaml
|
- path: ingress-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
name: phonebill-ingress
|
name: phonebill-ingress
|
||||||
|
|
||||||
# Deployment patches
|
|
||||||
- path: deployment-api-gateway-patch.yaml
|
- path: deployment-api-gateway-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@ -42,29 +39,27 @@ patches:
|
|||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: kos-mock
|
name: kos-mock
|
||||||
|
|
||||||
# Service Secret patches
|
|
||||||
- path: secret-user-service-patch.yaml
|
- path: secret-user-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
- path: secret-bill-service-patch.yaml
|
- path: secret-bill-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
- path: secret-product-service-patch.yaml
|
- path: secret-product-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
|
|
||||||
images:
|
images:
|
||||||
- name: docker.io/hiondal/api-gateway
|
- name: docker.io/hiondal/api-gateway
|
||||||
newTag: latest
|
newTag: dev-latest
|
||||||
- name: docker.io/hiondal/user-service
|
- name: docker.io/hiondal/user-service
|
||||||
newTag: latest
|
newTag: dev-latest
|
||||||
- name: docker.io/hiondal/bill-service
|
- name: docker.io/hiondal/bill-service
|
||||||
newTag: latest
|
newTag: dev-latest
|
||||||
- name: docker.io/hiondal/product-service
|
- name: docker.io/hiondal/product-service
|
||||||
newTag: latest
|
newTag: dev-latest
|
||||||
- name: docker.io/hiondal/kos-mock
|
- name: docker.io/hiondal/kos-mock
|
||||||
newTag: latest
|
newTag: dev-latest
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
data:
|
data:
|
||||||
|
|||||||
@ -16,7 +16,7 @@ spec:
|
|||||||
tls:
|
tls:
|
||||||
- hosts:
|
- hosts:
|
||||||
- phonebill.example.com
|
- phonebill.example.com
|
||||||
secretName: phonebill-prod-tls
|
secretName: phonebill-tls
|
||||||
rules:
|
rules:
|
||||||
- host: phonebill.example.com
|
- host: phonebill.example.com
|
||||||
http:
|
http:
|
||||||
|
|||||||
@ -1,27 +1,24 @@
|
|||||||
apiVersion: kustomize.config.k8s.io/v1beta1
|
apiVersion: kustomize.config.k8s.io/v1beta1
|
||||||
kind: Kustomization
|
kind: Kustomization
|
||||||
|
|
||||||
namespace: phonebill-prod
|
namespace: phonebill
|
||||||
|
|
||||||
resources:
|
resources:
|
||||||
- ../../base
|
- ../../base
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
# Common patches
|
|
||||||
- path: cm-common-patch.yaml
|
- path: cm-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- path: secret-common-patch.yaml
|
- path: secret-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- path: ingress-patch.yaml
|
- path: ingress-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
name: phonebill-ingress
|
name: phonebill-ingress
|
||||||
|
|
||||||
# Deployment patches
|
|
||||||
- path: deployment-api-gateway-patch.yaml
|
- path: deployment-api-gateway-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@ -42,29 +39,27 @@ patches:
|
|||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: kos-mock
|
name: kos-mock
|
||||||
|
|
||||||
# Service Secret patches
|
|
||||||
- path: secret-user-service-patch.yaml
|
- path: secret-user-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
- path: secret-bill-service-patch.yaml
|
- path: secret-bill-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
- path: secret-product-service-patch.yaml
|
- path: secret-product-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
|
|
||||||
images:
|
images:
|
||||||
- name: docker.io/hiondal/api-gateway
|
- name: docker.io/hiondal/api-gateway
|
||||||
newTag: latest
|
newTag: prod-latest
|
||||||
- name: docker.io/hiondal/user-service
|
- name: docker.io/hiondal/user-service
|
||||||
newTag: latest
|
newTag: prod-latest
|
||||||
- name: docker.io/hiondal/bill-service
|
- name: docker.io/hiondal/bill-service
|
||||||
newTag: latest
|
newTag: prod-latest
|
||||||
- name: docker.io/hiondal/product-service
|
- name: docker.io/hiondal/product-service
|
||||||
newTag: latest
|
newTag: prod-latest
|
||||||
- name: docker.io/hiondal/kos-mock
|
- name: docker.io/hiondal/kos-mock
|
||||||
newTag: latest
|
newTag: prod-latest
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "PROD_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
JWT_SECRET: "PROD_JWT_SECRET_REPLACE_WITH_SECURE_VALUE"
|
JWT_SECRET: "EK1ZV7vROOXREXbYe/BCISdQq0Yklk9JtoA2v88ux1DBDc0bDGiRRxHeDSb7GHkDP9IUYHMVsBi4/1rS4OhfRg=="
|
||||||
REDIS_PASSWORD: "PROD_REDIS_PASSWORD"
|
REDIS_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "PROD_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "PROD_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,7 +1,7 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
data:
|
data:
|
||||||
|
|||||||
@ -10,7 +10,7 @@ metadata:
|
|||||||
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
|
nginx.ingress.kubernetes.io/proxy-send-timeout: "60"
|
||||||
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
nginx.ingress.kubernetes.io/proxy-connect-timeout: "60"
|
||||||
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
nginx.ingress.kubernetes.io/ssl-redirect: "true"
|
||||||
cert-manager.io/cluster-issuer: "letsencrypt-staging"
|
cert-manager.io/cluster-issuer: "letsencrypt-prod"
|
||||||
spec:
|
spec:
|
||||||
ingressClassName: nginx
|
ingressClassName: nginx
|
||||||
tls:
|
tls:
|
||||||
|
|||||||
@ -7,21 +7,18 @@ resources:
|
|||||||
- ../../base
|
- ../../base
|
||||||
|
|
||||||
patches:
|
patches:
|
||||||
# Common patches
|
|
||||||
- path: cm-common-patch.yaml
|
- path: cm-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: ConfigMap
|
kind: ConfigMap
|
||||||
name: phonebill-common-config
|
name: cm-common
|
||||||
- path: secret-common-patch.yaml
|
- path: secret-common-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
- path: ingress-patch.yaml
|
- path: ingress-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Ingress
|
kind: Ingress
|
||||||
name: phonebill-ingress
|
name: phonebill-ingress
|
||||||
|
|
||||||
# Deployment patches
|
|
||||||
- path: deployment-api-gateway-patch.yaml
|
- path: deployment-api-gateway-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
@ -42,29 +39,27 @@ patches:
|
|||||||
target:
|
target:
|
||||||
kind: Deployment
|
kind: Deployment
|
||||||
name: kos-mock
|
name: kos-mock
|
||||||
|
|
||||||
# Service Secret patches
|
|
||||||
- path: secret-user-service-patch.yaml
|
- path: secret-user-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
- path: secret-bill-service-patch.yaml
|
- path: secret-bill-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
- path: secret-product-service-patch.yaml
|
- path: secret-product-service-patch.yaml
|
||||||
target:
|
target:
|
||||||
kind: Secret
|
kind: Secret
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
|
|
||||||
images:
|
images:
|
||||||
- name: docker.io/hiondal/api-gateway
|
- name: docker.io/hiondal/api-gateway
|
||||||
newTag: latest
|
newTag: staging-latest
|
||||||
- name: docker.io/hiondal/user-service
|
- name: docker.io/hiondal/user-service
|
||||||
newTag: latest
|
newTag: staging-latest
|
||||||
- name: docker.io/hiondal/bill-service
|
- name: docker.io/hiondal/bill-service
|
||||||
newTag: latest
|
newTag: staging-latest
|
||||||
- name: docker.io/hiondal/product-service
|
- name: docker.io/hiondal/product-service
|
||||||
newTag: latest
|
newTag: staging-latest
|
||||||
- name: docker.io/hiondal/kos-mock
|
- name: docker.io/hiondal/kos-mock
|
||||||
newTag: latest
|
newTag: staging-latest
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: bill-service-db-secret
|
name: secret-bill-service
|
||||||
labels:
|
labels:
|
||||||
app: bill-service
|
app: bill-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "STAGING_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,10 +1,10 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: phonebill-common-secret
|
name: secret-common
|
||||||
labels:
|
labels:
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
JWT_SECRET: "STAGING_JWT_SECRET_REPLACE_WITH_SECURE_VALUE"
|
JWT_SECRET: "EK1ZV7vROOXREXbYe/BCISdQq0Yklk9JtoA2v88ux1DBDc0bDGiRRxHeDSb7GHkDP9IUYHMVsBi4/1rS4OhfRg=="
|
||||||
REDIS_PASSWORD: "STAGING_REDIS_PASSWORD"
|
REDIS_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: product-service-db-secret
|
name: secret-product-service
|
||||||
labels:
|
labels:
|
||||||
app: product-service
|
app: product-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "STAGING_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -1,11 +1,11 @@
|
|||||||
apiVersion: v1
|
apiVersion: v1
|
||||||
kind: Secret
|
kind: Secret
|
||||||
metadata:
|
metadata:
|
||||||
name: user-service-db-secret
|
name: secret-user-service
|
||||||
labels:
|
labels:
|
||||||
app: user-service
|
app: user-service
|
||||||
app.kubernetes.io/part-of: phonebill
|
app.kubernetes.io/part-of: phonebill
|
||||||
type: Opaque
|
type: Opaque
|
||||||
stringData:
|
stringData:
|
||||||
DB_USERNAME: "unicorn"
|
DB_USERNAME: "unicorn"
|
||||||
DB_PASSWORD: "STAGING_DB_PASSWORD"
|
DB_PASSWORD: "P@ssw0rd$"
|
||||||
|
|||||||
@ -4,35 +4,32 @@ set -e
|
|||||||
ENVIRONMENT=${1:-dev}
|
ENVIRONMENT=${1:-dev}
|
||||||
IMAGE_TAG=${2:-latest}
|
IMAGE_TAG=${2:-latest}
|
||||||
|
|
||||||
echo "🚀 Deploying to ${ENVIRONMENT} environment with tag ${IMAGE_TAG}..."
|
echo "🚀 Starting deployment to ${ENVIRONMENT} environment..."
|
||||||
|
|
||||||
# 환경별 설정 파일 로드
|
|
||||||
source "$(dirname "$0")/../config/deploy_env_vars_${ENVIRONMENT}"
|
|
||||||
|
|
||||||
# 환경별 이미지 태그 업데이트
|
# 환경별 이미지 태그 업데이트
|
||||||
cd "$(dirname "$0")/../kustomize/overlays/${ENVIRONMENT}"
|
cd deployment/cicd/kustomize/overlays/${ENVIRONMENT}
|
||||||
|
|
||||||
# 서비스 목록
|
# 서비스 목록 (공백으로 구분)
|
||||||
services="api-gateway user-service bill-service product-service kos-mock"
|
services="api-gateway user-service bill-service product-service kos-mock"
|
||||||
|
|
||||||
# 각 서비스 이미지 태그 업데이트
|
# 각 서비스 이미지 태그 업데이트
|
||||||
for service in $services; do
|
for service in $services; do
|
||||||
echo "📦 Updating image tag for ${service}..."
|
echo "📦 Updating image tag for ${service}..."
|
||||||
kustomize edit set image docker.io/hiondal/$service:${ENVIRONMENT}-${IMAGE_TAG}
|
kustomize edit set image docker.io/hiondal/$service=docker.io/hiondal/$service:${ENVIRONMENT}-${IMAGE_TAG}
|
||||||
done
|
done
|
||||||
|
|
||||||
# 배포 실행
|
# 배포 실행
|
||||||
echo "📋 Applying Kustomize manifests..."
|
echo "📤 Applying Kubernetes manifests..."
|
||||||
kubectl apply -k .
|
kubectl apply -k .
|
||||||
|
|
||||||
# 배포 상태 확인
|
# 배포 상태 확인
|
||||||
echo "⏳ Waiting for deployments to be ready..."
|
echo "⏳ Waiting for deployments to be ready..."
|
||||||
for service in $services; do
|
for service in $services; do
|
||||||
echo " Checking ${service}..."
|
echo " Checking ${service}..."
|
||||||
kubectl rollout status deployment/$service -n ${namespace} --timeout=300s || echo " ⚠️ Timeout waiting for ${service}"
|
kubectl rollout status deployment/$service -n phonebill --timeout=300s
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "✅ Deployment completed successfully!"
|
echo "✅ Deployment completed successfully!"
|
||||||
echo ""
|
echo ""
|
||||||
echo "📊 Current status:"
|
echo "📊 Current deployment status:"
|
||||||
kubectl get pods -n ${namespace}
|
kubectl get pods -n phonebill
|
||||||
|
|||||||
@ -1,10 +1,12 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Base 리소스 누락 검증 스크립트
|
# Base 리소스 누락 검증 스크립트 (phonebill)
|
||||||
|
|
||||||
echo "🔍 Phonebill Base 리소스 누락 검증 시작..."
|
echo "🔍 phonebill Base 리소스 누락 검증 시작..."
|
||||||
|
|
||||||
BASE_DIR="deployment/cicd/kustomize/base"
|
BASE_DIR="deployment/cicd/kustomize/base"
|
||||||
MISSING_RESOURCES=0
|
MISSING_RESOURCES=0
|
||||||
|
REQUIRED_FILES=("deployment.yaml" "service.yaml")
|
||||||
|
OPTIONAL_FILES=("cm-" "secret-")
|
||||||
|
|
||||||
# 1. 각 서비스 디렉토리의 파일 확인
|
# 1. 각 서비스 디렉토리의 파일 확인
|
||||||
echo ""
|
echo ""
|
||||||
@ -15,33 +17,24 @@ for dir in $BASE_DIR/*/; do
|
|||||||
echo "=== $service ==="
|
echo "=== $service ==="
|
||||||
|
|
||||||
# 필수 파일 확인
|
# 필수 파일 확인
|
||||||
if [ -f "$dir/deployment.yaml" ]; then
|
for required in "${REQUIRED_FILES[@]}"; do
|
||||||
echo " ✅ deployment.yaml"
|
if [ -f "$dir$required" ]; then
|
||||||
|
echo " ✅ $required"
|
||||||
else
|
else
|
||||||
echo " ❌ MISSING REQUIRED: deployment.yaml"
|
echo " ❌ MISSING REQUIRED: $required"
|
||||||
((MISSING_RESOURCES++))
|
((MISSING_RESOURCES++))
|
||||||
fi
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
if [ -f "$dir/service.yaml" ]; then
|
# 선택적 파일 확인
|
||||||
echo " ✅ service.yaml"
|
for optional in "${OPTIONAL_FILES[@]}"; do
|
||||||
else
|
files=($(ls "$dir"$optional*".yaml" 2>/dev/null))
|
||||||
echo " ❌ MISSING REQUIRED: service.yaml"
|
if [ ${#files[@]} -gt 0 ]; then
|
||||||
((MISSING_RESOURCES++))
|
for file in "${files[@]}"; do
|
||||||
fi
|
|
||||||
|
|
||||||
# ConfigMap 확인
|
|
||||||
if ls "$dir"cm-*.yaml 1> /dev/null 2>&1; then
|
|
||||||
for file in "$dir"cm-*.yaml; do
|
|
||||||
echo " ✅ $(basename "$file")"
|
echo " ✅ $(basename "$file")"
|
||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Secret 확인
|
|
||||||
if ls "$dir"secret-*.yaml 1> /dev/null 2>&1; then
|
|
||||||
for file in "$dir"secret-*.yaml; do
|
|
||||||
echo " ✅ $(basename "$file")"
|
|
||||||
done
|
done
|
||||||
fi
|
|
||||||
echo ""
|
echo ""
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
@ -50,11 +43,15 @@ done
|
|||||||
echo "2. Common 리소스 확인:"
|
echo "2. Common 리소스 확인:"
|
||||||
COMMON_DIR="$BASE_DIR/common"
|
COMMON_DIR="$BASE_DIR/common"
|
||||||
if [ -d "$COMMON_DIR" ]; then
|
if [ -d "$COMMON_DIR" ]; then
|
||||||
for file in "$COMMON_DIR"/*.yaml; do
|
common_files=($(ls "$COMMON_DIR"/*.yaml 2>/dev/null))
|
||||||
if [ -f "$file" ]; then
|
if [ ${#common_files[@]} -gt 0 ]; then
|
||||||
|
for file in "${common_files[@]}"; do
|
||||||
echo " ✅ common/$(basename "$file")"
|
echo " ✅ common/$(basename "$file")"
|
||||||
fi
|
|
||||||
done
|
done
|
||||||
|
else
|
||||||
|
echo " ❌ Common 디렉토리에 YAML 파일이 없습니다"
|
||||||
|
((MISSING_RESOURCES++))
|
||||||
|
fi
|
||||||
else
|
else
|
||||||
echo " ❌ Common 디렉토리가 없습니다"
|
echo " ❌ Common 디렉토리가 없습니다"
|
||||||
((MISSING_RESOURCES++))
|
((MISSING_RESOURCES++))
|
||||||
@ -65,8 +62,9 @@ echo ""
|
|||||||
echo "3. kustomization.yaml 리소스 검증:"
|
echo "3. kustomization.yaml 리소스 검증:"
|
||||||
if [ -f "$BASE_DIR/kustomization.yaml" ]; then
|
if [ -f "$BASE_DIR/kustomization.yaml" ]; then
|
||||||
while IFS= read -r line; do
|
while IFS= read -r line; do
|
||||||
|
# resources 섹션의 YAML 파일 경로 추출
|
||||||
if [[ $line =~ ^[[:space:]]*-[[:space:]]*([^#]+\.yaml)[[:space:]]*$ ]]; then
|
if [[ $line =~ ^[[:space:]]*-[[:space:]]*([^#]+\.yaml)[[:space:]]*$ ]]; then
|
||||||
resource_path=$(echo "${BASH_REMATCH[1]}" | xargs)
|
resource_path=$(echo "${BASH_REMATCH[1]}" | xargs) # 공백 제거
|
||||||
full_path="$BASE_DIR/$resource_path"
|
full_path="$BASE_DIR/$resource_path"
|
||||||
if [ -f "$full_path" ]; then
|
if [ -f "$full_path" ]; then
|
||||||
echo " ✅ $resource_path"
|
echo " ✅ $resource_path"
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user