Docker + Jenkins + Kubernetes CI/CD流水线搭建:DevOps自动化部署完整教程

Hannah685
Hannah685 2026-02-26T16:18:12+08:00
0 0 0

引言

在现代软件开发中,DevOps已经成为提升开发效率和产品质量的关键实践。持续集成/持续部署(CI/CD)作为DevOps的核心组成部分,能够显著缩短软件交付周期,提高部署频率和质量。本文将详细介绍如何搭建一个完整的CI/CD流水线,整合Docker容器化技术、Jenkins自动化部署工具和Kubernetes集群管理平台,实现从代码提交到应用部署的全流程自动化。

什么是CI/CD

CI/CD是持续集成(Continuous Integration)和持续部署(Continuous Deployment)的缩写。持续集成是指开发人员频繁地将代码变更合并到主分支,并通过自动化测试验证变更的正确性。持续部署则是指在通过所有测试后,自动将应用部署到生产环境。

CI/CD的核心价值

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

环境准备

在开始搭建CI/CD流水线之前,我们需要准备相应的环境和工具。

系统要求

# 基础环境要求
- Linux/Windows/macOS系统
- Docker引擎(19.03+)
- Kubernetes集群(1.18+)
- Jenkins服务器(2.300+)
- Git版本控制系统

安装Docker

# Ubuntu/Debian系统安装Docker
sudo apt update
sudo apt install apt-transport-https ca-certificates curl gnupg lsb-release
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /usr/share/keyrings/docker-archive-keyring.gpg
echo "deb [arch=$(dpkg --print-architecture) signed-by=/usr/share/keyrings/docker-archive-keyring.gpg] https://download.docker.com/linux/ubuntu $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null
sudo apt update
sudo apt install docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 启动Docker服务
sudo systemctl start docker
sudo systemctl enable docker

安装Kubernetes集群

# 使用kubeadm安装Kubernetes集群
sudo apt update && sudo apt install -y apt-transport-https curl
curl -s https://packages.cloud.google.com/apt/doc/apt-key.gpg | sudo apt-key add -
echo "deb https://apt.kubernetes.io/ kubernetes-xenial main" | sudo tee -a /etc/apt/sources.list.d/kubernetes.list
sudo apt update
sudo apt install -y kubelet kubeadm kubectl
sudo apt-mark hold kubelet kubeadm kubectl

# 初始化集群
sudo kubeadm init --pod-network-cidr=10.244.0.0/16

# 配置kubectl
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

安装Jenkins

# 使用Docker安装Jenkins
docker run -d \
  --name jenkins \
  --restart=unless-stopped \
  -p 8080:8080 \
  -p 50000:50000 \
  -v jenkins_home:/var/jenkins_home \
  jenkins/jenkins:lts

# 获取初始密码
docker logs jenkins

Docker镜像构建

Docker容器化是CI/CD流程中的重要环节。我们将创建一个简单的Web应用并构建Docker镜像。

创建示例应用

// app.js - 简单的Node.js应用
const express = require('express');
const app = express();
const port = process.env.PORT || 3000;

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

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

app.listen(port, () => {
  console.log(`App listening at http://localhost:${port}`);
});

module.exports = app;
// package.json
{
  "name": "docker-cicd-demo",
  "version": "1.0.0",
  "description": "Docker CI/CD demo application",
  "main": "app.js",
  "scripts": {
    "start": "node app.js",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.0"
  },
  "devDependencies": {
    "jest": "^28.0.0"
  }
}

编写Dockerfile

# Dockerfile
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

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

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

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

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

# 健康检查
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 myapp:latest .

# 标签镜像
docker tag myapp:latest myregistry.com/myapp:latest

# 推送到镜像仓库
docker push myregistry.com/myapp:latest

Jenkins配置

Jenkins作为CI/CD的核心工具,需要进行相应的配置来支持自动化流程。

安装必要插件

# 在Jenkins Web界面安装以下插件
- Docker Pipeline
- Kubernetes
- Git
- Pipeline
- Blue Ocean
- Docker

配置Docker Registry

