Răsfoiți Sursa

修改jenkinsfile

yangliu 2 luni în urmă
părinte
comite
a2d77e76fb
1 a modificat fișierele cu 101 adăugiri și 74 ștergeri
  1. 101 74
      Jenkinsfile

+ 101 - 74
Jenkinsfile

@@ -6,6 +6,7 @@ pipeline {
         string(name: 'NAMESPACE', defaultValue: 'portal-frontend', description: 'K8s 命名空间')
         string(name: 'NAMESPACE', defaultValue: 'portal-frontend', description: 'K8s 命名空间')
         string(name: 'DOMAIN', defaultValue: 'radar-power.asia', description: 'Ingress 域名(留空则不创建 Ingress)')
         string(name: 'DOMAIN', defaultValue: 'radar-power.asia', description: 'Ingress 域名(留空则不创建 Ingress)')
         string(name: 'TLS_SECRET', defaultValue: 'portal-tls', description: 'TLS Secret 名称(仅在 DOMAIN 非空时使用)')
         string(name: 'TLS_SECRET', defaultValue: 'portal-tls', description: 'TLS Secret 名称(仅在 DOMAIN 非空时使用)')
+        booleanParam(name: 'FORCE_UPDATE_CONFIG', defaultValue: false, description: '强制更新配置(包括 Deployment 和 Ingress)')
     }
     }
 
 
     environment {
     environment {
@@ -28,8 +29,8 @@ pipeline {
                     echo ">>> 环境:${params.env}, Harbor项目:${env.HARBOR_PROJECT}, K8s命名空间:${params.NAMESPACE}"
                     echo ">>> 环境:${params.env}, Harbor项目:${env.HARBOR_PROJECT}, K8s命名空间:${params.NAMESPACE}"
                     if (params.DOMAIN?.trim()) {
                     if (params.DOMAIN?.trim()) {
                         echo ">>> 域名:${params.DOMAIN}, TLS Secret:${params.TLS_SECRET}"
                         echo ">>> 域名:${params.DOMAIN}, TLS Secret:${params.TLS_SECRET}"
-                        echo ">>> 注意:TLS Secret 应该已经存在,请确保命名空间一致"
                     }
                     }
+                    echo ">>> 强制更新配置:${params.FORCE_UPDATE_CONFIG}"
                 }
                 }
             }
             }
         }
         }
@@ -41,54 +42,54 @@ pipeline {
             }
             }
         }
         }
 
 
-        stage('🔧 构建 Docker 镜像') {
+        stage('�� 验证 TLS Secret') {
+            when {
+                expression { params.DOMAIN?.trim() }
+            }
             steps {
             steps {
                 script {
                 script {
                     sh """
                     sh """
-                        docker login -u ${HARBOR_USER} -p ${HARBOR_PASS} ${HARBOR_HOST}
-                        docker build --build-arg ENV=${params.env} -t ${IMAGE_TAG} .
+                        export KUBECONFIG=${KUBECONFIG_PATH}
+
+                        # 验证 TLS Secret 是否存在
+                        if ! kubectl get secret ${params.TLS_SECRET} -n ${params.NAMESPACE} >/dev/null 2>&1; then
+                            echo "❌ TLS Secret '${params.TLS_SECRET}' 在命名空间 '${params.NAMESPACE}' 中不存在!"
+                            echo "请先创建 TLS Secret:"
+                            echo "kubectl create secret tls ${params.TLS_SECRET} --cert=fullchain.pem --key=privkey.pem -n ${params.NAMESPACE}"
+                            exit 1
+                        fi
+
+                        echo "✅ TLS Secret '${params.TLS_SECRET}' 验证成功"
                     """
                     """
-                    echo "✅ 镜像构建成功:${IMAGE_TAG}"
                 }
                 }
             }
             }
         }
         }
 
 
-        stage('🚀 推送镜像到 Harbor') {
+        stage('🔧 构建 Docker 镜像') {
             steps {
             steps {
                 script {
                 script {
                     sh """
                     sh """
-                        docker push ${IMAGE_TAG}
-                        docker rmi ${IMAGE_TAG}
+                        docker login -u ${HARBOR_USER} -p ${HARBOR_PASS} ${HARBOR_HOST}
+                        docker build --build-arg ENV=${params.env} -t ${IMAGE_TAG} .
                     """
                     """
-                    echo "✅ 镜像推送并本地清理完成"
+                    echo "✅ 镜像构建成功:${IMAGE_TAG}"
                 }
                 }
             }
             }
         }
         }
 
 
