从Docker到K8S:Jenkins自动化部署实战全流程指南
你是不是经常听到 Docker、K8S、Jenkins 这些词感觉它们很重要但又觉得离自己很远或者你尝试过安装 Docker却被各种网络问题、镜像拉取失败、权限错误劝退最终停留在“Hello World”就没了下文又或者你看了很多“入门教程”却依然不知道如何把这些技术串联起来构建一个真正能用的、自动化的项目部署流程如果你有以上任何一种困惑那么这篇文章就是为你准备的。这不是一篇简单的命令罗列也不是一个“点到为止”的入门指南。我将从一个真实的、从零开始的场景出发带你完整地走通一条现代应用部署的核心路径在 Linux 服务器上用 Docker 封装你的应用用 Jenkins 搭建自动化流水线最终将应用部署到 K8S 集群中。这篇文章的核心判断是对于开发者或运维新手而言最大的障碍不是某个命令不会用而是缺乏一个完整的、可落地的“上下文”。你需要的不是孤立的“Docker安装命令”而是一个清晰的蓝图第一步做什么第二步为什么出了问题怎么查。本文将提供这个蓝图。读完本文你将能亲手完成以下事情在 CentOS 7/8 或 Ubuntu 服务器上成功安装并配置 Docker解决常见的镜像源和权限问题。编写一个简单的 Dockerfile将你的 Spring Boot 或 Python 应用打包成镜像。搭建一个 Jenkins并配置从代码拉取、构建、打包镜像到推送镜像仓库的完整 CI/CD 流水线。理解 K8S 最核心的概念Pod, Deployment, Service并编写 YAML 文件将你的应用部署到 K8S 集群。掌握整个流程中 90% 的常见错误排查方法。我们开始吧。1. 为什么是 Docker Jenkins K8S 解决的核心问题是什么在深入技术细节之前我们必须先回答一个根本问题为什么要学这一套组合拳它们各自解决了什么痛点想象一下传统的应用部署方式你需要在一台全新的服务器上安装 JDK、Tomcat、Python 环境、各种系统依赖库版本还不能错。部署过程繁琐环境差异巨大“在我机器上能跑”成了经典难题。Docker的出现首先解决了环境一致性问题。它把应用及其所有依赖代码、运行时、系统工具、库打包成一个轻量级的、可移植的“容器镜像”。这个镜像在任何安装了 Docker 的机器上运行表现都是一致的。它带来的直接价值是交付物从“代码文档”变成了“镜像”部署从“复杂的手工配置”变成了“一条运行命令”。但是每次代码更新都要手动构建镜像、上传、再部署吗这显然不高效。于是我们需要CI/CD持续集成/持续部署。Jenkins是这一领域的经典工具它像一个自动化的流水线工人。你提交代码到 GitJenkins 会自动拉取代码、运行测试、构建 Docker 镜像、推送到镜像仓库。它解决了流程自动化问题保证了软件交付的质量和频率。当你的应用从一个变成多个从一台服务器扩展到多台时如何管理这些容器的调度、网络、存储和生命周期手动操作 Docker 命令会变得极其困难。Kubernetes (K8S)就是容器编排领域的“操作系统”。它负责在集群中自动部署、扩展和管理容器化应用。它解决了大规模容器运维的复杂度问题让你可以声明式地描述“我需要 3 个应用实例并对外暴露 80 端口”K8S 会自动帮你实现。所以这条技术链的逻辑非常清晰开发 - Docker打包环境- Jenkins自动化构建- K8S自动化运维。接下来我们从最基础的 Docker 安装开始一步步构建这个链条。2. 环境准备选择你的战场在开始安装任何软件之前明确你的环境至关重要。本文将以最典型的Linux 服务器环境作为主战场因为生产环境绝大多数都运行在 Linux 上。同时也会简要说明 Windows/macOS 桌面环境Docker Desktop的差异。核心环境要求操作系统CentOS 7/8 或 Ubuntu 18.04/20.04/22.04 LTS。本文命令以 CentOS 7 为例Ubuntu 用户只需将yum替换为apt-get即可。用户权限你需要拥有sudo权限或直接是root用户。网络服务器需要能访问互联网以下载安装包和 Docker 镜像。对于国内环境配置镜像加速器是必须步骤。硬件至少 1GB 可用内存2GB 以上更佳。K8S 部分如果使用 Minikube 或 Kind 在单机学习需要更多资源。关于 Windows/macOS 上的 Docker Desktop对于本地开发和学习Docker Desktop 是极佳的选择。它提供了一个集成的环境。但请注意它本质上是在你的系统上创建了一个 Linux 虚拟机来运行 Docker 引擎。部分涉及 Linux 系统底层操作如修改daemon.json的路径和方式略有不同。本文的重点是面向生产环境的 Linux 服务器部署因此主要讲解 Linux 下的安装和配置。Docker Desktop 用户可以参考思路但具体路径请查阅官方文档。现在请登录你的 Linux 服务器我们开始安装 Docker。3. Docker 安装与“避坑”指南网上有很多 Docker 安装教程但很多人卡在安装后的第一步。我们不仅要安装还要一次性配置好避免后续的常见坑点。3.1 卸载旧版本如果是全新安装可跳过如果你的系统之前安装过 Docker建议先清理干净避免冲突。sudo yum remove docker \ docker-client \ docker-client-latest \ docker-common \ docker-latest \ docker-latest-logrotate \ docker-logrotate \ docker-engine3.2 安装必要的依赖和设置仓库# 安装 yum-utils它提供了 yum-config-manager 工具 sudo yum install -y yum-utils # 设置稳定的 Docker 仓库使用阿里云镜像加速下载安装包本身 sudo yum-config-manager \ --add-repo \ http://mirrors.aliyun.com/docker-ce/linux/centos/docker-ce.repo关键点这里使用的是阿里云的仓库镜像能显著加快安装包的下载速度。如果你在国外可以使用官方仓库https://download.docker.com/linux/centos/docker-ce.repo。3.3 安装 Docker 引擎# 安装最新版本的 Docker Engine、containerd 和 Docker Compose sudo yum install -y docker-ce docker-ce-cli containerd.io docker-compose-plugindocker-compose-plugin是新的 Docker Compose V2它集成在 Docker CLI 中通过docker compose命令使用比独立的docker-compose工具更好。3.4 启动 Docker 并设置开机自启# 启动 Docker 服务 sudo systemctl start docker # 设置 Docker 服务开机自启 sudo systemctl enable docker # 验证 Docker 是否安装成功 sudo docker run hello-world如果看到 “Hello from Docker!” 等信息说明 Docker 已经安装并运行成功。3.5 配置镜像加速器解决拉取镜像慢的问题这是新手最容易忽略也最影响体验的一步。Docker 官方镜像仓库在国外拉取镜像速度极慢甚至失败。必须配置国内镜像加速器。创建或修改 Docker 守护进程配置文件sudo tee /etc/docker/daemon.json -EOF { registry-mirrors: [ https://registry.docker-cn.com, https://hub-mirror.c.163.com, https://mirror.baidubce.com ] } EOF这里配置了三个常用的国内镜像源Docker 会按顺序尝试。重新加载配置并重启 Docker 服务sudo systemctl daemon-reload sudo systemctl restart docker验证加速器是否生效sudo docker info在输出信息中你应该能看到Registry Mirrors下列出了你刚才配置的镜像地址。3.6 将当前用户加入 Docker 组解决每次都要 sudo 的问题默认情况下执行docker命令需要sudo权限。为了方便可以将你的用户加入docker组。# 将当前登录用户加入 docker 组 sudo usermod -aG docker $USER # 退出当前终端并重新登录或者执行以下命令使组更改生效 newgrp docker # 验证无需 sudo 即可运行 docker 命令 docker ps现在你应该可以直接使用docker命令了。4. Docker 核心实战将你的应用打包成镜像安装好 Docker 只是第一步真正的价值在于“用”。我们来把一个简单的 Web 应用打包成 Docker 镜像。4.1 示例应用一个简单的 Python Flask 应用假设我们有一个最简单的 Flask 应用。在你的工作目录创建以下文件文件结构my-flask-app/ ├── app.py ├── requirements.txt └── Dockerfileapp.py内容from flask import Flask app Flask(__name__) app.route(/) def hello(): return Hello, Dockerized World! if __name__ __main__: app.run(host0.0.0.0, port5000)requirements.txt内容Flask2.3.24.2 编写 Dockerfile构建指令蓝图Dockerfile是构建镜像的配方。它是 Docker 学习的核心。Dockerfile内容# 第一阶段使用官方 Python 轻量级镜像作为基础 FROM python:3.9-slim # 设置工作目录后续命令都在此目录下执行 WORKDIR /app # 将依赖文件复制到工作目录 COPY requirements.txt . # 安装 Python 依赖使用国内 PyPI 镜像加速 RUN pip install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple # 将应用代码复制到工作目录 COPY . . # 声明容器运行时监听的端口 EXPOSE 5000 # 定义容器启动时执行的命令 CMD [python, app.py]关键点解释FROM指定基础镜像。-slim版本比完整版更小。WORKDIR相当于cd到/app目录。COPY将宿主机文件复制到镜像内。RUN在构建镜像时执行的命令这里用于安装依赖。我们使用了清华大学的 PyPI 镜像加速。EXPOSE声明端口这是一个文档性质的元数据实际映射需要在docker run时指定。CMD容器启动时执行的命令一个 Dockerfile 中只能有一个CMD。4.3 构建镜像并运行容器构建镜像在my-flask-app目录下执行。docker build -t my-flask-app:latest .-t参数给镜像打标签.表示使用当前目录的 Dockerfile。运行容器docker run -d -p 8080:5000 --name my-flask-container my-flask-app:latest-d后台运行。-p 8080:5000将宿主机的 8080 端口映射到容器的 5000 端口。--name给容器起个名字。验证应用打开浏览器访问http://你的服务器IP:8080应该看到 “Hello, Dockerized World!”。或者使用curl命令curl http://localhost:8080。查看容器日志docker logs my-flask-container进入容器内部用于调试docker exec -it my-flask-container /bin/bash执行后你就进入了容器的 Linux 环境可以查看文件、进程等。至此你已经完成了 Docker 的核心操作构建镜像和运行容器。接下来我们需要一个自动化工具来替我们执行这些重复的构建和推送命令。5. Jenkins 安装与 CI/CD 流水线搭建Jenkins 是一个开源的自动化服务器它的强大之处在于其插件生态系统和灵活的流水线Pipeline定义方式。5.1 使用 Docker 安装 Jenkins推荐方式既然我们已经会了 Docker为什么不直接用 Docker 来安装 Jenkins呢这能避免复杂的本地环境依赖。# 创建一个目录用于持久化 Jenkins 数据 sudo mkdir -p /var/jenkins_home sudo chown -R 1000:1000 /var/jenkins_home # Jenkins 容器内用户 UID 是 1000 # 运行 Jenkins 容器 docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /var/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ jenkins/jenkins:lts-jdk11参数解释-p 8080:8080Web 界面端口。-p 50000:50000代理通信端口。-v /var/jenkins_home:/var/jenkins_home将 Jenkins 数据卷挂载到宿主机防止容器删除后数据丢失。-v /var/run/docker.sock:/var/run/docker.sock和-v /usr/bin/docker:/usr/bin/docker这是关键这允许 Jenkins 容器直接调用宿主机的 Docker 引擎从而在 Jenkins 任务中执行docker build和docker push命令。这被称为Docker-out-of-Docker (DooD)模式。5.2 初始化 Jenkins访问http://你的服务器IP:8080。首次启动需要解锁。查看初始管理员密码docker logs jenkins在日志中找到类似Jenkins initial setup is required. Your password is: xxxxxxxxx的信息。输入密码选择“安装推荐的插件”。等待插件安装完成。创建第一个管理员用户。5.3 安装必要插件进入 Jenkins 后需要安装一些核心插件来支持我们的流水线Pipeline定义流水线的核心插件。Docker Pipeline在流水线中支持 Docker 相关步骤。Git从 Git 仓库拉取代码。Blue Ocean可选提供更直观的流水线可视化界面。安装路径Manage Jenkins-Manage Plugins-Available标签页搜索安装。5.4 配置 Docker 凭证和 Git 凭证为了让 Jenkins 能推送镜像到私有仓库如 Docker Hub、阿里云容器镜像服务和拉取代码需要配置凭证。Docker Hub 凭证以 Docker Hub 为例Manage Jenkins-Manage Credentials-(global)-Add Credentials。类型选择Username with password。输入你的 Docker Hub 用户名和密码。ID 可以设为docker-hub-cred方便在流水线中引用。Git 凭证如果你的仓库是私有的类似地添加一个Username with password或SSH Username with private key类型的凭证用于访问你的 Git 仓库如 GitHub, GitLab, Gitee。5.5 创建一个 Pipeline 任务点击新建 Item输入任务名如my-flask-app-pipeline选择Pipeline点击OK。在配置页面的Pipeline部分选择Pipeline script from SCM。SCM 选择Git填入你的 Git 仓库 URL例如https://github.com/yourname/my-flask-app.git并选择对应的凭证。指定分支例如*/main。脚本路径填写Jenkinsfile。这意味着 Jenkins 会从你仓库根目录的Jenkinsfile文件中读取流水线定义。5.6 编写 Jenkinsfile定义自动化流水线Jenkinsfile是流水线的核心它使用 Groovy 语法定义了一系列阶段Stage。在你的 Git 仓库根目录创建这个文件。Jenkinsfile内容pipeline { agent any // 在任何可用的代理上执行 environment { // 定义环境变量 DOCKER_IMAGE your-dockerhub-username/my-flask-app DOCKER_TAG build-${BUILD_NUMBER} REGISTRY_CREDENTIALS docker-hub-cred // 对应之前创建的凭证ID } stages { stage(Checkout) { steps { // 从 Git 拉取代码 checkout scm } } stage(Build Docker Image) { steps { script { // 使用宿主机 Docker 构建镜像 docker.build(${DOCKER_IMAGE}:${DOCKER_TAG}) } } } stage(Push Docker Image) { steps { script { // 登录 Docker Hub 并推送镜像 docker.withRegistry(https://registry.hub.docker.com, REGISTRY_CREDENTIALS) { docker.image(${DOCKER_IMAGE}:${DOCKER_TAG}).push() // 同时推送一个 latest 标签 docker.image(${DOCKER_IMAGE}:${DOCKER_TAG}).push(latest) } } } } // 你可以在这里添加更多阶段例如运行测试、部署到 K8S 等 stage(Deploy to K8S) { steps { script { // 这里假设你已经在 Jenkins 代理上配置了 kubectl 并连接到了 K8S 集群 // 实际部署步骤需要根据你的 K8S YAML 文件来定 sh kubectl apply -f k8s-deployment.yaml } } } } post { always { // 无论成功失败都执行的步骤例如清理工作空间 echo Pipeline finished. cleanWs() } success { echo Pipeline succeeded! } failure { echo Pipeline failed! } } }这个流水线定义了四个阶段Checkout拉取代码。Build Docker Image使用docker.build命令构建镜像。Push Docker Image登录 Docker Hub 并推送镜像。Deploy to K8S执行kubectl apply命令部署到 Kubernetes 集群需要提前配置好kubectl。现在当你向 Git 仓库推送代码时Jenkins 会自动触发这个流水线完成镜像的构建和推送。自动化构建的基石已经打下。接下来我们看如何用 K8S 来管理这个镜像的运行。6. Kubernetes (K8S) 入门与实战部署K8S 概念很多但对于入门我们只需要理解三个最核心的资源对象Pod、Deployment、Service。PodK8S 中最小的部署单元。一个 Pod 可以包含一个或多个容器通常是一个。我们的 Flask 应用容器就跑在 Pod 里。Deployment定义 Pod 的期望状态。例如“我需要运行 3 个完全相同的 Flask 应用 Pod”。Deployment 会确保始终有指定数量的 Pod 副本在运行自我修复并支持滚动更新。Service为一组 Pod 提供一个稳定的网络访问入口。Pod 是动态创建销毁的IP 会变。Service 提供一个固定的 IP 或 DNS 名并将流量负载均衡到后端的 Pod。6.1 搭建一个本地 K8S 学习环境Minikube在生产环境K8S 集群通常由多台服务器组成。对于学习和测试我们使用Minikube它可以在单机上快速创建一个单节点的 K8S 集群。在 Linux 上安装 Minikube# 下载 Minikube 二进制文件 curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 # 安装 Minikube sudo install minikube-linux-amd64 /usr/local/bin/minikube # 启动 Minikube 集群需要虚拟机驱动如 VirtualBox 或 KVM2 # 这里使用 docker 驱动需要先安装 Docker它利用宿主机的 Docker 环境更轻量 minikube start --driverdocker # 验证集群状态 minikube status kubectl get nodes # 应该能看到一个名为 minikube 的节点kubectl是 K8S 的命令行工具Minikube 会自动为你配置好。6.2 编写 K8S 部署文件现在我们编写一个 YAML 文件告诉 K8S 如何运行我们之前构建的 Flask 应用镜像。k8s-deployment.yaml内容apiVersion: apps/v1 kind: Deployment metadata: name: my-flask-app-deployment spec: replicas: 3 # 指定需要运行 3 个 Pod 副本 selector: matchLabels: app: my-flask-app template: metadata: labels: app: my-flask-app # 这个标签必须和上面的 selector 匹配 spec: containers: - name: my-flask-app image: your-dockerhub-username/my-flask-app:latest # 替换为你的镜像名 ports: - containerPort: 5000 # 容器监听的端口 resources: requests: memory: 128Mi cpu: 100m limits: memory: 256Mi cpu: 200m --- apiVersion: v1 kind: Service metadata: name: my-flask-app-service spec: selector: app: my-flask-app # 选择所有带有 appmy-flask-app 标签的 Pod ports: - protocol: TCP port: 80 # Service 对外的端口 targetPort: 5000 # 转发到 Pod 的哪个端口 type: LoadBalancer # 在云环境下这会创建一个外部负载均衡器。Minikube 中可以用 minikube service 命令访问。这个文件定义了两部分一个 Deployment确保始终有 3 个my-flask-appPod 在运行使用的镜像是我们推送到 Docker Hub 的镜像。一个 Service类型为LoadBalancer将外部对 Service 80 端口的访问负载均衡到后端 3 个 Pod 的 5000 端口。6.3 部署应用到 K8S 集群应用配置kubectl apply -f k8s-deployment.yaml输出deployment.apps/my-flask-app-deployment created和service/my-flask-app-service created。查看部署状态# 查看 Deployment 状态 kubectl get deployments # 查看 Pod 状态等待所有 Pod 变为 Running kubectl get pods # 查看 Service 状态 kubectl get svc访问应用 在 Minikube 中LoadBalancer类型的 Service 不会获得外部 IP但可以通过 Minikube 的特殊命令访问minikube service my-flask-app-service这个命令会打开浏览器访问到你的 Flask 应用。恭喜你已经成功地将一个应用通过 Docker 容器化用 Jenkins 实现了自动化构建和推送并最终部署到了 Kubernetes 集群中。这就是一个最基础的现代应用交付流水线。7. 全链路实战将 Jenkins 流水线与 K8S 部署对接在第 5 章的 Jenkinsfile 中我们预留了一个Deploy to K8S的阶段。现在我们来完善它让 Jenkins 在构建推送镜像后自动更新 K8S 集群中的部署。这需要解决一个问题Jenkins 如何执行kubectl命令我们需要在运行 Jenkins 的服务器或 Jenkins 的构建代理上安装和配置kubectl并使其能够访问你的 K8S 集群。7.1 在 Jenkins 服务器上配置 kubectl假设你的 Jenkins 以 Docker 容器形式运行在宿主机host-machine上。在宿主机安装 kubectl# 在 host-machine 上执行 curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl sudo install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl获取 K8S 集群配置 如果你用的是 Minikube配置通常位于~/.kube/config。我们需要将这个配置文件传递给 Jenkins 容器。# 在 host-machine 上查看 kubeconfig 路径 kubectl config view --minify --flatten更简单的方式是将宿主机的~/.kube目录挂载到 Jenkins 容器内。重新运行 Jenkins 容器挂载 kubeconfig 首先停止并删除旧的 Jenkins 容器docker stop jenkins docker rm jenkins然后重新运行增加一个卷挂载docker run -d \ --name jenkins \ -p 8080:8080 \ -p 50000:50000 \ -v /var/jenkins_home:/var/jenkins_home \ -v /var/run/docker.sock:/var/run/docker.sock \ -v /usr/bin/docker:/usr/bin/docker \ -v $HOME/.kube:/var/jenkins_home/.kube \ # 挂载 kubeconfig -v $HOME/.minikube:/var/jenkins_home/.minikube \ # 挂载 Minikube 证书如果需要 jenkins/jenkins:lts-jdk11这样Jenkins 容器内的kubectl命令需要安装就能使用宿主的集群配置了。在 Jenkins 容器内安装 kubectl 进入 Jenkins 容器安装docker exec -it jenkins /bin/bash # 在容器内执行 curl -LO https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl exit7.2 修改 Jenkinsfile 实现自动部署现在我们可以完善 Jenkinsfile 中的部署阶段。一个常见的策略是使用kubectl set image命令来更新 Deployment 中的镜像版本触发滚动更新。更新后的Jenkinsfile(Deploy 阶段):stage(Deploy to K8S) { steps { script { // 确保 kubectl 可用 sh kubectl version --client // 更新 Deployment 中的镜像触发滚动更新 sh kubectl set image deployment/my-flask-app-deployment \ my-flask-app${DOCKER_IMAGE}:${DOCKER_TAG} \ --record // 等待滚动更新完成 sh kubectl rollout status deployment/my-flask-app-deployment } } }这个阶段做了两件事kubectl set image将名为my-flask-app-deployment的 Deployment 中名为my-flask-app的容器镜像更新为我们刚刚构建的新镜像标签。kubectl rollout status等待这次更新完成确保新的 Pod 全部就绪旧的 Pod 被优雅终止。现在你的完整 CI/CD 流水线已经打通代码提交 - Jenkins 自动构建镜像 - 推送镜像仓库 - 自动更新 K8S 集群中的应用。8. 常见问题与排查思路FAQ在这一路上你几乎一定会遇到各种问题。这里列出最常见的一些及其解决方法。问题现象可能原因排查方式解决方案docker pull或docker build速度极慢或失败1. 未配置国内镜像加速器。2. 网络防火墙限制。1. 运行docker info查看Registry Mirrors。2. 尝试ping registry.hub.docker.com。1. 按本文 3.5 节配置/etc/docker/daemon.json。2. 检查服务器网络出口。docker: permission denied当前用户不在docker组。运行groups查看当前用户所属组。执行sudo usermod -aG docker $USER并重新登录。Jenkins 流水线中docker命令找不到Jenkins 容器内没有 Docker 客户端或挂载路径不对。在 Jenkins 流水线脚本中增加sh which docker或sh docker version检查。确保运行 Jenkins 容器时正确挂载了/usr/bin/docker和/var/run/docker.sock。Jenkins 推送镜像到仓库失败1. 凭证配置错误或 ID 不对。2. 镜像标签格式错误。1. 检查 Jenkins 凭证配置。2. 查看 Jenkins 构建日志中的详细错误。1. 确认凭证 ID 在Jenkinsfile的environment中引用正确。2. 确保镜像名符合仓库规范如 Docker Hub 为username/reponame。kubectl apply失败提示连接拒绝1.kubectl未安装或不在 PATH。2. K8S 集群未启动或配置错误。1. 执行kubectl cluster-info。2. 检查~/.kube/config文件内容。1. 安装kubectl。2. 启动 Minikubeminikube start。3. 确保 kubeconfig 正确挂载到 Jenkins 容器。K8S Pod 状态一直是Pending或CrashLoopBackOff1. 资源不足CPU/内存。2. 镜像拉取失败。3. 应用启动失败。1.kubectl describe pod pod-name查看事件。2.kubectl logs pod-name查看容器日志。1. 检查 Deployment 中资源请求/限制是否合理。2. 检查镜像名和标签是否正确网络是否通畅。3. 根据应用日志修复代码或配置。Service 无法访问1. Service 的selector与 Pod 的label不匹配。2.targetPort与容器端口不对应。3. Minikube 中未使用minikube service命令。1.kubectl describe svc service-name。2.kubectl get pods --show-labels。1. 确保 Service 的selector.app与 Pod 模板的labels.app完全一致。2. 确认containerPort和targetPort一致。3. 在 Minikube 中必须用minikube service命令访问LoadBalancer类型的 Service。9. 最佳实践与进阶建议当你跑通整个流程后以下建议可以帮助你将这个简单的流水线变得更健壮、更适用于生产环境。使用私有镜像仓库不要将生产镜像推送到 Docker Hub 等公共仓库。搭建或使用私有仓库如 Harbor、阿里云容器镜像服务 ACR、腾讯云 TCR 等。在 Jenkins 和 K8S 中配置相应的镜像拉取密钥imagePullSecrets。为镜像使用有意义的标签不要总是用latest。使用git commit hash、构建编号、版本号等作为标签便于追踪和回滚。例如myapp:${BUILD_NUMBER}-${GIT_COMMIT_SHORT}。在 Jenkins 流水线中加入测试阶段在构建镜像之前或之后加入单元测试、集成测试、代码质量扫描等阶段。只有测试通过才进入构建和部署阶段。使用 ConfigMap 和 Secret 管理配置不要将配置文件如数据库连接字符串硬编码在镜像或代码中。使用 K8S 的 ConfigMap 和 Secret 来管理配置并通过环境变量或卷挂载注入到容器中。定义资源请求和限制如本文示例所示在 Deployment 中为容器定义resources.requests和resources.limits。这有助于 K8S 调度器做出更好的决策并防止单个容器耗尽节点资源。实现健康检查在 Deployment 中配置livenessProbe和readinessProbe。前者告诉 K8S 何时重启容器后者告诉 K8S 何时可以将流量导入 Pod。这对于应用的高可用至关重要。考虑使用 Helm 或 Kustomize当你的 K8S 部署文件YAML越来越多、越来越复杂时手动管理会很困难。Helm 是 K8S 的包管理工具Kustomize 是原生配置管理工具它们都能帮助你更好地组织和管理部署清单。保护你的流水线Jenkins 凭证、K8S kubeconfig 都是敏感信息。确保 Jenkins 和集群的访问权限得到严格控制。考虑使用 Jenkins 的 “Pipeline Libraries” 或 “Shared Libraries” 来复用安全的部署逻辑。从 Docker 到 Jenkins 再到 K8S这条路径是现代云原生应用交付的基石。它看似复杂但拆解开来每一步都有其明确的目的和清晰的实践方法。本文带你走完了从零到一的全过程但每个环节都还有巨大的深度可以挖掘例如 Docker 镜像的优化、Jenkins 流水线的并行化与分布式构建、K8S 的监控与自动扩缩容等。建议你以本文为地图将每个环节都亲手实践一遍。遇到问题时善用docker logs、kubectl describe、kubectl logs和 Jenkins 控制台输出进行排查。真正的精通来自于在解决一个又一个具体问题的过程中积累的经验。现在你已经拥有了开始这段旅程的钥匙。