一、简介

在Kubernetes集群中,Pod是所有业务类型的基础,也是K8S管理的最小单位级,它是一个或多个容器的组合。这些容器共享存储、网络和命名空间,以及如何运行的规范。在Pod中,所有容器都被统一安排和调度,并运行在共享的上下文中。对于具体应用而言,Pod是它们的逻辑主机,Pod包含业务相关的多个应用容器。

二、Pod实现机制与设计模式

每个Pod都有一个特殊的被称为"根容器"的Pause 容器(Pause容器,又叫Infrastructure容器)。 Pause容器对应的镜像属于Kubernetes平台的一部分,除了Pause容器,每个Pod还包含一个或者多个紧密相关的用户业务容器。

众所周知,容器之间是通过Namespace隔离的,Pod要想解决上述应用场景,那么就要让Pod里的容器之间高效共享。
具体分为两个部分:网络和存储

  • 共享网络

kubernetes的解法是这样的:会在每个Pod里先启动一个infra container小容器,然后让其他的容器连接进来这个网络命名空间,然后其他容器看到的网络试图就完全一样了,即网络设备、IP地址、Mac地址等,这就是解决网络共享问题。在Pod的IP地址就是infra container的IP地址。

  • 共享存储

比如有两个容器,一个是nginx,另一个是普通的容器,普通容器要想访问nginx里的文件,就需要nginx容器将共享目录通过volume挂载出来,然后让普通容器挂载的这个volume,最后大家看到这个共享目录的内容一样。

例如:

# pod-write-read.yaml
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
containers:
- name: write
image: centos
command: ["bash","-c","for i in {1..100};do echo $i >> /data/hello;sleep 1;done"]
volumeMounts:
- name: data
mountPath: /data - name: read
image: centos
command: ["bash","-c","tail -f /data/hello"]
volumeMounts:
- name: data
mountPath: /data volumes:
- name: data
emptyDir: {}

上述示例中有两个容器,write容器负责提供数据,read消费数据,通过数据卷将写入数据的目录和读取数据的目录都放到了该卷中,这样每个容器都能看到该目录。
验证:

$ kubectl apply -f pod-write-read.yaml
$ kubectl logs my-pod -c read -f

在Pod中容器分为以下几个类型:

  • Infrastructure Container:基础容器,维护整个Pod网络空间,对用户不可见
  • InitContainers:初始化容器,先于业务容器开始执行,一般用于业务容器的初始化工作
  • Containers:业务容器,具体跑应用程序的镜像

三、镜像拉取策略

apiVersion: v1
kind: Pod
metadata:
name: pod001
spec:
containers:
- name: busybox001
image: busybox
imagePullPolicy: IfNotPresent

imagePullPolicy 字段有三个可选值:

  • IfNotPresent:镜像在宿主机上不存在时才拉取

  • Always:默认值,每次创建 Pod 都会重新拉取一次镜像

  • Never: Pod 永远不会主动拉取这个镜像

注意,这里的重启是指在Pod所在Node上面本地重启,并不会调度到其他Node上去。

四、资源限制

Pod资源配额有两种:

申请配额:调度时使用,参考是否有节点满足该配置

  • spec.containers[].resources.limits.cpu

  • spec.containers[].resources.limits.memory

限制配额:容器能使用的最大配置

  • spec.containers[].resources.requests.cpu

  • spec.containers[].resources.requests.memory

apiVersion: v1
kind: Pod
metadata:
name: pod002
spec:
containers:
- name: busybox002
image: busybox
resources:
requests:
memory: "64Mi"
cpu: "250m"
limits:
memory: "128Mi"
cpu: "500m"

其中cpu值比较抽象,可以这么理解:

1核=1000m

1.5核=1500m

那上面限制配置就是1核的二分之一(500m),即该容器最大使用半核CPU。

该值也可以写成浮点数,更容易理解:

半核=0.5

1核=1

1.5核=1.5

五、重启策略


apiVersion: v1
kind: Pod
metadata:
name: pod003
spec:
containers:
- name: busybox003
image: busybox
restartPolicy: Always

restartPolicy字段有三个可选值:

  • Always:当容器终止退出后,总是重启容器,默认策略

  • OnFailure:当容器异常退出(退出状态码非0)时,才重启容器。适于job

  • Never:当容器终止退出,从不重启容器。适于job

