这次我们来看一套面向2026年的容器化与云原生实战教程。这套内容不是零散的知识点堆砌,而是将 Docker、Kubernetes (K8S)、Jenkins 和 Linux 运维串联成一个完整的 CI/CD 实战项目。对于刚接触容器技术、想从零搭建一套自动化部署流水线的开发者或运维人员来说,这套教程的核心价值在于“学完就能用”——它清晰地展示了如何从单机 Docker 环境,一步步构建出具备自动构建、测试、部署能力的 K8S 集群。

如果你关心的是:如何在 Windows/macOS/Linux 上快速安装 Docker Desktop、如何编写高效的 Dockerfile、如何搭建一个最小可用的 K8S 集群(即使是单节点学习环境)、如何配置 Jenkins 实现代码提交即自动部署,以及如何解决过程中最常见的网络、存储、镜像拉取问题,那么这篇文章可以直接收藏。我们将避开庞杂的理论,聚焦于可执行的操作、可验证的结果和可复现的排错步骤。

1. 核心能力速览

本教程涵盖的技术栈和关键实践点如下表所示,这不仅是学习路径,也是一个最小可用的云原生交付流水线清单。

能力项 说明与目标
技术栈覆盖 Docker 容器化 -> Kubernetes 编排 -> Jenkins 自动化 -> Linux 基础运维
学习门槛 面向零基础或有一定 Linux 命令基础的开发者,无需预先精通所有组件。
环境要求 支持 Windows 10/11 (WSL2)、macOS 及主流 Linux 发行版。内存建议 8GB+,CPU 支持虚拟化。
核心产出 1. 一个可运行的 Docker 环境。
2. 一个单节点或多节点 K8S 集群。
3. 一套 Jenkins CI/CD 流水线,能自动构建 Docker 镜像并部署到 K8S。
关键技能点 Dockerfile 编写、Docker Compose、K8S Pod/Deployment/Service 配置、Jenkins Pipeline (Declarative), Helm Chart 基础。
排错重点 镜像拉取失败、网络策略冲突、持久化存储配置、Jenkins 插件依赖、K8S 资源权限。

2. 适用场景与使用边界

这套教程和实战项目主要适合以下几类读者:

  • 转型 DevOps 的传统开发/运维人员 :需要快速掌握容器化和自动化部署的核心技能链。
  • 计算机相关专业的学生 :希望通过一个完整的项目理解云原生技术的实际工作流,丰富简历项目经验。
  • 中小团队技术负责人 :计划引入容器化和自动化部署,需要一套经过验证的、可落地的入门方案进行技术预研。
  • 个人项目开发者 :希望为自己的应用搭建一套专业的、可扩展的部署环境。

需要明确的使用边界:

  1. 学习与预研环境 :教程中搭建的 K8S 集群(如使用 Minikube、K3s 或单 Master 集群)适用于开发、测试和学习, 不能直接等同于生产级的高可用集群 。生产环境需要考虑多 Master、etcd 集群、网络插件选型、监控日志体系等。
  2. 资源消耗 :在本地同时运行 Docker、K8S 集群和 Jenkins,对电脑内存和 CPU 有一定要求。如果资源紧张,建议按模块分步实践,或使用云服务器进行。
  3. 安全边界 :教程以保证功能跑通为首要目标,涉及的网络策略、镜像仓库认证、K8S RBAC 权限控制等安全最佳实践仅作引导性介绍。在生产部署前,必须系统性地加强安全配置。

3. 环境准备与前置条件

在开始动手之前,请确保你的实验环境满足以下基本要求。这是后续所有步骤能够顺利进行的基础。

3.1 硬件与操作系统

  • 操作系统 :Windows 10/11 (版本 2004 及以上,需启用 WSL2)、macOS 10.15+ 或任意主流 Linux 发行版(如 Ubuntu 20.04/22.04 LTS, CentOS 7/8)。
  • 内存 :建议 8 GB 或以上。运行 K8S 单节点集群至少需要 2-3 GB 空闲内存,加上 Jenkins 和 Docker,8GB 是流畅体验的起点。
  • CPU :现代双核以上处理器,并确保在 BIOS/UEFI 中已开启 虚拟化技术 (如 Intel VT-x 或 AMD-V)。这对于在 Windows/macOS 上运行 Docker Desktop 和 K8S 至关重要。
  • 磁盘空间 :至少预留 20 GB 可用空间,用于安装软件、拉取基础镜像和存储项目文件。

3.2 关键软件检查清单