// Jenkinsfile - 完整的CI/CD流水线定义
pipeline {
    agent any
    
    environment {
        DOCKER_REGISTRY = 'myregistry.com'
        DOCKER_IMAGE_NAME = 'myapp'
        KUBE_NAMESPACE = 'default'
    }
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo/app.git'
            }
        }
        
        stage('Build') {
            steps {
                script {
                    docker.build("${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${env.BUILD_NUMBER}")
                }
            }
        }
        
        stage('Test') {
            steps {
                script {
                    docker.image("${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${env.BUILD_NUMBER}").inside {
                        sh 'npm test'
                    }
                }
            }
        }
        
        stage('Push') {
            steps {
                script {
                    docker.withRegistry("https://${DOCKER_REGISTRY}", 'docker-registry-credentials') {
                        docker.image("${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${env.BUILD_NUMBER}").push()
                    }
                }
            }
        }
        
        stage('Deploy') {
            steps {
                script {
                    deployToKubernetes()
                }
            }
        }
    }
    
    post {
        success {
            echo 'Pipeline completed successfully!'
        }
        failure {
            echo 'Pipeline failed!'
        }
    }
}

def deployToKubernetes() {
    def deployment = """
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: ${DOCKER_REGISTRY}/${DOCKER_IMAGE_NAME}:${env.BUILD_NUMBER}
        ports:
        - containerPort: 3000
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
  name: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer
"""
    
    sh "echo '${deployment}' | kubectl apply -f -"
}

Jenkins Pipeline配置

// 简化版Jenkinsfile
pipeline {
    agent any
    
    tools {
        maven 'Maven-3.8.1'
        jdk 'JDK-11'
    }
    
    environment {
        MAVEN_HOME = tool 'Maven-3.8.1'
        JAVA_HOME = tool 'JDK-11'
        REGISTRY = 'docker.io'
        IMAGE_NAME = 'myapp'
    }
    
    stages {
        stage('Build') {
            steps {
                sh 'mvn clean package'
            }
            post {
                success {
                    archiveArtifacts artifacts: 'target/*.jar', fingerprint: true
                }
            }
        }
        
        stage('Test') {
            steps {
                sh 'mvn test'
            }
        }
        
        stage('Build Docker Image') {
            steps {
                script {
                    docker.build("${REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER}")
                }
            }
        }
        
        stage('Push to Registry') {
            steps {
                script {
                    docker.withRegistry("https://${REGISTRY}", 'dockerhub-credentials') {
                        docker.image("${REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER}").push()
                    }
                }
            }
        }
        
        stage('Deploy to Kubernetes') {
            steps {
                script {
                    def kubeconfig = readYaml file: 'kubeconfig.yaml'
                    withKubeConfig([credentialsId: 'kubeconfig-credentials']) {
                        sh "kubectl set image deployment/myapp-deployment myapp=${REGISTRY}/${IMAGE_NAME}:${env.BUILD_NUMBER}"
                    }
                }
            }
        }
    }
}

Kubernetes集群管理

Kubernetes作为容器编排平台,负责管理容器化应用的部署、扩展和运维。

创建Deployment配置

# deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: myapp-deployment
  labels:
    app: myapp
spec:
  replicas: 3
  selector:
    matchLabels:
      app: myapp
  template:
    metadata:
      labels:
        app: myapp
    spec:
      containers:
      - name: myapp
        image: myregistry.com/myapp:latest
        ports:
        - containerPort: 3000
        resources:
          requests:
            memory: "64Mi"
            cpu: "250m"
          limits:
            memory: "128Mi"
            cpu: "500m"
        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: myapp-service
spec:
  selector:
    app: myapp
  ports:
    - protocol: TCP
      port: 80
      targetPort: 3000
  type: LoadBalancer

配置Ingress控制器

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

配置资源限制和监控

# resource-limits.yaml
apiVersion: v1
kind: LimitRange
metadata:
  name: mem-limit-range
spec:
  limits:
  - default:
      memory: 512Mi
    defaultRequest:
      memory: 256Mi
    type: Container
---
apiVersion: v1
kind: ResourceQuota
metadata:
  name: mem-quota
spec:
  hard:
    requests.memory: "1Gi"
    limits.memory: "2Gi"

安全最佳实践

安全是CI/CD流程中不可忽视的重要环节。

密钥管理

# 使用Kubernetes Secret管理敏感信息
kubectl create secret generic docker-registry-credentials \
  --from-literal=username=your-username \
  --from-literal=password=your-password

# Jenkins凭据管理
# 在Jenkins中配置Docker Registry凭据

安全扫描

# 使用Trivy进行镜像安全扫描
docker run --rm -v /var/run/docker.sock:/var/run/docker.sock \
  aquasec/trivy image myregistry.com/myapp:latest

# 使用Clair进行容器镜像漏洞扫描
docker run -d --name clair \
  -p 6060:6060 \
  quay.io/coreos/clair:v2.1.0

网络安全

# NetworkPolicy配置
apiVersion: networking.k8s.io/v1
kind: NetworkPolicy
metadata:
  name: myapp-network-policy
