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: 1088user: {name: laoma, uid: 1088}
列表(数组)- 开头的一系列项names: - httpd - firewalldnames: [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 中的容器列表
nodeNamestring将 Pod 调度到指定节点
restartPolicystring重启策略:Always / OnFailure / Never
initContainers[]Object初始化容器,按顺序运行,全部成功后才会启动普通容器

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

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

4.3 镜像拉取策略(imagePullPolicy)

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

5. Pod 生命周期与状态

5.1 Pod 常见状态

状态含义
ContainerCreating正在创建容器(拉镜像、分配资源等)
RunningPod 已绑定节点,所有容器已创建,至少一个容器正在运行
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 关键字段速查表

层级字段作用
speccontainers定义容器列表
specrestartPolicy重启策略:Always / OnFailure / Never
specinitContainers初始化容器,按序执行
specnodeName指定调度节点
spec.containersimage镜像地址
spec.containersimagePullPolicy拉取策略:Always / IfNotPresent / Never
spec.containerscommand / args覆盖容器启动命令与参数
spec.containersenv环境变量列表

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 决定是否重试同左
典型用途初始化、依赖等待提供长期服务

更多推荐