Docker + Jenkins + Kubernetes 联合部署流水线:DevOps自动化运维实战

Yara50
Yara50 2026-03-06T06:08:11+08:00
0 0 1

标签:DevOps, Docker, Jenkins, Kubernetes, CI/CD
简介:手把手教学如何搭建完整的CI/CD流水线,整合Docker容器化、Jenkins自动化构建、Kubernetes集群部署,实现从代码提交到生产环境的全自动发布流程,提升团队交付效率。

一、引言:为什么需要 DevOps 流水线?

在现代软件开发中,快速迭代、持续交付已成为企业竞争力的核心要素。传统的“瀑布式”开发模式已无法满足敏捷开发的需求,而 DevOps 理念应运而生——通过自动化工具链打通开发(Development)与运维(Operations)之间的壁垒,实现 CI/CD(持续集成 / 持续交付) 的全流程自动化。

本篇文章将带你深入实践一套完整的 Docker + Jenkins + Kubernetes 联合部署流水线,涵盖从代码提交、自动构建、镜像打包、推送至私有仓库,到在 Kubernetes 集群中自动部署上线的全过程。这套方案已被广泛应用于中大型互联网公司的生产环境中,具有高可扩展性、高可靠性与强安全性。

二、技术栈概览与架构设计

2.1 核心组件介绍

组件 作用
Git 代码版本管理,作为流水线触发源
Jenkins CI/CD 引擎,负责任务调度、脚本执行、构建与部署
Docker 容器化工具,用于打包应用及其依赖
Kubernetes (k8s) 容器编排平台,实现应用的弹性伸缩、负载均衡与高可用部署
Harbor / Docker Registry 私有镜像仓库,用于安全存储和分发镜像
kubectl / Helm Kubernetes 命令行工具与包管理器

2.2 架构图(文字描述)

[开发者] → [Git 仓库]
           ↓
      [Jenkins 触发构建]
           ↓
   [Docker 构建镜像]
           ↓
[推送镜像到 Harbor]
           ↓
 [Helm Chart 打包 & 发布]
           ↓
[自动部署到 Kubernetes 集群]
           ↓
[应用运行于生产环境]

优势

  • 自动化减少人为错误
  • 可视化构建日志便于排查问题
  • 支持多环境(dev/test/prod)隔离部署
  • 支持灰度发布、回滚机制

三、前置准备:环境搭建

3.1 环境要求

项目 推荐配置
操作系统 Ubuntu 20.04 LTS / CentOS 7+
Jenkins v2.400+(推荐 LTS 版)
Docker v20.10+
Kubernetes v1.25+(Minikube / K3s / EKS / AKS 等)
Git v2.30+
Harbor v2.7+(支持 HTTPS 和 RBAC)

⚠️ 建议使用独立服务器或虚拟机进行部署,避免资源冲突。

3.2 安装 Docker

# Ubuntu/Debian
sudo apt update
sudo apt install -y docker.io

# 启用开机自启
sudo systemctl enable docker
sudo systemctl start docker

# 添加当前用户到 docker 组(避免 sudo)
sudo usermod -aG docker $USER
newgrp docker

3.3 安装 Jenkins

# 安装 Java 11(Jenkins 依赖)
sudo apt install -y openjdk-11-jdk

# 安装 Jenkins
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo gpg --dearmor -o /usr/share/keyrings/jenkins.gpg
echo deb [signed-by=/usr/share/keyrings/jenkins.gpg] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update
sudo apt install -y jenkins

# 启动 Jenkins
sudo systemctl enable jenkins
sudo systemctl start jenkins

📌 默认访问地址:http://<your-server-ip>:8080