spec:
  podSelector:
    matchLabels:
      app: myapp
  policyTypes:
  - Ingress
  - Egress
  ingress:
  - from:
    - namespaceSelector:
        matchLabels:
          name: frontend
    ports:
    - protocol: TCP
      port: 3000
  egress:
  - to:
    - namespaceSelector:
        matchLabels:
          name: backend
    ports:
    - protocol: TCP
      port: 53

监控和日志

完善的监控和日志系统对于CI/CD流程的运维至关重要。

集成Prometheus监控

# prometheus-config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: prometheus-config
data:
  prometheus.yml: |
    global:
      scrape_interval: 15s
    scrape_configs:
    - job_name: 'kubernetes-pods'
      kubernetes_sd_configs:
      - role: pod
      relabel_configs:
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_scrape]
        action: keep
        regex: true
      - source_labels: [__meta_kubernetes_pod_annotation_prometheus_io_port]
        action: replace
        target_label: __address__
        regex: (.+):(.+)
        replacement: $1:$2

集成ELK日志系统

# elasticsearch-deployment.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: elasticsearch
spec:
  replicas: 1
  selector:
    matchLabels:
      app: elasticsearch
  template:
    metadata:
      labels:
        app: elasticsearch
    spec:
      containers:
      - name: elasticsearch
        image: docker.elastic.co/elasticsearch/elasticsearch:7.17.0
        ports:
        - containerPort: 9200
        env:
        - name: discovery.type
          value: "single-node"

性能优化

构建缓存优化

# 优化的Dockerfile
FROM node:16-alpine

# 设置工作目录
WORKDIR /app

# 先复制package文件,利用Docker缓存
COPY package*.json ./

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

# 复制应用代码
COPY . .

# 暴露端口
EXPOSE 3000

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

Jenkins流水线优化

pipeline {
    agent any
    
    stages {
        stage('Checkout') {
            steps {
                git branch: 'main', url: 'https://github.com/your-repo/app.git'
            }
        }
        
        stage('Build') {
            steps {
                script {
                    // 使用并行构建提高效率
                    parallel {
                        stage('Build Frontend') {
                            steps {
                                sh 'npm run build'
                            }
                        }
                        stage('Build Backend') {
                            steps {
                                sh 'mvn clean package'
                            }
                        }
                    }
                }
            }
        }
        
        stage('Test') {
            steps {
                script {
                    // 并行测试执行
                    parallel {
                        stage('Unit Tests') {
                            steps {
                                sh 'npm test'
                            }
                        }
                        stage('Integration Tests') {
                            steps {
                                sh 'npm run integration-test'
                            }
                        }
                    }
                }
            }
        }
    }
}

故障排除和维护

常见问题解决

# 检查Jenkins服务状态
systemctl status jenkins

# 查看Docker容器状态
docker ps -a

# 检查Kubernetes集群状态
kubectl get nodes
kubectl get pods
kubectl get services

# 查看Jenkins日志
journalctl -u jenkins

自动化维护脚本

#!/bin/bash
# cleanup.sh - 清理过期资源的脚本

# 清理过期的Docker镜像
docker image prune -a -f

# 清理过期的Jenkins构建
# 需要通过Jenkins API实现

# 清理Kubernetes中的过期Pod
kubectl delete pods --selector=app=myapp --grace-period=0 --force

echo "Cleanup completed"

总结

通过本文的详细介绍,我们成功搭建了一个完整的Docker + Jenkins + Kubernetes CI/CD流水线。这个流水线涵盖了从代码提交、构建测试到自动化部署的完整流程,实现了DevOps的核心价值。

关键要点回顾

  1. 环境准备:正确配置Docker、Kubernetes和Jenkins环境
  2. 容器化:使用Dockerfile构建应用镜像并推送至镜像仓库
  3. 自动化部署:通过Jenkins Pipeline实现自动化构建和部署
  4. 集群管理:使用Kubernetes管理容器化应用的部署和运维
  5. 安全实践:实施安全最佳实践保护CI/CD流程
  6. 监控日志:建立完善的监控和日志系统
  7. 性能优化:通过各种优化技术提升流水线效率

未来扩展

这个CI/CD流水线还可以进一步扩展:

  • 集成更多的测试框架和质量检查工具
  • 实现蓝绿部署或金丝雀发布策略
  • 集成A/B测试和流量管理
  • 实现更复杂的多环境部署策略
  • 集成机器学习模型的自动化部署

通过持续优化和完善这个CI/CD流水线,团队可以显著提升软件交付效率和质量,实现真正的DevOps自动化部署。

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000