从Docker到K8S:新手避坑指南与实战入门

发布时间:2026/7/7 22:55:13
从Docker到K8S:新手避坑指南与实战入门 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度这类教程最值得先看的不是它覆盖了多少知识点而是能不能帮你把 Docker 和 Kubernetes 从“知道名字”变成“能在自己机器上跑起来、能处理实际问题”。很多人学容器和 K8S 卡在第一步环境装不上、概念太抽象、命令敲了没反应。这个教程的价值在于它试图用一套连贯的流程把安装、基础命令、核心概念和简单实战串起来目标是让你看完能自己搭出一个可用的最小环境。但这类“速通”教程也有个通病容易讲成命令罗列你跟着敲完了还是不知道为什么要这么做遇到自己项目里的配置文件、网络问题、存储挂载照样不会。所以我更建议把学习过程拆成三步先确保本地或虚拟机环境能稳定运行 Docker再用 Docker 理解容器的基础操作和镜像构建最后用 Minikube 或 K3s 这类轻量工具上手 K8S 的核心对象和调度。下面我会按这个实际落地的顺序把每个环节的关键操作、参数含义和最容易踩的坑点拆解一遍。1. 先别急着看 K8S从 Docker 环境准备和最小验证开始很多人一上来就被 Pod、Service、Deployment 这些概念绕晕了。其实 K8S 管理的是容器而容器最直接的体验来自 Docker。所以第一步不是安装 K8S而是先确保你的 Docker 能正常工作。1.1 环境选择与基础安装虚拟机还是云主机你可以在 Windows、macOS 或 Linux 上安装 Docker Desktop。但对于学习尤其是后续要接触 K8S 网络和存储我强烈建议使用一台 Linux 虚拟机。原因有两个一是 Linux 是 Docker 和 K8S 的原生运行环境兼容性问题最少二是很多生产环境也是 Linux提前熟悉命令行操作没坏处。方案一推荐本地虚拟机。使用 VirtualBox 或 VMware安装一个 Ubuntu 22.04 LTS 或 CentOS 7/8 Stream。分配至少 2 核 CPU、4GB 内存和 20GB 磁盘空间。这个配置足够同时运行 Docker 和一个轻量级 K8S如 Minikube。方案二云服务器。在主流云服务商购买一台最低配置的按量计费云服务器通常被称为“ECS”或“CVM”选择 Ubuntu 或 CentOS 镜像。好处是网络环境干净且能模拟公网访问场景。安装 Docker 本身很简单以 Ubuntu 为例官方的一键安装脚本通常可靠# 更新软件包索引 sudo apt-get update # 安装必要工具 sudo apt-get install ca-certificates curl # 添加 Docker 官方 GPG 密钥 sudo install -m 0755 -d /etc/apt/keyrings sudo curl -fsSL https://download.docker.com/linux/ubuntu/gpg -o /etc/apt/keyrings/docker.asc sudo chmod ar /etc/apt/keyrings/docker.asc # 设置仓库 echo \ deb [arch$(dpkg --print-architecture) signed-by/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/ubuntu \ $(. /etc/os-release echo $VERSION_CODENAME) stable | \ sudo tee /etc/apt/sources.list.d/docker.list /dev/null sudo apt-get update # 安装 Docker 引擎 sudo apt-get install docker-ce docker-ce-cli containerd.io docker-buildx-plugin docker-compose-plugin安装后最关键的一步是将当前用户加入docker组避免每次命令都要加sudosudo usermod -aG docker $USER执行后你需要退出当前终端并重新登录这个改动才会生效。这是第一个常见坑点很多人加了组就直接运行docker ps发现还是权限错误。1.2 验证安装与理解 Docker 守护进程环境装好不要马上拉镜像跑容器。先做几个基础验证理解 Docker 的组件。检查 Docker 服务状态sudo systemctl status docker你应该看到active (running)。如果没启动用sudo systemctl start docker启动它并用sudo systemctl enable docker设置开机自启。运行经典测试容器docker run hello-world这个命令会做几件事从 Docker Hub 拉取hello-world镜像如果本地没有创建一个容器执行容器内的程序打印一段欢迎信息然后容器退出。如果能看到成功输出的信息说明 Docker 引擎、镜像拉取和容器运行都正常。理解docker ps的输出docker ps -a-a参数会显示所有容器包括已退出的。你会看到刚才运行的hello-world容器状态是Exited。这里要理解几个关键字段CONTAINER ID: 容器的唯一标识。IMAGE: 创建容器所用的镜像。COMMAND: 容器启动时运行的命令。STATUS: 容器的状态Up、Exited。PORTS: 容器映射到主机的端口。NAMES: 容器的名称可自定义。这个阶段的目标是确保 Docker 服务在运行能拉取镜像能创建和运行容器并且你能看懂基础命令的输出。如果hello-world都跑不起来问题通常出在网络拉取镜像失败、权限用户不在 docker 组或服务状态上。2. 用 Docker 理解镜像、容器和基础操作能跑通hello-world只是开始。接下来要通过一个更实际的例子理解镜像和容器的关系以及如何管理它们。2.1 从拉取镜像到运行一个持久化服务我们用一个最常用的镜像nginx来演示。拉取镜像docker pull nginx:latest这里nginx是镜像名latest是标签Tag代表最新稳定版。生产环境通常使用具体版本号如nginx:1.24以避免因镜像更新引入意外变更。以后台模式运行一个 Nginx 容器docker run -d --name my-nginx -p 8080:80 nginx-d: 后台运行detached mode。--name my-nginx: 给容器起个名字方便后续管理。-p 8080:80: 端口映射将主机的 8080 端口映射到容器的 80 端口Nginx 默认监听端口。nginx: 使用的镜像。验证服务 在主机上打开浏览器访问http://localhost:8080如果主机是本地虚拟机或http://你的服务器IP:8080如果是云服务器。你应该能看到 Nginx 的欢迎页面。 同时用docker ps可以看到一个状态为Up的容器。查看容器日志docker logs my-nginx这会输出容器内 Nginx 服务的访问日志和错误日志。这是排查容器内应用问题的第一个入口。2.2 进入容器、修改内容与理解容器隔离性容器是隔离的环境。怎么查看和修改里面的东西进入运行中的容器docker exec -it my-nginx /bin/bashexec: 在已运行的容器中执行命令。-it: 分配一个交互式终端-i -t。/bin/bash: 要执行的命令即启动一个 Bash shell。 进入后你可以像操作一台独立 Linux 主机一样使用ls,cat,apt-get update等命令。试试cat /etc/nginx/nginx.conf查看 Nginx 配置。理解容器内修改的临时性 在容器内执行echo Hello from container /usr/share/nginx/html/test.txt然后在主机浏览器访问http://localhost:8080/test.txt能看到你写的文字。 但是如果你现在停止并删除这个容器docker stop my-nginx docker rm my-nginx然后重新用docker run -d --name new-nginx -p 8080:80 nginx启动一个新容器再去访问/test.txt会发现文件不见了。这说明对容器内文件系统的修改默认只存在于该容器的生命周期内容器删除修改即丢失。使用数据卷Volume持久化数据 为了解决上述问题需要把容器内需要持久化的目录如 Nginx 的 HTML 目录/usr/share/nginx/html挂载到主机的一个目录上。# 先在主机创建一个目录 mkdir -p ~/nginx-html # 运行容器并挂载数据卷 docker run -d --name nginx-with-volume -p 8081:80 -v ~/nginx-html:/usr/share/nginx/html nginx-v ~/nginx-html:/usr/share/nginx/html: 将主机的~/nginx-html目录挂载到容器的/usr/share/nginx/html。 现在你在主机~/nginx-html目录下放一个index.html文件刷新浏览器就能看到变化。即使删除容器主机上的文件依然存在重新挂载即可。这个阶段的目标是理解docker pull/run/ps/logs/exec/stop/rm这一套基础命令链明白镜像只读模板和容器运行时实例的区别并初步接触端口映射 (-p) 和数据持久化 (-v) 这两个核心概念。这是后续理解 K8S 中 Service 和 PersistentVolume 的基础。3. 构建自定义镜像与编写 Dockerfile只会用现成镜像不够你需要知道如何把自己的应用打包成镜像。这就要用到 Dockerfile。3.1 编写第一个 Dockerfile假设你有一个简单的 Python Web 应用文件结构如下my-python-app/ ├── app.py ├── requirements.txt └── Dockerfileapp.py内容from flask import Flask app Flask(__name__) app.route(/) def hello(): return Hello from my custom Docker image! if __name__ __main__: app.run(host0.0.0.0, port5000)requirements.txt内容flask2.3.3Dockerfile内容# 第一阶段使用官方 Python 轻量级镜像作为基础 FROM python:3.11-slim # 设置工作目录后续命令都在此目录下执行 WORKDIR /app # 将依赖文件复制到工作目录 COPY requirements.txt . # 安装 Python 依赖使用清华镜像源加速国内环境 RUN pip install --no-cache-dir -i https://pypi.tuna.tsinghua.edu.cn/simple -r requirements.txt # 将当前目录所有文件复制到工作目录 COPY . . # 声明容器运行时监听的端口 EXPOSE 5000 # 定义容器启动时执行的命令 CMD [python, app.py]3.2 构建镜像并运行在my-python-app目录下执行docker build -t my-python-app:1.0 .-t my-python-app:1.0: 为镜像打上标签名称:版本。.: 构建上下文路径Docker 会把当前目录下的文件发送给 Docker 守护进程。构建成功后运行容器docker run -d --name my-app -p 5000:5000 my-python-app:1.0访问http://localhost:5000你应该能看到自定义的问候语。3.3 Dockerfile 关键指令与最佳实践FROM: 必须且是第一条指令。选择合适的基础镜像如alpine,slim版本可以减小镜像体积。WORKDIR: 设置工作目录代替RUN cd ... ...这种复杂命令。COPYvsADD: 优先使用COPY它更透明。ADD有自动解压等额外功能但行为不够清晰。RUN: 执行命令并创建新的镜像层。合并多个RUN指令可以减少镜像层数例如RUN apt-get update apt-get install -y package1 package2 rm -rf /var/lib/apt/lists/*。EXPOSE: 声明端口是一种文档形式。实际映射端口仍需在docker run时用-p指定。CMD: 指定容器启动时的默认命令。一个 Dockerfile 只能有一个CMD。通常格式是CMD [executable, param1, param2]exec 格式。这个阶段的目标是能将自己的简单应用通过 Dockerfile 打包成镜像理解镜像分层构建的概念并掌握编写高效 Dockerfile 的几个基本原则。这是实现 CI/CD 和部署到 K8S 的前提。4. 从单机 Docker 到 Kubernetes 初体验理解了 Docker 之后K8S 就不再是空中楼阁。它要解决的核心问题是当你有成百上千个容器需要跨多台机器部署、管理、扩缩容和保持高可用时该怎么办4.1 选择本地 K8S 环境Minikube 还是 K3s对于学习和开发不建议直接在生产 K8S 集群上操作。本地轻量级方案是首选。Minikube: 官方维护的单节点 K8S 工具。它在你的机器上创建一个虚拟机并在里面运行一个单节点的 K8S 集群。功能完整最适合学习核心概念。K3s: Rancher 发布的轻量级 K8S易于安装资源占用更少甚至可以在树莓派上运行。它更适合边缘计算或资源受限的环境。对于初学者我推荐Minikube因为它最贴近标准 K8S 的体验且文档和社区支持最好。4.2 安装并启动 Minikube在已经安装好 Docker 的 Linux 虚拟机或 macOS/Windows 上安装 Minikube。安装 Minikube 二进制文件以 Linux 为例curl -LO https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64 sudo install minikube-linux-amd64 /usr/local/bin/minikube启动 Minikube 集群minikube start --driverdocker--driverdocker: 指定使用 Docker 作为底层容器运行时。Minikube 会在 Docker 内部再启动一个运行 K8S 组件的容器。 首次启动会下载基础镜像需要一些时间。成功后你会看到类似Done! kubectl is now configured to use minikube cluster的提示。配置 kubectlkubectl是管理 K8S 集群的命令行工具。Minikube 会自动为你配置好。验证一下kubectl cluster-info kubectl get nodes你应该能看到一个名为minikube的节点状态为Ready。4.3 部署第一个应用理解 Pod 和 Deployment在 K8S 中最小的部署单元不是容器而是Pod。一个 Pod 可以包含一个或多个紧密关联的容器。但通常我们不会直接创建 Pod而是通过Deployment来管理 Pod 的副本和生命周期。创建一个 Deployment 配置文件my-nginx-deployment.yamlapiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx spec: replicas: 2 # 指定 Pod 副本数为 2 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: nginx:1.24 ports: - containerPort: 80应用这个配置kubectl apply -f my-nginx-deployment.yaml查看部署状态kubectl get deployments kubectl get pods你会看到nginx-deployment创建了 2 个 Pod。kubectl get pods的输出中READY列显示1/1STATUS为Running时表示 Pod 已就绪。暴露服务创建 Service。 Pod 的 IP 是临时的且外部无法直接访问。需要通过Service来提供稳定的访问入口。 创建my-nginx-service.yamlapiVersion: v1 kind: Service metadata: name: nginx-service spec: selector: app: nginx # 这个选择器必须匹配 Deployment 中 Pod 的标签 ports: - protocol: TCP port: 80 # Service 对外暴露的端口 targetPort: 80 # 容器内监听的端口 type: NodePort # 类型为 NodePort会在集群每个节点上开放一个端口范围 30000-32767应用配置kubectl apply -f my-nginx-service.yaml。访问应用 获取 Service 的 NodePortkubectl get service nginx-service在输出中找到PORT(S)列例如80:30678/TCP其中30678就是 NodePort。 由于我们使用 Minikube可以通过以下命令快速获取访问 URLminikube service nginx-service --url它会返回一个类似http://192.168.49.2:30678的地址在浏览器中打开即可访问 Nginx。这个阶段的目标是在本地成功启动一个 K8S 集群Minikube使用kubectl命令与集群交互并通过 YAML 文件定义并部署一个最简单的多副本应用Deployment最后通过 Service 将其暴露给外部访问。理解Deployment - Pod - Container的层次关系以及Service通过标签选择器 (selector) 关联 Pod 的机制是 K8S 入门的核心。5. 深入 K8S 核心概念与日常操作掌握了基本部署流程后需要深入理解几个关键对象和它们的日常操作。5.1 核心对象关系图概念层面Deployment (定义Pod模板和副本数) | v Pod (一个或多个容器) --- 被 Service 通过 Label Selector 选中 | v Container(s) (运行你的应用)ConfigMap Secret: 用于将配置信息和敏感数据如密码与容器镜像解耦以环境变量或文件卷的形式注入到 Pod 中。PersistentVolume (PV) PersistentVolumeClaim (PVC): 用于管理持久化存储。PVC 是 Pod 对存储的“申请”PV 是集群中的存储资源。管理员创建 PV用户通过 PVC 消费。Namespace: 用于在同一个物理集群中创建多个虚拟集群实现资源隔离。kube-system、default都是内置的命名空间。5.2 常用 kubectl 命令与故障排查kubectl是你与集群交互的主要工具。除了get和apply以下命令至关重要查看详细信息kubectl describe pod pod-name # 查看 Pod 的详细状态、事件、配置 kubectl describe deployment deployment-name kubectl describe service service-namedescribe命令是排查 Pod 为什么处于Pending、CrashLoopBackOff等异常状态的第一选择。它会显示调度失败、镜像拉取失败、健康检查失败等具体原因。查看日志kubectl logs pod-name # 查看 Pod 内容器的标准输出日志 kubectl logs -f pod-name # 持续跟踪日志类似 tail -f kubectl logs pod-name -c container-name # 如果 Pod 有多个容器指定容器名进入 Pod 内的容器kubectl exec -it pod-name -- /bin/bash类似于docker exec用于调试容器内部。删除资源kubectl delete -f my-nginx-deployment.yaml # 通过文件删除 kubectl delete deployment nginx-deployment # 通过资源类型和名称删除 kubectl delete pod pod-name排查 Pod 启动失败的常见原因ImagePullBackOff: 镜像拉取失败。检查镜像名称、标签是否正确网络是否通畅是否有拉取私有镜像的凭证 (imagePullSecrets)。CrashLoopBackOff: 容器启动后立即退出。检查应用本身是否有错误查看kubectl logs。Pending: Pod 无法被调度到节点上。检查节点资源是否充足CPU、内存是否有节点选择器 (nodeSelector) 限制或是否存在污点 (Taint)。ErrImagePull: 同 ImagePullBackOff。5.3 应用更新、回滚与扩缩容更新镜像版本滚动更新kubectl set image deployment/nginx-deployment nginxnginx:1.25K8S 的 Deployment 默认采用滚动更新策略会逐步用新 Pod 替换旧 Pod确保服务不中断。可以通过kubectl rollout status deployment/nginx-deployment观察更新状态。回滚到上一版本kubectl rollout undo deployment/nginx-deployment查看更新历史kubectl rollout history deployment/nginx-deployment手动扩缩容kubectl scale deployment nginx-deployment --replicas5这个阶段的目标是熟练使用kubectl describe和kubectl logs进行故障排查理解 Pod 常见状态的含义并掌握应用更新、回滚和扩缩容的基本操作。这已经覆盖了日常运维的大部分场景。6. 向生产环境迈进配置、存储与健康检查要让应用在 K8S 上更健壮需要关注配置管理、数据持久化和应用健康状态监控。6.1 使用 ConfigMap 管理配置将配置与镜像分离。例如为 Nginx 创建一个自定义主页。创建 ConfigMapkubectl create configmap nginx-index-html --from-fileindex.html./my-index.html假设my-index.html文件内容为h1Hello from ConfigMap!/h1。在 Deployment 中挂载 ConfigMap 修改my-nginx-deployment.yaml在 Pod 模板的spec.containers下添加volumeMounts并在spec下添加volumesspec: containers: - name: nginx image: nginx:1.24 ports: - containerPort: 80 volumeMounts: - name: html-volume mountPath: /usr/share/nginx/html # 挂载到容器内的路径 volumes: - name: html-volume configMap: name: nginx-index-html # 引用刚才创建的 ConfigMap items: - key: index.html path: index.html应用更新后访问 Nginx主页内容将变为 ConfigMap 中定义的内容。6.2 使用 PersistentVolumeClaim 挂载持久化存储在 Minikube 中可以方便地使用hostPath类型的 PV但在生产环境通常会使用网络存储如 NFS、Ceph、云盘。创建 PVCmy-pvc.yamlapiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-data-pvc spec: accessModes: - ReadWriteOnce # 访问模式单节点读写 resources: requests: storage: 1Gi # 请求 1Gi 存储空间在 Deployment 中使用 PVC 在 Pod 模板的spec.containers中添加volumeMounts并在spec下添加volumes引用 PVCspec: containers: - name: nginx ... volumeMounts: - name:>containers: - name: nginx image: nginx:1.24 livenessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 # 容器启动后等待 5 秒开始探测 periodSeconds: 10 # 每 10 秒探测一次 readinessProbe: httpGet: path: / port: 80 initialDelaySeconds: 5 periodSeconds: 5这个阶段的目标是了解如何将应用配置外置ConfigMap如何为有状态应用提供持久化存储PVC以及如何通过健康检查让 K8S 更好地管理你的应用生命周期。这是将简单部署转化为可运维、高可用服务的关键步骤。7. 学习路径建议与常见避坑点最后结合我自己的经验给几条学习和实践的建议。7.1 学习路径规划第一阶段1-2周夯实 Docker 基础。做到能熟练构建自定义镜像理解 Dockerfile 每一行指令的作用掌握容器网络--network和数据卷-v的基本用法。第二阶段2-3周上手 Minikube 和 kubectl。反复练习 Deployment、Service、Pod、ConfigMap、PVC 这几个核心对象的 YAML 编写和命令操作。在本地部署一个多副本的 Web 应用如 WordPress MySQL并配置 Service 访问。第三阶段1-2个月深入学习核心概念。理解 K8S 的架构Master/Node、调度原理、网络模型CNI、服务发现CoreDNS、Ingress 控制器。可以尝试在云服务器上使用kubeadm手动搭建一个多节点集群这个过程能极大加深理解。第四阶段长期关注生态工具。学习 Helm包管理、Prometheus监控、Grafana可视化、EFK/ELK日志、GitOpsArgoCD/Flux等这些是构建完整云原生技术栈的组成部分。7.2 实践中的常见坑点镜像拉取失败确保镜像名称和标签正确。对于私有仓库需要在 Deployment 中配置imagePullSecrets。国内环境可能需要对 Docker Hub 配置镜像加速器。Pod 一直 Pending运行kubectl describe pod pod-name查看Events部分。常见原因是节点资源不足CPU、内存或 PVC 无法绑定没有可用的 PV。Service 无法访问检查 Service 的selector是否与 Pod 的labels完全匹配。检查 Pod 的containerPort是否与 Service 的targetPort一致。对于NodePort类型检查防火墙是否放行了节点的对应端口30000-32767。在集群内可以通过kubectl run -it --rm --imagebusybox test-pod -- sh启动一个临时 Pod用wget -O- service-name.namespace.svc.cluster.local:port测试服务发现。配置文件格式错误YAML 对缩进极其敏感务必使用空格而非 Tab。可以使用在线 YAML 校验工具或kubectl apply --dry-runclient -f your-file.yaml进行预检查。忘记清理资源学习过程中会创建大量临时资源。定期使用kubectl get all --all-namespaces查看并使用kubectl delete清理不再需要的 Deployment、Service、Pod、PVC 等避免资源浪费。我个人更建议把“速通”理解为快速建立核心概念和最小可运行环境而不是追求一次性掌握所有高级特性。真正的熟练来自于反复的实践和踩坑。先从在 Minikube 上稳定运行一个你自己打包的应用开始然后逐步加入配置、存储、健康检查再尝试搭建多节点集群。每一步都确保自己理解了背后的原理和命令的作用这样积累的经验才是扎实的。 30款热门AI模型一站整合DeepSeek/GLM/Qwen 随心用限时 5 折。 点击领海量免费额度