云原生核心技术 (7/12): K8s 核心概念白话解读(上):Pod 和 Deployment 究竟是什么?

大家好,欢迎来到《云原生核心技术》系列的第七篇!

在上一篇,我们成功地使用 Minikube 或 kind 在自己的电脑上搭建起了一个迷你但功能完备的 Kubernetes 集群。现在,我们就像一个拥有了一块崭新数字土地的农场主,是时候在这片土地上播种、耕作了。

那么问题来了,我们该如何把之前用 Docker 打包好的应用(容器)种植到 K8s 这片广袤的土地上呢?直接扔进去吗?

当然不行。K8s 有一套自己的"种植"规则。今天,我们就来学习这套规则里最基本的两个概念:PodDeployment。它们是你在 K8s 世界里打交道最多的两个朋友。


一、 Pod:K8s 世界的"原子单位",为什么不是直接部署容器?

在 Docker 的世界里,我们操作的最小单位是"容器"。但到了 K8s,你会发现最小的部署单位是一个叫 Pod 的东西。

一个常见的疑问是:为什么 K8s 不直接管理容器,非要引入一个 Pod 的概念呢?

为了回答这个问题,我们先来看一个比喻:

把一个容器 想象成一个

那么 Pod 就像一套房子

K8s 分配资源时,不是按"人头"(容器)分的,而是按"户口"(Pod)分的。它可以给一套房子(一个Pod)分配一个独立的 IP 地址、主机名和一套独立的"水电煤气"(网络、存储等资源)。

这套房子里,可以只住一个人(单容器 Pod),这也是最常见的用法。但 K8s 也允许你让多个人(多容器)合租在同一套房子里。

合租的好处是什么?

住在同一屋檐下的人,他们:

  1. 共享同一个"家庭住址" (共享网络命名空间):他们可以用 localhost 直接互相访问,就像家人之间串门一样,不需要出门绕到大街上(外部网络)。这对于需要紧密协作的程序(比如一个业务容器和一个日志收集容器)来说非常高效。
  2. 共享"储藏室"(共享存储卷 Volume):他们可以轻松地共享文件,就像家人共用一个冰箱一样。

总结一下:Pod 是 K8s 调度、管理和资源分配的最小单位。它将一个或多个紧密关联的容器打包在一起,为它们提供共享的存储和网络资源,形成一个内聚的服务单元。

动手:编写并运行你的第一个 Pod

在 K8s 中,我们通常不使用命令行直接创建资源,而是通过编写 YAML 文件来"声明"我们想要的状态。这就像给 K8s 一张建筑蓝图,它会负责照着蓝图施工。

创建一个名为 nginx-pod.yaml 的文件,内容如下:

yaml 复制代码
# nginx-pod.yaml

# API 版本,表明这个对象属于哪个 API 组
apiVersion: v1
# 资源类型,我们正在创建一个 Pod
kind: Pod
# 元数据,包含资源的名称、标签等信息
metadata:
  name: nginx-hello-pod
  labels:
    app: web
# 规格,定义了这个 Pod 的期望状态
spec:
  # Pod 中包含的容器列表
  containers:
  # 第一个容器
  - name: nginx-container
    # 使用的 Docker 镜像
    image: nginx:1.21
    # 容器需要暴露的端口
    ports:
    - containerPort: 80

现在,打开你的终端,使用 kubectl 来应用这个蓝图:

bash 复制代码
# 确保你的 kubectl 已经连接到 Minikube 或 kind 集群
kubectl apply -f nginx-pod.yaml

执行后,K8s 就会开始创建这个 Pod。我们可以查看它的状态:

bash 复制代码
kubectl get pods

# 你会看到类似下面的输出:
# NAME              READY   STATUS    RESTARTS   AGE
# nginx-hello-pod   1/1     Running   0          15s

Running 状态表示我们的 Nginx Pod 已经成功运行起来了!


二、 Deployment:应用的"状态维护者"与"智能管家"