在安装 Docker 之前,请先完成这些检查:

  1. Windows 用户 :确认已安装并启用 WSL 2 。在 PowerShell(管理员)中运行 wsl --list --verbose 查看。若未安装,请参考微软官方文档安装。
  2. 虚拟化检查
    • Windows:打开任务管理器 -> “性能”选项卡 -> “CPU”,查看“虚拟化”是否已启用。
    • Linux/macOS:通常在终端运行 egrep -c ‘(vmx|svm)’ /proc/cpuinfo (Linux) 或 sysctl -a | grep machdep.cpu.features (macOS),输出非0则支持。
  3. 网络准备 :确保主机可以正常访问互联网,用于下载安装包和拉取 Docker 镜像。了解公司或家庭网络是否有特殊的代理或防火墙规则。

4. Docker 安装与基础实战

Docker 是整个技术栈的基石。我们采用最通用的安装方式,并立即通过一个实战项目来巩固。

4.1 Docker 安装(以 Ubuntu 22.04 为例)

以下脚本完成了仓库配置、依赖安装和 Docker Engine 的安装。

# 1. 卸载旧版本(如有)
sudo apt-get remove docker docker-engine docker.io containerd runc

# 2. 安装依赖包,允许 apt 通过 HTTPS 使用仓库
sudo apt-get update
sudo apt-get install -y \
    ca-certificates \
    curl \
    gnupg \
    lsb-release

# 3. 添加 Docker 官方 GPG 密钥
sudo mkdir -p /etc/apt/keyrings
curl -fsSL https://download.docker.com/linux/ubuntu/gpg | sudo gpg --dearmor -o /etc/apt/keyrings/docker.gpg

# 4. 设置稳定版仓库
echo \
  "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.gpg] https://download.docker.com/linux/ubuntu \
  $(lsb_release -cs) stable" | sudo tee /etc/apt/sources.list.d/docker.list > /dev/null

# 5. 安装 Docker Engine
sudo apt-get update
sudo apt-get install -y docker-ce docker-ce-cli containerd.io docker-compose-plugin

# 6. 验证安装
sudo docker run hello-world

如果看到 “Hello from Docker!” 的输出,说明安装成功。 对于 Windows/macOS 用户,强烈建议直接下载并安装 Docker Desktop ,它集成了 Docker Engine、CLI 和图形化管理界面,并内置了 K8S 支持选项。

4.2 第一个 Docker 实战:容器化一个 Python Web 应用

我们创建一个简单的 Flask 应用并将其容器化。

  1. 创建项目目录及文件
    mkdir my-flask-app && cd my-flask-app
    
  2. 编写应用代码 app.py
    from flask import Flask
    app = Flask(__name__)
    
    @app.route(‘/‘)
    def hello():
        return ‘<h1>Hello, Docker & K8S!</h1><p>This is my first containerized app.</p>‘
    
    if __name__ == ‘__main__‘:
        app.run(host=‘0.0.0.0‘, port=5000)
    
  3. 编写依赖文件 requirements.txt
    Flask==2.3.2
    
  4. 编写 Dockerfile :这是构建镜像的“食谱”。
    # 使用官方 Python 轻量级镜像作为基础
    FROM python:3.9-slim
    
    # 设置工作目录
    WORKDIR /app
    
    # 复制依赖文件
    COPY requirements.txt .
    
    # 安装依赖,使用国内镜像源加速(可选)
    RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple
    
    # 复制应用代码
    COPY . .
    
    # 声明容器运行时暴露的端口
    EXPOSE 5000
    
    # 定义容器启动命令
    CMD [“python”, “app.py”]
    
  5. 构建 Docker 镜像
    # -t 为镜像打标签,格式为 name:tag
    docker build -t my-flask-app:1.0 .
    
    使用 docker images 查看构建成功的镜像。
  6. 运行容器
    # -d 后台运行,-p 将主机8080端口映射到容器5000端口
    docker run -d -p 8080:5000 --name my-flask-container my-flask-app:1.0
    
  7. 验证 :打开浏览器访问 http://localhost:8080 ,应该能看到 Flask 应用的欢迎页面。使用 docker ps 查看运行中的容器, docker logs my-flask-container 查看容器日志。

5. Kubernetes (K8S) 单机集群搭建与部署

在生产中,K8S 集群由多台机器组成。为了学习和开发,我们使用轻量级工具在单机上快速搭建一个集群。

5.1 使用 Minikube 搭建本地 K8S 集群

