GitHub Actions CI/CD 파이프라인 구축 완료

- Kustomize 기반 환경별 배포 자동화 구현
- dev/staging/prod 환경별 리소스 및 설정 차별화
- SonarQube 품질 분석 통합 (선택적 실행)
- 자동/수동 트리거 지원
- 수동 배포 스크립트 및 가이드 문서 제공

주요 구성 요소:
- GitHub Actions 워크플로우: .github/workflows/backend-cicd.yaml
- Kustomize 매니페스트: .github/kustomize/{base,overlays}
- 환경별 설정: .github/config/deploy_env_vars_*
- 배포 스크립트: .github/scripts/deploy-actions.sh
- 상세 가이드: .github/actions-pipeline-guide.md

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
hiondal 2025-09-15 15:08:49 +09:00
parent f3b068d101
commit c376b2f326
22 changed files with 379 additions and 328 deletions

303
.github/actions-pipeline-guide.md vendored Normal file
View File

@ -0,0 +1,303 @@
# 백엔드 GitHub Actions CI/CD 파이프라인 가이드
## 📋 개요
GitHub Actions를 이용한 백엔드 서비스 CI/CD 파이프라인 구축 가이드입니다.
Kustomize를 활용한 환경별 배포 자동화와 SonarQube 품질 분석을 포함합니다.
### 시스템 정보
- **시스템명**: phonebill
- **서비스 목록**: api-gateway, user-service, bill-service, product-service, kos-mock
- **JDK 버전**: 21
- **ACR 이름**: acrdigitalgarage01
- **리소스 그룹**: rg-digitalgarage-01
- **AKS 클러스터**: aks-digitalgarage-01
## 🏗️ 구축된 파일 구조
```
.github/
├── kustomize/
│ ├── base/
│ │ ├── kustomization.yaml
│ │ ├── namespace.yaml
│ │ ├── common/
│ │ │ ├── cm-common.yaml
│ │ │ ├── secret-common.yaml
│ │ │ ├── secret-imagepull.yaml
│ │ │ └── ingress.yaml
│ │ └── {service-name}/
│ │ ├── deployment.yaml
│ │ ├── service.yaml
│ │ ├── cm-{service-name}.yaml (존재 시)
│ │ └── secret-{service-name}.yaml (존재 시)
│ └── overlays/
│ ├── dev/
│ │ ├── kustomization.yaml
│ │ ├── cm-common-patch.yaml
│ │ ├── secret-common-patch.yaml
│ │ ├── ingress-patch.yaml
│ │ ├── deployment-{service-name}-patch.yaml
│ │ └── secret-{service-name}-patch.yaml
│ ├── staging/
│ └── prod/
├── config/
│ ├── deploy_env_vars_dev
│ ├── deploy_env_vars_staging
│ └── deploy_env_vars_prod
├── scripts/
│ └── deploy-actions.sh
└── workflows/
└── backend-cicd.yaml
```
## ⚙️ GitHub Repository 설정
### 1. Repository Secrets 설정
Repository Settings > Secrets and variables > Actions > Repository secrets에 다음을 등록:
```yaml
# Azure Service Principal
AZURE_CREDENTIALS:
{
"clientId": "{클라이언트ID}",
"clientSecret": "{클라이언트시크릿}",
"subscriptionId": "{구독ID}",
"tenantId": "{테넌트ID}"
}
# ACR Credentials
ACR_USERNAME: acrdigitalgarage01
ACR_PASSWORD: {ACR패스워드}
# Docker Hub (Rate Limit 해결용)
DOCKERHUB_USERNAME: {Docker Hub 사용자명}
DOCKERHUB_PASSWORD: {Docker Hub 패스워드}
# SonarQube (선택사항)
SONAR_TOKEN: {SonarQube토큰}
SONAR_HOST_URL: {SonarQube서버URL}
```
### 2. Repository Variables 설정
Repository Settings > Secrets and variables > Actions > Variables > Repository variables에 등록:
```yaml
ENVIRONMENT: dev # 기본값
SKIP_SONARQUBE: true # 기본값
```
### 3. ACR 패스워드 확인 방법
```bash
az acr credential show --name acrdigitalgarage01
```
## 🚀 CI/CD 파이프라인 구성
### 워크플로우 트리거
1. **자동 실행**:
- `main`, `develop` 브랜치에 Push
- `main` 브랜치로 Pull Request
2. **수동 실행**:
- Actions 탭 > "Backend Services CI/CD" > "Run workflow"
- 환경 선택: dev/staging/prod
- SonarQube 분석 여부 선택
### 파이프라인 단계
#### 1. Build and Test
- Gradle 빌드 (테스트 제외)
- SonarQube 분석 (선택적)
- 빌드 아티팩트 업로드
#### 2. Build and Push Docker Images
- Docker 이미지 빌드
- ACR에 푸시 (태그: {environment}-{timestamp})
#### 3. Deploy to Kubernetes
- Kustomize를 이용한 환경별 배포
- 배포 상태 확인
- Health Check
## 🔧 환경별 설정
### 개발 환경 (dev)
- **네임스페이스**: phonebill-dev
- **Replicas**: 1
- **Resources**: 256Mi/256m → 1024Mi/1024m
- **DDL**: update
- **Host**: phonebill-api.20.214.196.128.nip.io
- **SSL**: false
### 스테이징 환경 (staging)
- **네임스페이스**: phonebill-staging
- **Replicas**: 2
- **Resources**: 512Mi/512m → 2048Mi/2048m
- **DDL**: validate
- **Host**: staging.phonebill.com
- **SSL**: true (Let's Encrypt)
### 운영 환경 (prod)
- **네임스페이스**: phonebill-prod
- **Replicas**: 3
- **Resources**: 1024Mi/1024m → 4096Mi/4096m
- **DDL**: validate
- **JWT Token**: 1시간 (보안 강화)
- **Host**: phonebill.com
- **SSL**: true (Let's Encrypt)
## 📝 수동 배포 방법
### 스크립트 사용
```bash
# 개발 환경 배포
./.github/scripts/deploy-actions.sh dev latest
# 스테이징 환경 배포
./.github/scripts/deploy-actions.sh staging 20241215123456
# 운영 환경 배포
./.github/scripts/deploy-actions.sh prod 20241215123456
```
### kubectl 직접 사용
```bash
# 환경별 디렉토리로 이동
cd .github/kustomize/overlays/dev
# 이미지 태그 업데이트
kustomize edit set image acrdigitalgarage01.azurecr.io/phonebill/api-gateway:dev-20241215123456
# 배포 실행
kubectl apply -k .
```
## 🔄 롤백 방법
### 1. GitHub Actions를 통한 롤백
1. GitHub > Actions > 성공한 이전 워크플로우 선택
2. "Re-run all jobs" 클릭
### 2. kubectl을 이용한 롤백
```bash
# 특정 버전으로 롤백
kubectl rollout undo deployment/api-gateway -n phonebill-dev --to-revision=2
# 롤백 상태 확인
kubectl rollout status deployment/api-gateway -n phonebill-dev
```
### 3. 수동 스크립트를 이용한 롤백
```bash
# 이전 안정 버전 이미지 태그로 배포
./.github/scripts/deploy-actions.sh dev 20241214123456
```
## 🔍 SonarQube 설정
### Quality Gate 기준
- Coverage: >= 80%
- Duplicated Lines: <= 3%
- Maintainability Rating: <= A
- Reliability Rating: <= A
- Security Rating: <= A
### 프로젝트 생성
각 서비스별로 `phonebill-{service}-{environment}` 형식으로 프로젝트 생성
## 📊 모니터링 및 확인
### 배포 상태 확인
```bash
# Pod 상태 확인
kubectl get pods -n phonebill-dev
# 서비스 상태 확인
kubectl get services -n phonebill-dev
# Ingress 확인
kubectl get ingress -n phonebill-dev
# 로그 확인
kubectl logs -f deployment/api-gateway -n phonebill-dev
```
### Health Check
```bash
# API Gateway Health Check
kubectl -n phonebill-dev exec deployment/api-gateway -- curl -f http://localhost:8080/actuator/health
```
## ⚠️ 주의사항
1. **환경별 Secret 관리**:
- 현재는 동일한 값으로 설정되어 있음
- 실제 운영 시 환경별로 다른 값 설정 필요
2. **도메인 설정**:
- staging/prod 환경의 도메인은 실제 구매한 도메인으로 변경 필요
- SSL 인증서는 cert-manager 설정 필요
3. **리소스 한계**:
- 환경별 리소스 설정은 실제 부하에 맞게 조정 필요
4. **데이터베이스 연결**:
- 환경별로 다른 데이터베이스 인스턴스 사용 권장
## 🔧 문제 해결
### 일반적인 문제들
1. **이미지 Pull 실패**:
```bash
# Secret 확인
kubectl get secret secret-imagepull -n phonebill-dev -o yaml
```
2. **ConfigMap/Secret 업데이트 반영 안됨**:
```bash
# Pod 재시작
kubectl rollout restart deployment/api-gateway -n phonebill-dev
```
3. **Ingress IP 할당 안됨**:
```bash
# Ingress Controller 상태 확인
kubectl get pods -n ingress-nginx
```
## 📚 참고 자료
- [Kustomize 공식 문서](https://kustomize.io/)
- [GitHub Actions 문서](https://docs.github.com/en/actions)
- [Azure Container Registry 문서](https://docs.microsoft.com/en-us/azure/container-registry/)
- [Azure Kubernetes Service 문서](https://docs.microsoft.com/en-us/azure/aks/)
---
## 체크리스트
### 초기 설정
- [ ] GitHub Repository Secrets 설정 완료
- [ ] GitHub Repository Variables 설정 완료
- [ ] Azure Service Principal 생성 및 권한 설정
- [ ] ACR 접근 권한 확인
### 배포 테스트
- [ ] 개발 환경 배포 성공
- [ ] 스테이징 환경 배포 성공
- [ ] 운영 환경 배포 성공
- [ ] Health Check 통과
- [ ] 롤백 테스트 성공
### 모니터링 설정
- [ ] SonarQube 프로젝트 생성
- [ ] Quality Gate 설정
- [ ] 알림 설정 (선택사항)
이 가이드를 통해 GitHub Actions 기반의 완전 자동화된 CI/CD 파이프라인을 구축할 수 있습니다.

View File

@ -1,237 +0,0 @@
# 백엔드 GitHub Actions 파이프라인 구축 가이드
## 📋 프로젝트 정보
**시스템명**: phonebill
**서비스 목록**: api-gateway, user-service, bill-service, product-service, kos-mock
**JDK 버전**: 21
**실행 환경**:
- **ACR**: acrdigitalgarage01
- **리소스 그룹**: rg-digitalgarage-01
- **AKS 클러스터**: aks-digitalgarage-01
## 🚀 GitHub Repository 환경 구성
### Repository Secrets 설정
`Repository Settings > Secrets and variables > Actions > Repository secrets`에 등록:
```bash
# Azure Service Principal
AZURE_CREDENTIALS:
{
"clientId": "{클라이언트ID}",
"clientSecret": "{클라이언트시크릿}",
"subscriptionId": "{구독ID}",
"tenantId": "{테넌트ID}"
}
# ACR Credentials
ACR_USERNAME: acrdigitalgarage01
ACR_PASSWORD: {ACR패스워드}
# SonarQube (선택사항)
SONAR_TOKEN: {SonarQube토큰}
SONAR_HOST_URL: {SonarQube서버URL}
# Docker Hub (Rate Limit 해결용, 선택사항)
DOCKERHUB_USERNAME: {Docker Hub 사용자명}
DOCKERHUB_PASSWORD: {Docker Hub 패스워드}
```
### Repository Variables 설정
`Repository Settings > Secrets and variables > Actions > Variables > Repository variables`에 등록:
```bash
# Workflow 제어 변수
ENVIRONMENT: dev (기본값, 수동실행시 선택 가능: dev/staging/prod)
SKIP_SONARQUBE: true (기본값, 수동실행시 선택 가능: true/false)
```
### 사용 방법
- **자동 실행**: Push/PR 시 기본값 사용 (ENVIRONMENT=dev, SKIP_SONARQUBE=true)
- **수동 실행**: Actions 탭 > "Backend Services CI/CD" > "Run workflow" 버튼 클릭
- Environment: dev/staging/prod 선택
- Skip SonarQube Analysis: true/false 선택
## 📁 디렉토리 구조
```
.github/
├── kustomize/ # GitHub Actions 전용 Kustomize 매니페스트
│ ├── base/ # 기본 매니페스트
│ │ ├── kustomization.yaml
│ │ ├── namespace.yaml
│ │ ├── common/ # 공통 리소스
│ │ │ ├── cm-common.yaml
│ │ │ ├── secret-common.yaml
│ │ │ ├── secret-imagepull.yaml
│ │ │ └── ingress.yaml
│ │ ├── api-gateway/ # API Gateway 리소스
│ │ ├── user-service/ # User Service 리소스
│ │ ├── bill-service/ # Bill Service 리소스
│ │ ├── product-service/ # Product Service 리소스
│ │ └── kos-mock/ # KOS Mock 리소스
│ └── overlays/ # 환경별 오버레이
│ ├── dev/ # 개발 환경
│ ├── staging/ # 스테이징 환경
│ └── prod/ # 운영 환경
├── config/ # 환경별 배포 설정
│ ├── deploy_env_vars_dev
│ ├── deploy_env_vars_staging
│ └── deploy_env_vars_prod
├── scripts/ # 배포 스크립트
│ └── deploy-actions.sh
└── workflows/ # GitHub Actions 워크플로우
└── backend-cicd.yaml
```
## 🔄 환경별 설정
### DEV 환경
- **네임스페이스**: phonebill-dev
- **프로파일**: dev
- **DDL 모드**: update
- **리플리카**: 1개
- **리소스**: 256Mi/256m (요청), 1024Mi/1024m (제한)
- **도메인**: phonebill-api.20.214.196.128.nip.io (기존과 동일)
- **HTTPS**: 비활성화
### STAGING 환경
- **네임스페이스**: phonebill-staging
- **프로파일**: staging
- **DDL 모드**: validate
- **리플리카**: 2개
- **리소스**: 512Mi/512m (요청), 2048Mi/2048m (제한)
- **도메인**: phonebill.staging.example.com
- **HTTPS**: 활성화 (ssl-redirect: true)
### PROD 환경
- **네임스페이스**: phonebill-prod
- **프로파일**: prod
- **DDL 모드**: validate
- **리플리카**: 3개
- **리소스**: 1024Mi/1024m (요청), 4096Mi/4096m (제한)
- **도메인**: phonebill.example.com
- **HTTPS**: 활성화 (ssl-redirect: true)
- **JWT 토큰**: 보안 강화 (ACCESS: 1시간, REFRESH: 12시간)
## 🚀 배포 방법
### 1. 자동 배포 (GitHub Actions)
**코드 Push 시 자동 실행**:
```bash
git add .
git commit -m "feature: 새 기능 추가"
git push origin main # 또는 develop
```
**수동 트리거**:
1. GitHub > Actions 탭 이동
2. "Backend Services CI/CD" 선택
3. "Run workflow" 클릭
4. 환경(dev/staging/prod) 및 SonarQube 분석 여부 선택
5. "Run workflow" 실행
### 2. 수동 배포 (로컬)
```bash
# 개발 환경 배포
./.github/scripts/deploy-actions.sh dev latest
# 스테이징 환경 배포
./.github/scripts/deploy-actions.sh staging 20241215120000
# 운영 환경 배포
./.github/scripts/deploy-actions.sh prod 20241215120000
```
## 🔙 롤백 방법
### 1. GitHub Actions 롤백
```bash
# 이전 성공한 워크플로우 실행으로 롤백
1. GitHub > Actions > 성공한 이전 워크플로우 선택
2. "Re-run all jobs" 클릭
```
### 2. kubectl 롤백
```bash
# 특정 버전으로 롤백
kubectl rollout undo deployment/{환경}-{서비스명} -n phonebill-{환경} --to-revision=2
# 롤백 상태 확인
kubectl rollout status deployment/{환경}-{서비스명} -n phonebill-{환경}
```
### 3. 수동 스크립트 롤백
```bash
# 이전 안정 버전 이미지 태그로 배포
./.github/scripts/deploy-actions.sh {환경} {이전태그}
```
## 📊 SonarQube 프로젝트 설정
각 서비스별 프로젝트 생성 및 Quality Gate 설정:
```bash
Coverage: >= 80%
Duplicated Lines: <= 3%
Maintainability Rating: <= A
Reliability Rating: <= A
Security Rating: <= A
```
## ✅ 체크리스트
### 사전 준비
- [ ] GitHub Repository Secrets 설정 완료
- [ ] GitHub Repository Variables 설정 완료
- [ ] Azure Service Principal 권한 확인
- [ ] ACR 접근 권한 확인
- [ ] AKS 클러스터 접근 권한 확인
### 배포 확인
- [ ] GitHub Actions 워크플로우 정상 실행
- [ ] 모든 서비스 이미지 빌드 및 푸시 성공
- [ ] Kustomize 매니페스트 적용 성공
- [ ] 모든 Deployment 정상 배포 (Available 상태)
- [ ] Health Check 통과
- [ ] Ingress 정상 동작 확인
### 서비스 검증
- [ ] API Gateway 응답 확인: `curl -f http://localhost:8080/actuator/health`
- [ ] 각 서비스별 Pod 상태 확인: `kubectl get pods -n phonebill-{환경}`
- [ ] 서비스 연결 확인: `kubectl get services -n phonebill-{환경}`
- [ ] Ingress 설정 확인: `kubectl get ingress -n phonebill-{환경}`
## 🔧 문제 해결
### 일반적인 문제
1. **이미지 빌드 실패**: Dockerfile 경로 및 빌드 컨텍스트 확인
2. **매니페스트 적용 실패**: Kustomize 구문 오류 확인
3. **Pod 시작 실패**: 환경변수 및 Secret 설정 확인
4. **Health Check 실패**: 애플리케이션 로그 확인
### 로그 확인 명령어
```bash
# Pod 로그 확인
kubectl logs -n phonebill-{환경} {pod-name}
# Deployment 상태 확인
kubectl describe deployment -n phonebill-{환경} {deployment-name}
# 이벤트 확인
kubectl get events -n phonebill-{환경} --sort-by='.lastTimestamp'
```
---
## 📞 지원
구축 과정에서 문제가 발생하거나 추가 지원이 필요한 경우, 다음 사항을 포함하여 문의:
1. 환경 정보 (dev/staging/prod)
2. 오류 메시지 및 로그
3. 실행한 명령어
4. 현재 상태 (kubectl get all -n phonebill-{환경})
**구축 완료 🎉**

View File

@ -12,38 +12,34 @@ resources:
- common/secret-imagepull.yaml - common/secret-imagepull.yaml
- common/ingress.yaml - common/ingress.yaml
# API Gateway # API Gateway service
- api-gateway/deployment.yaml - api-gateway/deployment.yaml
- api-gateway/service.yaml - api-gateway/service.yaml
- api-gateway/cm-api-gateway.yaml - api-gateway/cm-api-gateway.yaml
# User Service # User service
- user-service/deployment.yaml - user-service/deployment.yaml
- user-service/service.yaml - user-service/service.yaml
- user-service/cm-user-service.yaml - user-service/cm-user-service.yaml
- user-service/secret-user-service.yaml - user-service/secret-user-service.yaml
# Bill Service # Bill service
- bill-service/deployment.yaml - bill-service/deployment.yaml
- bill-service/service.yaml - bill-service/service.yaml
- bill-service/cm-bill-service.yaml - bill-service/cm-bill-service.yaml
- bill-service/secret-bill-service.yaml - bill-service/secret-bill-service.yaml
# Product Service # Product service
- product-service/deployment.yaml - product-service/deployment.yaml
- product-service/service.yaml - product-service/service.yaml
- product-service/cm-product-service.yaml - product-service/cm-product-service.yaml
- product-service/secret-product-service.yaml - product-service/secret-product-service.yaml
# KOS Mock # KOS Mock service
- kos-mock/deployment.yaml - kos-mock/deployment.yaml
- kos-mock/service.yaml - kos-mock/service.yaml
- kos-mock/cm-kos-mock.yaml - kos-mock/cm-kos-mock.yaml
commonLabels:
app: phonebill
version: v1
images: images:
- name: acrdigitalgarage01.azurecr.io/phonebill/api-gateway - name: acrdigitalgarage01.azurecr.io/phonebill/api-gateway
newTag: latest newTag: latest

View File

@ -1,4 +1,4 @@
apiVersion: v1 apiVersion: v1
kind: Namespace kind: Namespace
metadata: metadata:
name: phonebill-dev name: phonebill-default

View File

@ -11,6 +11,14 @@ patches:
target: target:
kind: ConfigMap kind: ConfigMap
name: cm-common name: cm-common
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: deployment-api-gateway-patch.yaml - path: deployment-api-gateway-patch.yaml
target: target:
kind: Deployment kind: Deployment
@ -31,14 +39,6 @@ patches:
target: target:
kind: Deployment kind: Deployment
name: kos-mock name: kos-mock
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: secret-user-service-patch.yaml - path: secret-user-service-patch.yaml
target: target:
kind: Secret kind: Secret
@ -62,9 +62,4 @@ images:
- name: acrdigitalgarage01.azurecr.io/phonebill/product-service - name: acrdigitalgarage01.azurecr.io/phonebill/product-service
newTag: dev-latest newTag: dev-latest
- name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock - name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock
newTag: dev-latest newTag: dev-latest
namePrefix: dev-
commonLabels:
environment: dev

View File

@ -4,9 +4,9 @@ metadata:
name: cm-common name: cm-common
data: data:
CORS_ALLOWED_ORIGINS: "https://phonebill.example.com" CORS_ALLOWED_ORIGINS: "http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://phonebill.20.214.196.128.nip.io"
JWT_ACCESS_TOKEN_VALIDITY: "3600000" JWT_ACCESS_TOKEN_VALIDITY: "3600000"
JWT_REFRESH_TOKEN_VALIDITY: "43200000" JWT_REFRESH_TOKEN_VALIDITY: "86400000"
REDIS_PORT: "6379" REDIS_PORT: "6379"
SPRING_PROFILES_ACTIVE: "prod" SPRING_PROFILES_ACTIVE: "prod"
DDL_AUTO: "validate" DDL_AUTO: "validate"

View File

@ -10,8 +10,8 @@ spec:
- name: api-gateway - name: api-gateway
resources: resources:
requests: requests:
memory: "4096Mi" memory: "1024Mi"
cpu: "4096m" cpu: "1024m"
limits: limits:
memory: "4096Mi" memory: "4096Mi"
cpu: "4096m" cpu: "4096m"

View File

@ -10,8 +10,8 @@ spec:
- name: bill-service - name: bill-service
resources: resources:
requests: requests:
memory: "4096Mi" memory: "1024Mi"
cpu: "4096m" cpu: "1024m"
limits: limits:
memory: "4096Mi" memory: "4096Mi"
cpu: "4096m" cpu: "4096m"

View File

@ -10,8 +10,8 @@ spec:
- name: kos-mock - name: kos-mock
resources: resources:
requests: requests:
memory: "4096Mi" memory: "1024Mi"
cpu: "4096m" cpu: "1024m"
limits: limits:
memory: "4096Mi" memory: "4096Mi"
cpu: "4096m" cpu: "4096m"

View File

@ -10,8 +10,8 @@ spec:
- name: product-service - name: product-service
resources: resources:
requests: requests:
memory: "4096Mi" memory: "1024Mi"
cpu: "4096m" cpu: "1024m"
limits: limits:
memory: "4096Mi" memory: "4096Mi"
cpu: "4096m" cpu: "4096m"

View File

@ -10,8 +10,8 @@ spec:
- name: user-service - name: user-service
resources: resources:
requests: requests:
memory: "4096Mi" memory: "1024Mi"
cpu: "4096m" cpu: "1024m"
limits: limits:
memory: "4096Mi" memory: "4096Mi"
cpu: "4096m" cpu: "4096m"

View File

@ -2,7 +2,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: phonebill name: phonebill
annotations: annotations:
kubernetes.io/ingress.class: nginx kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true"
@ -11,10 +10,10 @@ spec:
ingressClassName: nginx ingressClassName: nginx
tls: tls:
- hosts: - hosts:
- phonebill.example.com - phonebill.com
secretName: phonebill-prod-tls secretName: prod-phonebill-tls
rules: rules:
- host: phonebill.example.com - host: phonebill.com
http: http:
paths: paths:
- path: /api/v1/auth - path: /api/v1/auth

View File

@ -11,6 +11,14 @@ patches:
target: target:
kind: ConfigMap kind: ConfigMap
name: cm-common name: cm-common
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: deployment-api-gateway-patch.yaml - path: deployment-api-gateway-patch.yaml
target: target:
kind: Deployment kind: Deployment
@ -31,14 +39,6 @@ patches:
target: target:
kind: Deployment kind: Deployment
name: kos-mock name: kos-mock
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: secret-user-service-patch.yaml - path: secret-user-service-patch.yaml
target: target:
kind: Secret kind: Secret
@ -62,9 +62,4 @@ images:
- name: acrdigitalgarage01.azurecr.io/phonebill/product-service - name: acrdigitalgarage01.azurecr.io/phonebill/product-service
newTag: prod-latest newTag: prod-latest
- name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock - name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock
newTag: prod-latest newTag: prod-latest
namePrefix: prod-
commonLabels:
environment: prod

View File

@ -4,7 +4,7 @@ metadata:
name: cm-common name: cm-common
data: data:
CORS_ALLOWED_ORIGINS: "https://phonebill.staging.example.com" CORS_ALLOWED_ORIGINS: "http://localhost:8081,http://localhost:8082,http://localhost:8083,http://localhost:8084,http://phonebill.20.214.196.128.nip.io"
JWT_ACCESS_TOKEN_VALIDITY: "18000000" JWT_ACCESS_TOKEN_VALIDITY: "18000000"
JWT_REFRESH_TOKEN_VALIDITY: "86400000" JWT_REFRESH_TOKEN_VALIDITY: "86400000"
REDIS_PORT: "6379" REDIS_PORT: "6379"

View File

@ -14,4 +14,4 @@ spec:
cpu: "512m" cpu: "512m"
limits: limits:
memory: "2048Mi" memory: "2048Mi"
cpu: "2048m" cpu: "2048m"

View File

@ -14,4 +14,4 @@ spec:
cpu: "512m" cpu: "512m"
limits: limits:
memory: "2048Mi" memory: "2048Mi"
cpu: "2048m" cpu: "2048m"

View File

@ -14,4 +14,4 @@ spec:
cpu: "512m" cpu: "512m"
limits: limits:
memory: "2048Mi" memory: "2048Mi"
cpu: "2048m" cpu: "2048m"

View File

@ -14,4 +14,4 @@ spec:
cpu: "512m" cpu: "512m"
limits: limits:
memory: "2048Mi" memory: "2048Mi"
cpu: "2048m" cpu: "2048m"

View File

@ -2,7 +2,6 @@ apiVersion: networking.k8s.io/v1
kind: Ingress kind: Ingress
metadata: metadata:
name: phonebill name: phonebill
annotations: annotations:
kubernetes.io/ingress.class: nginx kubernetes.io/ingress.class: nginx
nginx.ingress.kubernetes.io/ssl-redirect: "true" nginx.ingress.kubernetes.io/ssl-redirect: "true"
@ -11,10 +10,10 @@ spec:
ingressClassName: nginx ingressClassName: nginx
tls: tls:
- hosts: - hosts:
- phonebill.staging.example.com - staging.phonebill.com
secretName: phonebill-staging-tls secretName: staging-phonebill-tls
rules: rules:
- host: phonebill.staging.example.com - host: staging.phonebill.com
http: http:
paths: paths:
- path: /api/v1/auth - path: /api/v1/auth

View File

@ -11,6 +11,14 @@ patches:
target: target:
kind: ConfigMap kind: ConfigMap
name: cm-common name: cm-common
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: deployment-api-gateway-patch.yaml - path: deployment-api-gateway-patch.yaml
target: target:
kind: Deployment kind: Deployment
@ -31,14 +39,6 @@ patches:
target: target:
kind: Deployment kind: Deployment
name: kos-mock name: kos-mock
- path: ingress-patch.yaml
target:
kind: Ingress
name: phonebill
- path: secret-common-patch.yaml
target:
kind: Secret
name: secret-common
- path: secret-user-service-patch.yaml - path: secret-user-service-patch.yaml
target: target:
kind: Secret kind: Secret
@ -62,9 +62,4 @@ images:
- name: acrdigitalgarage01.azurecr.io/phonebill/product-service - name: acrdigitalgarage01.azurecr.io/phonebill/product-service
newTag: staging-latest newTag: staging-latest
- name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock - name: acrdigitalgarage01.azurecr.io/phonebill/kos-mock
newTag: staging-latest newTag: staging-latest
namePrefix: staging-
commonLabels:
environment: staging

View File

@ -47,13 +47,13 @@ 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
kubectl rollout status deployment/${ENVIRONMENT}-$service -n phonebill-${ENVIRONMENT} --timeout=300s kubectl rollout status deployment/$service -n phonebill-${ENVIRONMENT} --timeout=300s
done done
echo "🔍 Health check..." echo "🔍 Health check..."
# API Gateway Health Check (첫 번째 서비스가 API Gateway라고 가정) # API Gateway Health Check (첫 번째 서비스가 API Gateway라고 가정)
GATEWAY_SERVICE=${services[0]} GATEWAY_SERVICE=${services[0]}
GATEWAY_POD=$(kubectl get pod -n phonebill-${ENVIRONMENT} -l app.kubernetes.io/name=${ENVIRONMENT}-$GATEWAY_SERVICE -o jsonpath='{.items[0].metadata.name}') GATEWAY_POD=$(kubectl get pod -n phonebill-${ENVIRONMENT} -l app.kubernetes.io/name=$GATEWAY_SERVICE -o jsonpath='{.items[0].metadata.name}')
kubectl -n phonebill-${ENVIRONMENT} exec $GATEWAY_POD -- curl -f http://localhost:8080/actuator/health || echo "Health check failed, but deployment completed" kubectl -n phonebill-${ENVIRONMENT} exec $GATEWAY_POD -- curl -f http://localhost:8080/actuator/health || echo "Health check failed, but deployment completed"
echo "📋 Service Information:" echo "📋 Service Information:"

View File

@ -180,6 +180,12 @@ jobs:
- name: Set up Docker Buildx - name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3 uses: docker/setup-buildx-action@v3
- name: Login to Docker Hub (prevent rate limit)
uses: docker/login-action@v3
with:
username: ${{ secrets.DOCKERHUB_USERNAME }}
password: ${{ secrets.DOCKERHUB_PASSWORD }}
- name: Login to Azure Container Registry - name: Login to Azure Container Registry
uses: docker/login-action@v3 uses: docker/login-action@v3
with: with:
@ -261,18 +267,18 @@ jobs:
- name: Wait for deployments to be ready - name: Wait for deployments to be ready
run: | run: |
echo "Waiting for deployments to be ready..." echo "Waiting for deployments to be ready..."
kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-api-gateway --timeout=300s kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/api-gateway --timeout=300s
kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-user-service --timeout=300s kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/user-service --timeout=300s
kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-bill-service --timeout=300s kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/bill-service --timeout=300s
kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-product-service --timeout=300s kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/product-service --timeout=300s
kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/${{ env.ENVIRONMENT }}-kos-mock --timeout=300s kubectl -n phonebill-${{ env.ENVIRONMENT }} wait --for=condition=available deployment/kos-mock --timeout=300s
- name: Health Check - name: Health Check
run: | run: |
echo "🔍 Health Check starting..." echo "🔍 Health Check starting..."
# API Gateway Health Check # API Gateway Health Check
GATEWAY_POD=$(kubectl get pod -n phonebill-${{ env.ENVIRONMENT }} -l app.kubernetes.io/name=${{ env.ENVIRONMENT }}-api-gateway -o jsonpath='{.items[0].metadata.name}') GATEWAY_POD=$(kubectl get pod -n phonebill-${{ env.ENVIRONMENT }} -l app.kubernetes.io/name=api-gateway -o jsonpath='{.items[0].metadata.name}')
kubectl -n phonebill-${{ env.ENVIRONMENT }} exec $GATEWAY_POD -- curl -f http://localhost:8080/actuator/health || exit 1 kubectl -n phonebill-${{ env.ENVIRONMENT }} exec $GATEWAY_POD -- curl -f http://localhost:8080/actuator/health || exit 1
echo "✅ All services are healthy!" echo "✅ All services are healthy!"
@ -283,4 +289,4 @@ jobs:
kubectl get pods -n phonebill-${{ env.ENVIRONMENT }} kubectl get pods -n phonebill-${{ env.ENVIRONMENT }}
kubectl get services -n phonebill-${{ env.ENVIRONMENT }} kubectl get services -n phonebill-${{ env.ENVIRONMENT }}
kubectl get ingress -n phonebill-${{ env.ENVIRONMENT }} kubectl get ingress -n phonebill-${{ env.ENVIRONMENT }}
echo "Ingress IP: $(kubectl -n phonebill-${{ env.ENVIRONMENT }} get ingress phonebill-ingress -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo 'Pending')" echo "Ingress IP: $(kubectl -n phonebill-${{ env.ENVIRONMENT }} get ingress phonebill -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo 'Pending')"