mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 14:56:23 +00:00
501 lines
12 KiB
Markdown
501 lines
12 KiB
Markdown
# GitHub Actions CI/CD 파이프라인 구축 가이드
|
|
|
|
## 📋 목차
|
|
1. [개요](#개요)
|
|
2. [사전 준비사항](#사전-준비사항)
|
|
3. [GitHub 저장소 환경 구성](#github-저장소-환경-구성)
|
|
4. [디렉토리 구조](#디렉토리-구조)
|
|
5. [Kustomize 구조 설명](#kustomize-구조-설명)
|
|
6. [GitHub Actions 워크플로우](#github-actions-워크플로우)
|
|
7. [배포 방법](#배포-방법)
|
|
8. [롤백 방법](#롤백-방법)
|
|
9. [SonarQube 설정](#sonarqube-설정)
|
|
10. [트러블슈팅](#트러블슈팅)
|
|
|
|
---
|
|
|
|
## 개요
|
|
|
|
HGZero 프로젝트의 백엔드 서비스를 위한 GitHub Actions 기반 CI/CD 파이프라인입니다.
|
|
|
|
### 주요 기능
|
|
- ✅ Gradle 기반 빌드 및 테스트
|
|
- ✅ SonarQube 코드 품질 분석 (선택적)
|
|
- ✅ Azure Container Registry에 Docker 이미지 빌드 및 푸시
|
|
- ✅ Kustomize를 사용한 환경별(dev/staging/prod) 배포
|
|
- ✅ AKS 클러스터 자동 배포
|
|
|
|
### 지원 서비스
|
|
- **user**: 사용자 관리 서비스
|
|
- **meeting**: 회의 관리 서비스
|
|
- **stt**: 음성 인식 서비스
|
|
- **ai**: AI 처리 서비스
|
|
- **notification**: 알림 서비스
|
|
|
|
---
|
|
|
|
## 사전 준비사항
|
|
|
|
### 1. 프로젝트 정보
|
|
- **시스템명**: hgzero
|
|
- **ACR 이름**: acrdigitalgarage02
|
|
- **리소스 그룹**: rg-digitalgarage-02
|
|
- **AKS 클러스터**: aks-digitalgarage-02
|
|
- **네임스페이스**: hgzero
|
|
- **JDK 버전**: 21
|
|
|
|
### 2. 필수 도구
|
|
- Git
|
|
- kubectl
|
|
- Azure CLI
|
|
- Kustomize (자동 설치됨)
|
|
|
|
---
|
|
|
|
## GitHub 저장소 환경 구성
|
|
|
|
### 1. Repository Secrets 설정
|
|
|
|
`Repository Settings > Secrets and variables > Actions > Repository secrets`에 다음 항목을 등록하세요:
|
|
|
|
#### Azure 인증 정보
|
|
```json
|
|
AZURE_CREDENTIALS:
|
|
{
|
|
"clientId": "{클라이언트ID}",
|
|
"clientSecret": "{클라이언트시크릿}",
|
|
"subscriptionId": "{구독ID}",
|
|
"tenantId": "{테넌트ID}"
|
|
}
|
|
```
|
|
|
|
**예시:**
|
|
```json
|
|
{
|
|
"clientId": "5e4b5b41-7208-48b7-b821-d6d5acf50ecf",
|
|
"clientSecret": "ldu8Q~GQEzFYU.dJX7_QsahR7n7C2xqkIM6hqbV8",
|
|
"subscriptionId": "2513dd36-7978-48e3-9a7c-b221d4874f66",
|
|
"tenantId": "4f0a3bfd-1156-4cce-8dc2-a049a13dba23"
|
|
}
|
|
```
|
|
|
|
#### ACR Credentials
|
|
|
|
ACR Credential을 확인하려면:
|
|
```bash
|
|
az acr credential show --name acrdigitalgarage02
|
|
```
|
|
|
|
등록할 Secrets:
|
|
```
|
|
ACR_USERNAME: acrdigitalgarage02
|
|
ACR_PASSWORD: {ACR 패스워드}
|
|
```
|
|
|
|
#### SonarQube 설정
|
|
|
|
**SONAR_HOST_URL 확인:**
|
|
```bash
|
|
kubectl get svc -n sonarqube
|
|
```
|
|
출력된 External IP를 사용하여 `http://{External IP}` 형식으로 설정
|
|
|
|
**SONAR_TOKEN 생성:**
|
|
1. SonarQube에 로그인 (기본: admin/admin)
|
|
2. 우측 상단 'Administrator' > My Account 클릭
|
|
3. Security 탭 선택 후 토큰 생성
|
|
|
|
등록할 Secrets:
|
|
```
|
|
SONAR_TOKEN: {SonarQube 토큰}
|
|
SONAR_HOST_URL: http://{External IP}
|
|
```
|
|
|
|
#### Docker Hub (Rate Limit 해결용)
|
|
|
|
**패스워드 생성:**
|
|
1. [Docker Hub](https://hub.docker.com) 로그인
|
|
2. 우측 상단 프로필 아이콘 > Account Settings
|
|
3. 좌측 메뉴 'Personal Access Tokens' 클릭하여 생성
|
|
|
|
등록할 Secrets:
|
|
```
|
|
DOCKERHUB_USERNAME: {Docker Hub 사용자명}
|
|
DOCKERHUB_PASSWORD: {Docker Hub 패스워드 또는 토큰}
|
|
```
|
|
|
|
### 2. Repository Variables 설정
|
|
|
|
`Repository Settings > Secrets and variables > Actions > Variables > Repository variables`에 등록:
|
|
|
|
```
|
|
ENVIRONMENT: dev
|
|
SKIP_SONARQUBE: true
|
|
```
|
|
|
|
---
|
|
|
|
## 디렉토리 구조
|
|
|
|
```
|
|
.github/
|
|
├── workflows/
|
|
│ └── backend-cicd.yaml # GitHub Actions 워크플로우
|
|
├── kustomize/
|
|
│ ├── base/ # 기본 Kubernetes 매니페스트
|
|
│ │ ├── common/ # 공통 리소스
|
|
│ │ │ ├── cm-common.yaml
|
|
│ │ │ ├── secret-common.yaml
|
|
│ │ │ ├── secret-imagepull.yaml
|
|
│ │ │ └── ingress.yaml
|
|
│ │ ├── user/ # User 서비스
|
|
│ │ │ ├── deployment.yaml
|
|
│ │ │ ├── service.yaml
|
|
│ │ │ └── secret-user.yaml
|
|
│ │ ├── meeting/ # Meeting 서비스
|
|
│ │ ├── stt/ # STT 서비스
|
|
│ │ ├── ai/ # AI 서비스
|
|
│ │ ├── notification/ # Notification 서비스
|
|
│ │ └── kustomization.yaml
|
|
│ └── overlays/ # 환경별 오버레이
|
|
│ ├── dev/ # 개발 환경
|
|
│ │ ├── kustomization.yaml
|
|
│ │ ├── cm-common-patch.yaml
|
|
│ │ ├── secret-common-patch.yaml
|
|
│ │ ├── ingress-patch.yaml
|
|
│ │ ├── deployment-{service}-patch.yaml
|
|
│ │ └── secret-{service}-patch.yaml
|
|
│ ├── staging/ # 스테이징 환경
|
|
│ └── prod/ # 프로덕션 환경
|
|
├── config/ # 환경별 설정
|
|
│ ├── deploy_env_vars_dev
|
|
│ ├── deploy_env_vars_staging
|
|
│ └── deploy_env_vars_prod
|
|
└── scripts/
|
|
└── deploy-actions.sh # 수동 배포 스크립트
|
|
```
|
|
|
|
---
|
|
|
|
## Kustomize 구조 설명
|
|
|
|
### Base 구조
|
|
|
|
Base는 모든 환경에서 공통으로 사용되는 기본 매니페스트입니다.
|
|
|
|
**주요 리소스:**
|
|
- **ConfigMap (cm-common)**: 환경 변수, 프로파일 설정
|
|
- **Secret (secret-common)**: JWT 시크릿, Redis 패스워드
|
|
- **Ingress**: API 라우팅 규칙
|
|
- **Deployment**: 각 서비스별 배포 설정
|
|
- **Service**: 각 서비스별 ClusterIP 서비스
|
|
- **Secret**: 각 서비스별 데이터베이스 연결 정보
|
|
|
|
### Overlay 구조
|
|
|
|
각 환경(dev/staging/prod)별로 Base를 오버라이드합니다.
|
|
|
|
#### DEV 환경
|
|
- **Replicas**: 1
|
|
- **Resources**: CPU 256m-1024m, Memory 256Mi-1024Mi
|
|
- **Profile**: dev
|
|
- **DDL**: update
|
|
- **Log Level**: DEBUG
|
|
- **Image Tag**: dev-{timestamp}
|
|
|
|
#### STAGING 환경
|
|
- **Replicas**: 2
|
|
- **Resources**: CPU 512m-2048m, Memory 512Mi-2048Mi
|
|
- **Profile**: staging
|
|
- **DDL**: validate
|
|
- **Log Level**: INFO
|
|
- **Image Tag**: staging-{timestamp}
|
|
- **SSL**: Enabled
|
|
|
|
#### PROD 환경
|
|
- **Replicas**: 3
|
|
- **Resources**: CPU 1024m-4096m, Memory 1024Mi-4096Mi
|
|
- **Profile**: prod
|
|
- **DDL**: validate
|
|
- **Log Level**: WARN
|
|
- **JWT Expiration**: 짧게 설정 (보안 강화)
|
|
- **Image Tag**: prod-{timestamp}
|
|
- **SSL**: Enabled
|
|
|
|
---
|
|
|
|
## GitHub Actions 워크플로우
|
|
|
|
### 트리거 조건
|
|
|
|
1. **Push 이벤트**:
|
|
- 브랜치: `main`, `develop`
|
|
- 경로: 서비스 코드 변경 시 (`user/**`, `meeting/**` 등)
|
|
|
|
2. **Pull Request**:
|
|
- 대상 브랜치: `main`
|
|
|
|
3. **수동 실행 (workflow_dispatch)**:
|
|
- Environment 선택: dev/staging/prod
|
|
- SonarQube 분석 스킵 선택: true/false
|
|
|
|
### 워크플로우 단계
|
|
|
|
#### 1. Build Job
|
|
1. 소스코드 체크아웃
|
|
2. JDK 21 설정
|
|
3. 환경 결정 (input 또는 기본값 dev)
|
|
4. Gradle 빌드 (테스트 제외)
|
|
5. SonarQube 분석 (선택적)
|
|
6. 빌드 아티팩트 업로드
|
|
7. 이미지 태그 생성 (타임스탬프 기반)
|
|
|
|
#### 2. Release Job
|
|
1. 빌드 아티팩트 다운로드
|
|
2. Docker Buildx 설정
|
|
3. Docker Hub 로그인 (Rate Limit 방지)
|
|
4. ACR 로그인
|
|
5. 각 서비스별 Docker 이미지 빌드 및 푸시
|
|
|
|
#### 3. Deploy Job
|
|
1. Azure CLI 설치 및 로그인
|
|
2. kubectl 설정
|
|
3. AKS Credentials 가져오기
|
|
4. 네임스페이스 생성
|
|
5. Kustomize 설치
|
|
6. 이미지 태그 업데이트
|
|
7. 매니페스트 적용
|
|
8. Deployment Ready 대기
|
|
|
|
---
|
|
|
|
## 배포 방법
|
|
|
|
### 1. 자동 배포 (Push/PR)
|
|
|
|
코드를 `main` 또는 `develop` 브랜치에 push하면 자동으로 dev 환경에 배포됩니다.
|
|
|
|
```bash
|
|
git add .
|
|
git commit -m "feat: 새로운 기능 추가"
|
|
git push origin develop
|
|
```
|
|
|
|
### 2. 수동 배포 (GitHub Actions UI)
|
|
|
|
1. GitHub Repository > Actions 탭 이동
|
|
2. "Backend Services CI/CD" 워크플로우 선택
|
|
3. "Run workflow" 버튼 클릭
|
|
4. 환경 선택 (dev/staging/prod)
|
|
5. SonarQube 분석 스킵 여부 선택
|
|
6. "Run workflow" 실행
|
|
|
|
### 3. 로컬에서 수동 배포
|
|
|
|
```bash
|
|
# 스크립트 실행 권한 확인
|
|
chmod +x .github/scripts/deploy-actions.sh
|
|
|
|
# DEV 환경에 배포 (기본)
|
|
./.github/scripts/deploy-actions.sh dev latest
|
|
|
|
# STAGING 환경에 특정 이미지 태그로 배포
|
|
./.github/scripts/deploy-actions.sh staging 20250127120000
|
|
|
|
# PROD 환경에 배포
|
|
./.github/scripts/deploy-actions.sh prod 20250127120000
|
|
```
|
|
|
|
---
|
|
|
|
## 롤백 방법
|
|
|
|
### 1. GitHub Actions를 통한 롤백
|
|
|
|
1. GitHub > Actions > 성공한 이전 워크플로우 선택
|
|
2. "Re-run all jobs" 클릭
|
|
3. 이전 버전으로 재배포됨
|
|
|
|
### 2. kubectl을 이용한 롤백
|
|
|
|
```bash
|
|
# 특정 Revision으로 롤백
|
|
kubectl rollout undo deployment/user -n hgzero --to-revision=2
|
|
|
|
# 이전 버전으로 롤백
|
|
kubectl rollout undo deployment/user -n hgzero
|
|
|
|
# 롤백 상태 확인
|
|
kubectl rollout status deployment/user -n hgzero
|
|
|
|
# Rollout 히스토리 확인
|
|
kubectl rollout history deployment/user -n hgzero
|
|
```
|
|
|
|
### 3. 수동 스크립트를 이용한 롤백
|
|
|
|
```bash
|
|
# 이전 안정 버전의 이미지 태그로 배포
|
|
./.github/scripts/deploy-actions.sh dev 20250126110000
|
|
```
|
|
|
|
---
|
|
|
|
## SonarQube 설정
|
|
|
|
### 프로젝트 생성
|
|
|
|
각 서비스별로 SonarQube 프로젝트를 생성하세요:
|
|
- hgzero-user-dev
|
|
- hgzero-meeting-dev
|
|
- hgzero-stt-dev
|
|
- hgzero-ai-dev
|
|
- hgzero-notification-dev
|
|
|
|
### Quality Gate 설정
|
|
|
|
기본 Quality Gate 설정:
|
|
- **Coverage**: >= 80%
|
|
- **Duplicated Lines**: <= 3%
|
|
- **Maintainability Rating**: <= A
|
|
- **Reliability Rating**: <= A
|
|
- **Security Rating**: <= A
|
|
|
|
### Gradle 설정 (이미 구성됨)
|
|
|
|
```gradle
|
|
// build.gradle
|
|
plugins {
|
|
id 'org.sonarqube' version '4.0.0.2929'
|
|
id 'jacoco'
|
|
}
|
|
|
|
sonarqube {
|
|
properties {
|
|
property "sonar.projectKey", "hgzero-${project.name}"
|
|
property "sonar.projectName", "hgzero-${project.name}"
|
|
}
|
|
}
|
|
|
|
jacocoTestReport {
|
|
reports {
|
|
xml.enabled true
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 트러블슈팅
|
|
|
|
### 1. 이미지 Pull 실패
|
|
|
|
**증상**: `ImagePullBackOff` 또는 `ErrImagePull`
|
|
|
|
**해결 방법**:
|
|
```bash
|
|
# ACR 로그인 테스트
|
|
az acr login --name acrdigitalgarage02
|
|
|
|
# Image Pull Secret 재생성
|
|
kubectl delete secret acr-secret -n hgzero
|
|
kubectl create secret docker-registry acr-secret \
|
|
--docker-server=acrdigitalgarage02.azurecr.io \
|
|
--docker-username=acrdigitalgarage02 \
|
|
--docker-password={ACR_PASSWORD} \
|
|
-n hgzero
|
|
```
|
|
|
|
### 2. Deployment 타임아웃
|
|
|
|
**증상**: `deployment "user" exceeded its progress deadline`
|
|
|
|
**해결 방법**:
|
|
```bash
|
|
# Pod 상태 확인
|
|
kubectl get pods -n hgzero
|
|
|
|
# Pod 로그 확인
|
|
kubectl logs -n hgzero {pod-name}
|
|
|
|
# Events 확인
|
|
kubectl describe pod -n hgzero {pod-name}
|
|
```
|
|
|
|
### 3. Health Check 실패
|
|
|
|
**증상**: Deployment가 Ready 상태로 전환되지 않음
|
|
|
|
**해결 방법**:
|
|
```bash
|
|
# Actuator health 엔드포인트 확인
|
|
kubectl exec -n hgzero {pod-name} -- curl http://localhost:8080/actuator/health
|
|
|
|
# 애플리케이션 로그 확인
|
|
kubectl logs -n hgzero {pod-name} -f
|
|
```
|
|
|
|
### 4. Kustomize 빌드 오류
|
|
|
|
**증상**: `kustomize build` 실패
|
|
|
|
**해결 방법**:
|
|
```bash
|
|
# 로컬에서 Kustomize 검증
|
|
kubectl kustomize .github/kustomize/overlays/dev
|
|
|
|
# YAML 문법 검증
|
|
yamllint .github/kustomize/overlays/dev/*.yaml
|
|
```
|
|
|
|
### 5. SonarQube 연결 실패
|
|
|
|
**증상**: SonarQube Analysis 단계에서 연결 오류
|
|
|
|
**해결 방법**:
|
|
1. SONAR_HOST_URL이 올바른지 확인
|
|
2. SONAR_TOKEN이 유효한지 확인
|
|
3. SonarQube 서비스 상태 확인:
|
|
```bash
|
|
kubectl get pods -n sonarqube
|
|
kubectl logs -n sonarqube {sonarqube-pod}
|
|
```
|
|
|
|
### 6. 환경 변수 로드 실패
|
|
|
|
**증상**: 환경 설정 파일을 찾을 수 없음
|
|
|
|
**해결 방법**:
|
|
```bash
|
|
# 파일 존재 확인
|
|
ls -la .github/config/
|
|
|
|
# 파일 내용 확인
|
|
cat .github/config/deploy_env_vars_dev
|
|
```
|
|
|
|
---
|
|
|
|
## 참고 자료
|
|
|
|
- [Kustomize 공식 문서](https://kustomize.io/)
|
|
- [GitHub Actions 문서](https://docs.github.com/en/actions)
|
|
- [Azure Container Registry 문서](https://docs.microsoft.com/en-us/azure/container-registry/)
|
|
- [AKS 문서](https://docs.microsoft.com/en-us/azure/aks/)
|
|
- [SonarQube 문서](https://docs.sonarqube.org/)
|
|
|
|
---
|
|
|
|
## 문의 및 지원
|
|
|
|
문제가 발생하거나 질문이 있으시면:
|
|
1. GitHub Issues에 등록
|
|
2. DevOps 팀에 문의 (송주영)
|
|
3. Slack #devops 채널
|
|
|
|
---
|
|
|
|
**작성일**: 2025-01-27
|
|
**작성자**: DevOps Team (주영)
|
|
**버전**: 1.0.0
|