Kubernetes 零基础入门:从 Docker 容器到集群编排的第一条认知路径
如果你已经接触过 Docker,可能熟悉这样的流程:写一个 Dockerfile,构建镜像,然后通过 docker run 启动容器。
这套方式非常适合本地开发、运行单个服务,或快速验证一个想法。但当应用开始出现多个副本、多个服务、跨机器部署、故障恢复和持续发布等需求时,仅靠手工执行容器命令会迅速变得难以维护。
Kubernetes(常缩写为 K8s)正是为这类问题提供的容器编排平台:你声明“希望应用是什么状态”,它负责把应用调度到合适的位置,并持续尽量把实际状态维持在目标状态。
本文不讨论生产集群安装、高可用控制平面或复杂网络插件,而是建立从 Docker 到 Kubernetes 的最小认知闭环。
1. Docker 已经解决了什么?又还缺什么?
Docker 的核心价值是把应用及其依赖打包成镜像,并以容器形式运行。对开发者而言,这意味着:
- 环境更容易复现;
- 应用部署不再完全依赖“在服务器上手动装依赖”;
- 可以通过镜像版本管理应用交付物;
- 本地可以用
docker run很快启动服务。
但 Docker 的 docker run 更接近“在一台机器上启动一个或几个容器”。假设你的应用需要运行 3 个副本,并且要面对下面这些情况:
- 某个容器退出后,谁来自动重启或替换它?
- 一台机器故障后,谁来把应用放到另一台机器?
- 新版本发布时,如何逐步替换旧版本,避免一次性中断服务?
- 后端副本的 IP 会变化,前端应如何稳定地访问它?
- 配置、密码、访问权限和资源限制如何统一管理?
你当然可以自己用脚本、进程守护工具、负载均衡器和运维流程拼出一套方案。Kubernetes 的作用,是把这些围绕容器化应用运行的通用能力抽象为统一的 API 和对象模型。
可以先用一句话区分:Docker 更擅长构建和运行容器;Kubernetes 更擅长在集群中部署、连接、扩缩和维护容器化应用。
Kubernetes 并不是 Docker 的简单替代品。你仍然可以继续用 Docker 构建镜像;只是 Kubernetes 节点运行 Pod 时,需要通过兼容 CRI 的容器运行时工作。Kubernetes 在 v1.24 中移除了内置 dockershim,但这不影响由 docker build 生成的标准容器镜像被 Kubernetes 使用。
2. Kubernetes 的最小心智模型
不要一开始就试图记住所有组件。入门阶段,只需要理解这条主链路:

- 你使用
kubectl提交命令或 YAML 清单。 - 请求进入 Kubernetes API Server。
- 控制平面记录你的目标状态,并安排相关工作。
- 工作节点上的
kubelet接收任务,协同容器运行时启动 Pod。 - Kubernetes 控制器持续观察状态;如果实际状态偏离目标状态,就尝试进行调谐。
例如,你声明“我要运行 3 个副本”。即使其中一个 Pod 因故消失,Kubernetes 也会尝试创建替代 Pod,使副本数回到 3。
这里最重要的思维转变是:
- 命令式思维:我现在手动启动 3 个容器。
- 声明式思维:我希望系统始终维持 3 个副本。
Kubernetes 更强调后者。你描述目标,系统负责持续逼近目标。
注意:副本数达到 3,不必然等于有 3 个“可用”副本。应用是否就绪还取决于容器状态,以及后续会学习到的
readinessProbe等配置。
3. 必须先认识的 6 个对象
Kubernetes 的能力主要通过“对象”表达。对象是保存在 Kubernetes API 中的意图记录:spec 用于描述期望状态,系统再通过状态观察和控制器调谐来维持它。
Pod:最小部署单位,不等于容器
Pod 是 Kubernetes 中最小的可创建和管理的部署单位。一个 Pod 可以包含一个或多个容器;这些容器共享网络命名空间和存储资源。
这意味着:
- Pod 中的容器通常可以通过
localhost相互通信; - 一个 Pod 通常拥有自己的 IP;
- Pod 内多个容器适合处理紧密耦合的协作任务。
但对刚入门的应用而言,最常见的模式仍然是:一个 Pod 承载一个主应用容器。
因此,下面两句话都不够准确:
- “Pod 就是容器。”——不对,Pod 可以包含多个容器。
- “一个 Pod 必须有多个容器。”——也不对,单容器 Pod 非常常见。
Deployment:用来管理无状态应用副本
通常不应该直接手工创建裸 Pod。因为单独创建一个 Pod 后,它消失了,没有控制器会确保它被替代。
对于常见的无状态 Web 服务或 API 服务,应该使用 Deployment。Deployment 会管理 Pod 副本,并支持:
- 保持指定副本数;
- Pod 失败后的替换;
- 扩缩容;
- 滚动更新;
- 回滚到较早的 Deployment 修订版本。
可以把它理解为:Pod 是实际运行应用的实例,Deployment 是管理这些实例的负责人。
Service:为易变的 Pod 提供稳定入口
Pod 会被重建、替换和扩缩容,因此 Pod 名称和 IP 都不适合被其他服务长期依赖。
Service 通过标签选择一组 Pod,并为符合条件的后端端点提供稳定的网络访问抽象。客户端访问的是 Service,而不是某个具体 Pod。
这也是 Kubernetes 中服务发现的基础:
客户端 → Service → 一组匹配标签的 Pod
Service 常见类型包括:
ClusterIP:默认类型,仅在集群内部可访问;NodePort:通过节点端口暴露服务;LoadBalancer:在支持的云环境中申请外部负载均衡器。
本地学习时,不必急着理解所有暴露方式。使用 ClusterIP 配合 kubectl port-forward,就能完成稳定入口与本机访问的练习。
Namespace:资源的命名范围与隔离边界
Namespace 可以在同一个集群中隔离不同团队、项目或环境的资源。相同名称的 Deployment 或 Service 可以存在于不同 Namespace 中。
但零基础练习时,直接使用默认的 default Namespace 即可。用户数量较少、资源简单的集群通常无需过早设计多 Namespace 结构。
ConfigMap:普通配置
ConfigMap 用于保存非敏感配置,例如环境名称、功能开关、服务地址或普通配置文件。Pod 可以将它作为环境变量、命令参数或挂载文件使用。
Secret:敏感数据,但不是“默认保险箱”
Secret 用于保存密码、令牌和密钥等敏感信息。不过,Secret 的存在不自动等于“数据已经安全加密”。实际环境还需要关注访问控制、静态加密和密钥管理。
入门时只需先建立边界:
- 普通配置放 ConfigMap;
- 敏感配置放 Secret;
- 不要把密码直接写进镜像或提交到代码仓库。
4. 一张图理解核心对象关系
Deployment
└── 维护期望副本数
└── Pod × N
└── Container
Service
└── 通过 labels / selector 选择一组 Pod
└── 为这些 Pod 提供稳定访问入口
其中,labels 是连接对象的重要机制。
例如,Pod 带有标签:
labels:
app: docker-interest
而 Service 使用选择器:
selector:
app: docker-interest
那么这个 Service 就会把流量转发给带有该标签、且可作为后端端点使用的 Pod。
5. YAML 清单:Kubernetes 的声明式语言
Kubernetes 对象通常使用 YAML 文件定义。无论是 Deployment、Service 还是 ConfigMap,入门时都可以先关注四个顶层字段:
apiVersion: apps/v1 # 使用哪个 API 版本
kind: Deployment # 要创建什么对象
metadata: # 名称、标签、命名空间等元信息
spec: # 期望状态
下面是一个可直接学习的 Deployment 示例。它会创建两个 NGINX 副本:
apiVersion: apps/v1
kind: Deployment
metadata:
name: docker-interest
spec:
replicas: 2
selector:
matchLabels:
app: docker-interest
template:
metadata:
labels:
app: docker-interest
spec:
containers:
- name: web
image: nginx:1.27
ports:
- containerPort: 80
几个关键点:
replicas: 2:目标是维持两个 Pod 副本;selector.matchLabels:Deployment 用它识别自己管理的 Pod;template.metadata.labels:新建 Pod 会带上的标签;- 两处
app: docker-interest必须保持匹配; image:容器镜像;containerPort:声明容器使用的端口信息,但它本身不会自动把应用暴露到集群外。
接着,为这组 Pod 创建一个 Service:
apiVersion: v1
kind: Service
metadata:
name: docker-interest
spec:
selector:
app: docker-interest
ports:
- port: 80
targetPort: 80
type: ClusterIP
这里的 selector 会选择带有 app: docker-interest 标签的 Pod。Service 的 port 是服务端口,targetPort 是后端 Pod 中目标容器的端口。
6. 最小实践闭环:在本地部署一个应用
本文选择 kind 作为本地练习环境。kind 会使用容器作为 Kubernetes 节点,适合已经安装 Docker 或兼容容器运行时、希望快速创建本地集群的读者。
前置条件:已安装 Docker、
kind和kubectl。不同操作系统的安装方式不同,请以各工具官方安装说明为准。
第一步:创建集群
kind create cluster --name k8s-learning
kubectl get nodes
如果输出中节点状态为 Ready,说明本地集群已经可用。
第二步:保存并应用 YAML
将前面的两个 YAML 内容分别保存为:
deployment.yaml
service.yaml
然后执行:
kubectl apply -f deployment.yaml
kubectl apply -f service.yaml
查看资源状态:
kubectl get deployments
kubectl get pods
kubectl get services
你应该看到:
- 一个名为
docker-interest的 Deployment; - 两个由 Deployment 创建的 Pod;
- 一个同名的 ClusterIP Service。
如果 Pod 没有进入 Running 状态,优先执行:
kubectl describe pod <Pod名称>
初学阶段最常见的原因包括镜像拉取失败、镜像名称或标签不存在、网络问题,以及 YAML 中标签和选择器不匹配。
第三步:从本机访问 Service
由于当前 Service 是 ClusterIP,它默认只在集群内部可访问。为了避免不同本地环境中 NodePort 行为的差异,可以使用端口转发:
kubectl port-forward service/docker-interest 8080:80
保持该终端运行,然后在浏览器访问:
http://localhost:8080
你访问的不是某个固定 Pod,而是 Service 提供的稳定入口。
第四步:扩缩容
将副本数从 2 扩展到 3:
kubectl scale deployment/docker-interest --replicas=3
kubectl get pods
再缩回 1:
kubectl scale deployment/docker-interest --replicas=1
kubectl get pods
这一步体现了声明式管理:你不需要自己决定“启动哪个容器”,只需要修改目标副本数。
第五步:更新与回滚
当你有一个新的、确认存在的镜像版本标签时,可以修改 Deployment 中的 image 字段,再执行:
kubectl apply -f deployment.yaml
kubectl rollout status deployment/docker-interest
Deployment 默认会以滚动更新的方式逐步替换旧 Pod。若更新后发现问题,可以查看历史并回滚:
kubectl rollout history deployment/docker-interest
kubectl rollout undo deployment/docker-interest
这就是 Kubernetes 相比单次 docker run 更重要的一层能力:它管理的是持续运行的应用状态和发布过程,而不只是一次容器启动。
7. Docker 本地镜像与 kind 的一个常见坑
当你构建自己的镜像时,可能会这样做:
docker build -t my-app:0.1.0 .
但随后在 kind 集群里部署 my-app:0.1.0,却遇到 ImagePullBackOff。
原因是:你本机 Docker 中存在镜像,不代表 kind 节点一定能直接看到它。对于本地构建、未推送到镜像仓库的镜像,可以将镜像加载进 kind 集群:
kind load docker-image my-app:0.1.0 --name k8s-learning
同时建议使用明确的版本标签,例如 0.1.0,而不是直接使用 latest。对于带有非 latest 标签的镜像,Kubernetes 默认通常会使用 IfNotPresent 拉取策略;在本地练习中,如需明确表达这一意图,也可以显式设置:
imagePullPolicy: IfNotPresent
这样在节点已经拥有该镜像时,Kubernetes 会优先使用本地镜像,减少再次尝试远程拉取同名镜像造成的困惑。
8. 初学者最容易产生的误解
误解一:Pod 就是 Docker 容器
Pod 可以包含多个容器,并拥有共享网络与存储上下文。一个 Pod 经常只有一个主容器,但两者不是同义词。
误解二:先学会手动创建 Pod 就够了
学习 Pod 的结构是必要的,但实际运行无状态应用时,更常见的入口是 Deployment。Deployment 才负责副本维持、更新和替换。
误解三:Service 就是 Docker 的端口映射
Docker 的端口映射主要处理宿主机与容器端口的连通;Kubernetes Service 的核心价值还包括:为一组可替换 Pod 提供稳定访问入口、负载分发和服务发现。
误解四:Secret 天然等于安全加密
Secret 是敏感信息的对象类型,不代表你已经完成了加密、最小权限和审计设计。
误解五:学习 Kubernetes 就意味着必须自建生产集群
不必。许多团队使用托管 Kubernetes 服务;即使未来不负责集群运维,理解 Deployment、Service、配置、资源限制和发布机制,仍然会帮助你更好地交付容器化应用。
9. 学完这一篇后,下一步学什么?
完成本文的最小闭环后,建议按下面顺序继续:
- 健康检查与资源管理:
livenessProbe、readinessProbe、requests、limits; - 配置与密钥:ConfigMap、Secret、环境变量与挂载文件;
- 持久化存储:Volume、PersistentVolume、PersistentVolumeClaim;
- 流量入口:Ingress 或 Gateway API;
- 应用打包:Helm;
- 可观测性:日志、指标、告警与追踪;
- 权限与交付:RBAC、镜像仓库、CI/CD;
- 托管集群实践:理解云厂商 Kubernetes 服务的节点、网络、存储和身份集成方式。
结语
从 Docker 走向 Kubernetes,关键不是先背下大量名词,而是完成一次思维升级:
- Docker 让你能稳定地交付并运行一个容器;
- Kubernetes 让你能在集群环境中声明应用目标,并持续管理它的副本、访问方式和发布过程。
先把 Pod、Deployment、Service、标签、YAML 和声明式调谐 这条主线理解清楚,你就已经跨过了 Kubernetes 入门中最重要的一步。

347

被折叠的 条评论
为什么被折叠?



