mirror of
https://github.com/hwanny1128/HGZero.git
synced 2026-06-12 22:59:10 +00:00
add ci/cd
This commit is contained in:
@@ -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
|
||||
```
|
||||
@@ -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"
|
||||
Executable
+103
@@ -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"
|
||||
Executable
+133
@@ -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}"
|
||||
@@ -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
|
||||
@@ -0,0 +1,9 @@
|
||||
---
|
||||
# Namespace for HGZero application
|
||||
apiVersion: v1
|
||||
kind: Namespace
|
||||
metadata:
|
||||
name: hgzero
|
||||
labels:
|
||||
name: hgzero
|
||||
environment: production
|
||||
@@ -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
|
||||
@@ -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>
|
||||
Executable
+89
@@ -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}"
|
||||
@@ -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
|
||||
Reference in New Issue
Block a user