六、 健康检查

默认情况下,kubelet 根据容器状态作为健康依据,但不能容器中应用程序状态,例如程序假死。这就会导致无法提供服务,丢失流量。因此引入健康检查机制确保容器健康存活。

健康检查有两种类型:

  • livenessProbe

如果检查失败,将杀死容器,根据Pod的restartPolicy来操作。

  • readinessProbe

如果检查失败,Kubernetes会把Pod从service endpoints中剔除。

这两种类型支持三种检查方法:

  • httpGet

发送HTTP请求,返回200-400范围状态码为成功。

  • exec

执行Shell命令返回状态码是0为成功。

  • tcpSocket

发起TCP Socket建立成功。

# health-check.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
test: liveness
name: liveness-exec
spec:
containers:
- name: liveness
image: busybox
args:
- /bin/sh
- -c
- touch /tmp/healthy; sleep 30; rm -rf /tmp/healthy; sleep 60
livenessProbe:
exec:
command:
- cat
- /tmp/healthy
initialDelaySeconds: 5
periodSeconds: 5

上述示例:启动容器第一件事在容器内创建文件,停止30s,删除该文件,再停止60s,确保容器还在运行中。

验证现象:容器启动正常,30s后异常,会restartPolicy策略自动重建,容器继续正常,反复现象。

$ kubectl apply -f health-check.yaml
$ kubectl describe pod liveness-exec
$

七、调度策略

先看下创建一个Pod的工作流程: create pod -> apiserver -> write etcd -> scheduler -> bind pod to node -> write etcd -> kubelet( apiserver get pod) -> dcoekr api,create container -> apiserver -> update pod status to etcd -> kubectl get pods

Pod根据调度器默认算法将Pod分配到合适的节点上,一般是比较空闲的节点。但有些情况我们希望将Pod分配到指定节点,该怎么做呢?

这里给你介绍调度策略:nodeName、nodeSelector和污点

1)nodeName

nodeName用于将Pod调度到指定的Node名称上。
例如:下面示例会绕过调度系统,直接分配到k8s-node1节点。

# SchedulePolicy-nodeName.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: busybox
name: busyboxnn
namespace: default
spec:
nodeName: k8s-node1
containers:
- image: busybox
name: bs
command:
- "ping"
- "baidu.com"

执行&查看

$ kubectl apply -f SchedulePolicy-nodeName.yaml
$ kubectl get pod busyboxnn -o wide

2)nodeSelector

nodeSelector用于将Pod调度到匹配Label的Node上。先给规划node用途,然后打标签,例如将两台node划分给不同团队使用:

$ kubectl label nodes k8s-node1 team=a
$ kubectl label nodes k8s-node2 team=b

后在创建Pod只会被调度到含有team=a标签的节点上。

# SchedulePolicy-nodeSelector.yaml
apiVersion: v1
kind: Pod
metadata:
name: busyboxsn
namespace: default
spec:
nodeSelector:
team: b
containers:
- image: busybox
name: bs
command:
- "ping"
- "baidu.com"

执行&查看

$ kubectl apply -f SchedulePolicy-nodeSelector.yaml
$ kubectl get pod busyboxsn -o wide

3)taint(污点)与tolerations(容忍)

  • 污点应用场景:节点独占,例如具有特殊硬件设备的节点,如GPU
    设置污点命令:
    kubectl taint node [node] key=value[effect]

其中[effect] 可取值:

  • NoSchedule :一定不能被调度。
  • PreferNoSchedule:尽量不要调度。
  • NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。

示例:

先给节点设置污点,说明这个节点不是谁都可以调度过来的:

$ kubectl taint node k8s-node1  abc=123:NoSchedule

查看污点:

$ kubectl describe node k8s-node1 |grep Taints

然后在创建Pod只有声明了容忍污点(tolerations),才允许被调度到abc=123污点节点上

# SchedulePolicy-tolerations.yaml
apiVersion: v1
kind: Pod
metadata:
labels:
run: busybox
name: busybox3
namespace: default
spec:
tolerations:
- key: "abc"
operator: "Equal"
value: "123"
effect: "NoSchedule"
containers:
- image: busybox
name: bs
command:
- "ping"
- "baidu.com"

