理解Pod:Kubernetes中最核心的概念

378 阅读5分钟

理解Pod:Kubernetes中最核心的概念

为什么要有pod

Pod:含义是豌豆荚的意思,一个豌豆荚中是可以有多个豌豆的,同理,Kubernetes中的Pod,一个Pod中也可以有多个容器。

为了解决现实应用中多应用联合运行的问题,同时还要不破坏容器的隔离,就需要在容器外面再建立一个“收纳舱” ,让多个容器既保持相对独立,又能够小范围共享网络、存储等资源,而且永远是“绑在一起”的状态。

我们可以在 Pod 的 YAML 里看到,“spec.containers”字段其实是一个数组,里面允许定义多个容器。

为什么Pod是Kubernetes的核心对象

Kubernetes 让 Pod 去编排处理容器,然后把 Pod 作为应用调度部署的最小单位,Pod 也因此成为了 Kubernetes 世界里的“原子”,基于Pod就可以构建出更多更复杂的业务形态。

b5a7003788cb6f2b1c5c4f6873a8b5cf.jpg (1920×1298) (raw.githubusercontent.com)

所有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

image.png

查看Pod列表和运行状态

 kubectl get po

image-20230131164438685

查看Pod的详细状态

 kubectl describe pod busy-pod

image-20230131164644286

通常需要关注的是末尾的“Events”部分,它显示的是 Pod 运行过程中的一些关键节点事件。对于这个 busy-pod,因为它只执行了一条 echo 命令就退出了,而 Kubernetes 默认会重启 Pod,所以就会进入一个反复停止 - 启动的循环错误状态。

一个正常的Pod的详细状态

 kubectl describe pod ngx-pod

image-20230131170108699

 kubectl logs ngx-pod

image-20230131165940878

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进行查看

image-20230131170630524

总结

  1. 现实中经常会有多个进程密切协作才能完成任务的应用,而仅使用容器很难描述这种关系,所以就出现了 Pod,它“打包”一个或多个容器,保证里面的进程能够被整体调度。
  2. Pod 是 Kubernetes 管理应用的最小单位,其他的所有概念都是从 Pod 衍生出来的。
  3. Pod 也应该使用 YAML“声明式”描述,关键字段是“spec.containers”,列出名字、镜像、端口等要素,定义内部的容器运行状态。
  4. 操作 Pod 的命令很多与 Docker 类似,如 kubectl run、kubectl cp、kubectl exec 等,但有的命令有些小差异,使用的时候需要注意。 img

《极客时间-Kubernetes入门实战课》学习笔记 Day12 极客课程分享