🔐 第一次启动需输入初始密码(位于 /var/lib/jenkins/secrets/initialAdminPassword

3.4 安装 Kubernetes(以 Minikube 为例)

# 安装 kubectl
curl -LO "https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl

# 安装 Minikube
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 启动 Minikube
minikube start --driver=docker --cpus=4 --memory=8192MB

验证安装:

kubectl version --short
minikube status

3.5 安装 Harbor(私有镜像仓库)

使用官方 Helm Chart 快速部署:

# 添加 Harbor Helm 仓库
helm repo add harbor https://helm.goharbor.io
helm repo update

# 创建命名空间
kubectl create namespace harbor

# 部署 Harbor
helm install harbor harbor/harbor \
  --namespace harbor \
  --set hostname=harbor.yourdomain.com \
  --set http.port=80 \
  --set https.port=443 \
  --set expose.type=ingress \
  --set expose.ingress.hosts.core=harbor.yourdomain.com \
  --set expose.ingress.hosts.notary=notary.harbor.yourdomain.com \
  --set externalURL=https://harbor.yourdomain.com \
  --set adminPassword='Harbor123!' \
  --set persistence.enabled=true \
  --set persistence.size=10Gi

📝 替换 yourdomain.com 为真实域名或内网 IP 地址,并确保 DNS 可解析。

✅ 访问 https://harbor.yourdomain.com,登录默认账号 admin,密码为 Harbor123!

四、Jenkins 配置:核心构建引擎

4.1 安装必要插件

登录 Jenkins Web UI 后,进入 Manage Jenkins > Plugins > Available,安装以下插件:

  • Git Plugin
  • Docker Pipeline Plugin
  • Kubernetes Plugin
  • Pipeline Plugin
  • Credentials Binding Plugin
  • Blue Ocean (可选)

4.2 配置全局凭据

4.2.1 添加 Docker Hub 凭据(示例)

进入 Manage Jenkins > Manage Credentials > System > Global credentials (unrestricted)

  • Kind: Username with password
  • Scope: Global
  • Username: your-dockerhub-username
  • Password: your-dockerhub-password
  • ID: dockerhub-credentials

💡 建议使用个人访问令牌(PAT)替代明文密码。

4.2.2 添加 Kubernetes API 凭据

若使用 Kubernetes Plugin,需配置 kubeconfig 文件:

# 获取 kubeconfig
kubectl config view --raw > ~/.kube/config

# 将内容复制并粘贴为 Jenkins 凭据
Kind: `File`
ID: `k8s-kubeconfig`
Content: (整个 .kube/config 内容)

4.2.3 添加 Harbor 凭据

同样方式添加 Harbor 登录凭证:

  • Username: admin
  • Password: Harbor123!
  • ID: harbor-credentials

五、创建 Jenkins Pipeline:完整流水线定义

5.1 示例项目结构

假设你有一个简单的 Node.js 应用:

project-root/
├── src/
│   └── app.js
├── package.json
├── Dockerfile
├── Jenkinsfile
└── charts/
    └── myapp/
        ├── Chart.yaml
        ├── values.yaml
        └── templates/
            ├── deployment.yaml
            └── service.yaml

5.2 编写 Jenkinsfile(声明式流水线)

pipeline {
    agent any

    environment {
        // 设置环境变量
        DOCKER_IMAGE_NAME = 'myapp'
        DOCKER_TAG = "${env.BUILD_ID}"
        HARBOR_REGISTRY = 'harbor.yourdomain.com'
        HARBOR_NAMESPACE = 'library'
        IMAGE_NAME = "${HARBOR_REGISTRY}/${HARBOR_NAMESPACE}/${DOCKER_IMAGE_NAME}:${DOCKER_TAG}"

        // Helm 相关
        HELM_CHART_DIR = 'charts/myapp'
        RELEASE_NAME = 'myapp-release'
        NAMESPACE = 'production'
    }

    stages {
        stage('Checkout') {
            steps {
                script {
                    echo 'Cloning repository...'
                    checkout scm
                }
            }
        }

        stage('Build') {
            steps {
                script {
                    echo 'Building application...'
                    sh 'npm install'
                    sh 'npm run build'
                }
            }
        }

        stage('Test') {
            steps {
                script {
                    echo 'Running tests...'
                    sh 'npm test'
                }
            }
        }

        stage('Docker Build and Push') {
            steps {
                script {
                    echo 'Building Docker image...'
                    docker.build("${IMAGE_NAME}")
                    echo 'Pushing image to Harbor...'
                    docker.withRegistry("https://${HARBOR_REGISTRY}", 'harbor-credentials') {
                        docker.image("${IMAGE_NAME}").push()
                    }
                }
            }
        }

        stage('Deploy to Kubernetes') {
            steps {
                script {
                    echo 'Deploying using Helm...'
                    sh """
                        helm upgrade --install ${RELEASE_NAME} ${HELM_CHART_DIR} \\
                            --namespace ${NAMESPACE} \\
                            --set image.repository=${IMAGE_NAME} \\
                            --set image.tag=${DOCKER_TAG} \\
                            --create-namespace
                    """

                    echo 'Waiting for rollout...'
                    sh """
                        kubectl rollout status deployment/${RELEASE_NAME} \\
                            --namespace ${NAMESPACE} \\
                            --timeout=600s
                    """
                }
            }
        }
    }

    post {
        success {
            echo '✅ Deployment succeeded!'
            slackSend(channel: '#devops', message: "🎉 Deployment successful: ${IMAGE_NAME}")
        }
        failure {
            echo '❌ Deployment failed!'
            slackSend(channel: '#devops', message: "🚨 Deployment failed: ${BUILD_URL}")
        }
    }
}

📌 说明:

  • agent any 表示可在任意节点执行
  • environment 定义全局变量,便于复用
  • docker.withRegistry(...) 是 Jenkins Docker Pipeline 插件的关键语法
  • 使用 helm upgrade --install 实现幂等部署
  • post 块支持成功/失败通知(如 Slack)

六、Dockerfile 设计最佳实践

# Dockerfile
FROM node:18-alpine AS builder

WORKDIR /app

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

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

# 复制源码
COPY . .

# 构建前端(如果适用)
RUN npm run build

# 运行时阶段
FROM node:18-alpine AS runner

WORKDIR /app

# 复制构建产物
COPY --from=builder /app/dist ./dist
COPY --from=builder /app/package*.json ./

# 创建非 root 用户
RUN adduser -D -u 1001 appuser
USER appuser

# 暴露端口
EXPOSE 3000

# 启动命令
CMD ["node", "dist/index.js"]

✅ 最佳实践:

  • 使用多阶段构建(Multi-stage Build),减小镜像体积
  • 不要使用 root 用户运行服务
  • 使用 .dockerignore 排除不必要的文件(如 node_modules, .git
  • 明确指定基础镜像版本(避免不稳定的 latest)

七、Helm Chart 高级配置

7.1 Chart.yaml

apiVersion: v2
name: myapp
version: 0.1.0
description: A simple Node.js app deployed via Helm

7.2 values.yaml

# Default values for myapp
replicaCount: 2
image:
  repository: harbor.yourdomain.com/library/myapp
  tag: latest
  pullPolicy: IfNotPresent

service:
  type: ClusterIP
  port: 3000

resources:
  limits:
    memory: "128Mi"
    cpu: "500m"
  requests:
    memory: "64Mi"
    cpu: "250m"

env:
  NODE_ENV: production
  PORT: "3000"

7.3 deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: {{ include "myapp.fullname" . }}
  labels:
    app.kubernetes.io/name: {{ include "myapp.name" . }}
    app.kubernetes.io/instance: {{ .Release.Name }}
spec:
  replicas: {{ .Values.replicaCount }}
  selector:
    matchLabels:
      app.kubernetes.io/name: {{ include "myapp.name" . }}
      app.kubernetes.io/instance: {{ .Release.Name }}
  template:
    metadata:
      labels:
        app.kubernetes.io/name: {{ include "myapp.name" . }}
        app.kubernetes.io/instance: {{ .Release.Name }}
    spec:
      containers:
        - name: {{ .Chart.Name }}
          image: "{{ .Values.image.repository }}:{{ .Values.image.tag }}"
          imagePullPolicy: {{ .Values.image.pullPolicy }}
          ports:
            - containerPort: {{ .Values.service.port }}
          envFrom:
            - configMapRef:
                name: {{ include "myapp.fullname" . }}-configmap
          resources:
            {{- toYaml .Values.resources | nindent 8 }}

✅ 优势:

  • 支持参数化部署(不同环境传入不同 values)
  • 可通过 helm template 预览生成的 YAML
  • 支持 Helm Hooks(Pre-install, Post-upgrade 等)

八、高级功能与优化建议

8.1 多环境部署(dev/test/prod)

通过 Helm Values 差异化管理:

# dev/values.yaml
replicaCount: 1
image:
  tag: dev-${BUILD_ID}

# prod/values.yaml
replicaCount: 5
image:
  tag: stable-${BUILD_ID}

在 Jenkinsfile 中动态切换:

def envConfig = 'dev'  // 由参数决定
sh "helm upgrade --install ${RELEASE_NAME} ${HELM_CHART_DIR} --values charts/myapp/${envConfig}/values.yaml ..."

8.2 使用 Parameterized Build(参数化构建)

在 Jenkins 项目中启用参数化构建:

  • String Parameter: ENVIRONMENT(值:dev/test/prod)
  • Boolean Parameter: SKIP_TEST(是否跳过测试)

然后在 Jenkinsfile 中使用:

parameters {
    string(name: 'ENVIRONMENT', defaultValue: 'dev', description: 'Target environment')
    booleanParam(name: 'SKIP_TEST', defaultValue: false, description: 'Skip testing phase')
}

stage('Test') {
    when { expression { !params.SKIP_TEST } }
    steps {
        sh 'npm test'
    }
}

8.3 灰度发布与滚动更新策略

修改 Helm Chart 中的 Deployment:

strategy:
  rollingUpdate:
    maxSurge: 1
    maxUnavailable: 0

配合 helm upgrade --wait --timeout=300s 确保平滑升级。

8.4 日志与监控集成

  • 在 Jenkins Pipeline 中加入日志收集步骤:
    sh 'kubectl logs deployment/myapp-release -n production'
    
  • 使用 Prometheus + Grafana 监控 Pod 状态。
  • 集成 Loki 用于日志聚合。

8.5 安全加固措施

措施 说明
使用非 root 用户运行容器 减少权限攻击面
镜像签名(Cosign) 保证镜像来源可信
Harbor 仓库权限控制 按角色分配读写权限
Jenkins 权限矩阵(RBAC) 限制用户操作范围
Pipeline 审计日志 记录每次构建行为

九、常见问题排查与解决方案

问题 原因 解决方案
Jenkins 无法拉取镜像 Docker 权限不足 检查 docker 用户组、重启服务
Harbor 接收镜像失败 HTTPS 证书问题 添加信任证书或禁用验证(仅测试)
Helm 部署超时 Pod 启动慢或网络不通 检查 kubectl describe pod
Jenkins 报错 No such file or directory 路径错误或权限不足 检查工作目录与文件是否存在
构建失败但日志无明确信息 插件版本不兼容 升级 Jenkins 及相关插件

十、总结:打造可持续演进的 CI/CD 生态

通过本文的完整实践,我们已经构建了一套 基于 Docker + Jenkins + Kubernetes 的现代化 CI/CD 流水线。这套系统具备以下核心能力:

自动化:从代码提交到部署上线全程无需人工干预
可重复性:所有流程通过代码定义(Jenkinsfile、Helm Chart)
可观测性:构建日志、部署状态、监控指标一目了然
安全性:权限分离、镜像签名、私有仓库保障数据安全
可扩展性:支持多项目、多环境、多团队协作

🚀 下一步建议

  • 引入 Argo CD 做 GitOps,实现“声明式基础设施即代码”
  • 使用 Tekton 替代 Jenkins,获得更现代化的 CI/CD 引擎
  • 构建内部 DevOps 平台,提供自助式部署门户

十一、附录:一键脚本示例(初始化环境)

#!/bin/bash
# setup-devops.sh

echo "🚀 Starting DevOps environment setup..."

# 1. 安装 Docker
sudo apt update && sudo apt install -y docker.io

# 2. 安装 Jenkins
curl -fsSL https://pkg.jenkins.io/debian-stable/jenkins.io.key | sudo gpg --dearmor -o /usr/share/keyrings/jenkins.gpg
echo deb [signed-by=/usr/share/keyrings/jenkins.gpg] https://pkg.jenkins.io/debian-stable binary/ | sudo tee /etc/apt/sources.list.d/jenkins.list
sudo apt update && sudo apt install -y jenkins

# 3. 安装 Minikube & kubectl
curl -LO "https://dl.k8s.io/release/v1.29.0/bin/linux/amd64/kubectl"
sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl
curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
sudo install minikube-linux-amd64 /usr/local/bin/minikube

# 4. 启动服务
sudo systemctl enable docker jenkins
sudo systemctl start docker jenkins
minikube start --driver=docker --cpus=4 --memory=8192MB

echo "✅ Environment ready!"
echo "Access Jenkins at http://localhost:8080"
echo "Run 'minikube dashboard' to view cluster status"

十二、结语

在数字化转型浪潮下,高效的 CI/CD 流水线不仅是技术能力的体现,更是组织敏捷性的基石。掌握 Docker + Jenkins + Kubernetes 的联合部署,意味着你掌握了现代云原生时代的核心生产力工具。

无论你是 DevOps 工程师、研发主管,还是希望提升团队效率的技术负责人,这套实战方案都值得你深入研究与落地实施。

记住:自动化不是终点,而是起点。真正的价值在于通过自动化释放人力,去专注于更高阶的创新与架构设计。

📌 立即行动:将本文中的 Jenkinsfile、Dockerfile、Helm Chart 复制到你的项目中,从今天开始构建属于你的自动化发布流水线!

📢 关注我,获取更多 DevOps 系列实战文章:自动化部署、GitOps、可观测性、混沌工程……

相关推荐
广告位招租

相似文章

    评论 (0)

    0/2000