如果不配置容忍污点,则永远不会调度到k8s-node1。(也可以叫做反亲和性
去掉污点:

kubectl taint node k8s-node1 abc=123:NoSchedule

$ kubectl taint node k8s-node1 abc:NoSchedule-

master节点默认是打了污点标记,不调度的,去掉污点标记

#添加 尽量不调度 PreferNoSchedule
kubectl taint nodes k8s-master node-role.kubernetes.io/master:PreferNoSchedule
#去除污点NoSchedule,最后一个"-"代表删除
kubectl taint nodes k8s-master node-role.kubernetes.io/master:NoSchedule-

八、Pod状态

1)Pod常见状态

1、Pending:等待中

Pod已经被创建,但还没有完成调度,或者说有一个或多个镜像正处于从远程仓库下载的过程。处在这个阶段的Pod可能正在写数据到etcd中、调度、pull镜像或启动容器。

2、Running:运行中

该 Pod 已经绑定到了一个节点上,Pod 中所有的容器都已被创建。至少有一个容器正在运行,或者正处于启动或重启状态。

3、Succeeded:正常终止

Pod中的所有的容器已经正常的执行后退出,并且不会自动重启,一般会是在部署job的时候会出现。

4、Failed:异常停止

Pod 中的所有容器都已终止了,并且至少有一个容器是因为失败终止。也就是说,容器以非0状态退出或者被系统终止。

5、Terminating 或 Unknown 状态

从 v1.5 开始,Kubernetes 不会因为 Node 失联而删除其上正在运行的 Pod,而是将其标记为 Terminating 或 Unknown 状态。

6、Error 状态

通常处于 Error 状态说明 Pod 启动过程中发生了错误。常见的原因包括:

  • 依赖的 ConfigMap、Secret 或者 PV 等不存在
  • 请求的资源超过了管理员设置的限制,比如超过了 LimitRange 等
  • 违反集群的安全策略,比如违反了 PodSecurityPolicy 等
  • 容器无权操作集群内的资源,比如开启 RBAC 后,需要为 ServiceAccount 配置角色绑定。

7、Completed状态

状态由ContainerCreating变为Completed再变为CrashLoopBackOff,原因是command: 或args 参数错误无法正常执行。

用一张图来表示Pod的各个状态

2)Pod 其它状态详细说明

状态 描述
ContainerCreating 容器创建中
PodInitializing pod 初始化中
CrashLoopBackOff 容器曾经启动了,但可能又异常退出了,kubelet正在将它重启
InvalidImageName 无法解析镜像名称
ImageInspectError 无法校验镜像
ErrImageNeverPull 策略禁止拉取镜像
ImagePullBackOff 正在重试拉取
RegistryUnavailable 连接不到镜像中心
ErrImagePull 通用的拉取镜像出错
CreateContainerConfigError 不能创建kubelet使用的容器配置
CreateContainerError 创建容器失败
m.internalLifecycle.PreStartContainer 执行hook报错
RunContainerError 启动容器失败
PostStartHookError 执行hook报错
ContainersNotInitialized 容器没有初始化完毕
ContainersNotRead 容器没有准备完毕
DockerDaemonNotReady docker还没有完全启动
NetworkPluginNotReady 网络插件还没有完全启动

pod启动后停止问题总结(ContainerCreating-》Completed-》CrashLoopBackOff):

pod 是否能持续运行,是由执行命令决定的,执行命令如果一执行就停止,控制台也停止持续输出,pod生命周期就结束,pod状态就会变成CrashLoopBackOff。

pod资源清单

