Morse's Site
1173 字
6 分钟
Kubernetes - Pod
2020-05-15

Pod,是 Kubernetes 项目中最小的 API 对象. Pod, 是Kubernetes项目的原子调度单位.

为什么需要Pod?#

容器的本质是进程. 而在操作系统中, 进程并不是独自运行的, 而是以进程组的方式运行.

而在Kubernetes的设计中, 映射了这种进程与进程组的关系. 而这中关系的结果就是Pod.

在一个Pod中:

  1. 共享文件: 直接文件交换
  2. 共享网络: 使用localhost或socket文件通信, Pod只有一个IP地址.

Pod是一个逻辑的概念. 在Kubernetes中, 真正处理的还是Linux上的容器. 而并不存在一个所谓的Pod的边界或者隔离环境.

可以形象的比喻: Pod 扮演的是传统部署环境里“虚拟机”的角色。 所以调度, 网络, 存储, 以及安全相关的属性, 基本上都是Pod级别的.

一个Pod是怎样被创建出来的#

Pod是一组共享了某些资源的容器. 所以当需要启动一个Pod时. 需要先启动一个中间容器, 叫做infra容器.

在这个Pod中. infra容器永远都是第一个被创建的容器, 而用户在Pod中定义的容器则时通过Join Network Namesapce的方式. 与Infra容器关联在一起.

在kubernetes中. Infra容器使用的是: k8s.grc.io/pause镜像. 永远处于暂停状态的容器.

Pod的生命周期与Infra容器一致, 而与用户定义的容器无关.

Pod 在 Kubernetes 中的生命周期#

Pod的生命周期体现在status部分. 即: pod.status.phase. 表示pod的当前状态.

  • Pending: 这个状态意味着, Pod的yaml文件已提交给Kubernetes, API对象已经被创建并保存到Etcd当中. 但是, 这个Pod里有些容器因为某种原因而不能顺利创建. 比如: 调度不成功.
  • Running: Pod已经被调度成功, 跟一个具体的Node节点绑定. 它包含的容器都已经被创建成功, 并且至少有一个正在运行.
  • Successed: Pods里的所有容器都正常运行完毕, 并且已经退出了. 这种状态在Job/CronJob最常见
  • Failed: Pod里至少有一个容器不以正常状态(非0状态的返回码)退出. 这种状态出现, 需要debug这个容器应用.(可以查看pod的Event和日志)
  • Unknown: 异常状态. 意味着Pod的状态不能持续地被kubelet汇报给kube-apiserver. 这很有可能是主从节点(Master与Kubelet)之间的通信出现了问题.

Pod 中几个重要字段的含义和用法#

  • NodeSelector:是一个供用户将 Pod 与 Node 进行绑定的字段
apiVersion: v1
kind: Pod
...
spec:
 nodeSelector:
   disktype: ssd
  • NodeName:一旦 Pod 的这个字段被赋值,Kubernetes 项目就会被认为这个 Pod 已经经过了调度,调度的结果就是赋值的节点名字。所以,这个字段一般由调度器负责设置,但用户也可以设置它来“骗过”调度器,当然这个做法一般是在测试或者调试的时候才会用到。

  • HostAliases:定义了 Pod 的 hosts 文件(比如 /etc/hosts)里的内容

apiVersion: v1
kind: Pod
...
spec:
  hostAliases:
  - ip: "10.1.2.3"
    hostnames:
    - "foo.remote"
    - "bar.remote"
...
  • 共享PID Namespace: 在Pod的所有容器中, 每个容器进程对所有容器都是可见的.
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  shareProcessNamespace: true
  containers:
  - name: nginx
    image: nginx
  - name: shell
    image: busybox
    stdin: true
    tty: true

docker run -it-it交互是窗口,i表示的是stdin,t表示的是tty,后者表示的是终端交互窗口,可以接收用户的输入,并且输出结果,而若要需要实现输入信息,需要同时开启标准输入流,stdin正式用来做这个操作

Pod中Container的几个重要字段#

  • ImagePullPolicy: 镜像拉取策略

  • Lifecycle: Container Lifecycle Hooks, 容器状态变化时触发一系列的钩子.

apiVersion: v1
kind: Pod
metadata:
  name: lifecycle-demo
spec:
  containers:
  - name: lifecycle-demo-container
    image: nginx
    lifecycle:
      postStart:
        exec:
          command: ["/bin/sh", "-c", "echo Hello from the postStart handler > /usr/share/message"]
      preStop:
        exec:
          command: ["/usr/sbin/nginx","-s","quit"]

postStart: 容器启动后, 立即执行一个指定操作. 如果postStart执行超时, 会导致Pod也处于失败状态. 同时可以在Pod的Event中报出该容器启动失败的错误信息.

注意: postStart 并不能保证执行顺序. 也就是说postStart启动时, 镜像的启动(ENTRYPOINT)可能还没有结束.

preStop: 容器被杀死之前(比如: SIGKILL信号). preStop操作的执行, 是同步的. 所以preStop指令会阻塞当前容器杀死流程, 直到preStop操作结束, 才允许容器被杀死.

极客时间-深入剖析Kubernetes

#01 Blogs/Kubernetes#

Kubernetes - Pod
https://fuwari.vercel.app/posts/cncf/pod/
作者
Morse Hsiao
发布于
2020-05-15
许可协议
CC BY-NC-SA 4.0