Jenkins入门教程(十八):Jenkins与Kubernetes集成

Kubernetes已成为容器编排的事实标准,本文将详细介绍如何将Jenkins与Kubernetes集成,包括完整的配置步骤和Pipeline示例。

部署Jenkins到Kubernetes

使用Helm快速部署Jenkins到Kubernetes集群:

# 添加Jenkins Helm仓库
helm repo add jenkins https://charts.jenkins.io
helm repo update

# 创建命名空间
kubectl create namespace jenkins

# 创建values.yaml
cat > jenkins-values.yaml << 'EOF'
controller:
  adminUser: admin
  adminPassword: "your-secure-password"
  serviceType: LoadBalancer
  installPlugins:
    - kubernetes:latest
    - workflow-aggregator:latest
    - git:latest
    - docker-workflow:latest
  resources:
    requests:
      cpu: "500m"
      memory: "1Gi"
    limits:
      cpu: "2"
      memory: "4Gi"

persistence:
  enabled: true
  size: 50Gi

agent:
  enabled: true
  podTemplates:
    maven: |
      - name: maven
        label: maven
        containers:
          - name: maven
            image: maven:3.8-openjdk-17
            command: sleep
            args: infinity
EOF

# 安装Jenkins
helm install jenkins jenkins/jenkins -n jenkins -f jenkins-values.yaml

执行结果:

$ helm install jenkins jenkins/jenkins -n jenkins -f jenkins-values.yaml
NAME: jenkins
LAST DEPLOYED: Sat Feb  8 12:00:00 2026
NAMESPACE: jenkins
STATUS: deployed

NOTES:
1. Get your 'admin' user password by running:
  kubectl exec -it svc/jenkins -n jenkins -- /bin/cat /run/secrets/additional/chart-admin-password && echo

2. Get the Jenkins URL to visit:
  kubectl get svc -n jenkins

$ kubectl get pods -n jenkins
NAME                       READY   STATUS    RESTARTS   AGE
jenkins-0                  2/2     Running   0          5m

配置Kubernetes云

在Jenkins中配置Kubernetes作为云提供者:

  • 进入系统管理 > 节点管理 > 配置云 > 添加云 > Kubernetes
  • 配置以下参数:
名称: kubernetes
Kubernetes URL: https://kubernetes.default.svc
Kubernetes命名空间: jenkins
Jenkins URL: http://jenkins.jenkins.svc.cluster.local:8080
Jenkins通道: jenkins.jenkins.svc.cluster.local:50000

动态Pod Agent

使用Kubernetes插件动态创建Pod作为构建Agent:

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
metadata:
  labels:
    app: jenkins-agent
spec:
  containers:
  - name: jnlp
    image: jenkins/inbound-agent:latest
    resources:
      requests:
        memory: "256Mi"
        cpu: "100m"
  - name: maven
    image: maven:3.8-openjdk-17
    command:
    - sleep
    args:
    - infinity
    volumeMounts:
    - name: maven-cache
      mountPath: /root/.m2
  - name: docker
    image: docker:24-cli
    command:
    - sleep
    args:
    - infinity
    volumeMounts:
    - name: docker-sock
      mountPath: /var/run/docker.sock
  volumes:
  - name: maven-cache
    persistentVolumeClaim:
      claimName: maven-cache-pvc
  - name: docker-sock
    hostPath:
      path: /var/run/docker.sock
