在K8S集群中,集群直接管理的不是容器,而是Pod
Pod是K8S集群中最小的管理、创建、计划单元
什么是Pod
一个Pod中会含有一个或多个需要共同工作、共享资源的容器,组成一个对外提供服务的单一实例,并且容器之间共享网络和存储。
Pod的英文翻译是“豆荚”,是一个组,里面的“豆子”在组中共享组内的空间、资源,所以名字起得还是很形象的。
Pause容器
每个Pod中都有一个Pause容器。
Pause是基础设施容器,它为整个Pod中其他业务容器提供了各种命名空间资源
-
PID命名空间 - Pod中的不同应用程序可以看到其他应用程序的进程ID。
-
网络命名空间 - Pod中的多个容器能够访问同一个IP和端口范围。
-
IPC命名空间 - Pod中的多个容器能够使用SystemV IPC或POSIX消息队列进行通信。
-
UTS命名空间 - Pod中的多个容器共享一个主机名、Volumes。
具体可以到 www.ianlewis.org/en/almighty… 进行更多了解。
网络
每个Pod拥有一个独立的IP地址,Pod中的每个容器共享Pod的网络。
所以Pod内的容器可以使用localhost相互通信。
Pod中容器如果对外提供服务,则该服务的地址为Pod的地址:映射到Pod上的端口。
存储
在Pod中,可以指定一组Volumes为共享存储,所有的容器都可以访问它,并通过它共享数据。
另外Volumes还可以用于Pod中数据的持久化,以防其中某个容器重启而丢失数据。
为什么用Pod
为什么K8S不便直接管理容器,而是选择通过Pod来管理容器?
-
更方便的管理由一组容器组成的服务。整个服务的状态是由Pause容器来标记,由于它与业务无关,所以不容易异常,且可以代表整个Pod的状态。
-
解决耦合业务容器之间的通信问题。Pod可以提供共享的物理存储和网络资源
为什么不使用一个容器,里面运行多个服务呢?
首先这违背了一个容器一个服务的原则。如果把多个服务部署在一个容器中,虽然部署过程简单了很多,但是会遇到一些问题
-
容器还在运行,服务却出现了异常,集群无法及时感知
-
某个服务出现了需要升级,却需要重启整个容器,导致其他服务受影响(服务隔离)
-
日志收集相对混乱
Pod生命周期
Pod有一个PodStatus对象,其中定义了一个phase字段,该字段代表着当前Pod所处的运行阶段。该字段有以下值
-
挂起(Pending)
此时Pod已被 Kubernetes 系统接受,但有一个或者多个容器镜像尚未创建。等待时间包括调度 Pod 的时间和通过网络下载镜像的时间等 -
运行中(Running)
该Pod已经绑定到了一个节点上,Pod中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态 -
成功(Succeeded)
Pod中的所有容器都被成功终止,并且不会再重启 -
失败(Failed)
Pod中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,Pod中的某个容器出现了异常(这也是为什么不建议一个容器里运行多个服务) -
未知(Unknown)
因为某些原因无法取得Pod的状态,通常是因为与Pod所在主机通信失败
Pod的用法
Pod不具备自愈能力,一旦Pod所在的节点资源不够、或出现了一些其他异常,这个Pod便会被驱逐
所以一般情况下不会单独创建一个Pod,因为Pod的生命周期是短暂的,一旦Pod除了异常便可能会被抛弃销毁掉
一般情况下会有一个Controller来对Pod进行管理,而Controller会提供一个Pod Template来创建相应的Pod
Pod Template
从官网搞来一个Pod模板。使用这个可以创建一个包含一个busybox容器的Pod
apiVersion: v1
kind: Pod
metadata:
name: myapp-pod
labels:
app: myapp
spec:
containers:
- name: myapp-container
image: busybox
command: ['sh', '-c', 'echo Hello Kubernetes! && sleep 3600']
简单列一下Pod的相关配置,也可以点击Pod查看godoc.org上k8s对配置文件结构的定义
type Pod struct {
metav1.TypeMeta `json:",inline"`
metav1.ObjectMeta `json:"metadata,omitempty"`
// Pod的明确定义
Spec PodSpec `json:"spec,omitempty"`
// Pod的状态,这个不是配置项,只读,有系统维护
Status PodStatus `json:"status,omitempty"`
}
type PodSpec struct {
// 可以被容器挂载使用的卷列表
Volumes []Volume `json:"volumes,omitempty"`
// Pod的初始化容器容器列表,初始化容器将会在Pod启动之前按照顺序依次启动执行,任何初始化容器失败,都会看做Pod启动失败,然后根据Pod的restartPolicy进行相关处理
// 初始化容器列表目前不能被修改
InitContainers []Container `json:"initContainers,omitempty"`
// 应用容器列表
Containers []Container `json:"containers"`
// 短暂容器配置
EphemeralContainers []EphemeralContainer `json:"ephemeralContainers,omitempty"`
// Pod中容器的重启策略
// 值有Always、OnFailure和Never,默认为Always
RestartPolicy RestartPolicy `json:"restartPolicy,omitempty"`
// Pod被停止前的等待时间,必须为非负整数,0值则立刻停止,默认30秒
// 在系统给Pod发送了SIGTERM信号后开始计时,TerminationGracePeriodSeconds秒后结束Pod
// 实际上是给Pod一些缓冲时间来进行结束前的清理工作
TerminationGracePeriodSeconds *int64 `json:"terminationGracePeriodSeconds,omitempty"`
// Pod在存活了ActiveDeadlineSeconds秒之后将会被标记为failed,并杀死相关的容器
// 值必须为一个正整数
ActiveDeadlineSeconds *int64 `json:"activeDeadlineSeconds,omitempty"`
// 为Pod设置DNS策略
// 值可以为ClusterFirst(默认)、ClusterFirstWithHostNet, Default和None
// 此处配置将会与DNSConfig一同合并到Pod的DNS配置里
DNSPolicy DNSPolicy `json:"dnsPolicy,omitempty"`
// 节点标签选择器。通过设置该值可以让Pod部署在满足指定标签要求的节点上。
NodeSelector map[string]string `json:"nodeSelector,omitempty"`
// 该Pod实用的ServiceAccount名
ServiceAccountName string `json:"serviceAccountName,omitempty"`
// 自动挂载ServiceAccount凭证
AutomountServiceAccountToken *bool `json:"automountServiceAccountToken,omitempty"`
// 要被调度到的节点名称,简单粗暴
NodeName string `json:"nodeName,omitempty"`
// 是否使用宿主机的网络命名空间 默认false
HostNetwork bool `json:"hostNetwork,omitempty"`
// 是否使用Host的PID命名空间 默认false
HostPID bool `json:"hostPID,omitempty"`
// 是否使用Host的IPC命名空间 默认false
HostIPC bool `json:"hostIPC,omitempty"`
// 在所有容器与Pod之间共享Process命名空间 默认false
// 设置为true后,容器可以查看和发送新号给同一个Pod下其他容器的进程,而且容器中第一个进程的PID也不会是1
// 不能与HostPID同时为true
ShareProcessNamespace *bool `json:"shareProcessNamespace,omitempty"`
// 控制pod-level安全属性和容器的通用配置,默认为空
SecurityContext *PodSecurityContext `json:"securityContext,omitempty"`
// 查看 https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod
ImagePullSecrets []LocalObjectReference `json:"imagePullSecrets,omitempty"`
// Pod主机名称,默认使用系统定义的值
Hostname string `json:"hostname,omitempty"`
// 如果定义了,Pod的完整hostname值将为<hostname>.<subdomain>.<pod namespace>.svc.<cluster domain>
// 否则不会有域名部分
Subdomain string `json:"subdomain,omitempty"`
// Pod的亲和配置,通过该配置可以将节点调度到指定的环境中
Affinity *Affinity `json:"affinity,omitempty"`
// 调度器名称,默认使用默认调度器
SchedulerName string `json:"schedulerName,omitempty"`
// Pod的容忍配置,可以容忍节点的污点,通过该配置可以将节点调度到指定的环境中
Tolerations []Toleration `json:"tolerations,omitempty"`
// 为Pod增加额外的hosts配置
HostAliases []HostAlias `json:"hostAliases,omitempty"`
// 权重类型名称,可以通过配置此值来使用对应的PriorityClass
// system-node-critical和system-cluster-critical是两个定义了最高级权重的特殊值
// 如果此值未找到对应的权重类,则默认使用0
PriorityClassName string `json:"priorityClassName,omitempty"`
// 权重值,在Pod调度过程中会根据该值决定是否优先部署该Pod
// 当使用PriorityAdmission控制器的时候,此值不允许用户赋值,将会从PriorityClassName对应的PriorityClass上获取
Priority *int32 `json:"priority,omitempty"`
// DNS配置,将会合并到生成的DNS配置中。配置将基于DNSPolicy。
DNSConfig *PodDNSConfig `json:"dnsConfig,omitempty"`
// Pod是否就绪的判断列表
// Pod将在所有容器转改为就绪和所有这里定义的条件状态为True时就绪
ReadinessGates []PodReadinessGate `json:"readinessGates,omitempty"`
// 配置RuntimeClass的名称,默认为legacy
// 更多信息查看https://git.k8s.io/enhancements/keps/sig-node/runtime-class.md
RuntimeClassName *string `json:"runtimeClassName,omitempty"`
// Pod创建后会将一些服务信息以环境变量的形式注入Pod
// 可以通过 kubectl exec <pod-name> -- printenv 查看
// 如果不需要服务环境变量,可以通过将此值设置为false禁用,默认为true
EnableServiceLinks *bool `json:"enableServiceLinks,omitempty"`
// 标记是否会抢占低优先级的Pod,
// 值有PreemptLowerPriority(默认)和Never,分别代表会抢占低优先级Pod和不会抢占低优先级Pod
PreemptionPolicy *PreemptionPolicy `json:"preemptionPolicy,omitempty"`
// 配置Pod的开销情况 Kubernetes v1.16 alpha
// 在设置了该值以后,调度Pod的时候除了要考虑容器请求的资源以外,还会考虑Pod的开销
// 在驱逐其他Pod的时候,除了优先级、资源使用情况外,也会考虑Pod的开销情况
// 详情查看https://kubernetes.io/docs/concepts/configuration/pod-overhead/
Overhead ResourceList `json:"overhead,omitempty"`
// Pod的拓扑约束配置
// 详情查看https://kubernetes.io/docs/concepts/workloads/pods/pod-topology-spread-constraints/
TopologySpreadConstraints []TopologySpreadConstraint `json:"topologySpreadConstraints,omitempty"`
}