Docker + Jenkins + Kubernetes 完整CI/CD流水线构建实战

Diana73
Diana73 2026-01-26T23:13:30+08:00
0 0 3

前言

在现代软件开发中,持续集成(CI)和持续部署(CD)已经成为提高开发效率、保证代码质量的重要手段。本文将详细介绍如何使用Docker、Jenkins和Kubernetes构建一个完整的CI/CD流水线,帮助团队实现自动化构建、测试和部署流程。

什么是CI/CD

CI/CD(Continuous Integration/Continuous Delivery)是一种软件开发实践,通过自动化流程来缩短从代码提交到生产环境部署的时间。CI确保代码集成的频率和质量,而CD则确保软件可以快速、可靠地发布到生产环境。

CI/CD的核心价值

  • 提高交付速度:自动化减少人工干预,加快发布周期
  • 保证代码质量:自动化的测试确保每次提交都通过质量检查
  • 降低部署风险:标准化的部署流程减少人为错误
  • 提升团队协作:清晰的流程和反馈机制促进团队沟通

技术栈介绍

Docker容器化技术

Docker是一种开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的容器中,然后发布到任何流行的Linux机器上,也可以实现虚拟化。

# 示例Dockerfile
FROM node:16-alpine
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
EXPOSE 3000
CMD ["npm", "start"]

Jenkins自动化平台

Jenkins是一个开源的持续集成工具,提供了一系列插件来支持各种任务的自动化,包括构建、测试、部署等。

Kubernetes容器编排平台

Kubernetes是一个开源的容器编排平台,用于自动化部署、扩展和管理容器化应用程序。

环境准备

系统要求

  • Docker Engine 20.10+
  • Kubernetes集群(minikube或云环境)
  • Jenkins服务器
  • Git版本控制系统

安装必要组件

1. 安装Docker

# Ubuntu/Debian
sudo apt update
sudo apt install docker.io
sudo usermod -aG docker $USER

2. 安装kubectl

curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl"
chmod +x kubectl
sudo mv kubectl /usr/local/bin/

3. 安装Jenkins

# 使用Docker运行Jenkins
docker run -d \
  --name jenkins \
  --publish 8080:8080 \
  --publish 50000:50000 \
  --volume jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

Docker容器化应用

创建示例应用

我们以一个简单的Node.js应用为例:

// app.js
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

app.get('/', (req, res) => {
  res.json({
    message: 'Hello World!',
    timestamp: new Date().toISOString()
  });
});

app.get('/health', (req, res) => {
  res.status(200).json({ status: 'healthy' });
});

app.listen(port, () => {
  console.log(`Server running on port ${port}`);
});
{
  "name": "sample-app",
  "version": "1.0.0",
  "description": "Sample Node.js application",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.0"
  },
  "devDependencies": {
    "jest": "^29.0.0"
  }
}

编写Dockerfile

# Dockerfile
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 复制package文件
COPY package*.json ./

# 安装依赖
RUN npm ci --only=production

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# 启动应用
CMD ["npm", "start"]

构建和测试Docker镜像

# 构建镜像
docker build -t sample-app:latest .

# 运行容器
docker run -d -p 3000:3000 --name sample-app sample-app:latest

# 测试应用
curl http://localhost:3000/

Jenkins CI/CD流水线配置

安装Jenkins插件

在Jenkins中需要安装以下关键插件:

  1. Docker Pipeline - 支持Docker容器化构建
  2. Kubernetes - 与Kubernetes集成
  3. Git - 版本控制支持
  4. Pipeline - 流水线支持

创建流水线项目

在Jenkins中创建一个新的"Pipeline"项目,配置如下:

// Jenkinsfile
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'your-registry.com'
        APP_NAME = 'sample-app'
        VERSION = "${env.BUILD_NUMBER}"
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo/sample-app.git'
            }
        }
        
        stage('Build') {
            steps {
                script {
                    docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}")
                }
            }
        }
        
        stage('Test') {
            steps {
                sh '''
                    npm install
                    npm test
                '''
            }
        }
        
        stage('Push Image') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", "docker-hub-credentials") {
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}").push()
                    }
                }
            }
        }
        
        stage('Deploy to Kubernetes') {
            steps {
                script {
                    withKubeConfig([credentialsId: 'k8s-config']) {
                        sh """
                            kubectl set image deployment/${APP_NAME} ${APP_NAME}=${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}
                        """
                    }
                }
            }
        }
    }
    
    post {
        success {
            echo 'Pipeline completed successfully!'
        }
        failure {
            echo 'Pipeline failed!'
        }
    }
}

