在雲原生時代,微服務應用的部署載體逐漸轉向Kubernetes(K8s),而傳統的手動部署不僅效率低下,還難以適配K8s的容器化、集羣化部署場景。將Jenkins(成熟的CI/CD工具)與K8s相結合,能夠實現「代碼提交→鏡像構建→鏡像推送→K8s資源部署」的全流程自動化,既發揮Jenkins豐富的插件生態和靈活的任務配置優勢,又利用K8s的彈性伸縮、高可用特性保障應用部署質量,這是雲原生DevOps落地的核心方案之一。本文從實戰出發,手把手教你搭建K8s+Jenkins自動化部署流水線,完成雲原生應用的自動化交付。

一、先搞懂:核心概念與工作流程

1. 核心概念

  1. Jenkins:作為CI/CD流水線的「控制中心」,負責觸發任務、編排流程、調用插件執行構建和部署操作,需安裝K8s相關插件適配K8s環境;
  2. K8s集羣:作為應用的「部署運行環境」,接收Jenkins下發的部署指令,創建Pod、Service等資源,保障應用的穩定運行和彈性伸縮;
  3. Docker鏡像倉庫:用於存儲構建好的應用鏡像(如Harbor、Docker Hub),作為Jenkins與K8s之間的鏡像傳遞載體;
  4. K8s配置文件(yaml):定義應用的K8s部署資源(Deployment、Service),Jenkins通過執行kubectl命令應用該配置,完成應用部署。

2. 核心工作流程

一句話總結:代碼提交到代碼倉庫→Jenkins觸發流水線→拉取代碼構建Docker鏡像→推送鏡像到鏡像倉庫→使用kubectl命令將鏡像部署到K8s集羣→驗證應用部署效果,全程自動化閉環,適配雲原生場景。

二、實戰準備:環境搭建與插件配置

1. 前置環境要求

  1. 已搭建可用的K8s集羣(單節點k3s亦可,滿足測試需求);
  2. Jenkins已部署(推薦部署在K8s集羣內,或在集羣外服務器安裝並配置kubectl訪問權限);
  3. 已搭建鏡像倉庫(如Harbor,或使用公共Docker Hub);
  4. Jenkins節點安裝Docker、kubectl,並配置:
  • Docker可正常構建、推送鏡像;
  • kubectl已配置K8s集羣訪問憑證(~/.kube/config),可正常執行kubectl命令。

2. Jenkins安裝核心插件

登錄Jenkins後台,進入「系統管理」→「插件管理」,安裝以下必備插件:

  1. Git Plugin:拉取代碼倉庫中的項目代碼;
  2. Docker Plugin:構建、推送Docker鏡像;
  3. Kubernetes Plugin:適配K8s環境,簡化kubectl命令調用;
  4. Pipeline Plugin:通過Jenkinsfile定義流水線,支持代碼化配置。

3. 驗證環境配置

# 1. 在Jenkins節點驗證Docker可用
docker --version
docker login <你的鏡像倉庫地址> -u <用户名> -p <密碼>

# 2. 在Jenkins節點驗證kubectl可用(能訪問K8s集羣)
kubectl get nodes
kubectl get pods -n default

三、實戰1:準備項目資源(應用代碼+Dockerfile+K8s配置)

以Spring Boot應用為例,準備全流程所需的項目資源,放在同一Git代碼倉庫中,方便Jenkins拉取。

1. 編寫Dockerfile(構建應用鏡像)

項目根目錄創建Dockerfile,構建輕量級Spring Boot應用鏡像:

# 多階段構建,減小鏡像體積
FROM maven:3.8.8-openjdk-17 AS builder
WORKDIR /app
COPY pom.xml .
COPY src ./src
RUN mvn clean package -Dmaven.test.skip=true

FROM openjdk:17-slim
WORKDIR /app
COPY --from=builder /app/target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT ["java", "-jar", "app.jar"]

2. 編寫K8s部署配置文件(k8s-deploy.yaml)

項目根目錄創建k8s-deploy.yaml,定義Deployment和Service資源:

# K8s部署配置
apiVersion: apps/v1
kind: Deployment
metadata:
  name: spring-boot-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: spring-boot-app
  template:
    metadata:
      labels:
        app: spring-boot-app
    spec:
      containers:
      - name: spring-boot-app
        image: <你的鏡像倉庫地址>/spring-boot-app:${BUILD_NUMBER} # 鏡像標籤對應Jenkins構建編號
        ports:
        - containerPort: 8080
        resources:
          limits:
            cpu: 500m
            memory: 512Mi
---
apiVersion: v1
kind: Service
metadata:
  name: spring-boot-app-service
  namespace: default
spec:
  type: NodePort
  selector:
    app: spring-boot-app
  ports:
  - port: 8080
    targetPort: 8080
    nodePort: 30080 # 外部訪問端口

3. 編寫Jenkinsfile(定義流水線流程)

項目根目錄創建Jenkinsfile,定義「拉取代碼→構建鏡像→推送鏡像→部署到K8s」的流水線:

// Jenkinsfile 流水線定義
pipeline {
    agent any // 使用任意可用的Jenkins節點
    environment {
        // 定義環境變量,方便修改
        IMAGE_REPO = "<你的鏡像倉庫地址>/spring-boot-app"
        BUILD_NUMBER = "${env.BUILD_NUMBER}" // Jenkins構建編號,作為鏡像標籤
    }
    stages {
        // 階段1:拉取代碼(自動完成,無需額外腳本)
        stage('Pull Code') {
            steps {
                echo "開始拉取項目代碼..."
                checkout scm // 拉取當前流水線關聯的Git代碼倉庫
            }
        }
        
        // 階段2:構建Docker鏡像
        stage('Build Docker Image') {
            steps {
                echo "開始構建Docker鏡像..."
                sh "docker build -t ${IMAGE_REPO}:${BUILD_NUMBER} ."
            }
        }
        
        // 階段3:推送Docker鏡像到鏡像倉庫
        stage('Push Docker Image') {
            steps {
                echo "開始推送Docker鏡像到鏡像倉庫..."
                sh "docker push ${IMAGE_REPO}:${BUILD_NUMBER}"
            }
        }
        
        // 階段4:部署到K8s集羣
        stage('Deploy to K8s') {
            steps {
                echo "開始部署應用到K8s集羣..."
                // 替換K8s配置文件中的鏡像標籤,執行部署命令
                sh "sed -i 's/\${BUILD_NUMBER}/${BUILD_NUMBER}/g' k8s-deploy.yaml"
                sh "kubectl apply -f k8s-deploy.yaml"
                sh "kubectl rollout status deployment/spring-boot-app -n default" // 驗證部署狀態
            }
        }
    }
    post {
        // 流水線執行完成後輸出提示
        success {
            echo "應用部署成功!鏡像標籤:${IMAGE_REPO}:${BUILD_NUMBER}"
        }
        failure {
            echo "應用部署失敗,請查看流水線日誌排查問題!"
        }
    }
}

四、實戰2:搭建Jenkins流水線,觸發自動化部署

1. 創建Jenkins流水線任務

  1. 登錄Jenkins後台,點擊「新建任務」,輸入任務名稱,選擇「流水線」,點擊「確定」;
  2. 配置任務:
  • 「流水線」部分選擇「從SCM獲取Jenkinsfile」;
  • SCM類型選擇「Git」,輸入項目Git倉庫地址,配置倉庫訪問憑證;
  • 分支指定(如main),Jenkinsfile路徑填寫「Jenkinsfile」(項目根目錄);
  • 其他參數默認,點擊「保存」。

2. 觸發流水線並驗證

  1. 點擊任務頁面的「立即構建」,觸發流水線執行;
  2. 點擊「控制枱輸出」,查看各階段的執行日誌,若所有階段都顯示「成功」,説明流水線執行完成;
  3. 驗證K8s部署效果:
# 1. 查看K8s Deployment和Pod狀態
kubectl get deployments spring-boot-app -n default
kubectl get pods -n default | grep spring-boot-app

# 2. 驗證應用可訪問(通過NodePort訪問)
curl http://<K8s節點IP>:30080/hello

五、最佳實踐與新手避坑

1. 核心最佳實踐

  • 「鏡像標籤規範化」:使用Jenkins構建編號、Git提交哈希作為鏡像標籤,避免鏡像覆蓋,方便版本回滾;
  • 「K8s滾動更新」:使用kubectl rollout驗證部署狀態,支持應用的無感知更新,避免服務中斷;
  • 「憑證安全管理」:Jenkins中使用「憑證管理」存儲鏡像倉庫密碼、K8s訪問憑證,避免明文配置;
  • 「流水線緩存優化」:緩存Maven、Docker構建緩存,減少重複下載依賴,提升流水線執行效率。

2. 高頻避坑指南

  1. 流水線推送鏡像失敗:
  • 原因:Jenkins節點未登錄鏡像倉庫,或鏡像倉庫地址配置錯誤;
  • 解決:在Jenkins節點執行docker login完成登錄,或在Jenkins流水線中配置鏡像倉庫憑證。
  1. kubectl命令執行無權限:
  • 原因:Jenkins節點的kube/config配置錯誤,或對應的賬號無K8s部署權限;
  • 解決:驗證kube/config配置正確性,為K8s賬號綁定足夠的權限(如ClusterRole)。
  1. K8s Pod啓動失敗(鏡像拉取失敗):
  • 原因:K8s集羣節點無法訪問鏡像倉庫,或鏡像標籤不存在;
  • 解決:確保K8s節點能登錄鏡像倉庫,驗證鏡像推送是否成功,鏡像標籤配置是否一致。
  1. 流水線執行超時:
  • 原因:構建鏡像、推送鏡像或K8s部署耗時過長,超出Jenkins默認超時時間;
  • 解決:在Jenkins任務配置中延長超時時間,優化構建流程(如啓用緩存)。

六、總結

  1. 核心流程:準備項目資源(Dockerfile+K8s配置+Jenkinsfile)→ 配置Jenkins流水線 → 觸發構建 → 自動化部署到K8s → 驗證部署效果;
  2. 核心價值:K8s+Jenkins實現了雲原生應用的全流程自動化部署,既保障了應用的高可用運行,又提升了研發交付效率,是雲原生DevOps落地的核心方案;
  3. 實操核心:Jenkinsfile是流水線的靈魂,Dockerfile保障鏡像構建質量,K8s配置文件保障應用部署穩定,三者缺一不可;
  4. 進階方向:生產環境可結合Harbor私有鏡像倉庫、K8s Ingress、Jenkins流水線定時構建、故障自動回滾,實現更穩定、更高效的雲原生CI/CD閉環。

掌握K8s+Jenkins自動化部署的實戰技巧,就能順利完成雲原生DevOps的落地,實現應用的快速交付和穩定運行,為企業的數字化轉型和業務快速迭代打下堅實基礎。