K8S-Pod(上)

发布于:2025-09-06 ⋅ 阅读:(14) ⋅ 点赞:(0)

Pod概念

Pod 是可以在 Kubernetes 中创建和管理的、最小的可部署的计算单元

Pod是一组(一个或多个)容器;这些容器共享存储、网络、以及怎样运行这些容器的规约。Pod 中的内容总是并置(colocated)的并且一同调度,在共享的上下文中运行。Pod 所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器,这些容器相对紧密地耦合在一起。

核心特性

  • 共享上下文:Pod 的共享上下文包括一组 Linux 名字空间、控制组(CGroup)和可能一些其他的隔离方面。在 Pod 的上下文中,各独立的应用可能会进一步实施隔离。
  • 逻辑主机:Pod 类似于共享名字空间并共享文件系统卷的一组容器。
  • 容器运行时:为了运行 Pod,你需要提前在每个节点安装好容器运行时(如 Containerd 或 Docker)。

两种主要用法

单容器 Pod

最常见的 Kubernetes 使用模式,将 Pod 视为单个容器的包装器。Kubernetes 直接管理 Pod 而不是容器本身。

多容器 Pod

Pod 可以封装由紧密耦合且需要共享资源的多个并置容器组成的应用。这些位于同一位置的容器构成一个内聚的服务单元。

将多个并置、同管的容器组织到一个 Pod 是一种相对高级的使用场景。横向扩展应通过副本机制实现,而非在同一 Pod 中添加多个容器。

Pod 示例

下面是一个 Pod 示例,它由一个运行镜像 nginx:1.14.2 的容器组成。

# simple-pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:1.14.2
    ports:
    - containerPort: 80

要创建上面显示的 Pod,运行以下命令:

kubectl apply -f simple-pod.yaml

通过工作负载资源管理 Pod

使用工作负载资源来创建和管理 Pod。Pod 被设计成了相对临时性的、用后即抛的一次性实体。

直接创建 Pod 的问题

  • Pod 是临时性的,节点故障会导致 Pod 丢失
  • 缺乏扩缩容能力
  • 没有自动修复机制
  • 无法实现滚动更新

常见的工作负载资源

  • Deployment:适用于管理无状态应用,支持滚动更新和回滚
  • StatefulSet:适用于管理有状态应用,提供稳定的网络标识和持久存储。
  • DaemonSet:确保所有(或部分)节点上运行一个 Pod 的副本。
  • Job:用于运行一次性任务。
  • CronJob:用于运行周期性任务。

这些资源的控制器能够处理副本的管理、上线,并在 Pod 失效时提供自愈能力

Deployment示例

**apiVersion: apps/v1
kind: Deployment
metadata:
  name: nginx-deployment
  labels:
    app: nginx
spec:
  replicas: 3
  selector:
    matchLabels:
      app: nginx
  strategy:
    type: RollingUpdate
    rollingUpdate:
      maxSurge: 25%
      maxUnavailable: 25%
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx:1.25.3
        ports:
        - containerPort: 80**

Pod 模板

工作负载资源的控制器使用 Pod 模板 来创建和管理 Pod。Pod 模板是包含在工作负载对象中的规范,是目标状态的一部分。

apiVersion: batch/v1
kind: Job
metadata:
  name: hello
spec:
  template:
    # 这里是 Pod 模板
    spec:
      containers:
      - name: hello
        image: busybox:1.28
        command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
      restartPolicy: OnFailure
    # 以上为 Pod 模板

重要:修改 Pod 模板不会对已经存在的 Pod 直接起作用。控制器会根据新模板创建新的 Pod 来替换旧的 Pod。

Pod 生命周期

Pod 被调度到节点上后会一直保持运行,直到:

  • Pod 中的容器执行完毕。
  • Pod 对象被删除。
  • Pod 因资源不足而被驱逐。
  • 节点失效。

生命周期阶段

  1. Pending(挂起):Pod 已被 Kubernetes 系统接受,但有一个或多个容器尚未创建或运行。
  2. Running(运行中):Pod 已绑定到一个节点,所有容器都已创建。至少有一个容器仍在运行,或者正处于启动或重启过程中。
  3. Succeeded(成功):Pod 中的所有容器都已成功终止,并且不会再重启。
  4. Failed(失败):Pod 中的所有容器都已终止,并且至少有一个容器是因为失败终止。
  5. Unknown(未知):通常是由于无法与 Pod 所在节点的 kubelet 通信所致。

重启策略

通过 spec.restartPolicy 字段控制

  • Always:容器失败时总是重启(默认)。
  • OnFailure:容器以非零状态退出时重启。
  • Never:从不重启。

Init 容器

Pod 可以包含在应用容器启动前运行的 Init 容器。Init 容器总是运行到完成为止,并且每个 Init 容器都必须成功启动,下一个 Init 容器才能运行。如果 Init 容器失败,Kubernetes 会不断地重启 Pod,直到 Init 容器成功为止。

容器探针

-器进程还在运行,并不代表应用是健康的。它可能死锁、可能正在启动(但还未就绪)、可能依赖的服务不可用。探针让 Kubernetes 能够感知应用内部的真实状态,并做出相应决策。

