mirror of
https://github.com/hwanny1128/HGZero.git
synced 2025-12-06 05:36:23 +00:00
add ci/cd
This commit is contained in:
parent
decc4de180
commit
9adcab2048
254
.github/workflows/backend-cicd_ArgoCD.yaml
vendored
Normal file
254
.github/workflows/backend-cicd_ArgoCD.yaml
vendored
Normal file
@ -0,0 +1,254 @@
|
||||
name: Backend Services CI/CD
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [ main, develop ]
|
||||
paths:
|
||||
- 'user/**'
|
||||
- 'meeting/**'
|
||||
- 'stt/**'
|
||||
- 'ai/**'
|
||||
- 'notification/**'
|
||||
- 'common/**'
|
||||
- '.github/**'
|
||||
pull_request:
|
||||
branches: [ main ]
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
ENVIRONMENT:
|
||||
description: 'Target environment'
|
||||
required: true
|
||||
default: 'dev'
|
||||
type: choice
|
||||
options:
|
||||
- dev
|
||||
- staging
|
||||
- prod
|
||||
SKIP_SONARQUBE:
|
||||
description: 'Skip SonarQube Analysis'
|
||||
required: false
|
||||
default: 'true'
|
||||
type: choice
|
||||
options:
|
||||
- 'true'
|
||||
- 'false'
|
||||
|
||||
env:
|
||||
REGISTRY: acrdigitalgarage02.azurecr.io
|
||||
IMAGE_ORG: hgzero
|
||||
RESOURCE_GROUP: rg-digitalgarage-02
|
||||
AKS_CLUSTER: aks-digitalgarage-02
|
||||
NAMESPACE: hgzero
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and Test
|
||||
runs-on: ubuntu-latest
|
||||
outputs:
|
||||
image_tag: ${{ steps.set_outputs.outputs.image_tag }}
|
||||
environment: ${{ steps.set_outputs.outputs.environment }}
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Set up JDK 21
|
||||
uses: actions/setup-java@v3
|
||||
with:
|
||||
java-version: '21'
|
||||
distribution: 'temurin'
|
||||
cache: 'gradle'
|
||||
|
||||
- name: Determine environment
|
||||
id: determine_env
|
||||
run: |
|
||||
# Use input parameter or default to 'dev'
|
||||
ENVIRONMENT="${{ github.event.inputs.ENVIRONMENT || 'dev' }}"
|
||||
echo "environment=$ENVIRONMENT" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Load environment variables
|
||||
id: env_vars
|
||||
run: |
|
||||
ENV=${{ steps.determine_env.outputs.environment }}
|
||||
|
||||
# Initialize variables with defaults
|
||||
REGISTRY="acrdigitalgarage02.azurecr.io"
|
||||
IMAGE_ORG="hgzero"
|
||||
RESOURCE_GROUP="rg-digitalgarage-02"
|
||||
AKS_CLUSTER="aks-digitalgarage-02"
|
||||
NAMESPACE="hgzero"
|
||||
|
||||
# Read environment variables from .github/config file
|
||||
if [[ -f ".github/config/deploy_env_vars_${ENV}" ]]; then
|
||||
while IFS= read -r line || [[ -n "$line" ]]; do
|
||||
# Skip comments and empty lines
|
||||
[[ "$line" =~ ^#.*$ ]] && continue
|
||||
[[ -z "$line" ]] && continue
|
||||
|
||||
# Extract key-value pairs
|
||||
key=$(echo "$line" | cut -d '=' -f1)
|
||||
value=$(echo "$line" | cut -d '=' -f2-)
|
||||
|
||||
# Override defaults if found in config
|
||||
case "$key" in
|
||||
"resource_group") RESOURCE_GROUP="$value" ;;
|
||||
"cluster_name") AKS_CLUSTER="$value" ;;
|
||||
esac
|
||||
done < ".github/config/deploy_env_vars_${ENV}"
|
||||
fi
|
||||
|
||||
# Export for other jobs
|
||||
echo "REGISTRY=$REGISTRY" >> $GITHUB_ENV
|
||||
echo "IMAGE_ORG=$IMAGE_ORG" >> $GITHUB_ENV
|
||||
echo "RESOURCE_GROUP=$RESOURCE_GROUP" >> $GITHUB_ENV
|
||||
echo "AKS_CLUSTER=$AKS_CLUSTER" >> $GITHUB_ENV
|
||||
|
||||
- name: Grant execute permission for gradlew
|
||||
run: chmod +x gradlew
|
||||
|
||||
- name: Build with Gradle
|
||||
run: |
|
||||
./gradlew build -x test
|
||||
|
||||
- name: SonarQube Analysis & Quality Gate
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
|
||||
SONAR_HOST_URL: ${{ secrets.SONAR_HOST_URL }}
|
||||
run: |
|
||||
# Check if SonarQube should be skipped
|
||||
SKIP_SONARQUBE="${{ github.event.inputs.SKIP_SONARQUBE || 'true' }}"
|
||||
|
||||
if [[ "$SKIP_SONARQUBE" == "true" ]]; then
|
||||
echo "⏭️ Skipping SonarQube Analysis (SKIP_SONARQUBE=$SKIP_SONARQUBE)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Define services array
|
||||
services=(user meeting stt ai notification)
|
||||
|
||||
# Run tests, coverage reports, and SonarQube analysis for each service
|
||||
for service in "${services[@]}"; do
|
||||
./gradlew :$service:test :$service:jacocoTestReport :$service:sonar \
|
||||
-Dsonar.projectKey=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
|
||||
-Dsonar.projectName=hgzero-$service-${{ steps.determine_env.outputs.environment }} \
|
||||
-Dsonar.host.url=$SONAR_HOST_URL \
|
||||
-Dsonar.token=$SONAR_TOKEN \
|
||||
-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/**
|
||||
done
|
||||
|
||||
- name: Upload build artifacts
|
||||
uses: actions/upload-artifact@v4
|
||||
with:
|
||||
name: app-builds
|
||||
path: |
|
||||
user/build/libs/*.jar
|
||||
meeting/build/libs/*.jar
|
||||
stt/build/libs/*.jar
|
||||
ai/build/libs/*.jar
|
||||
notification/build/libs/*.jar
|
||||
|
||||
- name: Set outputs
|
||||
id: set_outputs
|
||||
run: |
|
||||
# Generate timestamp for image tag
|
||||
IMAGE_TAG=$(date +%Y%m%d%H%M%S)
|
||||
echo "image_tag=$IMAGE_TAG" >> $GITHUB_OUTPUT
|
||||
echo "environment=${{ steps.determine_env.outputs.environment }}" >> $GITHUB_OUTPUT
|
||||
|
||||
release:
|
||||
name: Build and Push Docker Images
|
||||
needs: build
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Download build artifacts
|
||||
uses: actions/download-artifact@v4
|
||||
with:
|
||||
name: app-builds
|
||||
|
||||
- name: Set environment variables from build job
|
||||
run: |
|
||||
echo "REGISTRY=${{ env.REGISTRY }}" >> $GITHUB_ENV
|
||||
echo "IMAGE_ORG=${{ env.IMAGE_ORG }}" >> $GITHUB_ENV
|
||||
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
|
||||
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
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
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: ${{ env.REGISTRY }}
|
||||
username: ${{ secrets.ACR_USERNAME }}
|
||||
password: ${{ secrets.ACR_PASSWORD }}
|
||||
|
||||
- name: Build and push Docker images for all services
|
||||
run: |
|
||||
# Define services array
|
||||
services=(user meeting stt ai notification)
|
||||
|
||||
# Build and push each service image
|
||||
for service in "${services[@]}"; do
|
||||
echo "Building and pushing $service..."
|
||||
docker build \
|
||||
--build-arg BUILD_LIB_DIR="$service/build/libs" \
|
||||
--build-arg ARTIFACTORY_FILE="$service.jar" \
|
||||
-f deployment/container/Dockerfile-backend \
|
||||
-t ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }} .
|
||||
|
||||
docker push ${{ env.REGISTRY }}/${{ env.IMAGE_ORG }}/$service:${{ needs.build.outputs.environment }}-${{ needs.build.outputs.image_tag }}
|
||||
done
|
||||
|
||||
update-manifest:
|
||||
name: Update Manifest Repository
|
||||
needs: [build, release]
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: Set image tag environment variable
|
||||
run: |
|
||||
echo "IMAGE_TAG=${{ needs.build.outputs.image_tag }}" >> $GITHUB_ENV
|
||||
echo "ENVIRONMENT=${{ needs.build.outputs.environment }}" >> $GITHUB_ENV
|
||||
|
||||
- name: Update Manifest Repository
|
||||
run: |
|
||||
# 매니페스트 레포지토리 클론
|
||||
REPO_URL=$(echo "https://github.com/hjmoons/hgzero-manifest.git" | sed 's|https://||')
|
||||
git clone https://${{ secrets.GIT_USERNAME }}:${{ secrets.GIT_PASSWORD }}@${REPO_URL} manifest-repo
|
||||
cd manifest-repo
|
||||
|
||||
# Kustomize 설치
|
||||
curl -s "https://raw.githubusercontent.com/kubernetes-sigs/kustomize/master/hack/install_kustomize.sh" | bash
|
||||
sudo mv kustomize /usr/local/bin/
|
||||
|
||||
# 매니페스트 업데이트
|
||||
cd hgzero/kustomize/overlays/${{ env.ENVIRONMENT }}
|
||||
|
||||
# 각 서비스별 이미지 태그 업데이트
|
||||
services="user meeting stt ai notification"
|
||||
for service in $services; do
|
||||
kustomize edit set image acrdigitalgarage02.azurecr.io/hgzero/$service:${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}
|
||||
done
|
||||
|
||||
# Git 설정 및 푸시
|
||||
cd ../../../..
|
||||
git config user.name "GitHub Actions"
|
||||
git config user.email "actions@github.com"
|
||||
git add .
|
||||
git commit -m "🚀 Update hgzero ${{ env.ENVIRONMENT }} images to ${{ env.ENVIRONMENT }}-${{ env.IMAGE_TAG }}"
|
||||
git push origin main
|
||||
|
||||
echo "✅ 매니페스트 업데이트 완료. ArgoCD가 자동으로 배포합니다."
|
||||
420
deploy/k8s/backend/README.md
Normal file
420
deploy/k8s/backend/README.md
Normal file
@ -0,0 +1,420 @@
|
||||
# HGZero 백엔드 서비스 Kubernetes 배포 가이드
|
||||
|
||||
## 개요
|
||||
|
||||
이 가이드는 HGZero 백엔드 서비스(User, Meeting, Notification)를 Azure Kubernetes Service(AKS)에 배포하는 방법을 설명합니다.
|
||||
|
||||
## 배포 환경
|
||||
|
||||
- **ACR(Azure Container Registry)**: acrdigitalgarage02
|
||||
- **AKS(Azure Kubernetes Service)**: aks-digitalgarage-02
|
||||
- **네임스페이스**: hgzero
|
||||
- **리소스 그룹**: rg-digitalgarage-02
|
||||
|
||||
## 서비스 구성
|
||||
|
||||
### 1. User Service
|
||||
- **포트**: 8080
|
||||
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/user-service:latest
|
||||
- **기능**: 사용자 인증 및 관리, LDAP 연동
|
||||
|
||||
### 2. Meeting Service
|
||||
- **포트**: 8081 (HTTP), 8082 (WebSocket)
|
||||
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest
|
||||
- **기능**: 회의 관리, WebSocket 통신
|
||||
|
||||
### 3. Notification Service
|
||||
- **포트**: 8082
|
||||
- **이미지**: acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest
|
||||
- **기능**: 알림 전송, 이메일 발송
|
||||
|
||||
## 리소스 할당
|
||||
|
||||
각 서비스는 다음과 같은 리소스를 사용합니다:
|
||||
|
||||
- **Requests**:
|
||||
- CPU: 256m
|
||||
- Memory: 256Mi
|
||||
- **Limits**:
|
||||
- CPU: 1024m
|
||||
- Memory: 1024Mi
|
||||
- **Replicas**: 1 (각 서비스)
|
||||
|
||||
## 사전 요구사항
|
||||
|
||||
1. **Azure CLI 설치**
|
||||
```bash
|
||||
# macOS
|
||||
brew install azure-cli
|
||||
|
||||
# Windows
|
||||
# Download from https://aka.ms/installazurecliwindows
|
||||
|
||||
# Linux
|
||||
curl -sL https://aka.ms/InstallAzureCLIDeb | sudo bash
|
||||
```
|
||||
|
||||
2. **kubectl 설치**
|
||||
```bash
|
||||
# macOS
|
||||
brew install kubectl
|
||||
|
||||
# Windows
|
||||
# Download from https://kubernetes.io/docs/tasks/tools/install-kubectl-windows/
|
||||
|
||||
# Linux
|
||||
curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
|
||||
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
|
||||
```
|
||||
|
||||
3. **Azure 로그인**
|
||||
```bash
|
||||
az login
|
||||
```
|
||||
|
||||
4. **ACR 로그인**
|
||||
```bash
|
||||
az acr login --name acrdigitalgarage02
|
||||
```
|
||||
|
||||
## 배포 파일 구조
|
||||
|
||||
```
|
||||
deploy/k8s/backend/
|
||||
├── namespace.yaml # 네임스페이스 정의
|
||||
├── configmap.yaml # ConfigMap (Redis, Mail 설정)
|
||||
├── secret-template.yaml # Secret 템플릿 (민감 정보)
|
||||
├── user-service.yaml # User Service 배포 매니페스트
|
||||
├── meeting-service.yaml # Meeting Service 배포 매니페스트
|
||||
├── notification-service.yaml # Notification Service 배포 매니페스트
|
||||
├── deploy.sh # 배포 스크립트
|
||||
├── undeploy.sh # 배포 해제 스크립트
|
||||
├── create-secrets.sh # Secret 생성 스크립트
|
||||
└── README.md # 이 문서
|
||||
```
|
||||
|
||||
## 배포 절차
|
||||
|
||||
### 1단계: AKS 클러스터 접근 설정
|
||||
|
||||
```bash
|
||||
# AKS credentials 가져오기
|
||||
az aks get-credentials \
|
||||
--resource-group rg-digitalgarage-02 \
|
||||
--name aks-digitalgarage-02 \
|
||||
--overwrite-existing
|
||||
|
||||
# 클러스터 연결 확인
|
||||
kubectl cluster-info
|
||||
```
|
||||
|
||||
### 2단계: 네임스페이스 생성
|
||||
|
||||
```bash
|
||||
kubectl apply -f namespace.yaml
|
||||
```
|
||||
|
||||
### 3단계: ConfigMap 생성
|
||||
|
||||
```bash
|
||||
kubectl apply -f configmap.yaml
|
||||
```
|
||||
|
||||
### 4단계: Secret 생성
|
||||
|
||||
옵션 A: 대화형 스크립트 사용 (권장)
|
||||
```bash
|
||||
./create-secrets.sh
|
||||
```
|
||||
|
||||
옵션 B: 직접 생성
|
||||
```bash
|
||||
# Database Secret
|
||||
kubectl create secret generic db-secret \
|
||||
--from-literal=host=<DB_HOST> \
|
||||
--from-literal=username=<DB_USERNAME> \
|
||||
--from-literal=password=<DB_PASSWORD> \
|
||||
--namespace=hgzero
|
||||
|
||||
# Azure Secret
|
||||
kubectl create secret generic azure-secret \
|
||||
--from-literal=eventhub-connection-string=<EVENTHUB_CONN> \
|
||||
--from-literal=blob-connection-string=<BLOB_CONN> \
|
||||
--namespace=hgzero
|
||||
|
||||
# Mail Secret
|
||||
kubectl create secret generic mail-secret \
|
||||
--from-literal=username=<MAIL_USERNAME> \
|
||||
--from-literal=password=<MAIL_PASSWORD> \
|
||||
--namespace=hgzero
|
||||
```
|
||||
|
||||
### 5단계: 서비스 배포
|
||||
|
||||
옵션 A: 자동 배포 스크립트 사용 (권장)
|
||||
```bash
|
||||
./deploy.sh
|
||||
```
|
||||
|
||||
옵션 B: 수동 배포
|
||||
```bash
|
||||
# ACR 연동 설정
|
||||
az aks update \
|
||||
-n aks-digitalgarage-02 \
|
||||
-g rg-digitalgarage-02 \
|
||||
--attach-acr acrdigitalgarage02
|
||||
|
||||
# 서비스 배포
|
||||
kubectl apply -f user-service.yaml
|
||||
kubectl apply -f notification-service.yaml
|
||||
kubectl apply -f meeting-service.yaml
|
||||
```
|
||||
|
||||
### 6단계: 배포 상태 확인
|
||||
|
||||
```bash
|
||||
# Deployment 상태 확인
|
||||
kubectl get deployments -n hgzero
|
||||
|
||||
# Pod 상태 확인
|
||||
kubectl get pods -n hgzero
|
||||
|
||||
# Service 확인
|
||||
kubectl get services -n hgzero
|
||||
|
||||
# 상세 정보 확인
|
||||
kubectl describe deployment user-service -n hgzero
|
||||
```
|
||||
|
||||
## 배포 확인 및 테스트
|
||||
|
||||
### Pod 로그 확인
|
||||
|
||||
```bash
|
||||
# User Service 로그
|
||||
kubectl logs -f deployment/user-service -n hgzero
|
||||
|
||||
# Meeting Service 로그
|
||||
kubectl logs -f deployment/meeting-service -n hgzero
|
||||
|
||||
# Notification Service 로그
|
||||
kubectl logs -f deployment/notification-service -n hgzero
|
||||
```
|
||||
|
||||
### Health Check
|
||||
|
||||
```bash
|
||||
# User Service health check
|
||||
kubectl port-forward svc/user-service 8080:8080 -n hgzero
|
||||
curl http://localhost:8080/actuator/health
|
||||
|
||||
# Meeting Service health check
|
||||
kubectl port-forward svc/meeting-service 8081:8081 -n hgzero
|
||||
curl http://localhost:8081/actuator/health
|
||||
|
||||
# Notification Service health check
|
||||
kubectl port-forward svc/notification-service 8082:8082 -n hgzero
|
||||
curl http://localhost:8082/actuator/health
|
||||
```
|
||||
|
||||
### Pod 내부 접속
|
||||
|
||||
```bash
|
||||
# Pod 내부로 접속하여 디버깅
|
||||
kubectl exec -it deployment/user-service -n hgzero -- /bin/sh
|
||||
```
|
||||
|
||||
## 배포 해제
|
||||
|
||||
### 전체 서비스 삭제
|
||||
|
||||
```bash
|
||||
./undeploy.sh
|
||||
```
|
||||
|
||||
### 개별 서비스 삭제
|
||||
|
||||
```bash
|
||||
kubectl delete -f user-service.yaml
|
||||
kubectl delete -f meeting-service.yaml
|
||||
kubectl delete -f notification-service.yaml
|
||||
```
|
||||
|
||||
### Secret 및 ConfigMap 삭제
|
||||
|
||||
```bash
|
||||
kubectl delete configmap redis-config mail-config -n hgzero
|
||||
kubectl delete secret db-secret azure-secret mail-secret -n hgzero
|
||||
```
|
||||
|
||||
### 네임스페이스 삭제
|
||||
|
||||
```bash
|
||||
kubectl delete namespace hgzero
|
||||
```
|
||||
|
||||
## 트러블슈팅
|
||||
|
||||
### Pod가 시작되지 않는 경우
|
||||
|
||||
```bash
|
||||
# Pod 상태 확인
|
||||
kubectl get pods -n hgzero
|
||||
|
||||
# Pod 상세 정보 확인
|
||||
kubectl describe pod <pod-name> -n hgzero
|
||||
|
||||
# Pod 로그 확인
|
||||
kubectl logs <pod-name> -n hgzero
|
||||
|
||||
# 이전 컨테이너 로그 확인 (재시작된 경우)
|
||||
kubectl logs <pod-name> -n hgzero --previous
|
||||
```
|
||||
|
||||
### 이미지 Pull 오류
|
||||
|
||||
```bash
|
||||
# ACR 연동 상태 확인
|
||||
az aks show -n aks-digitalgarage-02 -g rg-digitalgarage-02 --query "servicePrincipalProfile"
|
||||
|
||||
# ACR 재연동
|
||||
az aks update -n aks-digitalgarage-02 -g rg-digitalgarage-02 --attach-acr acrdigitalgarage02
|
||||
|
||||
# ImagePullSecret 확인
|
||||
kubectl get serviceaccount default -n hgzero -o yaml
|
||||
```
|
||||
|
||||
### Secret 관련 오류
|
||||
|
||||
```bash
|
||||
# Secret 존재 확인
|
||||
kubectl get secrets -n hgzero
|
||||
|
||||
# Secret 내용 확인
|
||||
kubectl get secret db-secret -n hgzero -o yaml
|
||||
|
||||
# Secret 재생성
|
||||
kubectl delete secret db-secret -n hgzero
|
||||
./create-secrets.sh
|
||||
```
|
||||
|
||||
### 네트워크 연결 문제
|
||||
|
||||
```bash
|
||||
# Service Endpoint 확인
|
||||
kubectl get endpoints -n hgzero
|
||||
|
||||
# DNS 확인
|
||||
kubectl run -it --rm debug --image=busybox --restart=Never -- nslookup user-service.hgzero.svc.cluster.local
|
||||
|
||||
# 네트워크 정책 확인
|
||||
kubectl get networkpolicies -n hgzero
|
||||
```
|
||||
|
||||
### 리소스 부족 문제
|
||||
|
||||
```bash
|
||||
# 노드 리소스 사용량 확인
|
||||
kubectl top nodes
|
||||
|
||||
# Pod 리소스 사용량 확인
|
||||
kubectl top pods -n hgzero
|
||||
|
||||
# 리소스 제한 조정 (필요 시)
|
||||
kubectl edit deployment user-service -n hgzero
|
||||
```
|
||||
|
||||
## 업데이트 및 롤링 배포
|
||||
|
||||
### 이미지 업데이트
|
||||
|
||||
```bash
|
||||
# 새 이미지 태그로 업데이트
|
||||
kubectl set image deployment/user-service \
|
||||
user-service=acrdigitalgarage02.azurecr.io/hgzero/user-service:v2.0.0 \
|
||||
-n hgzero
|
||||
|
||||
# 롤아웃 상태 확인
|
||||
kubectl rollout status deployment/user-service -n hgzero
|
||||
|
||||
# 롤아웃 히스토리 확인
|
||||
kubectl rollout history deployment/user-service -n hgzero
|
||||
```
|
||||
|
||||
### 롤백
|
||||
|
||||
```bash
|
||||
# 이전 버전으로 롤백
|
||||
kubectl rollout undo deployment/user-service -n hgzero
|
||||
|
||||
# 특정 revision으로 롤백
|
||||
kubectl rollout undo deployment/user-service --to-revision=2 -n hgzero
|
||||
```
|
||||
|
||||
## 모니터링
|
||||
|
||||
### Kubernetes Dashboard
|
||||
|
||||
```bash
|
||||
# Dashboard 접근
|
||||
az aks browse -n aks-digitalgarage-02 -g rg-digitalgarage-02
|
||||
```
|
||||
|
||||
### 리소스 모니터링
|
||||
|
||||
```bash
|
||||
# 실시간 리소스 사용량 모니터링
|
||||
watch kubectl top pods -n hgzero
|
||||
|
||||
# 이벤트 모니터링
|
||||
kubectl get events -n hgzero --sort-by='.lastTimestamp'
|
||||
```
|
||||
|
||||
## 보안 권장사항
|
||||
|
||||
1. **Secret 관리**
|
||||
- Secret은 절대 Git에 커밋하지 마세요
|
||||
- Azure Key Vault 통합을 고려하세요
|
||||
- Secret rotation 정책을 수립하세요
|
||||
|
||||
2. **네트워크 보안**
|
||||
- Network Policy를 활용하여 Pod 간 통신을 제한하세요
|
||||
- Service Mesh 도입을 고려하세요
|
||||
|
||||
3. **이미지 보안**
|
||||
- 정기적으로 이미지 스캔을 수행하세요
|
||||
- 최소 권한 원칙을 적용하세요
|
||||
|
||||
## 성능 최적화
|
||||
|
||||
1. **Auto Scaling 설정**
|
||||
```bash
|
||||
kubectl autoscale deployment user-service \
|
||||
--cpu-percent=70 \
|
||||
--min=1 \
|
||||
--max=5 \
|
||||
-n hgzero
|
||||
```
|
||||
|
||||
2. **리소스 조정**
|
||||
- 실제 사용량에 따라 requests/limits를 조정하세요
|
||||
- HPA(Horizontal Pod Autoscaler) 설정을 고려하세요
|
||||
|
||||
## 참고 자료
|
||||
|
||||
- [Azure Kubernetes Service 문서](https://docs.microsoft.com/azure/aks/)
|
||||
- [Kubernetes 공식 문서](https://kubernetes.io/docs/)
|
||||
- [kubectl 치트시트](https://kubernetes.io/docs/reference/kubectl/cheatsheet/)
|
||||
|
||||
## 지원 및 문의
|
||||
|
||||
문제 발생 시 다음 정보를 수집하여 보고해주세요:
|
||||
|
||||
```bash
|
||||
# 진단 정보 수집
|
||||
kubectl get all -n hgzero > hgzero-resources.txt
|
||||
kubectl describe pods -n hgzero > hgzero-pods-detail.txt
|
||||
kubectl logs deployment/user-service -n hgzero > user-service.log
|
||||
kubectl logs deployment/meeting-service -n hgzero > meeting-service.log
|
||||
kubectl logs deployment/notification-service -n hgzero > notification-service.log
|
||||
```
|
||||
20
deploy/k8s/backend/configmap.yaml
Normal file
20
deploy/k8s/backend/configmap.yaml
Normal file
@ -0,0 +1,20 @@
|
||||
---
|
||||
# Redis Configuration
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: redis-config
|
||||
namespace: hgzero
|
||||
data:
|
||||
host: "redis-service.hgzero.svc.cluster.local"
|
||||
port: "6379"
|
||||
---
|
||||
# Mail Configuration
|
||||
apiVersion: v1
|
||||
kind: ConfigMap
|
||||
metadata:
|
||||
name: mail-config
|
||||
namespace: hgzero
|
||||
data:
|
||||
host: "smtp.gmail.com"
|
||||
port: "587"
|
||||
103
deploy/k8s/backend/create-secrets.sh
Executable file
103
deploy/k8s/backend/create-secrets.sh
Executable file
@ -0,0 +1,103 @@
|
||||
#!/bin/bash
|
||||
|
||||
# HGZero Backend Services Secrets Creation Script
|
||||
# This script helps create Kubernetes secrets for the backend services
|
||||
|
||||
set -e
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
NAMESPACE="hgzero"
|
||||
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}HGZero Secrets Creation${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
|
||||
# Check if kubectl is installed
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
echo -e "${RED}Error: kubectl is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify connection to cluster
|
||||
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if namespace exists
|
||||
if ! kubectl get namespace ${NAMESPACE} &> /dev/null; then
|
||||
echo -e "${RED}Error: Namespace '${NAMESPACE}' does not exist${NC}"
|
||||
echo -e "${YELLOW}Please run deploy.sh first to create the namespace${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Function to prompt for secret value
|
||||
prompt_secret() {
|
||||
local prompt_text=$1
|
||||
local secret_value
|
||||
echo -n -e "${YELLOW}${prompt_text}: ${NC}"
|
||||
read -s secret_value
|
||||
echo ""
|
||||
echo -n "$secret_value"
|
||||
}
|
||||
|
||||
# Create Database Secret
|
||||
echo -e "${GREEN}Creating Database Secret...${NC}"
|
||||
DB_HOST=$(prompt_secret "Enter Database Host")
|
||||
DB_USERNAME=$(prompt_secret "Enter Database Username")
|
||||
DB_PASSWORD=$(prompt_secret "Enter Database Password")
|
||||
|
||||
kubectl create secret generic db-secret \
|
||||
--from-literal=host="${DB_HOST}" \
|
||||
--from-literal=username="${DB_USERNAME}" \
|
||||
--from-literal=password="${DB_PASSWORD}" \
|
||||
--namespace=${NAMESPACE} \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
echo -e "${GREEN}✓ Database secret created${NC}"
|
||||
echo ""
|
||||
|
||||
# Create Azure Secret
|
||||
echo -e "${GREEN}Creating Azure Secret...${NC}"
|
||||
EVENTHUB_CONN=$(prompt_secret "Enter EventHub Connection String")
|
||||
BLOB_CONN=$(prompt_secret "Enter Blob Storage Connection String")
|
||||
|
||||
kubectl create secret generic azure-secret \
|
||||
--from-literal=eventhub-connection-string="${EVENTHUB_CONN}" \
|
||||
--from-literal=blob-connection-string="${BLOB_CONN}" \
|
||||
--namespace=${NAMESPACE} \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
echo -e "${GREEN}✓ Azure secret created${NC}"
|
||||
echo ""
|
||||
|
||||
# Create Mail Secret
|
||||
echo -e "${GREEN}Creating Mail Secret...${NC}"
|
||||
MAIL_USERNAME=$(prompt_secret "Enter Mail Username")
|
||||
MAIL_PASSWORD=$(prompt_secret "Enter Mail Password")
|
||||
|
||||
kubectl create secret generic mail-secret \
|
||||
--from-literal=username="${MAIL_USERNAME}" \
|
||||
--from-literal=password="${MAIL_PASSWORD}" \
|
||||
--namespace=${NAMESPACE} \
|
||||
--dry-run=client -o yaml | kubectl apply -f -
|
||||
|
||||
echo -e "${GREEN}✓ Mail secret created${NC}"
|
||||
echo ""
|
||||
|
||||
# Verify secrets
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}Secrets Created Successfully${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
kubectl get secrets -n ${NAMESPACE}
|
||||
|
||||
echo ""
|
||||
echo -e "${YELLOW}Note: Secrets are stored in Kubernetes and can be viewed with:${NC}"
|
||||
echo -e " kubectl get secret <secret-name> -n ${NAMESPACE} -o yaml"
|
||||
133
deploy/k8s/backend/deploy.sh
Executable file
133
deploy/k8s/backend/deploy.sh
Executable file
@ -0,0 +1,133 @@
|
||||
#!/bin/bash
|
||||
|
||||
# HGZero Backend Services Kubernetes Deployment Script
|
||||
# Azure Container Registry: acrdigitalgarage02
|
||||
# Azure Kubernetes Service: aks-digitalgarage-02
|
||||
# Namespace: hgzero
|
||||
|
||||
set -e
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
ACR_NAME="acrdigitalgarage02"
|
||||
AKS_NAME="aks-digitalgarage-02"
|
||||
RESOURCE_GROUP="rg-digitalgarage-02"
|
||||
NAMESPACE="hgzero"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}HGZero Backend Services Deployment${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
|
||||
# Check if kubectl is installed
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
echo -e "${RED}Error: kubectl is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if Azure CLI is installed
|
||||
if ! command -v az &> /dev/null; then
|
||||
echo -e "${RED}Error: Azure CLI is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Login to Azure (if not already logged in)
|
||||
echo -e "${YELLOW}Checking Azure login status...${NC}"
|
||||
if ! az account show &> /dev/null; then
|
||||
echo -e "${YELLOW}Please login to Azure...${NC}"
|
||||
az login
|
||||
fi
|
||||
|
||||
# Get AKS credentials
|
||||
echo -e "${YELLOW}Getting AKS credentials...${NC}"
|
||||
az aks get-credentials --resource-group ${RESOURCE_GROUP} --name ${AKS_NAME} --overwrite-existing
|
||||
|
||||
# Verify connection to cluster
|
||||
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
|
||||
exit 1
|
||||
fi
|
||||
echo -e "${GREEN}✓ Successfully connected to ${AKS_NAME}${NC}"
|
||||
|
||||
# Create namespace if it doesn't exist
|
||||
echo -e "${YELLOW}Creating namespace '${NAMESPACE}'...${NC}"
|
||||
kubectl apply -f ${SCRIPT_DIR}/namespace.yaml
|
||||
echo -e "${GREEN}✓ Namespace created/verified${NC}"
|
||||
|
||||
# Apply ConfigMaps
|
||||
echo -e "${YELLOW}Applying ConfigMaps...${NC}"
|
||||
kubectl apply -f ${SCRIPT_DIR}/configmap.yaml
|
||||
echo -e "${GREEN}✓ ConfigMaps applied${NC}"
|
||||
|
||||
# Check if secrets exist
|
||||
echo -e "${YELLOW}Checking for secrets...${NC}"
|
||||
if ! kubectl get secret db-secret -n ${NAMESPACE} &> /dev/null || \
|
||||
! kubectl get secret azure-secret -n ${NAMESPACE} &> /dev/null || \
|
||||
! kubectl get secret mail-secret -n ${NAMESPACE} &> /dev/null; then
|
||||
echo -e "${RED}Warning: One or more secrets are missing!${NC}"
|
||||
echo -e "${YELLOW}Please create secrets using secret-template.yaml as reference${NC}"
|
||||
echo -e "${YELLOW}Example:${NC}"
|
||||
echo -e " kubectl create secret generic db-secret -n ${NAMESPACE} \\"
|
||||
echo -e " --from-literal=host=<DB_HOST> \\"
|
||||
echo -e " --from-literal=username=<DB_USERNAME> \\"
|
||||
echo -e " --from-literal=password=<DB_PASSWORD>"
|
||||
echo ""
|
||||
read -p "Do you want to continue without secrets? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${RED}Deployment cancelled${NC}"
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Configure ACR integration
|
||||
echo -e "${YELLOW}Configuring ACR integration...${NC}"
|
||||
az aks update -n ${AKS_NAME} -g ${RESOURCE_GROUP} --attach-acr ${ACR_NAME}
|
||||
echo -e "${GREEN}✓ ACR integration configured${NC}"
|
||||
|
||||
# Deploy services
|
||||
echo -e "${YELLOW}Deploying User Service...${NC}"
|
||||
kubectl apply -f ${SCRIPT_DIR}/user-service.yaml
|
||||
echo -e "${GREEN}✓ User Service deployed${NC}"
|
||||
|
||||
echo -e "${YELLOW}Deploying Notification Service...${NC}"
|
||||
kubectl apply -f ${SCRIPT_DIR}/notification-service.yaml
|
||||
echo -e "${GREEN}✓ Notification Service deployed${NC}"
|
||||
|
||||
echo -e "${YELLOW}Deploying Meeting Service...${NC}"
|
||||
kubectl apply -f ${SCRIPT_DIR}/meeting-service.yaml
|
||||
echo -e "${GREEN}✓ Meeting Service deployed${NC}"
|
||||
|
||||
# Wait for deployments to be ready
|
||||
echo -e "${YELLOW}Waiting for deployments to be ready...${NC}"
|
||||
kubectl wait --for=condition=available --timeout=300s \
|
||||
deployment/user-service \
|
||||
deployment/notification-service \
|
||||
deployment/meeting-service \
|
||||
-n ${NAMESPACE}
|
||||
|
||||
# Show deployment status
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}Deployment Status${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
kubectl get deployments -n ${NAMESPACE}
|
||||
echo ""
|
||||
kubectl get pods -n ${NAMESPACE}
|
||||
echo ""
|
||||
kubectl get services -n ${NAMESPACE}
|
||||
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}Deployment Completed Successfully!${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo ""
|
||||
echo -e "${YELLOW}Useful commands:${NC}"
|
||||
echo -e " View logs: kubectl logs -f deployment/<service-name> -n ${NAMESPACE}"
|
||||
echo -e " View pods: kubectl get pods -n ${NAMESPACE}"
|
||||
echo -e " Describe pod: kubectl describe pod <pod-name> -n ${NAMESPACE}"
|
||||
echo -e " Port forward: kubectl port-forward svc/<service-name> <local-port>:<service-port> -n ${NAMESPACE}"
|
||||
112
deploy/k8s/backend/meeting-service.yaml
Normal file
112
deploy/k8s/backend/meeting-service.yaml
Normal file
@ -0,0 +1,112 @@
|
||||
---
|
||||
# Meeting Service Deployment
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: meeting-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: meeting-service
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: meeting-service
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: meeting-service
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: meeting-service
|
||||
image: acrdigitalgarage02.azurecr.io/hgzero/meeting-service:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8081
|
||||
name: http
|
||||
- containerPort: 8082
|
||||
name: websocket
|
||||
env:
|
||||
- name: SPRING_PROFILES_ACTIVE
|
||||
value: "prod"
|
||||
- name: SERVER_PORT
|
||||
value: "8081"
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: host
|
||||
- name: DB_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: username
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: password
|
||||
- name: REDIS_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: host
|
||||
- name: REDIS_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: port
|
||||
- name: AZURE_EVENTHUB_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: azure-secret
|
||||
key: eventhub-connection-string
|
||||
- name: NOTIFICATION_SERVICE_URL
|
||||
value: "http://notification-service:8082"
|
||||
resources:
|
||||
requests:
|
||||
cpu: 256m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1024m
|
||||
memory: 1024Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: 8081
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: 8081
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
---
|
||||
# Meeting Service Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: meeting-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: meeting-service
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8081
|
||||
targetPort: 8081
|
||||
protocol: TCP
|
||||
name: http
|
||||
- port: 8082
|
||||
targetPort: 8082
|
||||
protocol: TCP
|
||||
name: websocket
|
||||
selector:
|
||||
app: meeting-service
|
||||
9
deploy/k8s/backend/namespace.yaml
Normal file
9
deploy/k8s/backend/namespace.yaml
Normal file
@ -0,0 +1,9 @@
|
||||
---
|
||||
# Namespace for HGZero application
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: hgzero
|
||||
labels:
|
||||
name: hgzero
|
||||
environment: production
|
||||
129
deploy/k8s/backend/notification-service.yaml
Normal file
129
deploy/k8s/backend/notification-service.yaml
Normal file
@ -0,0 +1,129 @@
|
||||
---
|
||||
# Notification Service Deployment
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: notification-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: notification-service
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: notification-service
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: notification-service
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: notification-service
|
||||
image: acrdigitalgarage02.azurecr.io/hgzero/notification-service:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8082
|
||||
name: http
|
||||
env:
|
||||
- name: SPRING_PROFILES_ACTIVE
|
||||
value: "prod"
|
||||
- name: SERVER_PORT
|
||||
value: "8082"
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: host
|
||||
- name: DB_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: username
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: password
|
||||
- name: REDIS_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: host
|
||||
- name: REDIS_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: port
|
||||
- name: AZURE_EVENTHUB_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: azure-secret
|
||||
key: eventhub-connection-string
|
||||
- name: AZURE_BLOB_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: azure-secret
|
||||
key: blob-connection-string
|
||||
- name: MAIL_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: mail-config
|
||||
key: host
|
||||
- name: MAIL_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: mail-config
|
||||
key: port
|
||||
- name: MAIL_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mail-secret
|
||||
key: username
|
||||
- name: MAIL_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mail-secret
|
||||
key: password
|
||||
resources:
|
||||
requests:
|
||||
cpu: 256m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1024m
|
||||
memory: 1024Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: 8082
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: 8082
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
---
|
||||
# Notification Service Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: notification-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: notification-service
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8082
|
||||
targetPort: 8082
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: notification-service
|
||||
36
deploy/k8s/backend/secret-template.yaml
Normal file
36
deploy/k8s/backend/secret-template.yaml
Normal file
@ -0,0 +1,36 @@
|
||||
---
|
||||
# Database Secret Template
|
||||
# Note: Replace base64 encoded values with your actual credentials
|
||||
# To encode: echo -n 'your-value' | base64
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: db-secret
|
||||
namespace: hgzero
|
||||
type: Opaque
|
||||
data:
|
||||
host: <BASE64_ENCODED_DB_HOST>
|
||||
username: <BASE64_ENCODED_DB_USERNAME>
|
||||
password: <BASE64_ENCODED_DB_PASSWORD>
|
||||
---
|
||||
# Azure Secret Template
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: azure-secret
|
||||
namespace: hgzero
|
||||
type: Opaque
|
||||
data:
|
||||
eventhub-connection-string: <BASE64_ENCODED_EVENTHUB_CONNECTION_STRING>
|
||||
blob-connection-string: <BASE64_ENCODED_BLOB_CONNECTION_STRING>
|
||||
---
|
||||
# Mail Secret Template
|
||||
apiVersion: v1
|
||||
kind: Secret
|
||||
metadata:
|
||||
name: mail-secret
|
||||
namespace: hgzero
|
||||
type: Opaque
|
||||
data:
|
||||
username: <BASE64_ENCODED_MAIL_USERNAME>
|
||||
password: <BASE64_ENCODED_MAIL_PASSWORD>
|
||||
89
deploy/k8s/backend/undeploy.sh
Executable file
89
deploy/k8s/backend/undeploy.sh
Executable file
@ -0,0 +1,89 @@
|
||||
#!/bin/bash
|
||||
|
||||
# HGZero Backend Services Kubernetes Undeployment Script
|
||||
|
||||
set -e
|
||||
|
||||
# Color codes for output
|
||||
RED='\033[0;31m'
|
||||
GREEN='\033[0;32m'
|
||||
YELLOW='\033[1;33m'
|
||||
NC='\033[0m' # No Color
|
||||
|
||||
# Configuration
|
||||
NAMESPACE="hgzero"
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
|
||||
echo -e "${YELLOW}======================================${NC}"
|
||||
echo -e "${YELLOW}HGZero Backend Services Undeployment${NC}"
|
||||
echo -e "${YELLOW}======================================${NC}"
|
||||
|
||||
# Check if kubectl is installed
|
||||
if ! command -v kubectl &> /dev/null; then
|
||||
echo -e "${RED}Error: kubectl is not installed${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Verify connection to cluster
|
||||
echo -e "${YELLOW}Verifying connection to Kubernetes cluster...${NC}"
|
||||
if ! kubectl cluster-info &> /dev/null; then
|
||||
echo -e "${RED}Error: Cannot connect to Kubernetes cluster${NC}"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if namespace exists
|
||||
if ! kubectl get namespace ${NAMESPACE} &> /dev/null; then
|
||||
echo -e "${YELLOW}Namespace '${NAMESPACE}' does not exist. Nothing to undeploy.${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
echo -e "${YELLOW}This will delete all services in namespace '${NAMESPACE}'${NC}"
|
||||
read -p "Are you sure you want to continue? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||
echo -e "${YELLOW}Undeployment cancelled${NC}"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# Delete services
|
||||
echo -e "${YELLOW}Deleting Meeting Service...${NC}"
|
||||
kubectl delete -f ${SCRIPT_DIR}/meeting-service.yaml --ignore-not-found=true
|
||||
echo -e "${GREEN}✓ Meeting Service deleted${NC}"
|
||||
|
||||
echo -e "${YELLOW}Deleting Notification Service...${NC}"
|
||||
kubectl delete -f ${SCRIPT_DIR}/notification-service.yaml --ignore-not-found=true
|
||||
echo -e "${GREEN}✓ Notification Service deleted${NC}"
|
||||
|
||||
echo -e "${YELLOW}Deleting User Service...${NC}"
|
||||
kubectl delete -f ${SCRIPT_DIR}/user-service.yaml --ignore-not-found=true
|
||||
echo -e "${GREEN}✓ User Service deleted${NC}"
|
||||
|
||||
# Delete ConfigMaps
|
||||
echo -e "${YELLOW}Deleting ConfigMaps...${NC}"
|
||||
kubectl delete -f ${SCRIPT_DIR}/configmap.yaml --ignore-not-found=true
|
||||
echo -e "${GREEN}✓ ConfigMaps deleted${NC}"
|
||||
|
||||
# Ask about secrets deletion
|
||||
echo ""
|
||||
echo -e "${YELLOW}Do you want to delete secrets as well?${NC}"
|
||||
echo -e "${RED}Warning: This will delete all database and Azure credentials${NC}"
|
||||
read -p "Delete secrets? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
kubectl delete secret db-secret azure-secret mail-secret -n ${NAMESPACE} --ignore-not-found=true
|
||||
echo -e "${GREEN}✓ Secrets deleted${NC}"
|
||||
fi
|
||||
|
||||
# Ask about namespace deletion
|
||||
echo ""
|
||||
echo -e "${YELLOW}Do you want to delete the namespace '${NAMESPACE}'?${NC}"
|
||||
read -p "Delete namespace? (y/N): " -n 1 -r
|
||||
echo
|
||||
if [[ $REPLY =~ ^[Yy]$ ]]; then
|
||||
kubectl delete namespace ${NAMESPACE}
|
||||
echo -e "${GREEN}✓ Namespace deleted${NC}"
|
||||
fi
|
||||
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
echo -e "${GREEN}Undeployment Completed${NC}"
|
||||
echo -e "${GREEN}======================================${NC}"
|
||||
102
deploy/k8s/backend/user-service.yaml
Normal file
102
deploy/k8s/backend/user-service.yaml
Normal file
@ -0,0 +1,102 @@
|
||||
---
|
||||
# User Service Deployment
|
||||
apiVersion: apps/v1
|
||||
kind: Deployment
|
||||
metadata:
|
||||
name: user-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: user-service
|
||||
tier: backend
|
||||
spec:
|
||||
replicas: 1
|
||||
selector:
|
||||
matchLabels:
|
||||
app: user-service
|
||||
template:
|
||||
metadata:
|
||||
labels:
|
||||
app: user-service
|
||||
tier: backend
|
||||
spec:
|
||||
containers:
|
||||
- name: user-service
|
||||
image: acrdigitalgarage02.azurecr.io/hgzero/user-service:latest
|
||||
imagePullPolicy: Always
|
||||
ports:
|
||||
- containerPort: 8080
|
||||
name: http
|
||||
env:
|
||||
- name: SPRING_PROFILES_ACTIVE
|
||||
value: "prod"
|
||||
- name: DB_HOST
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: host
|
||||
- name: DB_USERNAME
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: username
|
||||
- name: DB_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: db-secret
|
||||
key: password
|
||||
- name: REDIS_HOST
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: host
|
||||
- name: REDIS_PORT
|
||||
valueFrom:
|
||||
configMapKeyRef:
|
||||
name: redis-config
|
||||
key: port
|
||||
- name: AZURE_EVENTHUB_CONNECTION_STRING
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: azure-secret
|
||||
key: eventhub-connection-string
|
||||
resources:
|
||||
requests:
|
||||
cpu: 256m
|
||||
memory: 256Mi
|
||||
limits:
|
||||
cpu: 1024m
|
||||
memory: 1024Mi
|
||||
livenessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/liveness
|
||||
port: 8080
|
||||
initialDelaySeconds: 60
|
||||
periodSeconds: 10
|
||||
timeoutSeconds: 5
|
||||
failureThreshold: 3
|
||||
readinessProbe:
|
||||
httpGet:
|
||||
path: /actuator/health/readiness
|
||||
port: 8080
|
||||
initialDelaySeconds: 30
|
||||
periodSeconds: 5
|
||||
timeoutSeconds: 3
|
||||
failureThreshold: 3
|
||||
---
|
||||
# User Service Service
|
||||
apiVersion: v1
|
||||
kind: Service
|
||||
metadata:
|
||||
name: user-service
|
||||
namespace: hgzero
|
||||
labels:
|
||||
app: user-service
|
||||
spec:
|
||||
type: ClusterIP
|
||||
ports:
|
||||
- port: 8080
|
||||
targetPort: 8080
|
||||
protocol: TCP
|
||||
name: http
|
||||
selector:
|
||||
app: user-service
|
||||
Loading…
x
Reference in New Issue
Block a user