Kubernetes部署配置

创建Deployment配置

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: sample-app
  labels:
    app: sample-app
spec:
  replicas: 3
  selector:
    matchLabels:
      app: sample-app
  template:
    metadata:
      labels:
        app: sample-app
    spec:
      containers:
      - name: sample-app
        image: your-registry.com/sample-app:latest
        ports:
        - containerPort: 3000
        resources:
          requests:
            memory: "128Mi"
            cpu: "100m"
          limits:
            memory: "256Mi"
            cpu: "200m"
        livenessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 30
          periodSeconds: 10
        readinessProbe:
          httpGet:
            path: /health
            port: 3000
          initialDelaySeconds: 5
          periodSeconds: 5
---
apiVersion: v1
kind: Service
metadata:
  name: sample-app-service
spec:
  selector:
    app: sample-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer

创建Ingress配置

# ingress.yaml
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: sample-app-ingress
  annotations:
    nginx.ingress.kubernetes.io/rewrite-target: /
spec:
  rules:
  - host: sample-app.example.com
    http:
      paths:
      - path: /
        pathType: Prefix
        backend:
          service:
            name: sample-app-service
            port:
              number: 80

部署到Kubernetes集群

# 应用配置
kubectl apply -f deployment.yaml
kubectl apply -f ingress.yaml

# 查看部署状态
kubectl get pods
kubectl get services
kubectl get ingress

完整的CI/CD流程实现

1. Git仓库初始化

首先,我们需要在Git仓库中包含应用代码和配置文件:

# 初始化Git仓库
git init
git add .
git commit -m "Initial commit"

# 推送到远程仓库
git remote add origin https://github.com/your-repo/sample-app.git
git push -u origin main

2. Jenkins Pipeline优化

pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'your-registry.com'
        APP_NAME = 'sample-app'
        NAMESPACE = 'default'
        IMAGE_TAG = "${env.BUILD_NUMBER}"
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo/sample-app.git'
            }
        }
        
        stage('Build & Test') {
            steps {
                script {
                    // 构建Docker镜像
                    def dockerImage = docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}")
                    
                    // 运行测试
                    sh '''
                        npm install
                        npm test
                    '''
                    
                    // 保存镜像ID用于后续步骤
                    dockerImage.id
                }
            }
        }
        
        stage('Security Scan') {
            steps {
                script {
                    // 使用Trivy进行安全扫描
                    sh '''
                        docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
                            aquasec/trivy:latest image ${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}
                    '''
                }
            }
        }
        
        stage('Push to Registry') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", "docker-hub-credentials") {
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG}").push()
                        
                        // 推送latest标签
                        docker.image("${DOCKER_REGISTRY}/${APP_NAME}:latest").push()
                    }
                }
            }
        }
        
        stage('Deploy to Dev') {
            steps {
                script {
                    withKubeConfig([credentialsId: 'dev-k8s-config']) {
                        sh """
                            kubectl set image deployment/${APP_NAME} ${APP_NAME}=${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG} -n ${NAMESPACE}
                        """
                        
                        // 等待部署完成
                        sh "kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}"
                    }
                }
            }
        }
        
        stage('Run Integration Tests') {
            steps {
                script {
                    withKubeConfig([credentialsId: 'dev-k8s-config']) {
                        // 等待应用启动
                        sh '''
                            sleep 30
                            curl -f http://sample-app-service:80/health
                        '''
                    }
                }
            }
        }
        
        stage('Deploy to Production') {
            steps {
                script {
                    // 生产环境部署前确认
                    input message: 'Deploy to production?', ok: 'Deploy'
                    
                    withKubeConfig([credentialsId: 'prod-k8s-config']) {
                        sh """
                            kubectl set image deployment/${APP_NAME} ${APP_NAME}=${DOCKER_REGISTRY}/${APP_NAME}:${IMAGE_TAG} -n ${NAMESPACE}
                        """
                        
                        // 等待部署完成
                        sh "kubectl rollout status deployment/${APP_NAME} -n ${NAMESPACE}"
                    }
                }
            }
        }
    }
    
    post {
        success {
            echo "Pipeline completed successfully!"
            slackSend channel: '#deployments', message: ":white_check_mark: Pipeline successful for ${APP_NAME}:${IMAGE_TAG}"
        }
        failure {
            echo "Pipeline failed!"
            slackSend channel: '#deployments', message: ":x: Pipeline failed for ${APP_NAME}:${IMAGE_TAG}"
        }
    }
}