我们现在有了一个正在运行的 Pod。但是,如果这个 Pod 因为某些原因(比如程序 Bug、节点故障)挂掉了怎么办?它就真的消失了,没有人会去管它。这在生产环境中是绝对无法接受的。

我们需要一个更高级的"管家",它能确保我们的应用:

  • 永不宕机:如果一个 Pod 挂了,它能自动创建一个新的来替代。
  • 数量可控:我们可以告诉它,"请确保始终有3个相同的 Pod 在运行",它就会自动维护这个数量。
  • 轻松更新:当我们想更新应用版本时,它能平滑地、滚动地用新版 Pod 替换旧版 Pod,保证业务不中断。
  • 一键回滚:如果新版本有问题,它能一键回退到上一个稳定版本。

这个智能管家,就是 Deployment

再次使用比喻:

如果 Pod 是一间公寓 ,那么 Deployment 就是这栋公寓的物业经理

你不会亲自去管理每一间公寓的入住和维修。你只需要告诉物业经理:"我需要这栋楼里始终有50间公寓是租出去并且正常运作的,租户是 Nginx v1.21"。

经理会负责招租(创建 Pod),检查水电(监控 Pod 健康),如果租户跑了(Pod 挂了)就立刻找新租户(创建新 Pod),如果你想升级所有公寓的装修(更新应用版本),经理会一间一间地施工(滚动更新)。

动手:用 Deployment 部署应用

让我们来创建一个 nginx-deployment.yaml 文件,用 Deployment 的方式来部署 Nginx。

yaml 复制代码
# nginx-deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
spec:
  # 期望的 Pod 副本数量
  replicas: 3
  # 选择器,告诉 Deployment 要管理哪些 Pod
  # Deployment 通过这个标签找到它应该管理的 Pod
  selector:
    matchLabels:
      app: nginx-server
  # Pod 模板,这就是 Deployment 创建新 Pod 时使用的"蓝图"
  # 注意,这里的结构和我们上面定义的 Pod YAML 的 spec 部分几乎一样
  template:
    metadata:
      # Pod 的标签,必须和上面的 selector.matchLabels 匹配
      labels:
        app: nginx-server
    spec:
      containers:
      - name: nginx
        image: nginx:1.21
        ports:
        - containerPort: 80

应用这个 YAML 文件:

bash 复制代码
kubectl apply -f nginx-deployment.yaml

查看 Deployment 和它创建的 Pods:

bash 复制代码
kubectl get deployment

# 输出:
# NAME               READY   UP-TO-DATE   AVAILABLE   AGE
# nginx-deployment   3/3     3            3           20s

kubectl get pods

# 输出: (注意,Pod 名称是 Deployment 名称加上随机字符串)
# NAME                                READY   STATUS    RESTARTS   AGE
# nginx-deployment-6b6c47948c-7v9d8   1/1     Running   0          25s
# nginx-deployment-6b6c47948c-8l9f4   1/1     Running   0          25s
# nginx-deployment-6b6c47948c-k5z2x   1/1     Running   0          25s

看!Deployment 严格按照我们的要求 replicas: 3,创建并维护了3个 Nginx Pod。


三、实战演练:见证 Deployment 的"魔法时刻"

现在,让我们亲眼见证 Deployment 作为"智能管家"的神奇能力。

1. 魔法一:故障自愈 (Self-healing)

我们来手动"干掉"一个 Pod,模拟一次故障。

首先,获取 Pod 列表,随便挑一个名字记下来:
kubectl get pods

然后,无情地删除它:

bash 复制代码
# 将 <your-pod-name> 替换为你复制的 Pod 名称
kubectl delete pod <your-pod-name>

现在,立刻、马上再次查看 Pod 列表,并使用 -w (watch) 参数持续观察变化:

bash 复制代码
kubectl get pods -w