-        stage('�� 验证 TLS Secret') {
-            when {
-                expression { params.DOMAIN?.trim() }
-            }
+        stage('🚀 推送镜像到 Harbor') {
             steps {
             steps {
                 script {
                 script {
                     sh """
                     sh """
-                        export KUBECONFIG=${KUBECONFIG_PATH}
-
-                        # 验证 TLS Secret 是否存在
-                        if ! kubectl get secret ${params.TLS_SECRET} -n ${params.NAMESPACE} >/dev/null 2>&1; then
-                            echo "❌ TLS Secret '${params.TLS_SECRET}' 在命名空间 '${params.NAMESPACE}' 中不存在!"
-                            echo "请先创建 TLS Secret:"
-                            echo "kubectl create secret tls ${params.TLS_SECRET} --cert=fullchain.pem --key=privkey.pem -n ${params.NAMESPACE}"
-                            exit 1
-                        fi
-
-                        echo "✅ TLS Secret '${params.TLS_SECRET}' 验证成功"
+                        docker push ${IMAGE_TAG}
+                        docker rmi ${IMAGE_TAG}
                     """
                     """
+                    echo "✅ 镜像推送并本地清理完成"
                 }
                 }
             }
             }
         }
         }
 
 
-        stage('�� Kubernetes 部署') {
+        stage(' Kubernetes 部署') {
             steps {
             steps {
                 script {
                 script {
                     def domain = params.DOMAIN?.trim()
                     def domain = params.DOMAIN?.trim()
@@ -98,49 +99,17 @@ pipeline {
                         # 确保命名空间存在
                         # 确保命名空间存在
                         kubectl get ns ${params.NAMESPACE} >/dev/null 2>&1 || kubectl create ns ${params.NAMESPACE}
                         kubectl get ns ${params.NAMESPACE} >/dev/null 2>&1 || kubectl create ns ${params.NAMESPACE}
 
 
-                        # 如果 Deployment 存在,更新镜像
-                        if kubectl get deployment ${PROJECT_NAME} -n ${params.NAMESPACE} >/dev/null 2>&1; then
-                            echo ">>> Deployment 已存在,更新镜像..."
-                            kubectl set image deployment/${PROJECT_NAME} ${PROJECT_NAME}=${IMAGE_TAG} -n ${params.NAMESPACE}
-                            kubectl rollout status deployment/${PROJECT_NAME} -n ${params.NAMESPACE} --timeout=120s
+                        # 如果强制更新配置或 Deployment 不存在,则重新创建
+                        if [ "${params.FORCE_UPDATE_CONFIG}" = "true" ] || ! kubectl get deployment ${PROJECT_NAME} -n ${params.NAMESPACE} >/dev/null 2>&1; then
 
 
-                            # 更新 Ingress(如果提供了域名)
-                            if [ -n "${domain}" ]; then
-                                echo ">>> 更新 Ingress 配置..."
-                                kubectl apply -n ${params.NAMESPACE} -f - <<EOF
-apiVersion: networking.k8s.io/v1
-kind: Ingress
-metadata:
-  name: ${PROJECT_NAME}-ingress
-  annotations:
-    kubernetes.io/ingress.class: nginx
-    nginx.ingress.kubernetes.io/ssl-redirect: "true"
-    nginx.ingress.kubernetes.io/force-ssl-redirect: "true"
-    nginx.ingress.kubernetes.io/backend-protocol: "HTTP"
-    nginx.ingress.kubernetes.io/ssl-passthrough: "false"
-    nginx.ingress.kubernetes.io/proxy-body-size: "8m"
-    nginx.ingress.kubernetes.io/rewrite-target: /
-spec:
-  tls:
-  - hosts:
-    - ${domain}
-    secretName: ${params.TLS_SECRET}
-  rules:
-  - host: ${domain}
-    http:
-      paths:
-      - path: /
-        pathType: Prefix
-        backend:
-          service:
-            name: ${PROJECT_NAME}
-            port:
-              number: 80
-EOF
+                            if [ "${params.FORCE_UPDATE_CONFIG}" = "true" ]; then
+                                echo ">>> 强制更新配置,删除现有资源..."
+                                kubectl delete deployment ${PROJECT_NAME} -n ${params.NAMESPACE} --ignore-not-found=true
+                                kubectl delete svc ${PROJECT_NAME} -n ${params.NAMESPACE} --ignore-not-found=true
+                                kubectl delete ingress ${PROJECT_NAME}-ingress -n ${params.NAMESPACE} --ignore-not-found=true
                             fi
                             fi
-                        else
-                            # 创建新的 Deployment 和 Service
-                            echo ">>> 创建新的 Deployment 和 Service..."
+
+                            echo ">>> 创建 Deployment 和 Service..."
                             kubectl apply -n ${params.NAMESPACE} -f - <<EOF
                             kubectl apply -n ${params.NAMESPACE} -f - <<EOF
 apiVersion: apps/v1
 apiVersion: apps/v1
 kind: Deployment
 kind: Deployment
@@ -161,6 +130,25 @@ spec:
         image: ${IMAGE_TAG}
         image: ${IMAGE_TAG}
         ports:
         ports:
         - containerPort: 80
         - containerPort: 80
+        resources:
+          requests:
+            memory: "128Mi"
+            cpu: "100m"
+          limits:
+            memory: "256Mi"
+            cpu: "200m"
+        livenessProbe:
+          httpGet:
+            path: /
+            port: 80
+          initialDelaySeconds: 30
+          periodSeconds: 10
+        readinessProbe:
+          httpGet:
+            path: /
+            port: 80
+          initialDelaySeconds: 5
+          periodSeconds: 5
 ---
 ---
 apiVersion: v1
 apiVersion: v1
 kind: Service
 kind: Service
@@ -173,11 +161,12 @@ spec:
   ports:
   ports:
   - port: 80
   - port: 80
     targetPort: 80
     targetPort: 80
+    protocol: TCP
 EOF
 EOF
 
 
                             # 创建 Ingress(如果提供了域名)
                             # 创建 Ingress(如果提供了域名)
                             if [ -n "${domain}" ]; then
                             if [ -n "${domain}" ]; then
-                                echo ">>> 创建新的 Ingress..."
+                                echo ">>> 创建 Ingress..."
                                 kubectl apply -n ${params.NAMESPACE} -f - <<EOF
                                 kubectl apply -n ${params.NAMESPACE} -f - <<EOF
 apiVersion: networking.k8s.io/v1
 apiVersion: networking.k8s.io/v1
 kind: Ingress
 kind: Ingress
@@ -191,6 +180,8 @@ metadata:
     nginx.ingress.kubernetes.io/ssl-passthrough: "false"
     nginx.ingress.kubernetes.io/ssl-passthrough: "false"
     nginx.ingress.kubernetes.io/proxy-body-size: "8m"
     nginx.ingress.kubernetes.io/proxy-body-size: "8m"
     nginx.ingress.kubernetes.io/rewrite-target: /
     nginx.ingress.kubernetes.io/rewrite-target: /
+    nginx.ingress.kubernetes.io/ssl-ciphers: "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-RSA-AES128-SHA256:ECDHE-RSA-AES256-SHA384"
+    nginx.ingress.kubernetes.io/ssl-protocols: "TLSv1.2 TLSv1.3"
 spec:
 spec:
   tls:
   tls:
   - hosts:
   - hosts:
@@ -209,10 +200,16 @@ spec:
               number: 80
               number: 80
 EOF
 EOF
                             fi
                             fi
+
+                        else
+                            # 只更新镜像
+                            echo ">>> Deployment 已存在,仅更新镜像..."
+                            kubectl set image deployment/${PROJECT_NAME} ${PROJECT_NAME}=${IMAGE_TAG} -n ${params.NAMESPACE}
+                            echo "✅ 镜像更新完成,Kubernetes 将自动处理滚动更新"
                         fi
                         fi
 
 
-                        # 等待部署完成
-                        echo ">>> 等待部署完成..."
+                        # 等待 Deployment 就绪
+                        echo ">>> 等待 Deployment 就绪..."
                         kubectl wait --for=condition=available --timeout=300s deployment/${PROJECT_NAME} -n ${params.NAMESPACE}
                         kubectl wait --for=condition=available --timeout=300s deployment/${PROJECT_NAME} -n ${params.NAMESPACE}
 
 
                         # 显示部署状态
                         # 显示部署状态
@@ -222,18 +219,48 @@ EOF
 
 
                         # 如果配置了域名,显示访问信息
                         # 如果配置了域名,显示访问信息
                         if [ -n "${domain}" ]; then
                         if [ -n "${domain}" ]; then
-                            echo ">>> 应用部署完成!"
-                            echo ">>> 访问地址:https://${domain}"
-                            echo ">>> 注意:确保域名 ${domain} 已正确解析到集群公网IP"
+                            echo " 应用部署完成!"
+                            echo "🌐 访问地址:https://${domain}"
+                            echo "�� 注意:确保域名 ${domain} 已正确解析到集群公网IP"
                         else
                         else
-                            echo ">>> 应用部署完成!"
-                            echo ">>> 注意:未配置域名,请手动配置 Ingress 或使用 NodePort 访问"
+                            echo " 应用部署完成!"
+                            echo "📝 注意:未配置域名,请手动配置 Ingress 或使用 NodePort 访问"
                         fi
                         fi
                     """
                     """
                 }
                 }
             }
             }
         }
         }
 
 
+        stage('🔍 部署验证') {
+            when {
+                expression { params.DOMAIN?.trim() }
+            }
+            steps {
+                script {
+                    def domain = params.DOMAIN?.trim()
+                    sh """
+                        export KUBECONFIG=${KUBECONFIG_PATH}
+
+                        echo ">>> 验证部署状态..."
+
+                        # 检查 Pod 状态
+                        kubectl get pods -n ${params.NAMESPACE} -l app=${PROJECT_NAME}
+
+                        # 检查 Service 状态
+                        kubectl get svc -n ${params.NAMESPACE} ${PROJECT_NAME}
+
+                        # 检查 Ingress 状态
+                        kubectl get ingress -n ${params.NAMESPACE} ${PROJECT_NAME}-ingress
+
+                        # 检查 TLS Secret
+                        kubectl get secret -n ${params.NAMESPACE} ${params.TLS_SECRET}
+
+                        echo "✅ 部署验证完成"
+                    """
+                }
+            }
+        }
+
         stage('🧹 清理本地旧镜像(保留最新3个)') {
         stage('🧹 清理本地旧镜像(保留最新3个)') {
             steps {
             steps {
                 script {
                 script {