kubernetes-Pod深入理解

创建一个Pod的流程

Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。
其他组件监控自己负责的资源,当这些资源发生变化时,kube-apiserver会通知这些组件,这个过程类似于发布与订阅
在这里插入图片描述
创建一个pod的工作流程
1、创建pod:kubectl run web --image=nginx
2、apiserver收到创建pod的请求,将相关资源写入到etcd中
3、scheduler收到apiserver的通之,为未分配pod根据调度算法选择一台合适的节点进行绑定,相当于做一个记号,例如namenode=k8s-node1,在响应给apiserver、apiserver存储到etcd
4、kubelet收到apiserver的通知,将分配到我自己节点上的pod通过docker api创建,并汇报状态给apiserver
5、kubectl get pods查看创建的pod

当然还有两个组件,controller-manager和kube-proxy
 controller-manager控制器在创建pod过程中会参与进来,比如说创建一个deployment时,控制器就会在Scheduler之前进行干预
 kube-porxy负责网络,当创建service时就会干预进来

Pod中影响调度的主要属性

Pod调度策略有两个----资源调度依据调度策略
我简单的例出一些来

调度类型参数
资源调度依据resources:{}
调度策略schedulerName: default-scheduler(这个可以自己开发也可以用k8s自有的)
nodeName: " "
nodeSelector: {}
affinity:{}
tolerations: {}
资源限制

容器资源限制:

  • resources.limits.cpu
  • resources.limits.memory
    容器使用的最小资源需求,作为容器调度时资源分配的依据:
  • resources.requests.cpu
  • resources.requests.memory
    CPU单位:可以写成浮点数,例如0.5=500m,1=1000m

资源限制就是通过:limits,它限制了容器最大使用的资源
资源请求:requests,相当于预留资源(实际不占用),用于合理分配(所有的node相当于是一个资源池,资源池利用率就是根据requests计算的)

案例

在这里插入图片描述

# 创建好这个pod后,查看节点的资源分配
[root@k8s-master1 ~]# kubectl describe nodes k8s-node2

在这里插入图片描述
在这里插入图片描述

nodeSelector & nodeAffinity

nodeSelector:用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。
他可以约束Pod到特定节点运行,完全匹配节点标签
一般用于专用节点(根据业务线将Node分组管理),配备特殊的硬件,容器需要使用这些资源(部分Node配备GPU等其他资源)

# 在创建pod时根据匹配到的标签进行去分配,所以,对应的node节点也是需要打上标签的
# 那么第一步就是对指定节点打上标签(假如说第三台机器有GPU,为第三台机器打上标签)
# 标签的键值对为gpu和ok,当然这个可以是随便起的
[root@k8s-master ~]# kubectl label nodes  k8s-node2 gpu=ok
# 查看标签,可以看到k8s-node2是有gpu=ok的标签的
[root@k8s-master ~]# kubectl get node --show-labels
NAME         STATUS   ROLES                  AGE   VERSION   LABELS
k8s-master   Ready    control-plane,master   27m   v1.21.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-master,kubernetes.io/os=linux,node-role.kubernetes.io/control-plane=,node-role.kubernetes.io/master=,node.kubernetes.io/exclude-from-external-load-balancers=
k8s-node1    Ready    <none>                 14m   v1.21.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node1,kubernetes.io/os=linux
k8s-node2    Ready    <none>                 14m   v1.21.0   beta.kubernetes.io/arch=amd64,beta.kubernetes.io/os=linux,gpu=ok,kubernetes.io/arch=amd64,kubernetes.io/hostname=k8s-node2,kubernetes.io/os=linux

测试

# 创建一个pod,并指定标签
[root@k8s-master ~]# vim pod.yaml
apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
spec:
  nodeSelector:
    gpu: "ok"
  containers:
  - image: nginx
    name: web
    resources: {}
# 构建Pod
[root@k8s-master ~]# kubectl apply -f pod.yaml
# 查看状态,会发现他跑到了k8s-node2上,但是这样子不一定可以体现出nodeselector特性来
[root@k8s-master ~]# kubectl get pods -o wide
# 可以把k8s-node2的标签去除,看看pod会怎么样,去除后已存在的popd还是正常运行的
[root@k8s-master ~]# kubectl label nodes k8s-node2 gpu-
# 那么我们删除掉原来的pod重新创建下看看他还会被分配么
[root@k8s-master ~]# kubectl delete -f pod.yaml
[root@k8s-master ~]# kubectl apply -f pod.yaml
# 可以看到pod状态为pending状态,使用describe命令查看日志时也会发现该pod没有被分配
[root@k8s-master ~]# kubectl get pods -o wide
# 在来给某个节点打上gpu=ok的标签,这次给node1打标签
[root@k8s-master ~]# kubectl label node k8s-node1 gpu=ok
#查看状态时就会发现pod被分配并且创建到了node1上