apiVersion: v1     #必选,版本号,例如v1
kind: Pod   #必选,资源类型,例如 Pod
metadata:   #必选,元数据
name: string #必选,Pod名称
namespace: string #Pod所属的命名空间,默认为"default"
labels:    #自定义标签列表
- name: string  
spec: #必选,Pod中容器的详细定义
containers: #必选,Pod中容器列表
- name: string #必选,容器名称
image: string #必选,容器的镜像名称
imagePullPolicy: [ Always|Never|IfNotPresent ] #获取镜像的策略
command: [string] #容器的启动命令列表,如不指定,使用打包时使用的启动命令
args: [string] #容器的启动命令参数列表
workingDir: string #容器的工作目录
volumeMounts: #挂载到容器内部的存储卷配置
- name: string #引用pod定义的共享存储卷的名称,需用volumes[]部分定义的的卷名
mountPath: string #存储卷在容器内mount的绝对路径,应少于512字符
readOnly: boolean #是否为只读模式
ports: #需要暴露的端口库号列表
- name: string #端口的名称
containerPort: int #容器需要监听的端口号
hostPort: int #容器所在主机需要监听的端口号,默认与Container相同
protocol: string #端口协议,支持TCP和UDP,默认TCP
env: #容器运行前需设置的环境变量列表
- name: string #环境变量名称
value: string #环境变量的值
resources: #资源限制和请求的设置
limits: #资源限制的设置
cpu: string #Cpu的限制,单位为core数,将用于docker run --cpu-shares参数
memory: string #内存限制,单位可以为Mib/Gib,将用于docker run --memory参数
requests: #资源请求的设置
cpu: string #Cpu请求,容器启动的初始可用数量
memory: string #内存请求,容器启动的初始可用数量
lifecycle: #生命周期钩子
postStart: #容器启动后立即执行此钩子,如果执行失败,会根据重启策略进行重启
preStop: #容器终止前执行此钩子,无论结果如何,容器都会终止
livenessProbe: #对Pod内各容器健康检查的设置,当探测无响应几次后将自动重启该容器
exec:   #对Pod容器内检查方式设置为exec方式
command: [string] #exec方式需要制定的命令或脚本
httpGet: #对Pod内个容器健康检查方法设置为HttpGet,需要制定Path、port
path: string
port: number
host: string
scheme: string
HttpHeaders:
- name: string
value: string
tcpSocket: #对Pod内个容器健康检查方式设置为tcpSocket方式
port: number
initialDelaySeconds: 0 #容器启动完成后首次探测的时间,单位为秒
timeoutSeconds: 0    #对容器健康检查探测等待响应的超时时间,单位秒,默认1秒
periodSeconds: 0    #对容器监控检查的定期探测时间设置,单位秒,默认10秒一次
successThreshold: 0
failureThreshold: 0
securityContext:
privileged: false
restartPolicy: [Always | Never | OnFailure] #Pod的重启策略
nodeName: <string> #设置NodeName表示将该Pod调度到指定到名称的node节点上
nodeSelector: obeject #设置NodeSelector表示将该Pod调度到包含这个label的node上
imagePullSecrets: #Pull镜像时使用的secret名称,以key:secretkey格式指定
- name: string
hostNetwork: false #是否使用主机网络模式,默认为false,如果设置为true,表示使用宿主机网络
volumes: #在该pod上定义共享存储卷列表
- name: string #共享存储卷名称 (volumes类型有很多种)
emptyDir: {} #类型为emtyDir的存储卷,与Pod同生命周期的一个临时目录。为空值
hostPath: string #类型为hostPath的存储卷,表示挂载Pod所在宿主机的目录
path: string    #Pod所在宿主机的目录,将被用于同期中mount的目录
secret:    #类型为secret的存储卷,挂载集群与定义的secret对象到容器内部
scretname: string
items:
- key: string
path: string
configMap: #类型为configMap的存储卷,挂载预定义的configMap对象到容器内部
name: string
items:
- key: string
path: string

