Kubernetes 学习笔记:Pod 基础与 YAML 编排

本笔记聚焦于 Kubernetes Pod 的核心概念、YAML 编排语法以及 Pod 生命周期管理,剔除了 Volume 存储相关内容。通过大量可直接运行的示例代码,帮助读者快速掌握 Pod 的配置与运维。


1. YAML 格式精要

Kubernetes 中一切资源皆可用 YAML 描述。掌握 YAML 语法是编写 K8s 配置清单的第一步。

1.1 基本规则

  • 只使用空格缩进,禁止 Tab 键,习惯使用 2 个空格
  • 同一层级元素保持相同缩进。
  • 子元素比父元素多一层缩进。
  • 适当增加空行以提高可读性。
  • 在 Vim 中建议执行 :set paste 避免粘贴时自动缩进错乱。

1.2 常见数据结构

类型 描述 示例(普通格式) 示例(内联格式,不推荐)
注释 # 后的内容为注释 # 这是一条注释 some: value # 行末注释
字符串 通常不加引号,也可加单/双引号 name: laoma "name: laoma"
多行字符串 ` 保留换行;>` 将换行转为空格 `msg:
字典(映射) 键值对集合 user: name: laoma uid: 1088 user: {name: laoma, uid: 1088}
列表(数组) - 开头的一系列项 names: - httpd - firewalld names: [httpd, firewalld]

1.3 一个 Pod 的 YAML 示例

yaml

apiVersion: v1
kind: Pod
metadata:
  labels:
    run: wordpress
  name: wordpress
  namespace: pods
spec:
  containers:
  - image: wordpress
    imagePullPolicy: Always
    name: wordpress
  nodeName: worker31.laoma.cloud
  restartPolicy: Always

2. Kubernetes Pod 核心概念

Pod 是 Kubernetes 中最小的调度、管理和自愈单元,是容器的“外壳”与运行环境。

2.1 Pod 与容器的区别

特性 容器 Pod
最小调度单位
独立 IP
多容器支持 ✅(同一 Pod 内共享网络和存储)
生命周期管理 完整(重启策略、自愈)
所属层面 容器运行时 Kubernetes API 对象

一句话总结:Pod 是 Kubernetes 对容器的一层抽象,它封装了一个或多个紧密耦合的容器,并为它们提供了统一的网络命名空间、存储挂载和生命周期管理。

2.2 pause 容器的作用

每个 Pod 内部都会自动运行一个极简的 pause 容器(也叫 infra 容器),它的作用至关重要:

  • 持有 Pod 的 Linux Namespace:所有业务容器都加入 pause 的网络、PID 等命名空间,从而实现 localhost 互访和共享 IP。
  • 保证 Pod 生命周期稳定:pause 容器永远第一个启动、最后一个退出。即使业务容器崩溃重启,Pod 的 IP 和网络环境也不会改变。

3. 多容器 Pod 实践

3.1 示例:WordPress + MySQL 双容器 Pod

以下 YAML 定义了一个包含 MySQL 和 WordPress 两个容器的 Pod,它们通过 127.0.0.1 相互通信。

pod-blog.yaml

yaml

apiVersion: v1
kind: Pod
metadata:
  name: bbs
  labels:
    run: bbs
spec:
  containers:
  - image: mysql:latest
    imagePullPolicy: IfNotPresent
    name: mysql
    env:
    - name: MYSQL_ROOT_PASSWORD
      value: "123"
    - name: MYSQL_USER
      value: tom
    - name: MYSQL_PASSWORD
      value: "123"
    - name: MYSQL_DATABASE
      value: bbs
    ports:
    - containerPort: 3306
      name: mysql
      protocol: TCP
  - image: wordpress:latest
    imagePullPolicy: IfNotPresent
    name: wordpress
    env:
    - name: WORDPRESS_DB_USER
      value: tom
    - name: WORDPRESS_DB_PASSWORD
      value: "123"
    - name: WORDPRESS_DB_NAME
      value: bbs
    - name: WORDPRESS_DB_HOST
      value: "127.0.0.1"          # 使用本地回环地址访问同 Pod 内的 MySQL
    ports:
    - containerPort: 80
      name: wordpress
      protocol: TCP
      hostPort: 80                # 将容器的 80 端口映射到宿主机 80 端口

3.2 多容器 Pod 运维命令

bash

# 创建 Pod 并查看状态
kubectl apply -f pod-blog.yaml
kubectl get pods -o wide

# 在指定容器中执行命令(-c 指定容器名)
kubectl exec bbs -c wordpress -- hostname

# 向指定容器拷贝文件
kubectl cp /etc/hosts bbs:/new-hosts -c wordpress

# 创建 Service 暴露服务
kubectl expose pod bbs --type NodePort
kubectl get svc bbs

# 进入 MySQL 容器交互
kubectl exec -it bbs -c mysql -- mysql -utom -p123

4. Pod 关键属性详解

使用 kubectl explain 可以随时查阅字段说明,例如:kubectl explain pod.spec.containers

4.1 Pod 规格(spec)常用字段

字段 类型 说明
containers []Object 必填,Pod 中的容器列表
nodeName string 将 Pod 调度到指定节点
restartPolicy string 重启策略:Always / OnFailure / Never
initContainers []Object 初始化容器,按顺序运行,全部成功后才会启动普通容器

4.2 容器规格(containers)常用字段

字段 类型 说明
name string 必填,容器名称
image string 容器镜像
imagePullPolicy string 镜像拉取策略
command []string 覆盖容器的 ENTRYPOINT
args []string 覆盖容器的 CMD
env []Object 环境变量列表
ports []Object 暴露的端口列表

4.3 镜像拉取策略(imagePullPolicy)

策略值 行为
Always 每次都从仓库拉取最新镜像
IfNotPresent 本地有则用本地,无则拉取(推荐)
Never 仅使用本地镜像,不存在则报错

5. Pod 生命周期与状态

5.1 Pod 常见状态

状态 含义
ContainerCreating 正在创建容器(拉镜像、分配资源等)
Running Pod 已绑定节点,所有容器已创建,至少一个容器正在运行
Completed 所有容器正常退出,且重启策略为 Never
Error 容器异常终止
CrashLoopBackOff 容器反复崩溃,kubelet 正在指数退避重启
ErrImagePull / ImagePullBackOff 镜像拉取失败

5.2 容器状态(container states)

  • Waiting:等待某些条件满足(如镜像下载)。
  • Running:正在运行。
  • Terminated:运行结束(正常或异常)。

5.3 单容器 Pod 状态实验

YAML 1:正常退出的容器

yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 10']

观察状态变化:ContainerCreatingRunningCompleted

YAML 2:命令错误的容器

yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5']

观察状态:ContainerCreatingError

5.4 多容器 Pod 状态实验

一个容器正常,一个容器错误

yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: Never
  containers:
  - name: busybox1
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxx Hello Kubernetes! && sleep 5']
  - name: busybox2
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 20']

最终 Pod 状态会变为 Error只要有一个容器非正常退出,整个 Pod 就会进入失败状态


6. Pod 重启策略(restartPolicy)

重启策略针对 Pod 内的所有容器生效,当容器退出时,kubelet 根据策略决定是否重启。

策略 行为
Always 任何情况下退出都自动重启(默认值)
OnFailure 仅当退出码非 0(失败)时才重启
Never 无论何种退出码,都不重启

6.1 单容器重启策略实验

验证 OnFailure 策略下错误命令的重启行为

yaml

apiVersion: v1
kind: Pod
metadata:
  name: busybox
  labels:
    app: busybox
spec:
  restartPolicy: OnFailure
  containers:
  - name: busybox
    image: busybox
    imagePullPolicy: IfNotPresent
    command: ['sh', '-c', 'echoxxx Hello Kubernetes! && sleep 5']

Pod 会不断重启,状态在 ErrorRunning 之间反复。

6.2 多容器重启策略说明

  • 只要任意一个容器触发重启条件,kubelet 就会重启整个 Pod(所有容器重新创建)。
  • 使用 Always 策略时,即使所有容器都正常退出,Pod 也会被不断重启。
  • 使用 Never 策略时,Pod 退出后不再重启。

7. Init 容器(Init Containers)

Init 容器是一种特殊的容器,在 Pod 内的普通容器启动之前按顺序执行。只有当所有 Init 容器都成功完成,普通容器才会启动。

典型应用场景

  • 等待依赖服务就绪(如数据库、后端 API)。
  • 执行初始化操作(如数据库迁移、配置文件生成)。
  • 延迟主容器启动。

7.1 示例:等待服务就绪

以下 Pod 中的两个 Init 容器会轮询 DNS 解析 myservicemydb,解析成功后才启动主容器。

yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
  labels:
    app: myapp
spec:
  initContainers:
  - name: init-myservice
    image: busybox
    command: ['sh', '-c', 'until nslookup myservice; do echo waiting for myservice; sleep 2; done;']
  - name: init-mydb
    image: busybox
    command: ['sh', '-c', 'until nslookup mydb; do echo waiting for mydb; sleep 2; done;']
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'echo The app is running! && sleep 3600']

配套 Service(需提前创建):

yaml

apiVersion: v1
kind: Service
metadata:
  name: myservice
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9376
---
apiVersion: v1
kind: Service
metadata:
  name: mydb
spec:
  ports:
  - protocol: TCP
    port: 80
    targetPort: 9377

7.2 示例:通过共享卷传递初始化文件

yaml

apiVersion: v1
kind: Pod
metadata:
  name: myapp-pod
spec:
  volumes:
  - name: workdir
    emptyDir: {}
  initContainers:
  - name: init-create-file
    image: busybox
    command: ['sh', '-c', 'touch /work-dir/init-file.txt']
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"
  containers:
  - name: myapp-container
    image: busybox
    command: ['sh', '-c', 'ls -l /work-dir && sleep 3600']
    volumeMounts:
    - name: workdir
      mountPath: "/work-dir"

8. 静态 Pod(Static Pod)

静态 Pod 是由节点上的 kubelet 直接管理的 Pod,而非通过 API Server 创建。Kubernetes 控制平面组件(如 kube-apiserverkube-controller-manager)通常以静态 Pod 形式运行。

8.1 工作原理

  • kubelet 启动参数中通过 --pod-manifest-path 或配置文件中的 staticPodPath 指定一个目录。
  • kubelet 定期扫描该目录下的 YAML 文件,并自动创建/删除对应的静态 Pod。
  • 静态 Pod 在 API Server 中可见(以 NodeName 为前缀),但无法通过 API Server 修改或删除。

8.2 查看集群静态 Pod 配置

bash

# 查看 kubelet 的静态 Pod 目录
grep staticPodPath /var/lib/kubelet/config.yaml
# 输出:staticPodPath: /etc/kubernetes/manifests

# 查看控制平面组件的静态 Pod 定义文件
ls -1 /etc/kubernetes/manifests
# 输出:
# etcd.yaml
# kube-apiserver.yaml
# kube-controller-manager.yaml
# kube-scheduler.yaml

注意:切勿随意修改或删除 /etc/kubernetes/manifests 下的文件,否则可能导致集群控制平面故障。


9. 知识点一览表

9.1 YAML 数据结构速查

结构 写法示例
字典 key: subkey: value
列表 items: - item1 - item2
多行字符串(保留换行) `msg:
多行字符串(合并为一行) msg: > long long string