你会看到一个激动人心的场面:

  1. 你删除的那个 Pod 状态会变为 Terminating(正在终止)。
  2. 几乎在同一时间,一个新的 Pod 会立刻出现,状态从 Pending -> ContainerCreating -> Running
  3. 最终,Pod 的总数依然是3个!

这就是 K8s 的故障自愈能力,由 Deployment 精确执行。

2. 魔法二:滚动更新 (Rolling Update)

我们的应用要发布新版本了,比如把 Nginx 从 1.21 升级到 1.22

直接编辑 nginx-deployment.yaml 文件,将 image: nginx:1.21 修改为 image: nginx:1.22

yaml 复制代码
# ...
    spec:
      containers:
      - name: nginx
        image: nginx:1.22 # <--- 修改这里
        ports:
        - containerPort: 80

保存文件后,再次执行 apply 命令:
kubectl apply -f nginx-deployment.yaml

再次用 -w 观察 Pod 变化:kubectl get pods -w

你会看到 K8s 正在进行"滚动更新":

它会先创建一个新版本的 Pod,等新 Pod 启动并准备就绪后,再优雅地终止一个旧版本的 Pod。如此循环,直到所有 Pod 都被更新为新版本。整个过程服务不中断!

你可以通过以下命令查看更新状态:
kubectl rollout status deployment/nginx-deployment

3. 魔法三:一键回滚 (Rollback)

糟糕!新版本 1.22 有一个重大 Bug,我们需要紧急回退到上一个版本!

别慌,Deployment 已经为我们记录了历史版本。执行回滚命令即可:

bash 复制代码
kubectl rollout undo deployment/nginx-deployment

再次观察 Pod 变化 kubectl get pods -w,你会发现 K8s 又开始了一次滚动操作,这次是把 1.22 版本的 Pod 逐个替换回 1.21 版本。危机解除!


总结

今天我们学习了 K8s 中两个最核心、最基础的概念:

  • Pod: K8s 的原子调度单元,是容器的"家",为内部容器提供共享的网络和存储。
  • Deployment: Pod 的"智能管家",负责保证 Pod 的数量(副本)、实现故障自愈、并以安全、平滑的方式进行应用更新和回滚。

你现在已经掌握了在 K8s 中部署、更新和维护无状态应用的基本技能。我们已经成功地让应用在集群内部"活起来"并且"活得很好"。

但是,新的问题又来了:现在这些 Nginx 服务都运行在 K8s 集群内部,我们作为外部用户,如何才能访问到它们呢?

别急,这正是我们下一篇文章要解决的问题。在下一篇 《K8s 核心概念白话解读(下)》 中,我们将揭秘 ServiceIngress 这两个负责"对外暴露服务"和"管理流量"的关键角色。敬请期待!

相关推荐
小的博客12 分钟前
windows下安装Docker Desptop
运维·docker·容器
Zhu75842 分钟前
在k8s环境部署Apache zookeeper3.9.5,高可用,多pod
容器·kubernetes·apache
雨声不在1 小时前
macos 12使用docker
macos·docker·容器
云烟成雨TD2 小时前
Micrometer 系列【2】可观测性:指标(Metrics)
java·云原生·micrometer
运维老郭2 小时前
Ubuntu下编译安装Redis:从0到1可用的完整指南
运维·云原生
运维大师2 小时前
【K8S 运维实战】07-Pod生命周期与故障排查
运维·容器·kubernetes
Linux-187413 小时前
分布式链路追踪系统之二进制安装skywalking
elasticsearch·云原生·skywalking·分布式链路追踪系统·应用程序性能监控
BullSmall17 小时前
Anolis OS 8.10 完整安装 Docker CE(生产可用,解决 podman 冲突)
docker·容器·podman
heimeiyingwang18 小时前
【架构实战】可观测性三支柱:日志、指标、链路的融合
elasticsearch·架构·kubernetes
阿里云云原生20 小时前
阿里云 AgentTeams 7月第二周产品动态
云原生