3. 监控和告警配置

# prometheus-monitoring.yaml
apiVersion: monitoring.coreos.com/v1
kind: ServiceMonitor
metadata:
  name: sample-app-monitor
spec:
  selector:
    matchLabels:
      app: sample-app
  endpoints:
  - port: http
    path: /metrics
---
apiVersion: v1
kind: ConfigMap
metadata:
  name: sample-app-config
data:
  config.yaml: |
    prometheus:
      enabled: true
      scrape_interval: 30s
    alerting:
      rules:
        - name: high_cpu_usage
          condition: cpu_usage > 80
          duration: 5m

最佳实践和优化建议

1. 镜像安全最佳实践

# 安全的Dockerfile示例
FROM node:16-alpine

# 使用非root用户
RUN addgroup -g 1001 -S nodejs
RUN adduser -S nextjs -u 1001
USER nextjs

WORKDIR /app

# 复制package文件并安装依赖
COPY package*.json ./
RUN npm ci --only=production && npm cache clean --force

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

# 健康检查
HEALTHCHECK --interval=30s --timeout=3s --start-period=5s --retries=3 \
  CMD curl -f http://localhost:3000/health || exit 1

# 启动应用
CMD ["npm", "start"]

2. 流水线性能优化

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo/sample-app.git'
            }
        }
        
        stage('Parallel Build and Test') {
            parallel {
                stage('Build') {
                    steps {
                        script {
                            docker.build("${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}")
                        }
                    }
                }
                
                stage('Test') {
                    steps {
                        sh '''
                            npm install
                            npm test
                        '''
                    }
                }
            }
        }
        
        stage('Security Scan') {
            steps {
                script {
                    // 并行执行安全扫描
                    sh '''
                        docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
                            aquasec/trivy:latest image ${DOCKER_REGISTRY}/${APP_NAME}:${VERSION}
                    '''
                }
            }
        }
    }
}

3. 环境管理策略

# values-dev.yaml
image:
  repository: your-registry.com/sample-app
  tag: latest
replicaCount: 2
resources:
  limits:
    cpu: 500m
    memory: 512Mi
  requests:
    cpu: 250m
    memory: 256Mi
service:
  type: ClusterIP
  port: 80
# values-prod.yaml
image:
  repository: your-registry.com/sample-app
  tag: latest
replicaCount: 5
resources:
  limits:
    cpu: 1000m
    memory: 1024Mi
  requests:
    cpu: 500m
    memory: 512Mi
service:
  type: LoadBalancer
  port: 80

故障排除和监控

常见问题解决

1. Jenkins构建失败

# 检查Jenkins日志
docker logs jenkins

# 查看Docker构建错误
docker build -t sample-app:latest .

2. Kubernetes部署失败

# 检查Pod状态
kubectl get pods

# 查看Pod详细信息
kubectl describe pod <pod-name>

# 查看部署状态
kubectl rollout status deployment/sample-app

日志和监控

# 日志收集配置
apiVersion: v1
kind: ConfigMap
metadata:
  name: fluentd-config
data:
  fluent.conf: |
    <source>
      @type tail
      path /var/log/containers/*.log
      pos_file /var/log/fluentd-containers.log.pos
      tag kubernetes.*
      read_from_head true
      <parse>
        @type json
      </parse>
    </source>

总结

通过本文的详细介绍,我们构建了一个完整的CI/CD流水线,涵盖了从代码提交到Kubernetes部署的全过程。这个流水线具有以下特点:

  1. 自动化程度高:从代码构建、测试到部署全部自动化
  2. 安全性保障:包含安全扫描和镜像验证
  3. 环境隔离:支持开发、测试、生产环境分离
  4. 监控告警:完善的监控和告警机制

下一步建议

  1. 扩展测试覆盖:增加单元测试、集成测试、端到端测试
  2. 优化部署策略:实现蓝绿部署或滚动更新
  3. 增强安全性:实施更严格的安全扫描和访问控制
  4. 性能监控:添加APM工具进行应用性能监控

通过这样的CI/CD流水线,团队可以显著提高开发效率,减少人为错误,确保软件质量,最终实现更快的交付速度和更高的客户满意度。

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000