1. 系统要求与前置条件
1.1 硬件资源要求
| 环境 | CPU | 内存 | 磁盘 | 网络 |
|---|---|---|---|---|
| 开发环境(本地) | 4 核+ | 16GB+ | 100GB+ | 宽带接入 |
| 测试环境(K8s) | 8 核+ | 32GB+ | 500GB+ | 内网互通 |
| 生产环境(K8s 集群) | 16 核+ × 3 | 64GB+ × 3 | 1TB+ SSD | 高可用网络 |
| Jenkins 服务器 | 8 核+ | 16GB+ | 200GB+ | 访问 K8s 集群 |
1.2 软件依赖清单
🖥️ 操作系统
- Ubuntu 22.04 LTS / 24.04 LTS
- CentOS 7.9 / Rocky Linux 9.x
- macOS 13+ (开发环境)
- Windows 11 + WSL2 (开发环境)
🐳 容器运行时
- Docker 27.x / 26.x
- containerd 1.7.x
- Podman 4.x (可选)
- Harbor 2.10+ (镜像仓库)
⎈ Kubernetes
- Kubernetes 1.31.x / 1.30.x
- KubeSphere 3.4.x
- Helm 3.14.x
- kubectl 1.31.x
🔧 开发工具
- Java JDK 21 LTS
- Node.js 20 LTS / 22 LTS
- pnpm 9.x / npm 10.x
- Maven 3.9.x / Gradle 8.x
🗄️ 数据库与中间件
- PostgreSQL 16.x / 15.x
- Redis 7.2.x
- RabbitMQ 3.13.x / Kafka 3.6.x
- Elasticsearch 8.12.x
🚀 CI/CD 工具
- Jenkins 2.44x LTS
- GitLab 16.x / GitHub Enterprise
- SonarQube 10.x
- ArgoCD 2.10.x (可选)
⚠️ 重要提示:
- 确保所有服务器时间同步(NTP),时区统一为 Asia/Shanghai
- 关闭防火墙或开放必要端口(6443, 30443, 22, 80, 443 等)
- 配置 DNS 解析或 /etc/hosts 主机名映射
- 禁用 Swap 分区(Kubernetes 要求)
- 配置内核参数优化(net.ipv4.ip_forward 等)
2. 开发环境搭建(本地)
2.1 一键初始化脚本
#!/bin/bash
# scripts/setup/init-dev-env.sh - 开发环境初始化脚本
set -euo pipefail
log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
log_warn() { echo -e "\033[0;33m[WARN]\033[0m $1"; }
log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; }
# 检测操作系统
if [ -f /etc/os-release ]; then
source /etc/os-release
OS=$ID
else
OS=$(uname -s)
fi
log_info "Detected OS: ${OS}"
# 安装系统依赖
install_system_deps() {
log_info "Installing system dependencies..."
case $OS in
ubuntu|debian)
sudo apt-get update
sudo apt-get install -y \
git curl wget vim jq \
build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev \
llvm libncursesw5-dev xz-utils tk-dev \
libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev
;;
centos|rocky|rhel)
sudo yum install -y epel-release
sudo yum install -y \
git curl wget vim jq \
gcc gcc-c++ make openssl-devel \
bzip2-devel readline-devel sqlite-devel \
xz-devel ncurses-devel tk-devel libffi-devel
;;
darwin)
/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
brew install git curl wget vim jq
;;
*)
log_error "Unsupported OS: ${OS}"
exit 1
;;
esac
}
# 安装 Docker
install_docker() {
log_info "Installing Docker..."
case $OS in
ubuntu|debian)
curl -fsSL https://get.docker.com | sh -
;;
centos|rocky|rhel)
yum install -y yum-utils
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce docker-ce-cli containerd.io
;;
darwin)
log_info "Please install Docker Desktop from https://www.docker.com/products/docker-desktop"
;;
esac
sudo systemctl enable docker && sudo systemctl start docker
sudo usermod -aG docker $USER
log_info "Docker installed. Please logout and login again for group changes to take effect."
}
# 安装 Node.js (使用 nvm)
install_nodejs() {
log_info "Installing Node.js via nvm..."
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash
export NVM_DIR="$HOME/.nvm"
[-s "$NVM_DIR/nvm.sh"] && \. "$NVM_DIR/nvm.sh"
nvm install 20
nvm use 20
nvm alias default 20
npm install -g pnpm yarn
log_info "Node.js $(node -v) and npm $(npm -v) installed"
}
# 安装 Java JDK 21
install_java() {
log_info "Installing Java JDK 21..."
case $OS in
ubuntu|debian)
sudo apt-get install -y openjdk-21-jdk
;;
centos|rocky|rhel)
sudo yum install -y java-21-openjdk-devel
;;
darwin)
brew install openjdk@21
;;
esac
java -version
}
# 安装 kubectl 和 Helm
install_k8s_tools() {
log_info "Installing Kubernetes tools..."
# kubectl
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
rm -f kubectl
# Helm
curl https://raw.githubusercontent.com/helm/helm/main/scripts/get-helm-3 | bash
kubectl version --client
helm version
}
# 克隆项目代码
clone_repository() {
log_info "Cloning project repository..."
REPO_URL=${REPO_URL:-"git@gitlab.yourcompany.com:your-company/enterprise-monorepo.git"}
PROJECT_DIR=${PROJECT_DIR:-"$HOME/projects/enterprise-monorepo"}
mkdir -p $(dirname $PROJECT_DIR)
cd $(dirname $PROJECT_DIR)
if [ -d "$PROJECT_DIR" ]; then
log_warn "Project directory already exists. Skipping clone."
else
git clone $REPO_URL $PROJECT_DIR
fi
cd $PROJECT_DIR
}
# 安装项目依赖
install_project_deps() {
log_info "Installing project dependencies..."
cd $PROJECT_DIR
# 前端依赖
pnpm install --frozen-lockfile
# 后端依赖(Maven)
cd services && mvn dependency:go-offline -B
log_info "Project dependencies installed"
}
# 配置 Git
configure_git() {
log_info "Configuring Git..."
git config --global user.name "Your Name"
git config --global user.email "your.email@company.com"
git config --global init.defaultBranch main
git config --global core.autocrlf input
git config --global pull.rebase false
}
# 主流程
main() {
log_info "Starting development environment setup..."
install_system_deps
install_docker
install_nodejs
install_java
install_k8s_tools
configure_git
clone_repository
install_project_deps
log_info "✅ Development environment setup completed!"
log_info "Next steps:"
log_info " 1. Logout and login to apply Docker group changes"
log_info " 2. Configure your IDE (VS Code / IntelliJ IDEA)"
log_info " 3. Copy .env.example to .env.local and configure environment variables"
log_info " 4. Run 'pnpm run dev' to start development servers"
}
main "$@"
2.2 VS Code 工作区配置
# ===== .vscode/extensions.json =====
{
"recommendations": [
// TypeScript/JavaScript
"dbaeumer.vscode-eslint",
"esbenp.prettier-vscode",
// Java
"vscjava.vscode-java-pack",
"redhat.java",
"vscjava.vscode-java-dependency",
// Kubernetes & Docker
"ms-kubernetes-tools.vscode-kubernetes-tools",
"ms-azuretools.vscode-docker",
// Database
"mtxr.sqltools",
"mtxr.sqltools-driver-pg",
// Git
"gitlens.gitlens",
"github.vscode-pull-request-github",
// Utilities
"streetsidesoftware.code-spell-checker",
"tamasfe.even-better-toml",
"yzhang.markdown-all-in-one"
]
}
# ===== .vscode/settings.json =====
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.codeActionsOnSave": {
"source.fixAll.eslint": "explicit"
},
"[typescript]": {
"editor.defaultFormatter": "esbenp.prettier-vscode",
"editor.tabSize": 2
},
"[java]": {
"editor.defaultFormatter": "redhat.java",
"editor.tabSize": 4
},
"java.configuration.updateBuildConfiguration": "automatic",
"java.server.launchMode": "Standard",
"kubernetes.explorer.enabled": true,
"docker.explorer.enabled": true,
"files.exclude": {
"**/node_modules": true,
"**/.git": true,
"**/dist": true,
"**/target": true
},
"files.watcherExclude": {
"**/node_modules/**": true,
"**/.git/objects/**": true
}
}
3. Docker 容器化部署
3.1 Docker Compose 开发环境
# ===== deploy/docker/docker-compose.dev.yml =====
version: '3.8'
services:
# PostgreSQL 数据库
postgres:
image: postgres:16-alpine
container_name: app-postgres
environment:
POSTGRES_DB: appdb
POSTGRES_USER: admin
POSTGRES_PASSWORD: ${DB_PASSWORD:-devpassword123}
PGDATA: /var/lib/postgresql/data/pgdata
ports:
- "5432:5432"
volumes:
- postgres_data:/var/lib/postgresql/data
- ./init-scripts:/docker-entrypoint-initdb.d
healthcheck:
test: ["CMD-SHELL", "pg_isready -U admin -d appdb"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
# Redis 缓存
redis:
image: redis:7-alpine
container_name: app-redis
command: redis-server --appendonly yes
ports:
- "6379:6379"
volumes:
- redis_data:/data
healthcheck:
test: ["CMD", "redis-cli", "ping"]
interval: 10s
timeout: 5s
retries: 5
networks:
- app-network
# RabbitMQ 消息队列
rabbitmq:
image: rabbitmq:3-management-alpine
container_name: app-rabbitmq
environment:
RABBITMQ_DEFAULT_USER: guest
RABBITMQ_DEFAULT_PASS: guest
ports:
- "5672:5672" # AMQP
- "15672:15672" # Management UI
volumes:
- rabbitmq_data:/var/lib/rabbitmq
networks:
- app-network
# 用户服务
user-service:
build:
context: ../../services/user-service
dockerfile: Dockerfile
container_name: app-user-service
environment:
SPRING_PROFILES_ACTIVE: dev
DB_HOST: postgres
DB_PORT: 5432
DB_NAME: appdb
DB_USERNAME: admin
DB_PASSWORD: ${DB_PASSWORD:-devpassword123}
REDIS_HOST: redis
REDIS_PORT: 6379
RABBITMQ_HOST: rabbitmq
RABBITMQ_PORT: 5672
ports:
- "8081:8080"
depends_on:
postgres:
condition: service_healthy
redis:
condition: service_healthy
rabbitmq:
condition: service_started
volumes:
- ../../services/user-service/src:/app/src
networks:
- app-network
# API 网关
api-gateway:
build:
context: ../../services/api-gateway
dockerfile: Dockerfile
container_name: app-api-gateway
environment:
SPRING_PROFILES_ACTIVE: dev
USER_SERVICE_URL: http://user-service:8080
ports:
- "8080:8080"
depends_on:
- user-service
networks:
- app-network
# 前端应用
web-admin:
build:
context: ../../apps/web-admin
dockerfile: Dockerfile.dev
target: development
container_name: app-web-admin
environment:
NODE_ENV: development
VITE_API_BASE_URL: http://localhost:8080
ports:
- "3000:3000"
volumes:
- ../../apps/web-admin/src:/app/src
- ../../apps/web-admin/public:/app/public
depends_on:
- api-gateway
networks:
- app-network
volumes:
postgres_data:
redis_data:
rabbitmq_data:
networks:
app-network:
driver: bridge
3.2 启动与管理命令
# ===== scripts/docker/manage.sh =====
#!/bin/bash
COMPOSE_FILE="deploy/docker/docker-compose.dev.yml"
start() {
echo "Starting development environment..."
docker-compose -f ${COMPOSE_FILE} up -d
echo "Waiting for services to be ready..."
sleep 10
docker-compose -f ${COMPOSE_FILE} ps
}
stop() {
echo "Stopping all services..."
docker-compose -f ${COMPOSE_FILE} down
}
restart() {
stop
sleep 2
start
}
logs() {
SERVICE=${1:-""}
if [ -z "$SERVICE" ]; then
docker-compose -f ${COMPOSE_FILE} logs -f
else
docker-compose -f ${COMPOSE_FILE} logs -f ${SERVICE}
fi
}
exec() {
SERVICE=${1}
COMMAND=${2:-"/bin/bash"}
docker-compose -f ${COMPOSE_FILE} exec ${SERVICE} ${COMMAND}
}
rebuild() {
SERVICE=${1:-""}
if [ -z "$SERVICE"]; then
docker-compose -f ${COMPOSE_FILE} build --no-cache
else
docker-compose -f ${COMPOSE_FILE} build --no-cache ${SERVICE}
fi
}
clean() {
echo "Cleaning up all containers, volumes and networks..."
docker-compose -f ${COMPOSE_FILE} down -v --rmi all --remove-orphans
}
status() {
docker-compose -f ${COMPOSE_FILE} ps -a
echo ""
echo "Disk usage:"
docker system df
}
case ${1} in
start) start ;;
stop) stop ;;
restart) restart ;;
logs) logs ${2} ;;
exec) exec ${2} ${3} ;;
rebuild) rebuild ${2} ;;
clean) clean ;;
status) status ;;
*)
echo "Usage: $0 {start|stop|restart|logs|exec|rebuild|clean|status}"
exit 1
;;
esac
4. Kubernetes 集群部署
4.1 使用 kubeadm 部署 K8s 集群
# ===== 在所有节点执行(Master + Workers)=====
# 1. 禁用 Swap
sudo swapoff -a
sudo sed -i '/ swap / s/^\(.*\)$/#\1/g' /etc/fstab
# 2. 配置内核参数
cat > /etc/sysctl.d/k8s.conf << EOF
net.bridge.bridge-nf-call-ip6tables = 1
net.bridge.bridge-nf-call-iptables = 1
net.ipv4.ip_forward = 1
EOF
sysctl --system
# 3. 安装 containerd
curl -fsSL https://get.docker.com | sh -
sudo systemctl enable containerd && sudo systemctl start containerd
mkdir -p /etc/containerd
containerd config default > /etc/containerd/config.toml
sed -i 's/SystemdCgroup = false/SystemdCgroup = true/' /etc/containerd/config.toml
sudo systemctl restart containerd
# 4. 安装 kubeadm, kubelet, kubectl
curl -fsSL https://pkgs.k8s.io/core:/stable:/v1.31/deb/Release.key | sudo gpg --dearmor -o /etc/apt/keyrings/kubernetes-apt-keyring.gpg
echo 'deb [signed-by=/etc/apt/keyrings/kubernetes-apt-keyring.gpg] https://pkgs.k8s.io/core:/stable:/v1.31/deb/ /' | sudo tee /etc/apt/sources.list.d/kubernetes.list
sudo apt-get update
sudo apt-get install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl
# ===== 仅在 Master 节点执行 =====
# 5. 初始化集群
sudo kubeadm init \\
--pod-network-cidr=10.244.0.0/16 \\
--service-cidr=10.96.0.0/12 \\
--control-plane-endpoint=:6443
# 6. 配置 kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config
# 7. 安装网络插件(Calico)
kubectl apply -f https://raw.githubusercontent.com/projectcalico/calico/v3.27.0/manifests/calico.yaml
# 8. 生成 Worker 节点加入命令
kubeadm token create --print-join-command
# ===== 在 Worker 节点执行 =====
# 9. 加入集群(使用上一步生成的命令)
sudo kubeadm join :6443 --token --discovery-token-ca-cert-hash sha256:
# ===== 验证集群状态 =====
kubectl get nodes
kubectl get pods -A
4.2 部署应用到 Kubernetes
# ===== deploy/kubernetes/base/user-service-deployment.yaml =====
apiVersion: apps/v1
kind: Deployment
metadata:
name: user-service
namespace: default
labels:
app: user-service
version: v1
spec:
replicas: 2
selector:
matchLabels:
app: user-service
template:
metadata:
labels:
app: user-service
version: v1
spec:
containers:
- name: user-service
image: harbor.yourcompany.com/backend-services/user-service:v1.0.0
imagePullPolicy: IfNotPresent
ports:
- containerPort: 8080
name: http
env:
- name: SPRING_PROFILES_ACTIVE
value: "prod"
- name: DB_HOST
valueFrom:
configMapKeyRef:
name: app-config
key: db.host
- name: DB_PASSWORD
valueFrom:
secretKeyRef:
name: db-credentials
key: password
resources:
requests:
memory: "512Mi"
cpu: "250m"
limits:
memory: "1Gi"
cpu: "1000m"
livenessProbe:
httpGet:
path: /actuator/health/liveness
port: 8080
initialDelaySeconds: 60
periodSeconds: 10
readinessProbe:
httpGet:
path: /actuator/health/readiness
port: 8080
initialDelaySeconds: 30
periodSeconds: 5
imagePullSecrets:
- name: harbor-secret
---
apiVersion: v1
kind: Service
metadata:
name: user-service
namespace: default
spec:
selector:
app: user-service
ports:
- protocol: TCP
port: 80
targetPort: 8080
type: ClusterIP
---
apiVersion: autoscaling/v2
kind: HorizontalPodAutoscaler
metadata:
name: user-service-hpa
namespace: default
spec:
scaleTargetRef:
apiVersion: apps/v1
kind: Deployment
name: user-service
minReplicas: 2
maxReplicas: 10
metrics:
- type: Resource
resource:
name: cpu
target:
type: Utilization
averageUtilization: 70
- type: Resource
resource:
name: memory
target:
type: Utilization
averageUtilization: 80
5. KubeSphere 平台安装
5.1 安装 KubeSphere
# ===== 前提条件:已有 Kubernetes 集群 =====
# 1. 下载 KubeSphere 安装文件
curl -L https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/kubesphere-installer.yaml -o kubesphere-installer.yaml
curl -L https://github.com/kubesphere/ks-installer/releases/download/v3.4.1/cluster-configuration.yaml -o cluster-configuration.yaml
# 2. 执行安装
kubectl apply -f kubesphere-installer.yaml
kubectl apply -f cluster-configuration.yaml
# 3. 查看安装进度
kubectl logs -n kubesphere-system $(kubectl get pod -n kubesphere-system -l 'app in (ks-install, ks-installer)' -o jsonpath='{.items[0].metadata.name}') -f
# 4. 等待安装完成(约 10-15 分钟)
watch kubectl get pod -n kubesphere-system
# 5. 验证安装
kubectl get pod --all-namespaces
# 6. 获取访问地址
kubectl get svc -n kubesphere-system ks-console
# 默认登录信息:
# 用户名:admin
# 密码:P@88w0rd(首次登录需修改)
# 访问地址:http://:30880
# ===== 启用可插拔组件 =====
# 编辑 cluster-configuration.yaml,启用所需组件
kubectl edit cc ks-installer -n kubesphere-system
# 常见组件:
# - DevOps (Jenkins)
# - Monitoring (Prometheus + Grafana)
# - Logging (Elasticsearch + Fluent Bit + Kibana)
# - Service Mesh (Istio)
# - Alerting
# - Audit
# - Events
# - Notification
5.2 KubeSphere 关键配置
KubeSphere 控制台功能概览:
├── 📊 集群管理
│ ├── 集群状态监控
│ ├── 节点管理
│ ├── 存储管理
│ └── 网络策略
├── 👥 多租户管理
│ ├── 企业空间 (Workspace)
│ ├── 项目 (Project/Namespace)
│ ├── 用户与角色
│ └── 权限控制
├── 🚀 应用负载
│ ├── 工作负载 (Deployment/StatefulSet/DaemonSet)
│ ├── 服务发现 (Service/Ingress)
│ ├── 配置中心 (ConfigMap/Secret)
│ └── 定时任务 (CronJob)
├── 🔄 DevOps
│ ├── DevOps 项目
│ ├── 流水线 (Pipeline)
│ ├── 二进制制品
│ └── 代码质量 (SonarQube)
├── 📈 监控告警
│ ├── 资源监控
│ ├── 应用监控
│ ├── 告警策略
│ └── 通知渠道
├── 📝 日志查询
│ ├── 容器日志
│ ├── 事件日志
│ └── 审计日志
└── 🛒 应用商店
├── Helm Charts
├── 应用模板
└── 应用部署
6. Jenkins CI/CD 配置
6.1 Jenkins 安装与初始化
# ===== 使用 Helm 在 K8s 上安装 Jenkins =====
# 1. 添加 Helm Chart 仓库
helm repo add jenkins https://charts.jenkins.io
helm repo update
# 2. 创建命名空间
kubectl create namespace jenkins
# 3. 创建 values.yaml 配置文件
cat > jenkins-values.yaml << 'EOF'
jenkins:
adminUser: admin
adminPassword: admin123
persistence:
enabled: true
size: 50Gi
storageClass: nfs-client
agent:
enabled: true
replicas: 2
resources:
requests:
cpu: 500m
memory: 512Mi
limits:
cpu: 2000m
memory: 2Gi
env:
- name: JENKINS_URL
value: http://jenkins.jenkins.svc.cluster.local:8080
controller:
serviceType: LoadBalancer
servicePort: 8080
resources:
requests:
cpu: 1000m
memory: 2Gi
limits:
cpu: 4000m
memory: 8Gi
installPlugins:
- kubernetes:4174.v4230d0f28c6c
- workflow-aggregator:596.v8c21c963d92d
- git:5.2.1
- github:1.37.3
- pipeline-stage-view:2.28
- blueocean:1.27.9
- sonar:2.16.1
- docker-workflow:572.v950f58f60edf
- kubernetes-cli:1.12.1
EOF
# 4. 安装 Jenkins
helm install jenkins jenkins/jenkins -f jenkins-values.yaml -n jenkins
# 5. 获取初始密码
kubectl exec -it -n jenkins $(kubectl get pod -n jenkins -l app.kubernetes.io/component=jenkins-controller -o jsonpath='{.items[0].metadata.name}') -- cat /run/secrets/additional/chart-admin-password
# 6. 端口转发访问
kubectl port-forward -n jenkins svc/jenkins 8080:8080
# 访问 http://localhost:8080
6.2 Jenkins Pipeline 配置
# ===== Jenkinsfile (声明式 Pipeline) =====
pipeline {
agent {
kubernetes {
yaml """
apiVersion: v1
kind: Pod
spec:
containers:
- name: maven
image: maven:3.9-eclipse-temurin-21
command:
- cat
tty: true
- name: nodejs
image: node:20-alpine
command:
- cat
tty: true
- name: docker
image: docker:27-dind
securityContext:
privileged: true
"""
}
}
environment {
DOCKER_REGISTRY = 'harbor.yourcompany.com'
SONAR_HOST_URL = 'http://sonarqube:9000'
KUBECONFIG_CREDENTIALS_ID = 'kubeconfig-prod'
}
parameters {
choice(
name: 'DEPLOY_ENV',
choices: ['dev', 'staging', 'prod'],
description: '选择部署环境'
)
string(
name: 'GIT_BRANCH',
defaultValue: 'develop',
description: 'Git 分支'
)
}
stages {
stage('Checkout') {
steps {
checkout scm
}
}
stage('Install Dependencies') {
steps {
container('nodejs') {
sh 'pnpm install --frozen-lockfile'
}
container('maven') {
dir('services') {
sh 'mvn dependency:go-offline -B'
}
}
}
}
stage('Code Quality') {
parallel {
stage('ESLint') {
steps {
container('nodejs') {
sh 'pnpm run lint:all'
}
}
}
stage('SonarQube Analysis') {
steps {
container('maven') {
withSonarQubeEnv('sonarqube-prod') {
sh 'mvn clean verify sonar:sonar -Dsonar.projectKey=${JOB_NAME}'
}
}
}
}
}
}
stage('Unit Tests') {
steps {
container('maven') {
sh 'mvn test -B'
}
container('nodejs') {
sh 'pnpm run test:all --coverage'
}
}
post {
always {
junit allowEmptyResults: true, testResults: '**/target/surefire-reports/*.xml'
publishHTML([
allowMissing: false,
alwaysLinkToLastBuild: true,
keepAll: true,
reportDir: 'coverage',
reportFiles: 'lcov-report/index.html',
reportName: 'Coverage Report'
])
}
}
}
stage('Build') {
parallel {
stage('Build Backend') {
steps {
container('maven') {
dir('services') {
sh 'mvn clean package -DskipTests -B'
}
}
}
}
stage('Build Frontend') {
steps {
container('nodejs') {
dir('apps') {
sh 'pnpm run build:all'
}
}
}
}
}
}
stage('Build Docker Image') {
steps {
container('docker') {
script {
def services = ['user-service', 'order-service', 'payment-service']
services.each { service ->
def imageName = "${DOCKER_REGISTRY}/backend-services/${service}:${params.GIT_BRANCH}-${BUILD_NUMBER}"
sh """
docker build -t ${imageName} services/${service}/
docker push ${imageName}
"""
}
}
}
}
}
stage('Deploy to Kubernetes') {
when {
expression { return params.DEPLOY_ENV != 'dev' }
}
steps {
container('maven') {
withKubeConfig([credentialsId: KUBECONFIG_CREDENTIALS_ID]) {
sh """
kubectl set image deployment/user-service \
user-service=${DOCKER_REGISTRY}/backend-services/user-service:${params.GIT_BRANCH}-${BUILD_NUMBER} \
-n ${params.DEPLOY_ENV}
kubectl rollout status deployment/user-service -n ${params.DEPLOY_ENV} --timeout=300s
"""
}
}
}
}
stage('Smoke Test') {
steps {
sh '''
curl -f http://api-gateway.${DEPLOY_ENV}.svc.cluster.local/actuator/health || exit 1
'''
}
}
}
post {
success {
echo '✅ Pipeline completed successfully!'
slackSend(color: 'good', message: "Build #${BUILD_NUMBER} succeeded!")
}
failure {
echo '❌ Pipeline failed!'
slackSend(color: 'danger', message: "Build #${BUILD_NUMBER} failed!")
}
always {
cleanWs()
}
}
}
7. 项目初始化与数据库迁移
7.1 环境变量配置
# ===== .env.example =====
# 数据库配置
DB_HOST=localhost
DB_PORT=5432
DB_NAME=appdb
DB_USERNAME=admin
DB_PASSWORD=changeme
# Redis 配置
REDIS_HOST=localhost
REDIS_PORT=6379
REDIS_PASSWORD=
# RabbitMQ 配置
RABBITMQ_HOST=localhost
RABBITMQ_PORT=5672
RABBITMQ_USERNAME=guest
RABBITMQ_PASSWORD=guest
# JWT 配置
JWT_SECRET=your-super-secret-jwt-key-change-this-in-production
JWT_EXPIRATION=3600000
# API 配置
API_BASE_URL=http://localhost:8080
API_TIMEOUT=30000
# 邮件配置
SMTP_HOST=smtp.gmail.com
SMTP_PORT=587
SMTP_USERNAME=noreply@yourcompany.com
SMTP_PASSWORD=your-smtp-password
# 对象存储配置(OSS/S3)
OSS_ENDPOINT=oss-cn-hangzhou.aliyuncs.com
OSS_BUCKET=your-bucket
OSS_ACCESS_KEY=your-access-key
OSS_SECRET_KEY=your-secret-key
# 监控配置
SENTRY_DSN=https://xxx@sentry.io/xxx
ELASTIC_APM_SERVER_URL=http://apm-server:8200
# 功能开关
ENABLE_SWAGGER=true
ENABLE_ACTUATOR=true
ENABLE_DEV_TOOLS=false
# ===== 复制并配置 =====
cp .env.example .env.local
vim .env.local # 编辑实际配置
7.2 数据库初始化
# ===== 使用 Flyway 进行数据库迁移 =====
# 1. 项目结构
services/user-service/
├── src/main/resources/
│ └── db/migration/
│ ├── V1__init_schema.sql
│ ├── V2__add_user_profile.sql
│ ├── V3__add_index.sql
│ └── V4__add_audit_fields.sql
└── pom.xml
# ===== V1__init_schema.sql =====
-- 创建用户表
CREATE TABLE users (
id BIGSERIAL PRIMARY KEY,
username VARCHAR(50) NOT NULL UNIQUE,
email VARCHAR(100) NOT NULL UNIQUE,
password_hash VARCHAR(255) NOT NULL,
status VARCHAR(20) DEFAULT 'ACTIVE',
created_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP WITH TIME ZONE DEFAULT CURRENT_TIMESTAMP
);
-- 创建角色表
CREATE TABLE roles (
id SERIAL PRIMARY KEY,
name VARCHAR(50) NOT NULL UNIQUE,
description VARCHAR(200)
);
-- 创建用户角色关联表
CREATE TABLE user_roles (
user_id BIGINT REFERENCES users(id) ON DELETE CASCADE,
role_id INTEGER REFERENCES roles(id) ON DELETE CASCADE,
PRIMARY KEY (user_id, role_id)
);
-- 插入默认角色
INSERT INTO roles (name, description) VALUES
('ADMIN', '系统管理员'),
('USER', '普通用户'),
('GUEST', '访客');
# ===== 执行迁移 =====
# Maven 方式
cd services/user-service
mvn flyway:migrate
# 或者 Spring Boot 自动迁移(启动时自动执行)
./mvnw spring-boot:run
# ===== 验证迁移结果 =====
psql -h localhost -U admin -d appdb -c "\\dt"
psql -h localhost -U admin -d appdb -c "SELECT * FROM flyway_schema_history;"
7.3 种子数据填充
# ===== scripts/database/seed.sh =====
#!/bin/bash
DB_HOST=${DB_HOST:-"localhost"}
DB_PORT=${DB_PORT:-"5432"}
DB_NAME=${DB_NAME:-"appdb"}
DB_USER=${DB_USER:-"admin"}
log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
seed_admin_user() {
log_info "Seeding admin user..."
psql -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} << EOF
-- 创建默认管理员账户
INSERT INTO users (username, email, password_hash, status)
VALUES ('admin', 'admin@yourcompany.com', '\$2a\$10\$...', 'ACTIVE')
ON CONFLICT (username) DO NOTHING;
-- 分配管理员角色
INSERT INTO user_roles (user_id, role_id)
SELECT u.id, r.id
FROM users u, roles r
WHERE u.username = 'admin' AND r.name = 'ADMIN'
ON CONFLICT DO NOTHING;
EOF
}
seed_test_data() {
log_info "Seeding test data..."
psql -h ${DB_HOST} -p ${DB_PORT} -U ${DB_USER} -d ${DB_NAME} << EOF
-- 创建测试用户
INSERT INTO users (username, email, password_hash, status) VALUES
('test1', 'test1@example.com', '\$2a\$10\$...', 'ACTIVE'),
('test2', 'test2@example.com', '\$2a\$10\$...', 'ACTIVE'),
('test3', 'test3@example.com', '\$2a\$10\$...', 'ACTIVE')
ON CONFLICT (username) DO NOTHING;
-- 分配普通用户角色
INSERT INTO user_roles (user_id, role_id)
SELECT u.id, r.id
FROM users u, roles r
WHERE u.username IN ('test1', 'test2', 'test3') AND r.name = 'USER'
ON CONFLICT DO NOTHING;
EOF
}
case ${1} in
admin) seed_admin_user ;;
test) seed_test_data ;;
all)
seed_admin_user
seed_test_data
;;
*)
echo "Usage: $0 {admin|test|all}"
exit 1
;;
esac
8. 服务启动与验证
📋 启动验证清单
✓
1. 基础设施服务检查
PostgreSQL、Redis、RabbitMQ 等中间件正常运行,健康检查通过
✓
2. 后端服务启动
所有微服务成功启动,注册到服务发现,端口监听正常
✓
3. 前端应用启动
Web 管理端、移动端 H5 应用编译成功,开发服务器运行正常
✓
4. API 接口测试
核心 API 接口调用成功,返回预期数据,无 5xx 错误
✓
5. 数据库连接验证
应用能正常读写数据库,事务处理正确
✓
6. 缓存功能验证
Redis 缓存命中正常,分布式锁工作正确
✓
7. 消息队列验证
消息发送接收正常,消费者处理逻辑正确
✓
8. 监控告警验证
Prometheus 指标采集正常,Grafana 仪表板显示正确
8.1 快速验证脚本
#!/bin/bash
# scripts/verify/health-check.sh - 健康检查脚本
API_GATEWAY_URL=${API_GATEWAY_URL:-"http://localhost:8080"}
WEB_ADMIN_URL=${WEB_ADMIN_URL:-"http://localhost:3000"}
log_info() { echo -e "\033[0;32m[INFO]\033[0m $1"; }
log_warn() { echo -e "\033[0;33m[WARN]\033[0m $1"; }
log_error() { echo -e "\033[0;31m[ERROR]\033[0m $1"; }
check_service() {
NAME=${1}
URL=${2}
if curl -f -s -o /dev/null ${URL}; then
log_info "✓ ${NAME} is healthy (${URL})"
return 0
else
log_error "✗ ${NAME} is not responding (${URL})"
return 1
fi
}
check_database() {
log_info "Checking database connection..."
psql -h localhost -U admin -d appdb -c "SELECT 1;" > /dev/null 2>&1
if [ $? -eq 0 ]; then
log_info "✓ PostgreSQL connection successful"
else
log_error "✗ PostgreSQL connection failed"
return 1
fi
}
check_redis() {
log_info "Checking Redis connection..."
redis-cli ping > /dev/null 2>&1
if [ $? -eq 0 ]; then
log_info "✓ Redis connection successful"
else
log_error "✗ Redis connection failed"
return 1
fi
}
main() {
log_info "Starting health checks..."
echo ""
FAILED=0
# 检查中间件
check_database || ((FAILED++))
check_redis || ((FAILED++))
# 检查后端服务
check_service "API Gateway" "${API_GATEWAY_URL}/actuator/health" || ((FAILED++))
check_service "User Service" "${API_GATEWAY_URL}/api/users/health" || ((FAILED++))
# 检查前端应用
check_service "Web Admin" "${WEB_ADMIN_URL}" || ((FAILED++))
echo ""
if [ ${FAILED} -eq 0 ]; then
log_info "✅ All health checks passed!"
exit 0
else
log_error "❌ ${FAILED} health check(s) failed!"
exit 1
fi
}
main
9. 常见问题排查
🐛 Docker 相关问题
- 问题:容器无法启动
- 排查:
docker logs <container> - 解决:检查资源限制、网络配置
- 预防:设置合理的 resource limits
⎈ Kubernetes 相关问题
- 问题:Pod 一直处于 Pending 状态
- 排查:
kubectl describe pod <name> - 解决:检查节点资源、调度策略
- 预防:配置资源配额和 LimitRange
🗄️ 数据库连接问题
- 问题:应用无法连接数据库
- 排查:检查网络连通性、认证信息
- 解决:验证凭据、开放防火墙端口
- 预防:使用 Connection Pool,配置重试机制
🔄 CI/CD 流水线失败
- 问题:构建或部署失败
- 排查:查看 Console Output 日志
- 解决:修复代码错误、更新依赖
- 预防:本地先验证,配置通知告警
📚 故障排查通用流程:
- 收集信息:日志、监控指标、错误堆栈
- 定位范围:确定是网络、应用、还是基础设施问题
- 复现问题:在测试环境尝试复现
- 分析根因:使用 5 Why 分析法
- 实施修复:制定方案并验证
- 总结复盘:编写事故报告,制定预防措施
10. 运维监控与日志管理
10.1 Prometheus + Grafana 监控
# ===== 使用 Helm 安装 Prometheus Stack =====
helm repo add prometheus-community https://prometheus-community.github.io/helm-charts
helm repo update
helm install monitoring prometheus-community/kube-prometheus-stack \\
-n monitoring \\
--create-namespace \\
--set prometheus.service.type=LoadBalancer \\
--set grafana.service.type=LoadBalancer \\
--set grafana.adminPassword=admin123
# 访问地址:
# Prometheus: http://<NODE_IP>:30090
# Grafana: http://<NODE_IP>:30030
# 默认账号密码:admin / admin123
# ===== 配置告警规则 =====
cat > alert-rules.yaml << 'EOF'
apiVersion: monitoring.coreos.com/v1
kind: PrometheusRule
metadata:
name: app-alerts
namespace: monitoring
spec:
groups:
- name: app.rules
rules:
- alert: HighCPUUsage
expr: sum(rate(container_cpu_usage_seconds_total{namespace="production"}[5m])) by (pod) > 0.8
for: 5m
labels:
severity: warning
annotations:
summary: "High CPU usage detected"
description: "Pod {{ \$labels.pod }} CPU usage is above 80%"
- alert: PodCrashLooping
expr: rate(kube_pod_container_status_restarts_total{namespace="production"}[15m]) > 0
for: 5m
labels:
severity: critical
annotations:
summary: "Pod is crash looping"
description: "Pod {{ \$labels.pod }} is restarting frequently"
EOF
kubectl apply -f alert-rules.yaml
10.2 ELK 日志管理
# ===== 使用 Helm 安装 EFK Stack =====
helm repo add elastic https://helm.elastic.co
helm repo update
# 安装 Elasticsearch
helm install elasticsearch elastic/elasticsearch -n logging --create-namespace
# 安装 Fluent Bit(日志收集)
helm install fluent-bit fluent/fluent-bit -n logging \\
--set backend.type=es \\
--set backend.es.host=elasticsearch.logging.svc \\
--set backend.es.port=9200
# 安装 Kibana
helm install kibana elastic/kibana -n logging \\
--set service.type=LoadBalancer
# 访问 Kibana: http://<NODE_IP>:30560
# ===== Fluent Bit 配置示例 =====
cat > fluent-bit-config.yaml << 'EOF'
apiVersion: v1
kind: ConfigMap
metadata:
name: fluent-bit-config
namespace: logging
data:
fluent-bit.conf: |
[SERVICE]
Flush 5
Log_Level info
Daemon off
[INPUT]
Name tail
Path /var/log/containers/*.log
Parser docker
Tag kube.*
Refresh_Interval 10
[FILTER]
Name kubernetes
Match kube.*
Kube_URL https://kubernetes.default.svc:443
Kube_CA_File /var/run/secrets/kubernetes.io/serviceaccount/ca.crt
Kube_Token_File /var/run/secrets/kubernetes.io/serviceaccount/token
Merge_Log On
Keep_Log Off
K8S-Logging.Parser On
K8S-Logging.Exclude On
[OUTPUT]
Name es
Match *
Host elasticsearch.logging.svc
Port 9200
Logstash_Format On
Logstash_Prefix kubernetes-logs
Retry_Limit False
EOF
kubectl apply -f fluent-bit-config.yaml