170 lines
5.8 KiB
Bash
Executable File
170 lines
5.8 KiB
Bash
Executable File
#!/bin/bash
|
|
|
|
# Jovies Kubernetes 배포 스크립트
|
|
# 공통 유틸리티 함수 로드
|
|
source "$(dirname "${BASH_SOURCE[0]}")/common.sh"
|
|
|
|
# 스크립트 설정
|
|
setup_script
|
|
|
|
print_usage() {
|
|
echo ""
|
|
echo "사용법: $(basename "$0") [-n NAMESPACE] [-c CONTEXT] [--app-image IMAGE[:TAG]] [--build|--no-build] [--tag TAG] [--dry-run] [--yes]"
|
|
echo " -n, --namespace Kubernetes 네임스페이스 (기본: jovies)"
|
|
echo " -c, --context kubectl 컨텍스트 지정 (kubectl config current-context 기본)"
|
|
echo " --app-image app 디플로이먼트에 사용할 이미지 레퍼런스(예: your/repo:jovies)"
|
|
echo " --build 배포 전에 Dockerfile로 로컬 이미지를 빌드 (기본)"
|
|
echo " --no-build 빌드 생략"
|
|
echo " --tag --build 시 사용할 이미지 태그 (기본: jovies-app:local-<timestamp>)"
|
|
echo " --dry-run 실제 적용 대신 미리보기 수행"
|
|
echo " -y, --yes 확인 프롬프트 건너뛰기"
|
|
echo ""
|
|
}
|
|
|
|
# 기본값
|
|
K8S_NAMESPACE="jovies"
|
|
KUBE_CONTEXT=""
|
|
DRY_RUN="false"
|
|
APP_IMAGE=""
|
|
DO_BUILD="true"
|
|
IMAGE_TAG=""
|
|
SKIP_CONFIRM="false"
|
|
|
|
# 인자 파싱
|
|
while [[ $# -gt 0 ]]; do
|
|
case "$1" in
|
|
-n|--namespace)
|
|
K8S_NAMESPACE="$2"; shift; shift ;;
|
|
-c|--context)
|
|
KUBE_CONTEXT="$2"; shift; shift ;;
|
|
--dry-run)
|
|
DRY_RUN="true"; shift ;;
|
|
--app-image)
|
|
APP_IMAGE="$2"; shift; shift ;;
|
|
--build)
|
|
DO_BUILD="true"; shift ;;
|
|
--no-build)
|
|
DO_BUILD="false"; shift ;;
|
|
--tag)
|
|
IMAGE_TAG="$2"; shift; shift ;;
|
|
-y|--yes)
|
|
SKIP_CONFIRM="true"; shift ;;
|
|
-h|--help)
|
|
print_usage; exit 0 ;;
|
|
*)
|
|
log_warn "알 수 없는 인자: $1"; print_usage; exit 1 ;;
|
|
esac
|
|
done
|
|
|
|
# 사전 점검
|
|
check_required_dirs "deploy/k8s"
|
|
|
|
if ! command -v kubectl >/dev/null 2>&1; then
|
|
log_error "kubectl 이 설치되어 있지 않습니다. 설치 후 다시 시도하세요."
|
|
exit 1
|
|
fi
|
|
|
|
if ! command -v kompose >/dev/null 2>&1; then
|
|
log_warn "kompose 가 설치되어 있지 않습니다. 기존 생성된 매니페스트만 적용합니다."
|
|
fi
|
|
|
|
# K8S 디렉토리 설정 (prod 설정만 사용)
|
|
K8S_DIR="deploy/k8s"
|
|
|
|
# 컨텍스트 설정
|
|
if [[ -n "$KUBE_CONTEXT" ]]; then
|
|
log_info "kubectl 컨텍스트 설정: $KUBE_CONTEXT"
|
|
kubectl config use-context "$KUBE_CONTEXT"
|
|
else
|
|
CURRENT_CTX=$(kubectl config current-context 2>/dev/null || echo "")
|
|
if [[ -n "$CURRENT_CTX" ]]; then
|
|
log_info "현재 kubectl 컨텍스트: $CURRENT_CTX"
|
|
else
|
|
log_warn "kubectl 컨텍스트가 설정되어 있지 않습니다. kubeconfig 를 확인하세요."
|
|
fi
|
|
fi
|
|
|
|
# 네임스페이스 보장
|
|
if [[ "$K8S_NAMESPACE" != "default" ]]; then
|
|
if ! kubectl get namespace "$K8S_NAMESPACE" >/dev/null 2>&1; then
|
|
log_info "네임스페이스 생성: $K8S_NAMESPACE"
|
|
kubectl create namespace "$K8S_NAMESPACE"
|
|
fi
|
|
fi
|
|
|
|
# 빌드가 필요한 경우 로컬 이미지 빌드
|
|
if [[ "$DO_BUILD" == "true" && "$DRY_RUN" != "true" ]]; then
|
|
BUILD_CONTEXT="."
|
|
DOCKERFILE_PATH="deploy/docker/Dockerfile.prod"
|
|
if [[ -z "$IMAGE_TAG" ]]; then
|
|
IMAGE_TAG="jovies-app:local-$(date +%Y%m%d%H%M%S)"
|
|
fi
|
|
log_info "🔨 Docker 이미지 빌드: $IMAGE_TAG"
|
|
docker build -t "$IMAGE_TAG" -f "$DOCKERFILE_PATH" "$BUILD_CONTEXT"
|
|
# 빌드 결과를 배포 이미지로 기본 설정 (명시적으로 --app-image 주면 그 값이 우선)
|
|
if [[ -z "$APP_IMAGE" ]]; then
|
|
APP_IMAGE="$IMAGE_TAG"
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
log_info "📦 적용 대상 디렉토리: $K8S_DIR"
|
|
log_info "🧭 네임스페이스: $K8S_NAMESPACE"
|
|
if [[ -n "$APP_IMAGE" ]]; then
|
|
log_info "🖼️ 적용할 앱 이미지: $APP_IMAGE"
|
|
fi
|
|
|
|
# Dry-run 플래그 구성
|
|
APPLY_FLAGS=(apply -f "$K8S_DIR" -n "$K8S_NAMESPACE")
|
|
if [[ "$DRY_RUN" == "true" ]]; then
|
|
APPLY_FLAGS+=(--dry-run=client)
|
|
fi
|
|
|
|
# 적용 전 요약 및 사전 검증
|
|
log_info "📝 적용 요약:"
|
|
echo " - 디렉토리: $K8S_DIR"
|
|
echo " - 네임스페이스: $K8S_NAMESPACE"
|
|
if [[ -n "$KUBE_CONTEXT" ]]; then echo " - 컨텍스트: $KUBE_CONTEXT"; fi
|
|
if [[ "$DRY_RUN" == "true" ]]; then echo " - 모드: Dry Run"; fi
|
|
if grep -qE "^\s*image:\s*app(\s|$)" "$K8S_DIR/app-deployment.yaml" 2>/dev/null; then
|
|
if [[ -z "$APP_IMAGE" ]]; then
|
|
log_warn "app-deployment.yaml 에 image: app 이 설정되어 있습니다. 실제 레지스트리 이미지를 --app-image 로 지정하는 것을 권장합니다."
|
|
fi
|
|
fi
|
|
|
|
# 확인 후 진행
|
|
if [[ "$SKIP_CONFIRM" != "true" ]]; then
|
|
if ! confirm_action "계속 진행하시겠습니까?" "Y"; then
|
|
log_warn "사용자에 의해 취소되었습니다."
|
|
exit 0
|
|
fi
|
|
fi
|
|
|
|
echo ""
|
|
log_info "🚀 Kubernetes 리소스 적용 중..."
|
|
kubectl "${APPLY_FLAGS[@]}"
|
|
|
|
# 필요 시 이미지 오버라이드
|
|
if [[ -n "$APP_IMAGE" ]]; then
|
|
log_info "🔄 앱 디플로이먼트 이미지 업데이트: $APP_IMAGE"
|
|
kubectl -n "$K8S_NAMESPACE" set image deployment/jovies-app jovies-app="$APP_IMAGE"
|
|
# latest 태그나 기본 정책으로 인한 강제 Pull 방지
|
|
log_info "🛠️ 이미지 Pull 정책 패치: IfNotPresent"
|
|
kubectl -n "$K8S_NAMESPACE" patch deployment jovies-app \
|
|
--type='json' \
|
|
-p='[{"op":"replace","path":"/spec/template/spec/containers/0/imagePullPolicy","value":"IfNotPresent"}]' || true
|
|
fi
|
|
|
|
echo ""
|
|
log_info "📊 리소스 상태:"
|
|
kubectl get all -n "$K8S_NAMESPACE"
|
|
|
|
echo ""
|
|
log_info "📄 유용한 명령어:"
|
|
echo " - 삭제: kubectl delete -f $K8S_DIR -n $K8S_NAMESPACE"
|
|
echo " - 로그: kubectl logs deploy/jovies-app -n $K8S_NAMESPACE -f"
|
|
echo " - 상세: kubectl describe deploy/jovies-app -n $K8S_NAMESPACE"
|
|
echo " - 포트 포워드: kubectl port-forward -n $K8S_NAMESPACE deploy/jovies-app 3002:3000"
|
|
|
|
log_info "✅ Kubernetes 배포 작업 완료"
|