pod 是在kubernetes 中创建和管理的、最小的可部署的计算单元。
pod 是一组容器,这些容器 共享 存储、网络以及怎样运行这些容器的申明。
pod中的内容总是 并置的(colocated) 并且 一同调度,在共享的上下文中运行。
pod所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器,这些容器相对紧密的耦合在一起,在非云环境中,在相同的物理机或者虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。
除了应用容器,pod还可以包含 在pod启动期间运行的init容器
pod的共享上下文包括一组linux的 命名空间、控制组和一些其他的隔离容器的技术。在pod的上下文中,每个独立的应用可能会进一步实施隔离
pod类似于共享命名空间并共享文件系统卷的一组容器
下面是一个使用pod的示例,它由一个运行径向nginx:1.14.2的容器组成
apiVersion: v1
kind: Pod
metadata:
name: nginx
spec:
containers:
- name: nginx
image: nginx:1.14.2
ports:
- containerPort: 80
要创建上面显示的pod,可以通过执行下面的这条命令实现:
kubectl apply -f https://k8s.io/examples/pods/simple-pod.yaml
注意:pod通常不是直接创建的,而是使用工作负载资源创建的
通常情况下我们不需要直接创建pod,甚至是单实例pod。
相反,我们会使用诸如 Deployment 或 job 这类工作负载资源来创建pod
如果 pod 需要跟踪状态,可以考虑 StatefulSet
资源
kubernetes
集群中的pod主要有两种用法:
sidecar
)容器则刷新或更新这些文件每个pod都旨在运行给定应用程序的单个实例,如果希望 横向扩展应用程序(如:运行多个实例以提供更多的资源),则应该使用多个pod, 每个实例使用一个pod。
在kubernetes
中,这种通常被称为副本(Replication),通常使用一种工作负载资源及其控制器来创建和管理一组pod副本
pod被设计成支持形成内聚服务单元多个协作过程(形式为容器)
pod中的容器被自动安排到集群中的同一物理机或虚拟机上, 并可以一起进行调度。容器之间可以共享资源和依赖、彼此通信、协调何时以及何种方式终止自身。
例如:你可能有一个容器,为共享卷中的文件提供 Web 服务器支持,以及一个单独的 “边车 (sidercar)” 容器负责从远端更新这些文件,如下图所示:
有些pod 具有应用容器和init容器,init容器
会在启动应用容器之前运行并完成
特性状态:
启用SideCarContainers
特性门控,允许为容器指定restartPolicy:Always
设置重启策略为always会确保 init容器
在pod的整个生命周期内保持运行
pod天生的为其他成员容器提供了两种共享资源:网络和存储
我们很少在kubernetes
中直接创建一个个的pod
,甚至是单实例(Singleton
)的pod
。这是因为pod被设计成了相对临时性的、用后即抛的一次性实体。
当pod由控制器创建时,他被调度在集群的节点上运行。pod会保持在该节点上运行,直到pod结束执行、pod对象被删除、pod因资源不足被驱逐或者节点失效为止。
通过将 .spec.os.name
设置为 windows
或linux
以表示希望pod运行在哪个操作系统之上。这两个选项是木棉kubernetes支持的操作系统列表
在kubernetes v1.28
版本中,为此字段设置的值对pod的调度没有影响。
设置.spec.os.name
有助于确定性的标识pod的操作系统并用于验证。
如果指定的 Pod 操作系统与运行 kubelet 所在节点的操作系统不同, 那么 kubelet 将会拒绝运行该 Pod。 Pod 安全标准也使用这个字段来避免强制执行与该操作系统无关的策略
可以通过 工作负载资源来创建和管理多个pod。
资源的控制器能够处理副本的管理、上线。并在pod失效时提供自愈能力。
例如:如果一个节点失败,控制器注意到该节点上的pod已经停止工作,就可以创建替换性的pod。调度器会将替身pod调度到一个健康的节点上运行
工作负载资源的控制器通常使用 pod模板(pod template)来替我们创建pod并管理他们
pod模板是包含在工作负载对象中的规范,用来创建pod。这类负载资源包括Deployment
、Job
和DaemonSet
工作负载控制器会使用负载对象中的PodTemplate
来生成实际的pod。PodTemplate
是用来运行应用时指定的负载资源的目标状态的一部分。
下面的示例是一个job清单,其中的template
指示启动一个容器。该pod中的容器会打印一条消息之后暂停。
apiVersion: batch/v1
kind: Job
metadata:
name: hello
spec:
template:
# 这里是 Pod 模板
spec:
containers:
- name: hello
image: busybox:1.28
command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
restartPolicy: OnFailure
# 以上为 Pod 模板
修改pod模板 或者 切换到新的pod模板 都不会对已经存在的pod直接起作用。如果改变工作负载资源的 Pod 模板,工作负载资源需要使用更新后的模板来创建 Pod, 并使用新创建的 Pod 替换旧的 Pod。
例如,StatefulSet 控制器 针对 每个 StatefulSet 对象 确保运行中的 Pod 与当前的 Pod 模板匹配。如果编辑 StatefulSet 以更改其 Pod 模板, StatefulSet 将开始基于更新后的模板创建新的 Pod。
在节点上,kubelet 并不直接监测或管理与 Pod 模板相关的细节或模板的更新,这些细节都被抽象出来。 这种抽象和关注点分离简化了整个系统的语义, 并且使得用户可以在不改变现有代码的前提下就能扩展集群的行为。
正如前面所说,当某工作负载的pod模板被改变时,控制器会基于更新的模板创建新的pod对象,而不是对现有的pod对象执行更新或者修补操作。
kubernetes并不会禁止我们直接去修改pod。对运行中的pod的某些字段执行就地更新操作还是可能的。不过,类似于patch
和replace
这类更新操作有一些限制。
namespace
、name
、uid
或者creationTimestamp
字段;generation
字段是比较特别的,如果更新该字段,只能增加取值而不能减少metadata.deletionTimestamp
已经被设置,则不可以向metadata.finalizers
列表中添加新的条目spec.containers[*].image
、spec.initContainers[*].image
、spec.activeDeadlineSeconds
或spec.tolerations
之外的字段。对于spec.tolerations
,只被允许添加新的条目到其中spec.activeDeadlineSeconds
字段时,以下两种更新操作是被允许的:pod使他的成员容器间能够进行数据共享和通信
一个pod可以设置一组共享的存储卷。
pod中所有的容器都可以访问该共享卷,从而允许这些容器共享数据。
卷还允许pod中的持久数据保留下来,即使其中的ring器需要重新启动。
每个pod都在每个地址族中获得一个唯一的IP地址。pod中的每个容器共享网络名字空间,包括IP地址和网络端口。
pod内的容器可以使用localhost
互相通信。当pod中的容器与pod外的实体通信时,他们必须协调如何使用共享的网络资源(如端口)
在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,并且可以通过 localhost 发现对方。
他们也能通过如 SystemV 信号量或 POSIX 共享内存这类标准的进程间通信方式互相通信。
不同 Pod 中的容器的 IP 地址互不相同,如果没有特殊配置,就无法通过 OS 级 IPC 进行通信。
如果某容器希望与运行于其他 Pod 中的容器通信,可以通过 IP 联网的方式实现
Pod 中的所有容器都可以在特权模式下运行,以使用原本无法访问的操作系统管理权能。 此模式同时适用于 Windows 和 Linux。
在linux中,pod中的所有容器都可以使用容器规约中的安全性上下文中的privileged
(linux)参数启用特权模式。这对于想要使用操作系统管理权能的容器很有用。
在windows中,可以使用pod规约中安全上下文的windowsOptions.hostProcess
参数来创建Windows HostProcess Pod
。这些pod中的所有容器都必须以 Windows HostProcess
容器方式运行。
Windows HostProcess Pod
可以直接运行在主机上,它也能像 Linux 特权容器一样,用于执行管理任务
静态 Pod(Static Pod) 直接由特定节点上的 kubelet 守护进程管理, 不需要 API 服务器看到它们。 尽管大多数 Pod 都是通过控制面(例如,Deployment) 来管理的,对于静态 Pod 而言,kubelet 直接监控每个 Pod,并在其失效时重启
静态 Pod 通常绑定到某个节点上的 kubelet。 其主要用途是运行自托管的控制面。 在自托管场景中,使用 kubelet 来管理各个独立的控制面组件。
kubelet 自动尝试为每个静态 Pod 在 Kubernetes API 服务器上创建一个镜像 Pod。 这意味着在节点上运行的 Pod 在 API 服务器上是可见的,但不可以通过 API 服务器来控制
静态 Pod 的 spec 不能引用其他的 API 对象(例如: ServiceAccount、 ConfigMap、 Secret 等)。
Probe 是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 可以执行三种动作:
ExecAction(借助容器运行时执行)
TCPSocketAction(由 kubelet 直接检测)
HTTPGetAction(由 kubelet 直接检测)