'''
        }
    }
    
    stages {
        stage('Check Pod Info') {
            steps {
                sh '''
                    echo "Pod Name: $HOSTNAME"
                    echo "Node Name: $NODE_NAME"
                '''
            }
        }
        
        stage('Build with Maven') {
            steps {
                container('maven') {
                    sh '''
                        echo "=== Maven Version ==="
                        mvn -version
                        
                        echo "=== Building ==="
                        mvn clean package -DskipTests
                    '''
                }
            }
        }
        
        stage('Build Docker Image') {
            steps {
                container('docker') {
                    sh '''
                        echo "=== Docker Version ==="
                        docker version
                        
                        echo "=== Building Image ==="
                        docker build -t myapp:${BUILD_NUMBER} .
                    '''
                }
            }
        }
    }
}

执行结果示例

[Pipeline] podTemplate
[Pipeline] {
[Pipeline] node
Created Pod: jenkins/my-pipeline-1-abc123-xyz789
[Normal] Scheduled: Successfully assigned jenkins/my-pipeline-1-abc123-xyz789 to node-01
[Normal] Pulling: Pulling image "maven:3.8-openjdk-17"
[Normal] Pulled: Successfully pulled image in 5.2s
[Normal] Created: Created container maven
[Normal] Started: Started container maven
Agent my-pipeline-1-abc123-xyz789 is provisioned from template my-pipeline-1

[Pipeline] {
[Pipeline] stage
[Pipeline] { (Check Pod Info)
[Pipeline] sh
+ echo 'Pod Name: my-pipeline-1-abc123-xyz789'
Pod Name: my-pipeline-1-abc123-xyz789
+ echo 'Node Name: node-01'
Node Name: node-01

[Pipeline] stage
[Pipeline] { (Build with Maven)
[Pipeline] container
[Pipeline] {
[Pipeline] sh
+ echo '=== Maven Version ==='
=== Maven Version ===
+ mvn -version
Apache Maven 3.8.7
Maven home: /usr/share/maven
Java version: 17.0.9

部署应用到Kubernetes

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: kubectl
    image: bitnami/kubectl:latest
    command: ["sleep", "infinity"]
'''
        }
    }
    
    environment {
        KUBECONFIG = credentials('kubeconfig-prod')
    }
    
    stages {
        stage('Deploy') {
            steps {
                container('kubectl') {
                    sh '''
                        echo "Deploying to Kubernetes..."
                        
                        # 更新镜像版本
                        kubectl set image deployment/myapp \
                            myapp=registry.example.com/myapp:${BUILD_NUMBER} \
                            -n production
                        
                        # 等待部署完成
                        kubectl rollout status deployment/myapp -n production --timeout=300s
                        
                        # 显示部署状态
                        kubectl get pods -n production -l app=myapp
                    '''
                }
            }
        }
        
        stage('Verify') {
            steps {
                container('kubectl') {
                    sh '''
                        echo "Verifying deployment..."
                        
                        # 检查Pod状态
                        kubectl get pods -n production -l app=myapp -o wide
                        
                        # 检查服务
                        kubectl get svc -n production -l app=myapp
                    '''
                }
            }
        }
    }
}

完整CI/CD示例

pipeline {
    agent {
        kubernetes {
            yaml '''
apiVersion: v1
kind: Pod
spec:
  containers:
  - name: maven
    image: maven:3.8-openjdk-17
    command: ["sleep", "infinity"]
  - name: kaniko
    image: gcr.io/kaniko-project/executor:debug
    command: ["sleep", "infinity"]
    volumeMounts:
    - name: docker-config
      mountPath: /kaniko/.docker
  - name: kubectl
    image: bitnami/kubectl:latest
    command: ["sleep", "infinity"]
  volumes:
  - name: docker-config
    secret:
      secretName: docker-registry-creds
'''
        }
    }
    
    environment {
        REGISTRY = 'registry.example.com'
        IMAGE_NAME = 'myapp'
    }
    
    stages {
        stage('Build') {
            steps {
                container('maven') {
                    sh 'mvn clean package -DskipTests'
                }
            }
        }
        
        stage('Test') {
            steps {
                container('maven') {
                    sh 'mvn test'
                }
            }
        }
        
        stage('Build Image') {
            steps {
                container('kaniko') {
                    sh '''
                        /kaniko/executor \
                            --context=dir://. \
                            --destination=${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} \
                            --destination=${REGISTRY}/${IMAGE_NAME}:latest
                    '''
                }
            }
        }
        
        stage('Deploy') {
            when {
                branch 'main'
            }
            steps {
                container('kubectl') {
                    sh '''
                        kubectl set image deployment/${IMAGE_NAME} \
                            ${IMAGE_NAME}=${REGISTRY}/${IMAGE_NAME}:${BUILD_NUMBER} \
                            -n production
                        kubectl rollout status deployment/${IMAGE_NAME} -n production
                    '''
                }
            }
        }
    }
}

资源管理

为Pod配置资源限制,避免构建任务消耗过多资源:

containers:
- name: maven
  image: maven:3.8-openjdk-17
  resources:
    requests:
      memory: "512Mi"
      cpu: "250m"
    limits:
      memory: "2Gi"
      cpu: "1"

总结

本文详细介绍了Jenkins与Kubernetes的集成,包括部署Jenkins到K8s、配置动态Pod Agent、部署应用等完整流程。云原生环境下,这种集成是CI/CD的最佳实践。

下一篇我们将学习Jenkins的性能优化与监控。

发表回复

后才能评论