Minikube 是最流行的本地单节点 K8S 方案。

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

# 2. 启动集群(需要提前安装好 Docker)
minikube start --driver=docker

# 3. 验证集群状态
minikube status
kubectl get nodes # 如果 kubectl 未安装,minikube 会提示安装命令

kubectl 是操作 K8S 的命令行工具。Minikube 启动后,会自动配置 kubectl 的上下文。

5.2 将 Flask 应用部署到 K8S

现在,我们把之前容器化的 Flask 应用部署到 Minikube 集群中。

  1. 创建 Deployment :Deployment 管理 Pod(容器组)的副本和更新策略。
    # flask-deployment.yaml
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: flask-app-deployment
    spec:
      replicas: 2 # 运行2个副本(Pod)
      selector:
        matchLabels:
          app: flask-app
      template:
        metadata:
          labels:
            app: flask-app
        spec:
          containers:
          - name: flask-app
            image: my-flask-app:1.0 # 使用本地构建的镜像
            ports:
            - containerPort: 5000
            resources:
              requests:
                memory: “64Mi”
                cpu: “250m”
              limits:
                memory: “128Mi”
                cpu: “500m”
    
  2. 应用配置
    kubectl apply -f flask-deployment.yaml
    
  3. 创建 Service :Service 为 Pod 提供一个稳定的网络访问入口。
    # flask-service.yaml
    apiVersion: v1
    kind: Service
    metadata:
      name: flask-app-service
    spec:
      selector:
        app: flask-app # 选择标签为 app: flask-app 的 Pod
      ports:
        - protocol: TCP
          port: 80 # Service 对外的端口
          targetPort: 5000 # 容器内部的端口
      type: NodePort # 类型为 NodePort,会在每个节点上开放一个端口(30000-32767)
    
    kubectl apply -f flask-service.yaml
    
  4. 访问应用
    # 获取 Service 的 NodePort 端口
    kubectl get svc flask-app-service
    # 输出中会有一行类似:80:3xxxx/TCP,其中 3xxxx 就是节点端口
    
    # 获取 Minikube 节点的 IP
    minikube ip
    
    # 在浏览器中访问:http://<minikube-ip>:<node-port>
    
    你应该能看到和之前 Docker 运行时一样的页面。通过 kubectl get pods 可以看到两个 Pod 正在运行。

6. Jenkins 安装与 CI/CD 流水线配置

Jenkins 是整个自动化流程的“大脑”。我们将它安装在 Docker 中,并配置一个 Pipeline 任务,实现代码提交 -> 自动构建镜像 -> 更新 K8S 部署。

6.1 使用 Docker 运行 Jenkins

# 创建 Jenkins 数据卷,防止数据丢失
mkdir -p ~/jenkins_home
chmod 777 ~/jenkins_home # 注意权限问题,生产环境需细化权限

# 运行 Jenkins 容器
docker run -d \
  --name jenkins \
  -p 8080:8080 \
  -p 50000:50000 \
  -v ~/jenkins_home:/var/jenkins_home \
  -v /var/run/docker.sock:/var/run/docker.sock \
  -v $(which docker):/usr/bin/docker \
  jenkins/jenkins:lts-jdk17
  • -v /var/run/docker.sock:/var/run/docker.sock :这是 Docker in Docker (DinD) 的一种简便方式,让 Jenkins 容器能使用宿主机的 Docker 引擎。
  • 访问 http://localhost:8080 ,根据提示从容器日志 ( docker logs jenkins ) 中获取初始管理员密码完成安装。

6.2 安装必要插件

首次登录后,在“系统管理” -> “插件管理” -> “可选插件”中,搜索并安装以下关键插件:

  • Pipeline :支持声明式流水线。
  • Docker Pipeline :在流水线中执行 Docker 命令。
  • Kubernetes CLI :在流水线中执行 kubectl 命令。
  • Git :从 Git 仓库拉取代码。

6.3 配置 Jenkins 凭据与工具

  1. 配置 Docker Hub 凭据 (如果你有公共/私有仓库):在“凭据” -> “系统” -> “全局凭据”中,添加用户名密码类型的凭据,用于推送镜像。
  2. 配置 kubeconfig :为了让 Jenkins 能访问 Minikube 集群,需要将宿主机的 ~/.kube/config 文件内容复制到 Jenkins 的一个“Secret file”类型凭据中,或在 Jenkins 容器内安装 kubectl 并配置。

