Jenkinsfile 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156
  1. pipeline {
  2. agent any
  3. parameters {
  4. choice(name: 'env', choices: ['dev', 'test', 'prod'], description: '部署环境')
  5. string(name: 'NAMESPACE', defaultValue: 'portal-frontends', description: 'K8s 命名空间')
  6. }
  7. environment {
  8. PROJECT_NAME = 'portal-service-frontend'
  9. BUILD_DIR = 'dist'
  10. NODE_ENV = 'production'
  11. HARBOR_HOST = '8.130.28.21:81'
  12. KUBECONFIG_PATH = '/root/.kube/config'
  13. NODE1_IP = '172.27.73.147'
  14. NODE2_IP = '172.27.73.146'
  15. HARBOR_USER = 'admin'
  16. HARBOR_PASS = 'Hfln@1024'
  17. HARBOR_RETENTION_ID = '1'
  18. DOMAIN = 'radar-power.asia'
  19. TLS_CERT_PATH = '/data/cert/radar-power.asia.pem'
  20. TLS_KEY_PATH = '/data/cert/radar-power.asia.key'
  21. TLS_SECRET_NAME = 'portal-tls'
  22. INGRESS_CLASS = 'nginx' // 新增 ingress class 环境变量
  23. }
  24. stages {
  25. // ... 省略前面步骤不变 ...
  26. stage('📦 处理命名空间和 TLS Secret') {
  27. steps {
  28. script {
  29. sh """
  30. export KUBECONFIG=${env.KUBECONFIG_PATH}
  31. # 判断命名空间是否存在,不存在则创建
  32. if ! kubectl get ns ${params.NAMESPACE} >/dev/null 2>&1; then
  33. echo ">>> 命名空间 ${params.NAMESPACE} 不存在,正在创建..."
  34. kubectl create namespace ${params.NAMESPACE}
  35. else
  36. echo ">>> 命名空间 ${params.NAMESPACE} 已存在"
  37. fi
  38. # 判断 TLS Secret 是否存在,不存在则创建
  39. if ! kubectl get secret ${env.TLS_SECRET_NAME} -n ${params.NAMESPACE} >/dev/null 2>&1; then
  40. echo ">>> 未检测到 TLS Secret ${env.TLS_SECRET_NAME},正在创建..."
  41. kubectl create secret tls ${env.TLS_SECRET_NAME} \
  42. --cert=${env.TLS_CERT_PATH} \
  43. --key=${env.TLS_KEY_PATH} \
  44. -n ${params.NAMESPACE}
  45. else
  46. echo ">>> TLS Secret ${env.TLS_SECRET_NAME} 已存在,跳过创建"
  47. fi
  48. """
  49. }
  50. }
  51. }
  52. stage('📦 部署到 Kubernetes') {
  53. steps {
  54. script {
  55. def ingressBlock = """---
  56. apiVersion: networking.k8s.io/v1
  57. kind: Ingress
  58. metadata:
  59. name: ${env.PROJECT_NAME}
  60. namespace: ${params.NAMESPACE}
  61. annotations:
  62. nginx.ingress.kubernetes.io/rewrite-target: /
  63. spec:
  64. ingressClassName: ${env.INGRESS_CLASS} # 指定 ingressClassName
  65. tls:
  66. - hosts:
  67. - ${env.DOMAIN}
  68. secretName: ${env.TLS_SECRET_NAME}
  69. rules:
  70. - host: ${env.DOMAIN}
  71. http:
  72. paths:
  73. - path: /
  74. pathType: Prefix
  75. backend:
  76. service:
  77. name: ${env.PROJECT_NAME}
  78. port:
  79. number: 80
  80. """
  81. def deployYaml = """apiVersion: apps/v1
  82. kind: Deployment
  83. metadata:
  84. name: ${env.PROJECT_NAME}
  85. namespace: ${params.NAMESPACE}
  86. spec:
  87. replicas: 2
  88. selector:
  89. matchLabels:
  90. app: ${env.PROJECT_NAME}
  91. template:
  92. metadata:
  93. labels:
  94. app: ${env.PROJECT_NAME}
  95. spec:
  96. containers:
  97. - name: ${env.PROJECT_NAME}
  98. image: ${env.IMAGE_TAG}
  99. ports:
  100. - containerPort: 80
  101. env:
  102. - name: NODE_ENV
  103. value: "${params.env}"
  104. ---
  105. apiVersion: v1
  106. kind: Service
  107. metadata:
  108. name: ${env.PROJECT_NAME}
  109. namespace: ${params.NAMESPACE}
  110. spec:
  111. type: NodePort
  112. selector:
  113. app: ${env.PROJECT_NAME}
  114. ports:
  115. - port: 80
  116. targetPort: 80
  117. nodePort: 30088
  118. ${ingressBlock}
  119. """
  120. writeFile file: 'deploy.yaml', text: deployYaml
  121. sh """
  122. export KUBECONFIG=${env.KUBECONFIG_PATH}
  123. kubectl apply -f deploy.yaml
  124. kubectl rollout status deployment/${env.PROJECT_NAME} -n ${params.NAMESPACE} --timeout=120s || echo '[rollout timeout or incomplete]'
  125. """
  126. echo ">>> ✅ 部署完成(含 Ingress),访问地址:https://${env.DOMAIN}/ (请确保 DNS 已指向 Ingress 公网 IP 且 secret ${env.TLS_SECRET_NAME} 已创建)"
  127. }
  128. }
  129. }
  130. // ... 其余步骤不变 ...
  131. }
  132. post {
  133. success {
  134. echo "✅ 构建 & 部署成功 🎉"
  135. }
  136. failure {
  137. echo "❌ 构建或部署失败,请检查日志"
  138. }
  139. always {
  140. cleanWs()
  141. }
  142. }
  143. }