惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

The GitHub Blog
The GitHub Blog
S
SegmentFault 最新的问题
MyScale Blog
MyScale Blog
有赞技术团队
有赞技术团队
V
Visual Studio Blog
T
The Blog of Author Tim Ferriss
爱范儿
爱范儿
Vercel News
Vercel News
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
Y
Y Combinator Blog
Blog — PlanetScale
Blog — PlanetScale
D
DataBreaches.Net
美团技术团队
Microsoft Security Blog
Microsoft Security Blog
大猫的无限游戏
大猫的无限游戏
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
酷 壳 – CoolShell
酷 壳 – CoolShell
GbyAI
GbyAI
A
About on SuperTechFans
云风的 BLOG
云风的 BLOG
The Cloudflare Blog
宝玉的分享
宝玉的分享
V
V2EX
Microsoft Azure Blog
Microsoft Azure Blog

lvbibir's Blog

shell | 磁盘空间分析脚本 Linux cat 和 tee 命令写入文件 python | 使用 uv 管理你的 python 环境 Claude Code 完整配置指南 windows | mihomo 内核独立部署指南 linux | 磁盘扩容 wsl | 释放长久运行占用的磁盘空间 mysql | 线程上限问题处理 麒麟 7.6 安装谷歌 OTP 认证模块 suse 12sp5 升级 openssh 及 openssl suse 12sp5 部署 mysql 5.7 《谁的青春不迷茫》 docker | centos7 部署 docker vim | 基础配置和使用 windows | rime 输入法 & 雾凇方案 shell | sshpass 批量传输文件及执行命令 wsl | 原生 linux 方式安装 docker nodejs | fnm + pnpm 开发环境配置 wsl | 安装配置 miniconda 虚拟环境 wsl | 自动更新系统代理 wsl | bashrc 环境变量不正确加载的处理方法 wsl | win10 安装 wsl2 troubleshooting | ssh 成功但是 scp 失败 linux | 常用命令总结 docker 部署 piclist shell | 检测网站存活并自动钉钉告警 Zabbix | 监控端口连通性并自动追踪 TCP 路由 windows | 自定义开机快速启动项 windows | miniconda 配置 python 虚拟环境 Zabbix | 监控主机到指定 ip 的流量大小
kubernetes | 调度
lvbibir · 2022-10-03 · via lvbibir's Blog

0 前言

基于 centos7.9docker-ce-20.10.18kubelet-1.22.3-0

1 创建 pod 的工作流程

  1. kubectl run nginx –image=nginx
  2. kubectl 将创建 pod 的请求发送到 apiserver
  3. apiserver 将请求信息写入 etcd
  4. apiserver 通知 scheduler,收到请求信息后根据调度算法将 pod 分配到合适节点
  5. scheduler 给 pod 标记调度结果,并返回给 apiserver
  6. apiserver 收到后写入 etcd
  7. 对应节点的 kubelet 收到创建 pod 的事件,从 apiserver 获取到 pod 的相关信息
  8. kubelet 调用 docker api 创建 pod 所需的容器
  9. 创建完成之后将 pod 状态汇报给 apiserver
  10. apiserver 将收到的 pod 状态写入 apiserver
  11. kubectl get pods 即可收到相关信息

2 资源限制对 pod 调度的影响

容器资源限制:

  • resources.limits.cpu
  • resources.limits.memory

容器使用的最小资源需求,并不是实际占用,是预留资源:

  • resources.requests.cpu
  • resources.requests.memory
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: web
    image: nginx
    resources:
      requests:
        memory: "64Mi"
        cpu: "250m" #cpu单位也可以写浮点数,例如0.25=250m,代表四分之一核cpu
      limits:
        memory: "128Mi"
        cpu: "500m"

3 nodeSelector

nodeSelector 用于将 Pod 调度到匹配 Label 的 Node 上,如果没有匹配的标签会调度失败。

先创建 pod 后打标签,起始出于 pending 状态,打好标签后,pod 会正常分配

给节点打标签:

kubectl label nodes [node] key=value # 打lable, value可以是空
kubectl label nodes [node] key- # 删除label
kubectl get nodes -l key=value # 根据label筛选
# 示例
kubectl label nodes k8s-node1 disktype=ssd
kubectl label nodes k8s-node1 disktype-

示例

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodeselector
spec:
  containers:
  - name: nginx
    image: nginx:1.19
  nodeSelector:
    disktype: "ssd"

4 nodeAffinity

节点亲和性概念上类似于 nodeSelector, 它使你可以根据节点上的标签来约束 Pod 可以调度到哪些节点上。 节点亲和性有两种:

  • requiredDuringSchedulingIgnoredDuringExecution: 调度器只有在规则被满足的时候才能执行调度。此功能类似于 nodeSelector, 但其语法表达能力更强。
  • preferredDuringSchedulingIgnoredDuringExecution: 调度器会尝试寻找满足对应规则的节点。如果找不到匹配的节点,调度器仍然会调度该 Pod。

先创建 pod 后打标签起始出于 pending 状态,打好标签后,pod 会正常分配

IgnoredDuringExecution 意味着如果节点标签在 Kubernetes 调度 Pod 后发生了变更,Pod 仍将继续运行。

