企业运维实战--k8s学习笔记 k8s调度

1.kubernetes调度介绍

调度器通过 kubernetes 的 watch 机制来发现集群中新创建且尚未被调度到 Node 上的 Pod。调度器会将发现的每一个未调度的 Pod 调度到一个合适的 Node 上来运行。

kube-scheduler 是 Kubernetes 集群的默认调度器,并且是集群控制面的一部分。如果你真的希望或者有这方面的需求,kube-scheduler 在设计上是允许你自己写一个调度组件并替换原有的 kube-scheduler。

在做调度决定时需要考虑的因素包括:单独和整体的资源请求、硬件/软件/策略限制、亲和以及反亲和要求、数据局域性、负载间的干扰等等。

默认策略可以参考:https://kubernetes.io/zh/docs/concepts/scheduling/kube-scheduler/

2.nodename节点选择约束

nodeName 是节点选择约束的最简单方法,但一般不推荐。如果 nodeName 在 PodSpec 中指定了,则它优先于其他的节点选择方法。

使用 nodeName 来选择节点的一些限制:

如果指定的节点不存在。
如果指定的节点没有资源来容纳 pod,则pod 调度失败。
云环境中的节点名称并非总是可预测或稳定的。

3.nodeSelector 亲和

nodeSelector 是节点选择约束的最简单推荐形式。给选择的节点添加标签,通过标签来进行调度。

3.1.节点亲和

创建目录并编写资源清单
vi pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  nodeSelector:
    disktype: ssd

执行并查看状态

kubectl apply -f pod.yaml 
kubectl get pod -o wide

在这里插入图片描述
成功运行的原因为我们的结点上有ssd的标签

kubectl get nodes --show-labels 

在这里插入图片描述
节点亲和性pod示例

kubectl delete -f pod.yaml
vi pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:  #必须满足
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
              - ssd
              - fc

刚才的实验发现nginx pod在server3上则我们
将3上的标签去掉在执行查看

kubectl label nodes server3 disktype-
kubectl apply -f pod.yaml
kubectl get pod -o wide

在这里插入图片描述发现被调度到server2
在这里插入图片描述kubectl label nodes server3 disktype=ssd
将标签加回去后再次编辑pod.yaml
kubectl delete -f pod.yaml
vi pod.yaml

apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    env: test
spec:
  containers:
  - name: nginx
    image: nginx
    imagePullPolicy: IfNotPresent
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: disktype
            operator: In
            values:
              - ssd
              - fc
      preferredDuringSchedulingIgnoredDuringExecution: #倾向满足
        - weight: 1
          preference:
            matchExpressions:
            - key: role
              operator: In
              values:
              - prod

执行后再次查看 再次被调度回到server3

kubectl apply -f  pod.yaml 
kubectl get pod -o wide

在这里插入图片描述

3.2示例

保留前面的nginx pod
pod亲和,mysql容器亲和nginx pod
注意使用的mysql镜像版本为 image: mysql:5.7
仓库里需要有。
在这里插入图片描述

vi pod1.yaml

apiVersion: v1
kind: Pod
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  containers:
  - name: mysql
    image: mysql:5.7
    env:
     - name: "MYSQL_ROOT_PASSWORD"
       value: "westos"
  affinity:
    podAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
      - labelSelector:
          matchExpressions:
          - key: env    ###通过kubectl get pod --show-labels找到
            operator: In
            values:
            - test   ##同上
        topologyKey: kubernetes.io/hostname

执行清单pod2.yaml,查看信息

kubectl apply -f pod1.yaml
kubectl get pod -o wide

在这里插入图片描述
pod反亲和

vi pod1.yaml

 podAntiAffinity:

在这里插入图片描述执行查看
在这里插入图片描述我们可以看到mysql节点并不在nginx服务的同个节点上,实现服务与数据分离,被调度到server2。

4.Taints(污点)

NodeAffinity节点亲和性,是Pod上定义的一种属性,使Pod能够按我们的要求调度到某个Node上,而Taints则恰恰相反,它可以让Node拒绝运行Pod,甚至驱逐Pod。

Taints(污点)是Node的一个属性,设置了Taints后,所以Kubernetes是不会将Pod调度到这个Node上的。
于是Kubernetes就给Pod设置了个属性Tolerations(容忍),只要Pod能够容忍Node上的污点,那么Kubernetes就会忽略Node上的污点,就能够(不是必须)把Pod调度过去。

可以使用命令 kubectl taint 给节点增加一个 taint:

kubectl taint nodes node1 key=value:NoSchedule //创建
kubectl describe nodes server1 |grep Taints //查询
kubectl taint nodes node1 key:NoSchedule- //删除

其中[effect] 可取值: [ NoSchedule | PreferNoSchedule | NoExecute ]

NoSchedule:POD 不会被调度到标记为 taints 节点。
PreferNoSchedule:NoSchedule的软策略版本。
NoExecute:该选项意味着一旦 Taint 生效,如该节点内正在运行的 POD 没有对应 Tolerate设置,会直接被逐出。

如Kubernetes集群主机,就是被设置了污点,因此一般部署pod时候不选择该节点为部署节点matser的污点 的信息为:

 kubectl  describe  nodes server1 | grep Taints
Taints: node-role.kubernetes.io/master:NoSchedule

4.1添加污点

4.1.1 NoSchedule

kubectl taint node server3 k1=v1:NoSchedule
kubectl delete -f pod.yaml 
kubectl apply -f  pod.yaml 
kubectl get pod -o wide

在这里插入图片描述发现原本在server3运行的pod 运行不了了

4.1.2 .NoExecute

创建一个控制器

vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 3
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
     # tolerations:
     #- operator: "Exists"

添加NoExecute:
该选项意味着一旦 Taint 生效,如该节点内正在运行的 POD 没有对应 Tolerate 设置,会直接被逐出。被驱逐到其他node节点。
kubectl taint nodes server2 key=value:NoExecute
因为没有容忍及其他node所有pod全部pending
在这里插入图片描述我们如果去掉server3的污点则会全部调度到srever3中

kubectl taint node server3 k1=v1:NoSchedule-
kubectl get pod -o wide

在这里插入图片描述

4.2添加容忍

本来server1是不加入集群的,我们现在设置让他加入集群中
我们来测试:

vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 30  #数量太小server1调度的几率小
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
      tolerations:
      - operator: "Exists"    ##容忍万物

删除执行查看

kubectl delete -f deployment.yaml 
kubectl apply -f  deployment.yaml 
kubectl get pod -o wide

在这里插入图片描述
发现有server1

4.3cordon、drain、delete

影响Pod调度的指令还有:cordon、drain、delete,后期创建的pod都不会被调度到该节点上,但操作的暴力程度不一样。
cordon 停止调度:
影响最小,只会将node调为SchedulingDisabled,新创建pod,不会被调度到该节点,节点原有pod不受影响,仍正常对外提供服务。
drain 驱逐节点:
首先驱逐node上的pod,在其他节点重新创建,然后将节点调为SchedulingDisabled。
delete 删除节点
最暴力的一个,首先驱逐node上的pod,在其他节点重新创建,然后,从master节点删除该node,master失去对其控制,如要恢复调度,需进入node节点,重启kubelet服务


vi deployment.yaml

apiVersion: apps/v1
kind: Deployment
metadata:
  name: web-server
spec:
  selector:
    matchLabels:
      app: nginx
  replicas: 6
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx

执行查看调度节点

kubectl apply -f deployment.yaml
kubectl get pod -o wide

在这里插入图片描述

4.3.1 cordon

关闭server3的集群调度

kubectl cordon server3
kubectl get pod -o wide
kubectl get node

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

全部被驱逐到server2
重新server3的调度

kubectl uncordon server3
kubectl get node

在这里插入图片描述

4.3.2 drain

kubectl drain server2 --ignore-daemonsets
在这里插入图片描述
server2里的东西全部被调度走别的节点

kubectl get node

在这里插入图片描述kubectl uncordon server2
重启

4.3.3 delete

直接删除掉节点server3
kubectl delete node server3

在这里插入图片描述

将server3重新加入调度node节点
需要在server3上重启kubelet服务

server3:
systemctl restart kubelet
server1:
kubectl get node

在这里插入图片描述

5. 添加新的集群node

因为token只会存在23小时,所以需要重新创建

kubeadm token create
kubeadm token list
在这里插入图片描述

还需要token-cert-hash
这个值不会变化,查出来即可

openssl x509 -pubky -in /etc/kubernetes/pki/ca.crt | openssl rsa -pubinoutform der 2>/dev/null | \
openssl dgst -sha256 -hex | sed 's/^.* //'

在这里插入图片描述

然后用下述指令加入集群

kubeadm join 172.25.0.2:6443 --token ******** --discovery-token-ca-cert-hash sha256:*******************请添加图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

lll_cf

喜欢

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值