9.2 Pod 关键字段速查表

层级 字段 作用
spec containers 定义容器列表
spec restartPolicy 重启策略:Always / OnFailure / Never
spec initContainers 初始化容器,按序执行
spec nodeName 指定调度节点
spec.containers image 镜像地址
spec.containers imagePullPolicy 拉取策略:Always / IfNotPresent / Never
spec.containers command / args 覆盖容器启动命令与参数
spec.containers env 环境变量列表

9.3 Pod 生命周期状态速查

状态 含义 常见原因
Pending 等待调度或拉取镜像 资源不足、镜像拉取慢
ContainerCreating 正在创建容器 拉取镜像中
Running 运行中 至少一个容器仍在运行
Completed 成功完成 所有容器正常退出,且重启策略为 Never
Error 容器异常退出 命令错误、OOMKilled 等
CrashLoopBackOff 反复崩溃重启中 容器启动后立即退出
ImagePullBackOff 镜像拉取失败 镜像名错误、仓库认证失败

9.4 常用 kubectl 命令速查

命令 用途
kubectl explain pod.spec.containers 查看字段文档
kubectl apply -f <file> 创建/更新资源
kubectl get pods -o wide 查看 Pod 及所在节点、IP
kubectl describe pod <name> 查看 Pod 详细事件和状态
kubectl exec <pod> -c <container> -- <cmd> 在指定容器中执行命令
kubectl cp <src> <pod>:<dest> -c <container> 向容器拷贝文件
kubectl delete pod <name> --force 强制删除 Pod
kubectl logs <pod> -c <container> 查看容器日志

9.5 Init 容器与普通容器对比

特性 Init 容器 普通容器
运行顺序 先于普通容器,且按顺序执行 所有 Init 容器成功后并行启动
生命周期 执行完即退出 持续运行(或按命令退出)
失败处理 根据 restartPolicy 决定是否重试 同左
典型用途 初始化、依赖等待 提供长期服务

更多推荐