6.4 创建第一个 Pipeline 任务

  1. 在 Jenkins 首页点击“新建任务”,输入任务名(如 flask-app-pipeline ),选择“流水线”,点击确定。
  2. 在流水线配置页面的“Pipeline”区域,选择“Pipeline script”,并填入以下脚本:
    pipeline {
        agent any // 使用任意可用的代理执行器
        environment {
            // 定义环境变量
            DOCKER_IMAGE = ‘your-dockerhub-username/my-flask-app:${BUILD_NUMBER}‘
            KUBE_CONFIG = credentials(‘minikube-kubeconfig‘) // 引用凭据ID
        }
        stages {
            stage(‘Checkout‘) {
                steps {
                    // 从 Git 仓库拉取代码(此处需替换为你的仓库地址)
                    git ‘https://github.com/your-username/my-flask-app.git‘
                }
            }
            stage(‘Build Docker Image‘) {
                steps {
                    script {
                        // 使用宿主机 Docker 构建镜像
                        docker.build(DOCKER_IMAGE)
                    }
                }
            }
            stage(‘Push to Registry‘) {
                steps {
                    script {
                        // 登录 Docker Hub 并推送镜像(需配置凭据)
                        docker.withRegistry(‘https://registry.hub.docker.com‘, ‘docker-hub-credential‘) {
                            docker.image(DOCKER_IMAGE).push()
                        }
                    }
                }
            }
            stage(‘Deploy to K8S‘) {
                steps {
                    script {
                        // 将 kubeconfig 写入文件
                        writeFile file: ‘${WORKSPACE}/kubeconfig‘, text: KUBE_CONFIG
                        // 使用 kubectl 设置上下文并更新部署的镜像
                        sh “““
                            kubectl --kubeconfig=${WORKSPACE}/kubeconfig set image deployment/flask-app-deployment flask-app=${DOCKER_IMAGE} --record
                        ”““
                    }
                }
            }
        }
        post {
            always {
                // 清理工作空间
                cleanWs()
            }
        }
    }
    
  3. 点击保存。点击“立即构建”来触发流水线。在“阶段视图”中,你可以实时看到每个步骤的执行状态和日志。

7. 资源占用与性能观察

在本地运行这一整套环境,了解其资源消耗对于规划生产环境至关重要。

  • Docker Daemon :作为后台服务,常驻内存约 200-500 MB,CPU 占用很低。
  • Minikube 集群 :启动一个单节点集群(包含 API Server、etcd、Scheduler 等核心组件),会占用约 2-3 GB 内存和 1-2 个 CPU 核心。使用 minikube dashboard 命令打开仪表板可以直观查看资源使用情况。
  • Jenkins 容器 :Jenkins 本身(Java 应用)内存占用在 500 MB 到 1 GB 之间,具体取决于安装的插件数量和并发任务数。可以通过 docker stats jenkins 命令监控。
  • 应用 Pod :我们的 Flask 应用 Pod,每个副本请求 64Mi 内存,实际占用可能更低。使用 kubectl top pods 命令查看实际资源使用。
  • 磁盘空间 :Docker 镜像和容器、K8S 的 etcd 数据、Jenkins 的工作空间和构建历史会持续占用磁盘。定期清理无用镜像 ( docker image prune ) 和 Jenkins 旧构建记录是必要的。

性能优化小贴士

  1. 限制资源 :始终在 K8S 的 Deployment 中为容器设置 resources.requests resources.limits ,防止单个应用异常消耗所有资源。
  2. 使用轻量级基础镜像 :如 python:3.9-slim python:3.9 体积小很多。Alpine Linux 镜像更小,但可能遇到兼容性问题。
  3. Jenkins 代理 :对于大型项目,不要将所有构建任务都放在 Master 节点。可以配置 Kubernetes 插件,让 Jenkins 在 K8S 集群中动态创建 Pod 作为构建代理,任务完成后销毁,节省资源。

8. 常见问题与排查方法

在实践过程中,你几乎一定会遇到下面这些问题。这里提供快速的排查思路。

