理解Pod:Kubernetes中最核心的概念
为什么要有pod
Pod:含义是豌豆荚的意思,一个豌豆荚中是可以有多个豌豆的,同理,Kubernetes中的Pod,一个Pod中也可以有多个容器。
为了解决现实应用中多应用联合运行的问题,同时还要不破坏容器的隔离,就需要在容器外面再建立一个“收纳舱” ,让多个容器既保持相对独立,又能够小范围共享网络、存储等资源,而且永远是“绑在一起”的状态。
我们可以在 Pod 的 YAML 里看到,“spec.containers”字段其实是一个数组,里面允许定义多个容器。
为什么Pod是Kubernetes的核心对象
Kubernetes 让 Pod 去编排处理容器,然后把 Pod 作为应用调度部署的最小单位,Pod 也因此成为了 Kubernetes 世界里的“原子”,基于Pod就可以构建出更多更复杂的业务形态。

所有Kubernetes资源都直接或间接依附在Pod上,所有的Kubernetes功能都必须通过Pod来实现,所以 Pod 理所当然地成为了 Kubernetes 的核心对象。
使用YAML描述Pod
Pod里的一些常用字段
因为 Pod 也是 API 对象,所以它也必然具有 apiVersion、kind、metadata、spec 这四个基本组成部分。
apiVersion、kind、metadata
“apiVersion”和“kind”这两个字段很简单,对于 Pod 来说分别是固定的值 v1 和 Pod,而一般来说,“metadata”里应该有 name 和 labels 这两个字段。
- name: Pod必须要有一个名字,这是Kubernetes里所有资源对象的一个约定,Pod对象建议加一个 pod 后缀。
- labels: 可以根据运行环境,使用env=dev/test/prod,或根据所在数据中心,使用region=north/south,或根据应用所在系统中的层次,使用tier=front/middle/back
apiVersion: v1
kind: Pod
metadata:
name: busy-pod
labels:
owner: chrono
env: demo
region: north
tier: back
spec
spec”字段由于需要管理、维护 Pod 这个 Kubernetes 的基本调度单元,里面有非常多的关键信息。
可以采用kubectl explain来查看hostname、restartPolicy等字段。
containers
“containers”是一个数组,里面的每一个元素又是一个 container 对象,也就是容器。
和 Pod 一样,container 对象也必须要有一个 name 表示名字,然后当然还要有一个 image 字段来说明它使用的镜像,这两个字段是必须要有的,否则 Kubernetes 会报告数据验证错误。
container 对象的其他字段基本上都可以和“入门篇”学过的 Docker、容器技术对应,理解起来难度不大,我就随便列举几个:
- image:如果镜像的tag是latest,那么无论imagePullpolicy策略是什么,无论本地是否已存在该镜像文件,一定会先联网查询镜像信息
- ports:列出容器对外暴露的端口,和 Docker 的 -p 参数有点像。
- imagePullPolicy:指定镜像的拉取策略,可以是 Always/Never/IfNotPresent,一般默认是 IfNotPresent,也就是说只有本地不存在才会远程拉取镜像,可以减少网络消耗。
- env:定义 Pod 的环境变量,和 Dockerfile 里的 ENV 指令有点类似,但它是运行时指定的,更加灵活可配置。
- command:定义容器启动时要执行的命令,相当于 Dockerfile 里的 ENTRYPOINT 指令。
- args:它是 command 运行时的参数,相当于 Dockerfile 里的 CMD 指令,这两个命令和 Docker 的含义不同,要特别注意。
spec:
containers:
- image: busybox:latest
name: busy
imagePullPolicy: IfNotPresent
env:
- name: os
value: "ubuntu"
- name: debug
value: "on"
command:
- /bin/echo
args:
- "$(os), $(debug)"
这里我为 Pod 指定使用镜像 busybox:latest,拉取策略是 IfNotPresent ,然后定义了 os 和 debug 两个环境变量,启动命令是 /bin/echo,参数里输出刚才定义的环境变量。
使用kubectl操作Pod
创建和删除Pod
使用kubectl apply、kubectl delete,用 -f 参数指定 YAML 文件创建或者删除 Pod
kubectl apply -f busy-pod.yml
kubectl delete -f busy-pod.yml
因为在YAML中定义了“name”,所以也可以直接指定名字来删除
kubectl delete pod busy-pod
查看Pod的运行日志
和 Docker 不一样,Kubernetes 的 Pod 不会在前台运行,只能在后台(相当于默认使用了参数 -d),所以输出信息不能直接看到。我们可以用命令 kubectl logs,它会把 Pod 的标准输出流信息展示给我们看,在这里就会显示出预设的两个环境变量的值:
kubectl logs busy-pod
查看Pod列表和运行状态
kubectl get po
查看Pod的详细状态
kubectl describe pod busy-pod
通常需要关注的是末尾的“Events”部分,它显示的是 Pod 运行过程中的一些关键节点事件。对于这个 busy-pod,因为它只执行了一条 echo 命令就退出了,而 Kubernetes 默认会重启 Pod,所以就会进入一个反复停止 - 启动的循环错误状态。
一个正常的Pod的详细状态
kubectl describe pod ngx-pod
kubectl logs ngx-pod
cp 和 exec
echo 'aaa' > a.txt
kubectl cp a.txt ngx-pod:/tmp
kubectl exec -it ngx-pod -- sh
将a.txt使用 kubectl cp 拷贝进 Pod 的“/tmp”目录
使用exec添加-it参数进入Pod进行查看
总结
- 现实中经常会有多个进程密切协作才能完成任务的应用,而仅使用容器很难描述这种关系,所以就出现了 Pod,它“打包”一个或多个容器,保证里面的进程能够被整体调度。
- Pod 是 Kubernetes 管理应用的最小单位,其他的所有概念都是从 Pod 衍生出来的。
- Pod 也应该使用 YAML“声明式”描述,关键字段是“spec.containers”,列出名字、镜像、端口等要素,定义内部的容器运行状态。
- 操作 Pod 的命令很多与 Docker 类似,如 kubectl run、kubectl cp、kubectl exec 等,但有的命令有些小差异,使用的时候需要注意。
《极客时间-Kubernetes入门实战课》学习笔记 Day12