探针类型

  • livenessProbe:检测容器是否正在运行。如果失败,kubelet 会杀死容器,然后根据重启策略进行处理。
  • readinessProbe:检测容器是否已准备好服务请求。如果失败,端点控制器将从与 Pod 匹配的所有 Service 的端点中移除该 Pod 的 IP 地址。
  • startupProbe:指示容器内的应用是否已启动。如果提供了启动探针,则所有其他探针都会被禁用,直到它成功为止。

探针的三种动作

  • ExecAction:在容器内执行指定命令。
    • 如果命令退出码为 0,则认为诊断成功。
    • 配置 : livenessProbe: exec: command: - cat - /tmp/healthy
  • TCPSocketAction:对指定端口上的容器 IP 地址进行 TCP 检查。
    • 如果端口能连通,则认为诊断成功。
    • 配置 : livenessProbe: tcpSocket: port: 8080
  • HTTPGetAction:对指定端口和路径上的容器 IP 地址执行 HTTP Get 请求。
    • 如果响应的状态码在 200 到 399 之间,则认为诊断成功。
    • 配置 : livenessProbe: httpGet: path: /healthz port: 8080 httpHeaders: - name: Custom-Header value: Awesome

Pod 的资源共享和通信

存储

  • 一个 Pod 可以设置一组共享的存储卷(Volume)。Pod 中的所有容器都可以访问该共享卷,从而允许这些容器共享数据。卷还允许 Pod 中的持久数据保留下来,即使其中的容器需要重新启动。
  • 容器中的文件系统是临时的,容器重启后文件会丢失。

卷是一个目录,可以被 Pod 中的一个或多个容器访问。卷的生命周期不属于容器,它由 Pod 和外部存储源决定。

类型
  • emptyDir
    • 生命周期:与 Pod 的生命周期完全一致。Pod 被删除,数据也随之删除。
    • 用途:用于 Pod 内容器之间的临时数据共享(例如,一个容器生产数据,另一个容器消费数据)。节点重启后数据也会丢失。
  • hostPath:
    • 生命周期:将节点上的文件系统目录或文件挂载到 Pod 中。数据持久化在节点上,即使 Pod 被删除,数据依然存在。
  • configMap / secret:
    • 生命周期:将 Kubernetes 对象(ConfigMap/Secret)中的数据作为文件或环境变量注入到容器中。
  • 持久卷 (persistentVolumeClaim - PVC):
    • 生产环境的标准做法。
    • 生命周期:独立于 Pod。Pod 被删除后,数据依然安全地保存在外部存储系统中(如云硬盘、NFS、Ceph 等)。
    • 工作原理:管理员预先创建持久卷 (PersistentVolume, PV):代表一块实际的网络存储。用户创建持久卷声明 (PersistentVolumeClaim, PVC):像一个“申请单”,声明需要多大的存储、需要什么访问模式(如 ReadWriteOnce)。在 Pod 中通过 volumes.persistentVolumeClaim 字段绑定 PVC。

PVC示例

apiVersion: v1
kind: Pod
metadata:
  name: my-app-with-db
spec:
  containers:
  - name: app
    image: my-app:latest
    volumeMounts:
    - name: data-storage # 挂载名为 data-storage 的卷
      mountPath: /var/data # 挂载到容器内的路径

  volumes:
  - name: data-storage # 定义卷的名称
    persistentVolumeClaim:
      claimName: my-pvc # 指定要使用的PVC名称

网络

  • 每个 Pod 都在每个地址族中获得一个唯一的 IP 地址
  • Pod 中的每个容器共享网络名字空间,包括 IP 地址和网络端口。
  • Pod 内的容器可以使用 localhost 互相通信。
  • 不同 Pod 中的容器具有不同的 IP 地址,需要通过 Pod IP 进行通信。

网络实现细节:

  1. 暂停容器 (Pause Container)

    • 当创建一个 Pod 时,Kubernetes 会先创建一个名为 pause 的极小容器。它的唯一作用是持有 Pod 的网络命名空间 (Network Namespace)
    • Pod 内的其他容器(用户容器)会通过 Docker 的 --net=container:<id> 参数加入到这个 pause 容器的网络命名空间中,从而实现网络共享。
  2. 容器间通信

    • 在同一个 Pod 内,容器可以通过 localhost 和端口号直接通信,就像在同一台机器上一样。
  3. Pod 间通信

    • Pod-to-Pod:通过对方的 Pod IP 直接通信。这是最基础的通信方式,但 Pod IP 是临时的,Pod 重启后会改变。
    • Service:为了解决 Pod IP 不固定的问题,Kubernetes 引入了 Service。Service 是一个稳定的抽象层,它有一个固定的 虚拟 IP (VIP) 和 DNS 名称。Service 通过标签选择器 (Selector) 将流量负载均衡到一组后端 Pod 上。
      • ClusterIP:默认类型,在集群内部暴露 Service。
      • NodePort:通过每个节点的静态端口暴露 Service。
      • LoadBalancer:使用云提供商的负载均衡器对外暴露 Service。
    • Ingress:用于管理外部访问集群内服务的 HTTP/HTTPS 路由规则,提供更高级的功能如基于域名和路径的路由、SSL 终止等。它本身不是一种 Service,而是位于 Service 之前的入口控制器。
示例:网络访问流程

外部用户 -> (通过 LoadBalancer/NodePort) -> Service (VIP) -> (通过 iptables/IPVS 规则) -> 目标 Pod (在某个节点上)。

K8S官方文档
参考文章
K8Buard关于Pod存储官方文档


网站公告

今日签到

点亮在社区的每一天
去签到