【K8S】整体原理-什么是K8S的Pod

什么是Pod

Pod是K8S的一个逻辑概念,Pod其实是一组紧密协作的容器,容器就是我们应用程序执行代码的地方,在K8S里管理员要去管理应用的生命周期(包括异常退出等),那就需要获取应用运行的状态,获取应用的状态需要获取容器的运行状态。容器在K8S里是一个单进程,该进程就是应用进程,这样就可以从外部获取容器现在的状态,一个Pod内所有的进程共享资源。

为什么K8S要有Pod

方便去管理容器进程,也就是方便管理容器内主要的应用进程。
在这里插入图片描述

图为物理机,物理机上已经安装好了Kubelet进程,Kubelet接收到安装文件(一个有Pod信息)会先创建Infra Container(是一个镜像,大概 100~200KB 左右,永远处于暂停状态的容器。是用来对Pod共享网络的)会对Docker0这个网桥进行网络连接,然后其他Pod内部的容器在依次创建后会共享Infra网络,实现一个Pod内的网络共享。存储的共享还是需要每个Pod去挂载相同的存储地址来实现。

容器内使用Pod信息

1.通过环境变量

env:

  - name: NODE_NAME
    valueFrom:
      fieldRef:
        fieldPath: spec.nodeName # 根据配置 "层级.引用" 类似key-value

2.通过配置文件

volumes:  # 使用volume挂载到Pod
  - name: podinfo
    downwardAPI: # 使用该API,支持Pod和Container的信息
      items:
        - path: "labels"
          fieldRef:
            fieldPath: metadata.labels

Pod健康检查

有三类探针:

  • LivenessProbe: 判断是否存活,kubelet默认会重启不是存活的Pod
  • ReadinessProbe:判断是否可用,service只有在readinessProbe为ready状态,对外提供服务
  • StartupProbe:有且仅有一次的超长启动延时(针对慢应用)

探针的实现方式:

  • ExeAction:容器内部执行运行命令,返回码为0,代表健康
livenessProbe:
  exec:
    command:
    - cat 
    - /tmp/health
  • TCPSocketAction: 通过容器IP+端口,执行TCP检查,能够建立TCP连接,代表健康
livenessProbe:
  tcpSocket:
    port: 80
  • HTTPGetAction:HTTP Get响应状态码在200-400之间,代表健康
livenessProbe:
  httpGet:
    path: /health
    port: 80
  initialDelaySeconds: 30  # 容器首次健康服务检查等待时间
  timeoutSeconds: 1  # 等待健康检查相应的时间

Pod资源控制

资源控制范围包括:CPU,Memory和扩展资源如GPU(扩展资源只能获取整数个资源)

  • Containers下面resource中进行资源的request和limits配置

apiVersion: v1
kind: Pod
metadata:
  name: test
spec:
  containers:
  - name: test
    image: busybox
    resources: # 机器上至少有这么多的资源才能被创建
      request:
      memory: "64Mi"
      cpu: "250m"
      ephemeral-storage: "2Gi"
    limits:  # 机器上至多有这么多的资源能被使用
      memory: "128Mi"
      cpu: "500m"
      ephemeral-storage: "4Gi"
  • 资源Quota

限制每个Namespace资源用量,超出限制时,用户无法提交新建

apiVersion: v1
kind: ResourceQuota
metadata:
  name: demo
  namespace: demo
spec:
  hard:
    cpu: "1000"  #这个namespace下面的所有Pod使用的资源总量不超过1000
    memory: 200Gi
    pods: "10"

Pod Qos服务质量

就是说我们有多个Pod,每一个Pod重要程度不一样,比如某些Pod就算是在资源不足的时候我们也不希望他们会被驱逐。

所以可以对Pod的服务质量进行一个分类,分别是Guranteed,Bursable和BestEffort

Guranteed:Pod里面每个容器都会有内存和CPU的request声明和limit声明,且request和limit必须是一致的,以此告诉K8S这些Pod很重要,一定要保证Pod正常运行。

Bursable: 至少有一个容器存在内存和CPU的一个request,优先级比Guranteed低

BestEffort:request和limit都不填,意味着这个Pod可有可无

系统用request进行调度的,对CPU资源而言,系统会对Guranteed的Pod单独划分CPU资源,Bursable和BestEffort共用CPU资源(按照权重来使用不同的时间片),内存对资源而说,会对Pod划分OOMScore,score越高越优先被杀掉,Guranteed固定为-998,BestEffort固定为1000,Bursable则是按照内存大小和节点关系会根据算法计算出2~999范围内的值 ,资源不足发生驱逐时,优先驱逐BestEffort定义的容器。

Pod的调度

当我们希望Pod能够在指定的机器上运行的时候,或者定义那两个Pod在同一个机器上,或者定义那两个Pod不在同一个机器上,就要用到亲和度。