nodeAffinity:节点情和性,与nodeSelector作用一样,但相比更灵活,满足更多条件

  • 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作符:In、Notln、Exists、DoesNotExist、Gt、Lt
  • 调度分为软策略和硬策略,而不是硬性要求
    • 硬(required):必须满足
    • 软(preferred):尝试满足,但不保证

硬性策略测试测试

# 现在官网复制一下实例,地址如下
# https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/
# 修改其内容
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/e2e-az-name
            operator: In
            values:
            - e2e-az1
            - e2e-az2
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: another-node-label-key
            operator: In
            values:
            - another-node-label-value
  containers:
  - name: with-node-affinity
    image: k8s.gcr.io/pause:2.0
-------------------------------------------------------------------------
# 修改为
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution: # 硬性策略
        nodeSelectorTerms:
        - matchExpressions:       # 这三行是固定格式,不需要去管他
          - key: gpu              # 标签的键
            operator: In          # 动作,表示这个节点上有key=values的值
            values:               # 标签的值,可以有多个值
            - ok
  containers:
  - name: with-node-affinity
    image: nginx
# 创建
[root@k8s-master ~]# kubectl apply -f pod-nodeaffinity.yaml

软性策略测试测试
软性策略即使没有匹配到对应的键值,他也会去分配

# 修改内容如下,然后进行创建
apiVersion: v1
kind: Pod
metadata:
  name: with-node-affinity
spec:
  affinity:
    nodeAffinity:
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1                         # 权重,只是会去优先分配,软性的不会像硬性那样固定
        preference:
          matchExpressions:
          - key: gpu
            operator: In
            values:
            - ok2
  containers:
  - name: with-node-affinity
    image: nginx
Taint(污点)与Tolerations(污点容忍)

基于节点标签分配是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的Node上,其实我们也可以站在Node的角度上,通过在Node上添加污点属性,来避免Pod被分配到不合适的节点上

  • Taints:避免Pod调度到特定Node上
  • Tolerations:允许Pod调度到持有Taints的Node上

添加污点的格式
一、给节点添加污点
格式:kubectl taint node [node] key=value:[effect]
例如:kubectl taint node k8s-node1 gpu=yes:NoSchedule
验证:kubectl describe node k8s-node1 | grep Taint

其中[effect]可取值

  • NoSchedule:一定不能被调度(新来的不要来,在这儿的就别动了)
  • PreferNoSchedule:尽量不要调度(尽量不要来,除非没办法)
  • NoExecute:不仅不会调度,还会驱逐Node上已有的Pod(新来的不要来,在这里的也走)

二、添加污点容忍(tolrations)字段到Pod配置中
如果没有配置污点容忍的话,那么所有的Pod都不会被分配到有污点的节点上
(注意:master自带一个污点)

# 添加污点
[root@k8s-master ~]# kubectl taint node k8s-node1 gpu=yes:NoSchedule
# 在pod的yaml文件中配置污点容忍,使其可以调度掉有污点的主机上去
# 添加污点容忍可以去官网搜索taint即可
apiVersion: v1
kind: Pod
metadata:
  name: pod-taint
spec:
  tolerations:
  - key: "gpu"
    operator: "equal"      # 这个操作符也有多个参数可以支持
    effect: "NoSchedule"
    value: "yes"
  containers:
  - image: nginx
    name: web
    resources: {}

可以去看看calico.yaml中的污点容忍的,他的匹配范围极大,只要有"NoSchedule"的就去容忍

# calico.yaml污点容忍配置如下
      tolerations:
        # Mark the pod as a critical add-on for rescheduling.
        - key: CriticalAddonsOnly
          operator: Exists
        - key: node-role.kubernetes.io/master
          effect: NoSchedule

三、去掉污点
kubectl taint node [node] key:[effect]-

nodeName

nodeName:指定节点名称,用于将Pod调度到指定的Node上,不经过调度器

apiVersion: v1
kind: Pod
metadata:
  name: pod-taint
spec:
  # 指哪儿打哪儿,因为不经过调度器,所以在配置nodename时即使该节点有污点,也会创建成功
  nodename: k8s-node1
  containers:
  - image: nginx
    name: web
    resources: {}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值