问题现象 可能原因 排查方式 解决方案
docker run 报错:端口被占用 主机端口已被其他进程使用。 `netstat -tulpn grep :8080 (Linux) 或 lsof -i :8080` (macOS)。
Minikube 启动失败 1. 虚拟化未开启。
2. 驱动不匹配。
3. 网络问题。
1. 检查 BIOS 虚拟化设置。
2. 查看 minikube start --driver=docker 的详细日志 ( --alsologtostderr )。
3. 检查防火墙或代理。
1. 开启 BIOS 虚拟化。
2. 尝试其他驱动,如 --driver=hyperkit (macOS)。
3. 配置正确的 HTTP/HTTPS 代理。
kubectl get pods 显示 ImagePullBackOff 1. 镜像名称错误或不存在。
2. 私有仓库无权限。
kubectl describe pod <pod-name> 查看 Events 详情。 1. 检查 Deployment YAML 中的 image 字段。
2. 为私有仓库创建 imagePullSecrets
Jenkins Pipeline 中 Docker 命令失败 Jenkins 容器内无法访问 Docker 守护进程。 在 Pipeline 的 sh 步骤中运行 docker version 测试。 确保启动 Jenkins 容器时正确挂载了 Docker Socket ( -v /var/run/docker.sock:/var/run/docker.sock )。
Jenkins 无法执行 kubectl kubectl 未安装或 kubeconfig 配置错误。 在 Jenkins 的“脚本命令行”中尝试执行 kubectl get nodes 1. 在 Jenkins 容器内安装 kubectl
2. 确保提供的 kubeconfig 文件内容正确且上下文指向目标集群。
Pipeline 推送镜像到 Docker Hub 失败 认证失败。 检查 Jenkins 中 Docker Hub 凭据的 ID 是否与 Pipeline 脚本中引用的 docker-hub-credential 一致。 在 Jenkins 凭据管理页面检查或重新配置凭据。
应用更新后,浏览器访问仍是旧版本 浏览器缓存或 K8S Service 负载均衡到旧 Pod。 1. 使用浏览器无痕模式访问。
2. kubectl get pods 查看新 Pod 是否已就绪 ( Running )。
3. kubectl describe svc 查看 Endpoints 是否指向新 Pod IP。
1. 清理浏览器缓存。
2. 等待 K8S 滚动更新完成。 Deployment 的 strategy 可控制更新速度。

9. 最佳实践与进阶方向

当你成功跑通整个流程后,以下实践能让你的项目更健壮、更接近生产标准。

  1. 基础设施即代码 (IaC) :不要手动点击 Jenkins 界面创建任务。将 Jenkins Pipeline 脚本(Jenkinsfile)存放在项目代码库根目录,在 Jenkins 中创建“流水线任务来自 SCM”的任务,实现流水线配置的版本化管理。
  2. 使用 Helm 管理 K8S 应用 :将 Deployment、Service、ConfigMap 等 YAML 文件打包成 Helm Chart。只需一个 helm install 命令即可部署整个应用,并通过 values.yaml 轻松配置不同环境(开发、测试、生产)的参数。
  3. 引入镜像仓库 :在生产中,不应直接使用 Docker Hub 的公共仓库。搭建私有镜像仓库(如 Harbor)或使用云服务商提供的仓库,并配置镜像扫描和安全策略。
  4. 完善的监控与日志 :为 K8S 集群部署 Prometheus 和 Grafana 来监控资源指标和应用性能。使用 EFK(Elasticsearch, Fluentd, Kibana)或 Loki 栈来集中收集和查询容器日志。
  5. GitOps 工作流 :考虑使用 Argo CD 或 Flux 等 GitOps 工具。将应用所需的 K8S 清单文件存储在 Git 仓库中,Argo CD 会自动同步仓库与集群的状态,实现声明式、自动化的持续部署。
  6. 安全加固
    • 容器安全 :使用非 root 用户运行容器,定期扫描镜像漏洞。
    • K8S RBAC :为 Jenkins 等服务账户配置最小必要权限,而非使用 cluster-admin
    • 网络策略 :使用 Calico 等网络插件定义 Pod 间的网络隔离策略。

这套从 Docker 到 K8S 再到 Jenkins CI/CD 的实战链路,清晰地展示了一个现代化应用从代码到上线的核心自动化流程。最大的价值不在于一次性记住所有命令,而在于理解了每个环节的职责和衔接方式。当你再次遇到“如何自动部署”这类问题时,你的思路会非常清晰:容器化 -> 编排定义 -> 自动化触发。

最先应该验证的是 Docker 部分,确保你能成功构建和运行一个自定义镜像。最容易踩的坑集中在网络和权限上,比如 Jenkins 与 Docker/K8S 的通信问题。后续的进阶,可以从优化 Pipeline 效率(并行阶段)、增加测试环节、集成代码质量扫描、实现蓝绿部署等方面深入。建议将本教程中的每个 YAML 文件和脚本都保存下来,它们是你构建更复杂流水线的最佳起点。

更多推荐