操作符:In、NotIn、Exists、DoesNotExist、Gt、Lt

示例

apiVersion: v1
kind: Pod
metadata:
  name: with-affinity-anti-affinity
spec:
  affinity:
    nodeAffinity:
      requiredDuringSchedulingIgnoredDuringExecution:
        nodeSelectorTerms:
        - matchExpressions:
          - key: kubernetes.io/os
            operator: In
            values:
            - linux
            - windows
      preferredDuringSchedulingIgnoredDuringExecution:
      - weight: 1
        preference:
          matchExpressions:
          - key: label-1
            operator: In
            values:
            - key-1
      - weight: 50
        preference:
          matchExpressions:
          - key: label-2
            operator: In
            values:
            - key-2
  containers:
  - name: with-node-affinity
    image: registry.k8s.io/pause:2.0

5 Taint(污点)

Taints:避免 Pod 调度到特定 Node 上

应用场景:

  • 专用节点,例如配备了特殊硬件的节点
  • 基于 Taint 的驱逐

设置污点:

kubectl taint node [node] key=value:[effect] 
# 其中[effect]可取值:
# - NoSchedule :一定不能被调度。
# - PreferNoSchedule:尽量不要调度。
# - NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。

去掉污点:

kubectl taint node [node] key:[effect]-

示例

[root@k8s-node1 ~]# kubectl label node k8s-node2 disktype=ssd
node/k8s-node2 labeled
[root@k8s-node1 ~]# kubectl taint node k8s-node2 disktype=ssd:NoSchedule
node/k8s-node2 tainted
[root@k8s-node1 ~]# kubectl describe node k8s-node2 | grep -i taints
Taints:             disktype=ssd:NoSchedule

Tolerations(污点容忍)

允许 Pod 调度到持有 Taints 的 Node 上,但不是绝对分配到指定的标签,搭配 nodeSelector 或者 nodeAffinity 使用,实现将 pod 分配到特定污点的节点上

      tolerations:              #设置容忍所有污点,防止节点被设置污点
        - operator: "Exists"

示例

[root@k8s-node1 ~]# kubectl describe node k8s-node2 | grep -i taints Taint
Taints:             disktype=ssd:NoSchedule
[root@k8s-node1 ~]# kubectl apply -f pod-tolerations.yaml
[root@k8s-node1 ~]# kubectl get pods pod-tolerations -o wide
pod-tolerations   1/1     Running   0          13s   10.244.169.183   k8s-node2   <none>           <none>

yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-tolerations
spec:
  containers:
  - name: nginx
    image: nginx:1.19
  nodeSelector:
    disktype: "ssd"
  tolerations:
  - key: "disktype"
    operator: "Equal"
    value: "ssd"
    effect: "NoSchedule"

6 nodeName

指定节点名称,用于将 Pod 调度到指定的 Node 上,不经过调度器 scheduler,所以无视污点

示例

[root@k8s-node1 ~]# kubectl describe node k8s-node2| grep Taint
Taints:             disktype=ssd:NoSchedule
[root@k8s-node1 ~]# kubectl apply -f pod-nodename.yaml
pod/pod-nodename created
[root@k8s-node1 ~]# kubectl get pod pod-nodename -o wide
NAME           READY   STATUS    RESTARTS   AGE   IP               NODE        NOMINATED NODE   READINESS GATES
pod-nodename   1/1     Running   0          27s   10.244.169.184   k8s-node2   <none>           <none>

yaml

apiVersion: v1
kind: Pod
metadata:
  name: pod-nodename
spec:
  containers:
  - name: nginx
    image: nginx
  nodeName: k8s-node2

7 DaemonSet 控制器

DaemonSet 功能:

  • 在每一个 Node 上运行一个 Pod
  • 新加入的 Node 也同样会自动运行一个 Pod

应用场景:网络插件、监控 Agent、日志 Agent,比如 k8s 的 calico-node 和 kube-proxy 组件

示例

[root@k8s-node1 ~]# kubectl apply -f daemonset-filebeat.yaml
[root@k8s-node1 ~]# kubectl get pods -n kube-system -o wide |grep filebeat
filebeat-2c6p4       1/1     Running   0               90s    10.244.107.246   k8s-node3   <none>           <none>
filebeat-4ffcx        1/1     Running   0               90s    10.244.36.65     k8s-node1   <none>           <none>
filebeat-h7959       1/1     Running   0               90s    10.244.169.186   k8s-node2   <none>           <none>

yaml

apiVersion: apps/v1
kind: DaemonSet
metadata:
  name: filebeat
  namespace: kube-system
spec:
  selector:
    matchLabels:
      name: filebeat
  template:
    metadata:
      labels:
        name: filebeat
    spec:
      containers:
      - name: log
        image: elastic/filebeat:7.3.2
        volumeMounts:
        - mountPath: /log/
          name: log
      volumes:
      - name: log
        hostPath:
          path: /var/lib/docker/containers/
          type: Directory
      tolerations:
      - key: "node-role.kubernetes.io/master"
        operator: "Exists"
        effect: "NoSchedule"

以上