1108 lines
27 KiB
Bash
Executable File
1108 lines
27 KiB
Bash
Executable File
#!/bin/bash
|
||
# 灵境万象系统 - 一键部署到 Kubernetes v1.0.0
|
||
# Created Time: 2025-11-26
|
||
|
||
set -e
|
||
|
||
# 颜色定义
|
||
RED='\033[0;31m'
|
||
GREEN='\033[0;32m'
|
||
YELLOW='\033[1;33m'
|
||
BLUE='\033[0;34m'
|
||
NC='\033[0m' # No Color
|
||
|
||
echo -e "${BLUE}=========================================${NC}"
|
||
echo -e "${BLUE}🚀 灵境万象系统 - K8s 一键部署 v1.0.0${NC}"
|
||
echo -e "${BLUE}=========================================${NC}"
|
||
echo ""
|
||
|
||
# 加载版本配置
|
||
if [ -f "monitoring-versions.env" ]; then
|
||
source monitoring-versions.env
|
||
echo -e "${GREEN}✅ 已加载版本配置文件${NC}"
|
||
else
|
||
echo -e "${YELLOW}⚠️ 未找到版本配置文件,使用默认配置${NC}"
|
||
LJWX_VERSION="2.0.3"
|
||
LJWX_MYSQL_VERSION="2.0.3"
|
||
LJWX_REDIS_VERSION="2.0.3"
|
||
LJWX_BOOT_VERSION="2.0.3"
|
||
LJWX_BIGSCREEN_VERSION="2.0.3"
|
||
LJWX_ADMIN_VERSION="2.0.3"
|
||
fi
|
||
|
||
# 配置参数
|
||
NAMESPACE="${K8S_NAMESPACE:-ljwx-system}"
|
||
REGISTRY="${PRIVATE_REGISTRY:-localhost:15000}"
|
||
IMAGE_PREFIX="ljwx"
|
||
K8S_DIR="./k8s"
|
||
|
||
# 运行模式
|
||
BUILD_IMAGES="${BUILD_IMAGES:-true}" # 是否构建镜像
|
||
PUSH_IMAGES="${PUSH_IMAGES:-true}" # 是否推送镜像
|
||
CREATE_NAMESPACE="${CREATE_NAMESPACE:-true}" # 是否创建命名空间
|
||
DEPLOY_MYSQL="${DEPLOY_MYSQL:-true}" # 是否部署 MySQL
|
||
DEPLOY_REDIS="${DEPLOY_REDIS:-true}" # 是否部署 Redis
|
||
DEPLOY_APPS="${DEPLOY_APPS:-true}" # 是否部署应用
|
||
|
||
# MySQL 配置
|
||
MYSQL_ROOT_PASSWORD="${MYSQL_ROOT_PASSWORD:-123456}"
|
||
MYSQL_DATABASE="${MYSQL_DATABASE:-lj-06}"
|
||
MYSQL_USER="${MYSQL_USER:-root}"
|
||
|
||
# Redis 配置
|
||
REDIS_PASSWORD="${REDIS_PASSWORD:-123456}"
|
||
|
||
# 打印带颜色的消息
|
||
print_info() {
|
||
echo -e "${BLUE}ℹ ${NC}$1"
|
||
}
|
||
|
||
print_success() {
|
||
echo -e "${GREEN}✅${NC} $1"
|
||
}
|
||
|
||
print_warning() {
|
||
echo -e "${YELLOW}⚠️${NC} $1"
|
||
}
|
||
|
||
print_error() {
|
||
echo -e "${RED}❌${NC} $1"
|
||
}
|
||
|
||
print_header() {
|
||
echo ""
|
||
echo -e "${BLUE}=========================================${NC}"
|
||
echo -e "${BLUE}$1${NC}"
|
||
echo -e "${BLUE}=========================================${NC}"
|
||
}
|
||
|
||
# 检查必要工具
|
||
check_prerequisites() {
|
||
print_header "检查前置条件"
|
||
|
||
# 检查 kubectl
|
||
if ! command -v kubectl &> /dev/null; then
|
||
print_error "kubectl 未安装,请先安装 kubectl"
|
||
exit 1
|
||
fi
|
||
print_success "kubectl 已安装"
|
||
|
||
# 检查 K8s 集群连接
|
||
if ! kubectl cluster-info &> /dev/null; then
|
||
print_error "无法连接到 Kubernetes 集群"
|
||
print_info "请检查 kubectl 配置: kubectl config view"
|
||
exit 1
|
||
fi
|
||
print_success "Kubernetes 集群连接正常"
|
||
|
||
# 显示集群信息
|
||
CLUSTER_NAME=$(kubectl config current-context)
|
||
print_info "当前集群: $CLUSTER_NAME"
|
||
|
||
# 检查 Docker
|
||
if ! command -v docker &> /dev/null; then
|
||
print_error "Docker 未安装,请先安装 Docker"
|
||
exit 1
|
||
fi
|
||
print_success "Docker 已安装"
|
||
|
||
# 检查本地 Registry
|
||
if curl -s -f --max-time 3 "http://$REGISTRY/v2/_catalog" > /dev/null 2>&1; then
|
||
print_success "本地 Registry 运行正常 ($REGISTRY)"
|
||
else
|
||
print_warning "本地 Registry 未运行,将无法推送镜像"
|
||
read -p "是否继续(使用已有镜像)? (y/n) " -n 1 -r
|
||
echo
|
||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||
exit 1
|
||
fi
|
||
BUILD_IMAGES=false
|
||
PUSH_IMAGES=false
|
||
fi
|
||
}
|
||
|
||
# 创建 K8s 配置目录
|
||
create_k8s_dir() {
|
||
print_header "创建 K8s 配置目录"
|
||
|
||
mkdir -p "$K8S_DIR"/{namespace,configmap,secret,mysql,redis,boot,bigscreen,admin,ingress}
|
||
print_success "K8s 配置目录已创建"
|
||
}
|
||
|
||
# 生成 Namespace
|
||
generate_namespace() {
|
||
print_info "生成 Namespace 配置..."
|
||
|
||
cat > "$K8S_DIR/namespace/namespace.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Namespace
|
||
metadata:
|
||
name: $NAMESPACE
|
||
labels:
|
||
name: $NAMESPACE
|
||
app: ljwx
|
||
environment: production
|
||
EOF
|
||
|
||
print_success "Namespace 配置已生成"
|
||
}
|
||
|
||
# 生成 ConfigMap
|
||
generate_configmap() {
|
||
print_info "生成 ConfigMap 配置..."
|
||
|
||
cat > "$K8S_DIR/configmap/ljwx-config.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: ConfigMap
|
||
metadata:
|
||
name: ljwx-config
|
||
namespace: $NAMESPACE
|
||
data:
|
||
mysql.host: "ljwx-mysql"
|
||
mysql.port: "3306"
|
||
mysql.database: "$MYSQL_DATABASE"
|
||
redis.host: "ljwx-redis"
|
||
redis.port: "6379"
|
||
timezone: "Asia/Shanghai"
|
||
log.level: "INFO"
|
||
EOF
|
||
|
||
print_success "ConfigMap 配置已生成"
|
||
}
|
||
|
||
# 生成 Secret
|
||
generate_secret() {
|
||
print_info "生成 Secret 配置..."
|
||
|
||
# Base64 编码密码
|
||
MYSQL_PASSWORD_B64=$(echo -n "$MYSQL_ROOT_PASSWORD" | base64)
|
||
REDIS_PASSWORD_B64=$(echo -n "$REDIS_PASSWORD" | base64)
|
||
|
||
cat > "$K8S_DIR/secret/ljwx-secret.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Secret
|
||
metadata:
|
||
name: ljwx-secret
|
||
namespace: $NAMESPACE
|
||
type: Opaque
|
||
data:
|
||
mysql-root-password: $MYSQL_PASSWORD_B64
|
||
mysql-user: $(echo -n "$MYSQL_USER" | base64)
|
||
mysql-password: $MYSQL_PASSWORD_B64
|
||
mysql-database: $(echo -n "$MYSQL_DATABASE" | base64)
|
||
redis-password: $REDIS_PASSWORD_B64
|
||
EOF
|
||
|
||
print_success "Secret 配置已生成"
|
||
}
|
||
|
||
# 生成 MySQL 部署配置
|
||
generate_mysql_manifest() {
|
||
print_info "生成 MySQL 部署配置..."
|
||
|
||
cat > "$K8S_DIR/mysql/mysql-statefulset.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ljwx-mysql
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-mysql
|
||
spec:
|
||
type: ClusterIP
|
||
clusterIP: None # Headless service for StatefulSet
|
||
ports:
|
||
- port: 3306
|
||
targetPort: 3306
|
||
name: mysql
|
||
selector:
|
||
app: ljwx-mysql
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: StatefulSet
|
||
metadata:
|
||
name: ljwx-mysql
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-mysql
|
||
spec:
|
||
serviceName: ljwx-mysql
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: ljwx-mysql
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ljwx-mysql
|
||
spec:
|
||
containers:
|
||
- name: mysql
|
||
image: $REGISTRY/$IMAGE_PREFIX/ljwx-mysql:$LJWX_MYSQL_VERSION
|
||
imagePullPolicy: IfNotPresent
|
||
ports:
|
||
- containerPort: 3306
|
||
name: mysql
|
||
env:
|
||
- name: MYSQL_ROOT_PASSWORD
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: mysql-root-password
|
||
- name: MYSQL_DATABASE
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.database
|
||
- name: TZ
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: timezone
|
||
resources:
|
||
requests:
|
||
memory: "512Mi"
|
||
cpu: "250m"
|
||
limits:
|
||
memory: "2Gi"
|
||
cpu: "1000m"
|
||
volumeMounts:
|
||
- name: mysql-data
|
||
mountPath: /var/lib/mysql
|
||
- name: mysql-logs
|
||
mountPath: /var/log/mysql
|
||
livenessProbe:
|
||
exec:
|
||
command:
|
||
- mysqladmin
|
||
- ping
|
||
- -h
|
||
- localhost
|
||
initialDelaySeconds: 60
|
||
periodSeconds: 30
|
||
timeoutSeconds: 10
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
exec:
|
||
command:
|
||
- mysqladmin
|
||
- ping
|
||
- -h
|
||
- localhost
|
||
initialDelaySeconds: 10
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
volumeClaimTemplates:
|
||
- metadata:
|
||
name: mysql-data
|
||
spec:
|
||
accessModes: [ "ReadWriteOnce" ]
|
||
resources:
|
||
requests:
|
||
storage: 10Gi
|
||
- metadata:
|
||
name: mysql-logs
|
||
spec:
|
||
accessModes: [ "ReadWriteOnce" ]
|
||
resources:
|
||
requests:
|
||
storage: 1Gi
|
||
EOF
|
||
|
||
print_success "MySQL 配置已生成"
|
||
}
|
||
|
||
# 生成 Redis 部署配置
|
||
generate_redis_manifest() {
|
||
print_info "生成 Redis 部署配置..."
|
||
|
||
cat > "$K8S_DIR/redis/redis-deployment.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ljwx-redis
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-redis
|
||
spec:
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 6379
|
||
targetPort: 6379
|
||
name: redis
|
||
selector:
|
||
app: ljwx-redis
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: ljwx-redis
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-redis
|
||
spec:
|
||
replicas: 1
|
||
selector:
|
||
matchLabels:
|
||
app: ljwx-redis
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ljwx-redis
|
||
spec:
|
||
containers:
|
||
- name: redis
|
||
image: $REGISTRY/$IMAGE_PREFIX/ljwx-redis:$LJWX_REDIS_VERSION
|
||
imagePullPolicy: IfNotPresent
|
||
ports:
|
||
- containerPort: 6379
|
||
name: redis
|
||
env:
|
||
- name: TZ
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: timezone
|
||
resources:
|
||
requests:
|
||
memory: "128Mi"
|
||
cpu: "100m"
|
||
limits:
|
||
memory: "512Mi"
|
||
cpu: "500m"
|
||
volumeMounts:
|
||
- name: redis-data
|
||
mountPath: /data
|
||
livenessProbe:
|
||
exec:
|
||
command:
|
||
- redis-cli
|
||
- ping
|
||
initialDelaySeconds: 30
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
exec:
|
||
command:
|
||
- redis-cli
|
||
- ping
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
timeoutSeconds: 3
|
||
failureThreshold: 3
|
||
volumes:
|
||
- name: redis-data
|
||
emptyDir: {}
|
||
EOF
|
||
|
||
print_success "Redis 配置已生成"
|
||
}
|
||
|
||
# 生成 Boot 后端部署配置
|
||
generate_boot_manifest() {
|
||
print_info "生成 Boot 后端部署配置..."
|
||
|
||
cat > "$K8S_DIR/boot/boot-deployment.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ljwx-boot
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-boot
|
||
spec:
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 9998
|
||
targetPort: 9998
|
||
name: http
|
||
selector:
|
||
app: ljwx-boot
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: ljwx-boot
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-boot
|
||
spec:
|
||
replicas: 2
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxUnavailable: 0
|
||
maxSurge: 1
|
||
selector:
|
||
matchLabels:
|
||
app: ljwx-boot
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ljwx-boot
|
||
spec:
|
||
initContainers:
|
||
- name: wait-for-mysql
|
||
image: busybox:1.35
|
||
command:
|
||
- sh
|
||
- -c
|
||
- |
|
||
until nc -z ljwx-mysql 3306; do
|
||
echo "Waiting for MySQL..."
|
||
sleep 3
|
||
done
|
||
echo "MySQL is ready"
|
||
- name: wait-for-redis
|
||
image: busybox:1.35
|
||
command:
|
||
- sh
|
||
- -c
|
||
- |
|
||
until nc -z ljwx-redis 6379; do
|
||
echo "Waiting for Redis..."
|
||
sleep 3
|
||
done
|
||
echo "Redis is ready"
|
||
containers:
|
||
- name: boot
|
||
image: $REGISTRY/$IMAGE_PREFIX/ljwx-boot:$LJWX_BOOT_VERSION
|
||
imagePullPolicy: IfNotPresent
|
||
ports:
|
||
- containerPort: 9998
|
||
name: http
|
||
env:
|
||
- name: SPRING_PROFILES_ACTIVE
|
||
value: "common"
|
||
- name: MYSQL_HOST
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.host
|
||
- name: MYSQL_PORT
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.port
|
||
- name: MYSQL_DATABASE
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.database
|
||
- name: MYSQL_USER
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: mysql-user
|
||
- name: MYSQL_PASSWORD
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: mysql-password
|
||
- name: REDIS_HOST
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: redis.host
|
||
- name: REDIS_PORT
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: redis.port
|
||
- name: REDIS_PASSWORD
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: redis-password
|
||
- name: TZ
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: timezone
|
||
resources:
|
||
requests:
|
||
memory: "512Mi"
|
||
cpu: "250m"
|
||
limits:
|
||
memory: "2Gi"
|
||
cpu: "1000m"
|
||
livenessProbe:
|
||
httpGet:
|
||
path: /actuator/health
|
||
port: 9998
|
||
initialDelaySeconds: 120
|
||
periodSeconds: 30
|
||
timeoutSeconds: 10
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /actuator/health
|
||
port: 9998
|
||
initialDelaySeconds: 30
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
startupProbe:
|
||
httpGet:
|
||
path: /actuator/health
|
||
port: 9998
|
||
initialDelaySeconds: 60
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 12
|
||
EOF
|
||
|
||
print_success "Boot 后端配置已生成"
|
||
}
|
||
|
||
# 生成 Bigscreen 部署配置
|
||
generate_bigscreen_manifest() {
|
||
print_info "生成 Bigscreen 大屏部署配置..."
|
||
|
||
cat > "$K8S_DIR/bigscreen/bigscreen-deployment.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ljwx-bigscreen
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-bigscreen
|
||
spec:
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 5001
|
||
targetPort: 5001
|
||
name: http
|
||
selector:
|
||
app: ljwx-bigscreen
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: ljwx-bigscreen
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-bigscreen
|
||
spec:
|
||
replicas: 2
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxUnavailable: 0
|
||
maxSurge: 1
|
||
selector:
|
||
matchLabels:
|
||
app: ljwx-bigscreen
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ljwx-bigscreen
|
||
annotations:
|
||
prometheus.io/scrape: "true"
|
||
prometheus.io/port: "5001"
|
||
prometheus.io/path: "/metrics"
|
||
spec:
|
||
initContainers:
|
||
- name: wait-for-mysql
|
||
image: busybox:1.35
|
||
command:
|
||
- sh
|
||
- -c
|
||
- |
|
||
until nc -z ljwx-mysql 3306; do
|
||
echo "Waiting for MySQL..."
|
||
sleep 3
|
||
done
|
||
echo "MySQL is ready"
|
||
containers:
|
||
- name: bigscreen
|
||
image: $REGISTRY/$IMAGE_PREFIX/ljwx-bigscreen:$LJWX_BIGSCREEN_VERSION
|
||
imagePullPolicy: IfNotPresent
|
||
ports:
|
||
- containerPort: 5001
|
||
name: http
|
||
env:
|
||
- name: MYSQL_HOST
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.host
|
||
- name: MYSQL_PORT
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.port
|
||
- name: MYSQL_USER
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: mysql-user
|
||
- name: MYSQL_PASSWORD
|
||
valueFrom:
|
||
secretKeyRef:
|
||
name: ljwx-secret
|
||
key: mysql-password
|
||
- name: MYSQL_DATABASE
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: mysql.database
|
||
- name: REDIS_HOST
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: redis.host
|
||
- name: REDIS_PORT
|
||
valueFrom:
|
||
configMapKeyRef:
|
||
name: ljwx-config
|
||
key: redis.port
|
||
- name: ENV
|
||
value: "production"
|
||
resources:
|
||
requests:
|
||
memory: "256Mi"
|
||
cpu: "100m"
|
||
limits:
|
||
memory: "1Gi"
|
||
cpu: "500m"
|
||
livenessProbe:
|
||
httpGet:
|
||
path: /api/health
|
||
port: 5001
|
||
initialDelaySeconds: 60
|
||
periodSeconds: 30
|
||
timeoutSeconds: 10
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /api/health
|
||
port: 5001
|
||
initialDelaySeconds: 10
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
EOF
|
||
|
||
print_success "Bigscreen 大屏配置已生成"
|
||
}
|
||
|
||
# 生成 Admin 前端部署配置
|
||
generate_admin_manifest() {
|
||
print_info "生成 Admin 前端部署配置..."
|
||
|
||
cat > "$K8S_DIR/admin/admin-deployment.yaml" <<EOF
|
||
apiVersion: v1
|
||
kind: Service
|
||
metadata:
|
||
name: ljwx-admin
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-admin
|
||
spec:
|
||
type: ClusterIP
|
||
ports:
|
||
- port: 80
|
||
targetPort: 80
|
||
name: http
|
||
selector:
|
||
app: ljwx-admin
|
||
---
|
||
apiVersion: apps/v1
|
||
kind: Deployment
|
||
metadata:
|
||
name: ljwx-admin
|
||
namespace: $NAMESPACE
|
||
labels:
|
||
app: ljwx-admin
|
||
spec:
|
||
replicas: 2
|
||
strategy:
|
||
type: RollingUpdate
|
||
rollingUpdate:
|
||
maxUnavailable: 0
|
||
maxSurge: 1
|
||
selector:
|
||
matchLabels:
|
||
app: ljwx-admin
|
||
template:
|
||
metadata:
|
||
labels:
|
||
app: ljwx-admin
|
||
spec:
|
||
containers:
|
||
- name: admin
|
||
image: $REGISTRY/$IMAGE_PREFIX/ljwx-admin:$LJWX_ADMIN_VERSION
|
||
imagePullPolicy: IfNotPresent
|
||
ports:
|
||
- containerPort: 80
|
||
name: http
|
||
resources:
|
||
requests:
|
||
memory: "64Mi"
|
||
cpu: "50m"
|
||
limits:
|
||
memory: "256Mi"
|
||
cpu: "200m"
|
||
livenessProbe:
|
||
httpGet:
|
||
path: /
|
||
port: 80
|
||
initialDelaySeconds: 10
|
||
periodSeconds: 10
|
||
timeoutSeconds: 5
|
||
failureThreshold: 3
|
||
readinessProbe:
|
||
httpGet:
|
||
path: /
|
||
port: 80
|
||
initialDelaySeconds: 5
|
||
periodSeconds: 5
|
||
timeoutSeconds: 3
|
||
failureThreshold: 3
|
||
EOF
|
||
|
||
print_success "Admin 前端配置已生成"
|
||
}
|
||
|
||
# 生成 Ingress 配置
|
||
generate_ingress_manifest() {
|
||
print_info "生成 Ingress 配置..."
|
||
|
||
local DOMAIN="${LJWX_DOMAIN:-ljwx.local}"
|
||
|
||
cat > "$K8S_DIR/ingress/ingress.yaml" <<EOF
|
||
apiVersion: networking.k8s.io/v1
|
||
kind: Ingress
|
||
metadata:
|
||
name: ljwx-ingress
|
||
namespace: $NAMESPACE
|
||
annotations:
|
||
nginx.ingress.kubernetes.io/rewrite-target: /
|
||
nginx.ingress.kubernetes.io/ssl-redirect: "false"
|
||
spec:
|
||
ingressClassName: nginx
|
||
rules:
|
||
- host: $DOMAIN
|
||
http:
|
||
paths:
|
||
- path: /api
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: ljwx-boot
|
||
port:
|
||
number: 9998
|
||
- path: /bigscreen
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: ljwx-bigscreen
|
||
port:
|
||
number: 5001
|
||
- path: /
|
||
pathType: Prefix
|
||
backend:
|
||
service:
|
||
name: ljwx-admin
|
||
port:
|
||
number: 80
|
||
EOF
|
||
|
||
print_success "Ingress 配置已生成"
|
||
}
|
||
|
||
# 生成所有配置
|
||
generate_all_manifests() {
|
||
print_header "生成 K8s 配置文件"
|
||
|
||
create_k8s_dir
|
||
generate_namespace
|
||
generate_configmap
|
||
generate_secret
|
||
generate_mysql_manifest
|
||
generate_redis_manifest
|
||
generate_boot_manifest
|
||
generate_bigscreen_manifest
|
||
generate_admin_manifest
|
||
generate_ingress_manifest
|
||
|
||
print_success "所有 K8s 配置文件已生成"
|
||
}
|
||
|
||
# 构建镜像
|
||
build_images() {
|
||
if [ "$BUILD_IMAGES" != "true" ]; then
|
||
print_info "跳过镜像构建(BUILD_IMAGES=false)"
|
||
return
|
||
fi
|
||
|
||
print_header "构建 Docker 镜像"
|
||
|
||
print_info "开始构建所有镜像..."
|
||
./build-and-push.sh all
|
||
|
||
print_success "镜像构建完成"
|
||
}
|
||
|
||
# 部署到 K8s
|
||
deploy_to_k8s() {
|
||
print_header "部署到 Kubernetes"
|
||
|
||
# 创建 Namespace
|
||
if [ "$CREATE_NAMESPACE" = "true" ]; then
|
||
print_info "创建 Namespace: $NAMESPACE"
|
||
kubectl apply -f "$K8S_DIR/namespace/namespace.yaml"
|
||
print_success "Namespace 创建完成"
|
||
fi
|
||
|
||
# 部署 ConfigMap 和 Secret
|
||
print_info "部署 ConfigMap 和 Secret..."
|
||
kubectl apply -f "$K8S_DIR/configmap/ljwx-config.yaml"
|
||
kubectl apply -f "$K8S_DIR/secret/ljwx-secret.yaml"
|
||
print_success "ConfigMap 和 Secret 部署完成"
|
||
|
||
# 部署 MySQL
|
||
if [ "$DEPLOY_MYSQL" = "true" ]; then
|
||
print_info "部署 MySQL..."
|
||
kubectl apply -f "$K8S_DIR/mysql/mysql-statefulset.yaml"
|
||
print_success "MySQL 部署完成"
|
||
|
||
# 等待 MySQL 就绪
|
||
print_info "等待 MySQL 就绪..."
|
||
kubectl wait --for=condition=ready pod -l app=ljwx-mysql -n $NAMESPACE --timeout=300s || true
|
||
fi
|
||
|
||
# 部署 Redis
|
||
if [ "$DEPLOY_REDIS" = "true" ]; then
|
||
print_info "部署 Redis..."
|
||
kubectl apply -f "$K8S_DIR/redis/redis-deployment.yaml"
|
||
print_success "Redis 部署完成"
|
||
|
||
# 等待 Redis 就绪
|
||
print_info "等待 Redis 就绪..."
|
||
kubectl wait --for=condition=ready pod -l app=ljwx-redis -n $NAMESPACE --timeout=120s || true
|
||
fi
|
||
|
||
# 部署应用
|
||
if [ "$DEPLOY_APPS" = "true" ]; then
|
||
print_info "部署应用服务..."
|
||
kubectl apply -f "$K8S_DIR/boot/boot-deployment.yaml"
|
||
kubectl apply -f "$K8S_DIR/bigscreen/bigscreen-deployment.yaml"
|
||
kubectl apply -f "$K8S_DIR/admin/admin-deployment.yaml"
|
||
print_success "应用服务部署完成"
|
||
|
||
# 等待应用就绪
|
||
print_info "等待应用就绪..."
|
||
kubectl wait --for=condition=ready pod -l app=ljwx-boot -n $NAMESPACE --timeout=300s || true
|
||
kubectl wait --for=condition=ready pod -l app=ljwx-bigscreen -n $NAMESPACE --timeout=180s || true
|
||
kubectl wait --for=condition=ready pod -l app=ljwx-admin -n $NAMESPACE --timeout=120s || true
|
||
fi
|
||
|
||
# 部署 Ingress
|
||
print_info "部署 Ingress..."
|
||
kubectl apply -f "$K8S_DIR/ingress/ingress.yaml"
|
||
print_success "Ingress 部署完成"
|
||
}
|
||
|
||
# 验证部署
|
||
verify_deployment() {
|
||
print_header "验证部署状态"
|
||
|
||
# 检查 Pods
|
||
print_info "检查 Pods 状态..."
|
||
kubectl get pods -n $NAMESPACE -o wide
|
||
echo ""
|
||
|
||
# 检查 Services
|
||
print_info "检查 Services..."
|
||
kubectl get svc -n $NAMESPACE
|
||
echo ""
|
||
|
||
# 检查 Ingress
|
||
print_info "检查 Ingress..."
|
||
kubectl get ingress -n $NAMESPACE
|
||
echo ""
|
||
|
||
# 统计 Pod 状态
|
||
TOTAL_PODS=$(kubectl get pods -n $NAMESPACE --no-headers 2>/dev/null | wc -l | tr -d ' ')
|
||
RUNNING_PODS=$(kubectl get pods -n $NAMESPACE --field-selector=status.phase=Running --no-headers 2>/dev/null | wc -l | tr -d ' ')
|
||
READY_PODS=$(kubectl get pods -n $NAMESPACE -o json 2>/dev/null | jq '[.items[] | select(.status.conditions[] | select(.type=="Ready" and .status=="True"))] | length')
|
||
|
||
print_info "Pod 状态统计:"
|
||
echo " 总计: $TOTAL_PODS"
|
||
echo " 运行中: $RUNNING_PODS"
|
||
echo " 就绪: $READY_PODS"
|
||
echo ""
|
||
|
||
if [ "$READY_PODS" = "$TOTAL_PODS" ]; then
|
||
print_success "所有 Pods 已就绪!"
|
||
else
|
||
print_warning "部分 Pods 未就绪,请查看详细状态"
|
||
fi
|
||
}
|
||
|
||
# 显示访问信息
|
||
show_access_info() {
|
||
print_header "访问信息"
|
||
|
||
local DOMAIN="${LJWX_DOMAIN:-ljwx.local}"
|
||
local INGRESS_IP=$(kubectl get svc -n ingress-nginx ingress-nginx-controller -o jsonpath='{.status.loadBalancer.ingress[0].ip}' 2>/dev/null || echo "待获取")
|
||
|
||
if [ "$INGRESS_IP" = "待获取" ]; then
|
||
INGRESS_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}' 2>/dev/null || echo "localhost")
|
||
fi
|
||
|
||
echo ""
|
||
print_success "部署完成!"
|
||
echo ""
|
||
echo "========================================="
|
||
echo "访问地址:"
|
||
echo "========================================="
|
||
echo "管理后台: http://$DOMAIN"
|
||
echo "后端 API: http://$DOMAIN/api"
|
||
echo "数据大屏: http://$DOMAIN/bigscreen"
|
||
echo ""
|
||
echo "Ingress IP: $INGRESS_IP"
|
||
echo ""
|
||
echo "如果使用本地域名,请添加到 /etc/hosts:"
|
||
echo " $INGRESS_IP $DOMAIN"
|
||
echo ""
|
||
echo "========================================="
|
||
echo "命名空间: $NAMESPACE"
|
||
echo "镜像仓库: $REGISTRY"
|
||
echo "版本信息:"
|
||
echo " - Boot: $LJWX_BOOT_VERSION"
|
||
echo " - Bigscreen: $LJWX_BIGSCREEN_VERSION"
|
||
echo " - Admin: $LJWX_ADMIN_VERSION"
|
||
echo " - MySQL: $LJWX_MYSQL_VERSION"
|
||
echo " - Redis: $LJWX_REDIS_VERSION"
|
||
echo ""
|
||
echo "========================================="
|
||
echo "常用命令:"
|
||
echo "========================================="
|
||
echo "查看 Pods: kubectl get pods -n $NAMESPACE"
|
||
echo "查看日志: kubectl logs -f <pod-name> -n $NAMESPACE"
|
||
echo "进入容器: kubectl exec -it <pod-name> -n $NAMESPACE -- /bin/sh"
|
||
echo "删除部署: kubectl delete namespace $NAMESPACE"
|
||
echo "查看事件: kubectl get events -n $NAMESPACE --sort-by='.lastTimestamp'"
|
||
echo ""
|
||
}
|
||
|
||
# 主函数
|
||
main() {
|
||
# 检查前置条件
|
||
check_prerequisites
|
||
|
||
# 生成 K8s 配置
|
||
generate_all_manifests
|
||
|
||
# 构建镜像
|
||
build_images
|
||
|
||
# 部署到 K8s
|
||
deploy_to_k8s
|
||
|
||
# 验证部署
|
||
sleep 5
|
||
verify_deployment
|
||
|
||
# 显示访问信息
|
||
show_access_info
|
||
}
|
||
|
||
# 显示帮助信息
|
||
show_help() {
|
||
cat <<EOF
|
||
灵境万象系统 - Kubernetes 一键部署脚本
|
||
|
||
用法:
|
||
$0 [选项]
|
||
|
||
选项:
|
||
--help 显示帮助信息
|
||
--skip-build 跳过镜像构建
|
||
--skip-push 跳过镜像推送
|
||
--skip-mysql 跳过 MySQL 部署(使用外部数据库)
|
||
--skip-redis 跳过 Redis 部署(使用外部缓存)
|
||
--namespace <name> 指定命名空间(默认: ljwx-system)
|
||
--registry <addr> 指定镜像仓库(默认: localhost:15000)
|
||
--domain <domain> 指定访问域名(默认: ljwx.local)
|
||
|
||
环境变量:
|
||
K8S_NAMESPACE K8s 命名空间
|
||
PRIVATE_REGISTRY 私有镜像仓库地址
|
||
BUILD_IMAGES 是否构建镜像 (true/false)
|
||
PUSH_IMAGES 是否推送镜像 (true/false)
|
||
DEPLOY_MYSQL 是否部署 MySQL (true/false)
|
||
DEPLOY_REDIS 是否部署 Redis (true/false)
|
||
MYSQL_ROOT_PASSWORD MySQL root 密码(默认: 123456)
|
||
MYSQL_DATABASE MySQL 数据库名(默认: lj-06)
|
||
REDIS_PASSWORD Redis 密码(默认: 123456)
|
||
LJWX_DOMAIN 访问域名(默认: ljwx.local)
|
||
|
||
示例:
|
||
# 完整部署
|
||
$0
|
||
|
||
# 跳过镜像构建(使用已有镜像)
|
||
$0 --skip-build
|
||
|
||
# 使用外部数据库
|
||
$0 --skip-mysql --skip-redis
|
||
|
||
# 指定命名空间和域名
|
||
K8S_NAMESPACE=ljwx-prod LJWX_DOMAIN=ljwx.example.com $0
|
||
|
||
更多信息请参考: README.md
|
||
EOF
|
||
}
|
||
|
||
# 解析命令行参数
|
||
while [[ $# -gt 0 ]]; do
|
||
case $1 in
|
||
--help)
|
||
show_help
|
||
exit 0
|
||
;;
|
||
--skip-build)
|
||
BUILD_IMAGES=false
|
||
shift
|
||
;;
|
||
--skip-push)
|
||
PUSH_IMAGES=false
|
||
shift
|
||
;;
|
||
--skip-mysql)
|
||
DEPLOY_MYSQL=false
|
||
shift
|
||
;;
|
||
--skip-redis)
|
||
DEPLOY_REDIS=false
|
||
shift
|
||
;;
|
||
--namespace)
|
||
NAMESPACE="$2"
|
||
shift 2
|
||
;;
|
||
--registry)
|
||
REGISTRY="$2"
|
||
shift 2
|
||
;;
|
||
--domain)
|
||
export LJWX_DOMAIN="$2"
|
||
shift 2
|
||
;;
|
||
*)
|
||
print_error "未知选项: $1"
|
||
echo "使用 --help 查看帮助"
|
||
exit 1
|
||
;;
|
||
esac
|
||
done
|
||
|
||
# 执行主函数
|
||
main
|