Kubernetes 学习笔记:Pod 基础与 YAML 编排
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']
观察状态变化:ContainerCreating → Running → Completed
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']
观察状态:ContainerCreating → Error
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 会不断重启,状态在 Error 与 Running 之间反复。
6.2 多容器重启策略说明
- 只要任意一个容器触发重启条件,kubelet 就会重启整个 Pod(所有容器重新创建)。
- 使用
Always策略时,即使所有容器都正常退出,Pod 也会被不断重启。 - 使用
Never策略时,Pod 退出后不再重启。
7. Init 容器(Init Containers)
Init 容器是一种特殊的容器,在 Pod 内的普通容器启动之前按顺序执行。只有当所有 Init 容器都成功完成,普通容器才会启动。
典型应用场景:
- 等待依赖服务就绪(如数据库、后端 API)。
- 执行初始化操作(如数据库迁移、配置文件生成)。
- 延迟主容器启动。
7.1 示例:等待服务就绪
以下 Pod 中的两个 Init 容器会轮询 DNS 解析 myservice 和 mydb,解析成功后才启动主容器。
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-apiserver、kube-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 决定是否重试 |
同左 |
| 典型用途 | 初始化、依赖等待 | 提供长期服务 |
更多推荐
所有评论(0)