Kubernetes(k8s)pod详解的更多相关文章

  1. Kubernetes 部署策略详解-转载学习

    Kubernetes 部署策略详解 参考:https://www.qikqiak.com/post/k8s-deployment-strategies/ 在Kubernetes中有几种不同的方式发布应 ...

  2. services资源+pod详解

    services资源+pod详解 一.Service 虽然每个Pod都会分配一个单独的Pod IP,然而却存在如下两问题: Pod IP 会随着Pod的重建产生变化 Pod IP 仅仅是集群内可见的虚 ...

  3. 自动化集成:Kubernetes容器引擎详解

    前言:该系列文章,围绕持续集成:Jenkins+Docker+K8S相关组件,实现自动化管理源码编译.打包.镜像构建.部署等操作:本篇文章主要描述Kubernetes引擎用法. 一.基础简介 Kube ...

  4. [Kubernetes]yaml文件详解

    应前一段时间夸下的海口:[Kubernetes]如何使用yaml文件使得可以向外暴露服务,说过要写一篇关于yaml文件详解的文章出来的,今天来总结一下.yaml文件用在很多地方,但是这里以介绍在Kub ...

  5. K8s架构详解

    每个微服务通过 Docker 进行发布,随着业务的发展,系统中遍布着各种各样的容器.于是,容器的资源调度,部署运行,扩容缩容就是我们要面临的问题. 基于 Kubernetes 作为容器集群的管理平台被 ...

  6. Kubernetes Pod详解

    目录 基本概念 pod资源配额 容器的健康检查 静态pod 基本概念 Pod是kubernetes集群中最基本的资源对象.每个pod由一个或多个业务容器和一个根容器(Pause容器)组成.Kubern ...

  7. kubernetes创建资源对象yaml文件例子--pod详解

    apiVersion: v1 #指定api版本,此值必须在kubectl apiversion中 kind: Pod #指定创建资源的角色/类型 metadata: #资源的元数据/属性 name: ...

  8. kubernetes 实践四:Pod详解

    本篇是关于k8s的Pod,主要包括Pod和容器的使用.Pod的控制和调度管理.应用配置管理等内容. Pod的定义 Pod是k8s的核心概念一直,就名字一样,是k8s中一个逻辑概念.Pod是docekr ...

  9. K8S学习笔记之Kubernetes 部署策略详解

    0x00 概述 在Kubernetes中有几种不同的方式发布应用,所以为了让应用在升级期间依然平稳提供服务,选择一个正确的发布策略就非常重要了. 选择正确的部署策略是要依赖于我们的业务需求的,下面我们 ...

  10. 使用acs-engine在Azure中国区部署kubernetes集群详解

    转载请注明出处:http://www.cnblogs.com/wayneiscoming/p/7649642.html 1. acs-engine简介 ACS是微软在2015年12月推出的一项基于容器 ...

随机推荐

  1. react中如何正确使用setState(附例子)

    概述 setState中对于某个state多次修改,只执行一次(最后一次),所以可以将修改放在同一次中 import React, {Component} from 'react'; class De ...

  2. 图形学的up

    https://space.bilibili.com/512313464 c++ 路线有前者的经历https://mp.weixin.qq.com/s?__biz=Mzg2MDU0ODM3MA==&a ...

  3. Job for nfs-server.service failed because the control process exited with error code. See "systemctl status nfs-server.service" and "journalctl -xe" for details.

    问题: 解决:

  4. 最好用的 vue v-for直接循环案例

    vue v-for直接循环数字,也就是固定次数 项目中需要做一个酒店星级,酒店星级就是固定的5星,根据后台返回的数据来显示几星级 <!--星级,循环固定次数 5次 根据酒店等级显示亮的星星和灰色 ...

  5. Docker emqx实践

    把emqx服务迁移到另一台服务器上 1.新服务器安装docker apt  install docker.io 1.从服务器上导出镜像 导出镜像文件: docker export 55d48d3a13 ...

  6. ubuntu 系统增加源和删除源文件

    一.添加PPA源文件 语法格式:sudo add-apt-repository ppa:user/ppa-name 示例: sudo add-apt-repository ppa:sergiomeji ...

  7. nacos2.1 新增配置发布失败。请检查参数是否正确

    使用官方的docker部署方式,部署了一个单节点nacos server,部署完了后发布配置信息,报错"新增配置发布失败.请检查参数是否正确" 解决方法: 在nacos mysql ...

  8. Android 系统完整的权限列表

    访问登记属性  android.permission.ACCESS_CHECKIN_PROPERTIES ,读取或写入登记check-in数据库属性表的权限  获取错略位置  android.perm ...

  9. python编程中的if __name__ == 'main': 的作用

    python的文件有两种使用的方法,第一是直接作为脚本执行,第二是import到其他的python脚本中被调用(模块重用)执行. 因此if __name__ == 'main': 的作用就是控制这两种 ...

  10. x-www-form-urlencoded请求封装

    <dependency> <groupId>commons-httpclient</groupId> <artifactId>commons-httpc ...