Pod亲和调度

1.PodAffinity
  • requiredDuringSchedulingIgnoredDuringExecution:强制亲和(调度时,执行亲和校验;运行时,忽略标签内发生的变化带来的影响)
  • preferredDuringSchedulingIgnoredDuringExecution:优先亲和
affinity:
  podAffinity:
    requiredDuringSchedulingIgnoredDuringExecution:
    - labelSelector:
      matchExpressions:
      - key: security
        operator: In #操作符 In NotIn Exist DoesNotExist Gt Lt
        values:
        - S1
      topogyKey: kubernetes.io/hostname #设置拓扑键,默认的设置topology.kubernetes.io/region topology.kubernetes.io/zone
2.podAntAffinity
  • requiredDuringSchedulingIgnoredDuringExecution:强制反亲和
  • preferredDuringSchedulingIgnoredDuringExecution:优先反亲和

Node亲和调度

1.NodeSelector: 强制调度到指定节点(强制调度Pod在指定的机器上创建)

2.NodeAffinity

  • requiredDuringSchedulingIgnoredDuringExecution:强制反亲和
  • preferredDuringSchedulingIgnoredDuringExecution:优先反亲和
3.Taint:一个Node可以有多个Taints

​ 1.行为模式有:

  • PreferNoSchedule: 尽量不要调度过来

  • NoSchedule:禁止Pod调度来

  • NoExecute: 驱逐没有tolerantion的Pod,并禁止调度新的(如果有的Pod已经在运行了,而且没有tolerantion,就会被杀掉并调度到新的机器上)

    apiVersion: v1
    kind: Node
    metadata:
      name: demo
    spec:
      taints:
      - key: "k1"
        value: "v1"
        effect: "NoSchedule"
    

    2.Pod的tolernation,只有设置对应的tolernation才能调度到有Taint的Node上

apiVersion: v1
kind: Pod
metadata:
  namespace: demo
  name: demo
spec:
  containers:
  - image: busybox
    name: demo
  tolerations:
  - key: "k1"
    operator: "Equal"
    value: "v1"  # 当op=Exist 可以为空 key和value和effect必须匹配上面的taints,这样Pod才能被调度到打了taint的Node上
    effect: "NodSechedule"  # 可以为空,匹配所有
    tolerationsSeconds: 3600   #taint添加后,pod还能在node上运行的时间

优先级调度

很多Pod同时创建时,有的优先级高,有的优先级低。这时kubelet会根据Pod配置priority,得分高的会对得分低的进行资源抢占

1.使用PriorityClass创建节点,Pod中通过PriorityClassName引用相应优先级

apiVersion: v1
kind: PriortyClass
metadata:
  name: high
value: 1000
globalDefault: false

2.系统默认优先级

​ 1.没有设置均为0

​ 2.用户可配置最大优先级为10亿,系统级别优先级为20亿

​ 3.内置系统优先级:system-cluster-critical,system-node-critical

Pod调度过程

用户调教Yaml文件,webhook controller 会先对文件进行校验,校验成功后,Api-Server会创建Pod对象,这个对象会保存到ETCD里面。此时Pod的Node名称为空(这个Pod已经有了,但是还没有落实到相应的节点上),Kube Scheduler (Kube Scheduler 会不断查看资源对象,发现某个Pod刚创建,但Node是空的,就会创建)会watch到Pod的创建,同时发现Node名称为空,会找到合适的Node,并修改Pod名称为相应的Node名,相应节点上的kubelet watch(这个进程会不断的请求Api-Server去发现他的节点上有个Pod需不需要创建) 到Pod需要创建,会在Node节点上创建容器和网络。

其他

InitContainer

比普通容器先启动,执行成功后普通容器才能启动,且是按照顺序执行,执行完之后会关闭。普通容器可以并发启动。

Sidecar 容器设计模式

用一个辅助容器做辅助工作,如日志收集,debug,前置操作等。好处:对应业务代码没有侵入:功能解耦,共享,模式包括:

代理模式:代理网络等

适配器模型:适配不同外观需求

Pod容灾

让Pod在不同的区域内分布,实现Pod容灾

topologySpreadConstraints:
  - topogyKey: address
    maxSkew: 1  # 用于指明Pod在各个zone中容忍的最大不均匀数,值越小每个zone中Pod分布越均匀
    whenUnsatisfiable: DoesNotSchedule
    labelSelector:
      matchLabels:
        app: myapp

Pod容灾

让Pod在不同的区域内分布,实现Pod容灾

topologySpreadConstraints:
  - topogyKey: address
    maxSkew: 1  # 用于指明Pod在各个zone中容忍的最大不均匀数,值越小每个zone中Pod分布越均匀
    whenUnsatisfiable: DoesNotSchedule
    labelSelector:
      matchLabels:
        app: myapp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值