文章目录
- 1、什么是pod
- 2、pod的使用
- 2.1 用于管理pod的工作负载资源
- 2.2 pod怎样管理多个容器
- 2.3 pod 操作系统
- 2.4 pod和控制器
- 2.5 pod模板
- 3、pod的更新与替换
- 3.1 资源共享和通信
- 3.2 pod中的存储
- 3.3 pod联网
- 4、容器的特权模式
- 4.1 linux 特权容器
- 4.2 windows特权容器
- 5、静态pod
- 6、容器探针
1、什么是pod
pod 是在kubernetes 中创建和管理的、最小的可部署的计算单元。
pod 是一组容器,这些容器 共享 存储、网络以及怎样运行这些容器的申明。
pod中的内容总是 并置的(colocated) 并且 一同调度,在共享的上下文中运行。
pod所建模的是特定于应用的“逻辑主机”,其中包含一个或多个应用容器,这些容器相对紧密的耦合在一起,在非云环境中,在相同的物理机或者虚拟机上运行的应用类似于在同一逻辑主机上运行的云应用。
除了应用容器,pod还可以包含 在pod启动期间运行的init容器
pod的共享上下文包括一组linux的 命名空间、控制组和一些其他的隔离容器的技术。在pod的上下文中,每个独立的应用可能会进一步实施隔离
pod类似于共享命名空间并共享文件系统卷的一组容器
2、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通常不是直接创建的,而是使用工作负载资源创建的
2.1 用于管理pod的工作负载资源
通常情况下我们不需要直接创建pod,甚至是单实例pod。
相反,我们会使用诸如 Deployment 或 job 这类工作负载资源来创建pod
如果 pod 需要跟踪状态,可以考虑 StatefulSet
资源
kubernetes
集群中的pod主要有两种用法:
- 运行单个容器的pod
“每个 Pod 一个容器” 模型是最常见的 Kubernetes 用例; 在这种情况下,可以将 Pod 看作单个容器的包装器,并且 Kubernetes 直接管理 Pod,而不是容器 - 运行多个协同工作的容器的pod
pod可能封装 由多个紧密耦合且需要共享资源的共处容器组成的应用程序。
这些位于同一位置的容器可能形成单个内聚的服务单元
一个容器将文件从共享卷提供给公众,而另一个单独的 “边车”(sidecar
)容器则刷新或更新这些文件
pod将这些容器和存储资源打包为一个可管理的实体
每个pod都旨在运行给定应用程序的单个实例,如果希望 横向扩展应用程序(如:运行多个实例以提供更多的资源),则应该使用多个pod, 每个实例使用一个pod。
在kubernetes
中,这种通常被称为副本(Replication),通常使用一种工作负载资源及其控制器来创建和管理一组pod副本
2.2 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因资源不足被驱逐或者节点失效为止。
2.3 pod 操作系统
通过将 .spec.os.name
设置为 windows
或linux
以表示希望pod运行在哪个操作系统之上。这两个选项是木棉kubernetes支持的操作系统列表
在kubernetes v1.28
版本中,为此字段设置的值对pod的调度没有影响。
设置.spec.os.name
有助于确定性的标识pod的操作系统并用于验证。
如果指定的 Pod 操作系统与运行 kubelet 所在节点的操作系统不同, 那么 kubelet 将会拒绝运行该 Pod。 Pod 安全标准也使用这个字段来避免强制执行与该操作系统无关的策略
2.4 pod和控制器
可以通过 工作负载资源来创建和管理多个pod。
资源的控制器能够处理副本的管理、上线。并在pod失效时提供自愈能力。
例如:如果一个节点失败,控制器注意到该节点上的pod已经停止工作,就可以创建替换性的pod。调度器会将替身pod调度到一个健康的节点上运行
2.5 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 模板相关的细节或模板的更新,这些细节都被抽象出来。 这种抽象和关注点分离简化了整个系统的语义, 并且使得用户可以在不改变现有代码的前提下就能扩展集群的行为。
3、pod的更新与替换
正如前面所说,当某工作负载的pod模板被改变时,控制器会基于更新的模板创建新的pod对象,而不是对现有的pod对象执行更新或者修补操作。
kubernetes并不会禁止我们直接去修改pod。对运行中的pod的某些字段执行就地更新操作还是可能的。不过,类似于patch
和replace
这类更新操作有一些限制。
- Pod的绝大多数元数据都是不可改变的
例如:我们不能改变其namespace
、name
、uid
或者creationTimestamp
字段;generation
字段是比较特别的,如果更新该字段,只能增加取值而不能减少 - 如果
metadata.deletionTimestamp
已经被设置,则不可以向metadata.finalizers
列表中添加新的条目 - pod更新不可以改变除
spec.containers[*].image
、spec.initContainers[*].image
、spec.activeDeadlineSeconds
或spec.tolerations
之外的字段。对于spec.tolerations
,只被允许添加新的条目到其中 - 在更新
spec.activeDeadlineSeconds
字段时,以下两种更新操作是被允许的:
如果该字段尚未设置,可以将其设置为一个正数
如果该字段已经设置为一个正数,可以将其设置为一个更小的非负的整数
3.1 资源共享和通信
pod使他的成员容器间能够进行数据共享和通信
3.2 pod中的存储
一个pod可以设置一组共享的存储卷。
pod中所有的容器都可以访问该共享卷,从而允许这些容器共享数据。
卷还允许pod中的持久数据保留下来,即使其中的ring器需要重新启动。
3.3 pod联网
每个pod都在每个地址族中获得一个唯一的IP地址。pod中的每个容器共享网络名字空间,包括IP地址和网络端口。
pod内的容器可以使用localhost
互相通信。当pod中的容器与pod外的实体通信时,他们必须协调如何使用共享的网络资源(如端口)
在同一个 Pod 内,所有容器共享一个 IP 地址和端口空间,并且可以通过 localhost 发现对方。
他们也能通过如 SystemV 信号量或 POSIX 共享内存这类标准的进程间通信方式互相通信。
不同 Pod 中的容器的 IP 地址互不相同,如果没有特殊配置,就无法通过 OS 级 IPC 进行通信。
如果某容器希望与运行于其他 Pod 中的容器通信,可以通过 IP 联网的方式实现
4、容器的特权模式
Pod 中的所有容器都可以在特权模式下运行,以使用原本无法访问的操作系统管理权能。 此模式同时适用于 Windows 和 Linux。
4.1 linux 特权容器
在linux中,pod中的所有容器都可以使用容器规约中的安全性上下文中的privileged
(linux)参数启用特权模式。这对于想要使用操作系统管理权能的容器很有用。
4.2 windows特权容器
在windows中,可以使用pod规约中安全上下文的windowsOptions.hostProcess
参数来创建Windows HostProcess Pod
。这些pod中的所有容器都必须以 Windows HostProcess
容器方式运行。
Windows HostProcess Pod
可以直接运行在主机上,它也能像 Linux 特权容器一样,用于执行管理任务
5、静态pod
静态 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 等)。
6、容器探针
Probe 是由 kubelet 对容器执行的定期诊断。要执行诊断,kubelet 可以执行三种动作:
ExecAction(借助容器运行时执行)
TCPSocketAction(由 kubelet 直接检测)
HTTPGetAction(由 kubelet 直接检测)