创建一个pod 的工作流程
 
 
kubectl run pod2 --image=nginx
 
 
1、kubectl向apiserver发起创建pod请求,apiserver将创建pod配置写入etcd
2、scheduler收到apiserver有新pod的事件,scheduler根据自身调度算法选择一个合适的节点,并打标记 pod=k8s-node1
3、kubelet收到分配到自己节点的pod,调用docker api创建容器,并获取容器状态汇报给apiserver
 
 
controller-manager 负责控制器的创建,例如deployment
 
 
kube-proxy 负责service的创建
 
  
  
 
requests:最小的申请值,limits:容器最大使用上限
2、requests 必须小于limits,小于limits 20%-30%(良性)
、limits尽量不要超过宿主机实际物理配置,不然限制没意义
4、requests会影响pod调度,必须有节点能够满足该配置pod才能运行
5、requests只是一个预留性质,并非实际占用
 
 
节点资源空闲
 
 
节点资源紧张
 
  
 
Kubernetes基于list-watch机制的控制器架构,实现组件间交互的解耦。
 
 
其他组件监控自己负责的资源,当这些资源发生变化时, kubeapiserver会通知这些组件,这个过程类似于发布与订阅。
 
 
  

    
Pod中影响调度的主要属性
  
  

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

      
nodeSelector & nodeAffinity的区别
nodeSelector:
  
用于将Pod调度到匹配Label的Node上,如果没有匹配的标签会调度失败。
  
作用:
  
• 约束Pod到特定的节点运行
  
• 完全匹配节点标签
  
应用场景:
  
• 专用节点:根据业务线将Node分组管理
  
• 配备特殊硬件:部分Node配有SSD硬盘、 GPU
  
案例: 确保Pod分配到具有SSD硬盘的节点上
第一步:给节点添加标签
  
格式: kubectl label nodes <node-name> <label-key>=<label-value>
例如: kubectl label nodes k8s-node1 disktype=ssd
验证: kubectl get nodes --show-labels
      
#yaml文件
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
nodeSelector:
disktype: “ssd”
containers:
- name: nginx
image: nginx:1.19  
第二步:添加nodeSelector字段到Pod配置中
  
最后,验证:
kubectl get pods -o wide
删除节点标签: kubectl label node k8s-node1 <label-key>
    
nodeAffinity:
  
节点亲和类似于nodeSelector,可以根据节点上 的标签来约束Pod可以调度到哪些节点。
  
相比nodeSelector
• 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作
符有: In、 NotIn、 Exists、 DoesNotExist、 Gt、 Lt
• 调度分为软策略和硬策略,而不是硬性要求
• 硬(required):必须满足
• 软(preferred):尝试满足,但不保证
  
  

  
Taint(污点)与Tolerations(污点容忍)
  
基于节点标签分配是站在Pod的角度上,通过在Pod上添加属性,来确定Pod是否要调度到指定的Node上,其实我们也可以站在 Node的角度上,通过在Node上添加污点属性,来避免Pod被分配到不合适的节点上。
    
Taints:
Tolerations:
    
第一步:给节点添加污点
  
格式: 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
  
  

  
  

  
第二步:
  
如果希望Pod可以被分配到带有污点的节点上,要在Pod配置
   
中添加污点容忍(tolrations)字段
  
删除污点: kubectl taint node [node] key:[effect]-
    
nodeName: 指定节点名称,用于将Pod调度到指定的Node上,不经过调度器。
  
#yaml案例
apiVersion: v1
kind: Pod
metadata:
name: my-pod
spec:
nodeName: k8s-node2
containers:
- name: web
image: nginx  
1、nodeselector与taint是分别独立,两者都用都必须满足
  
2、这两个完美组合,指哪打哪
  
3、如果加污点容忍,该pod会肯定分配到带有污点的节点上嘛?
  
不会
    
master节点为什么打污点?
  
1、管理节点
  
2、安全
  
tolerations:
# Make sure calico-node gets scheduled on all nodes.
- effect: NoSchedule
operator: Exists
# Mark the pod as a critical add-on for rescheduling.
- key: CriticalAddonsOnly
operator: Exists
- effect: NoExecute
operator: Exists
    
deployment特点:用镜像可以启动多个pod副本,一模一样,会分散到集群节点上。
    
DaemonSet功能
  
• 在每一个Node上运行一个Pod
  
• 新加入的Node也同样会自动运行一个Pod
    
应用场景:网络插件、监控Agent、日志Agent
  
  

  
示例:部署一个日志采集程序
  
  

  
调度失败原因分析
  
#查看调度结果:
   
kubectl get pod <NAME> -o wide
      
查看调度失败原因:
   
节点CPU/内存不足
   
有污点,没容忍
   
没有匹配到节点标签
    
1、多个pod副本如何统一对外提供服务?
  
增加负载均衡器
  
2、pod短暂的,如何保障这一组pod的准确性?
  
可以指定pod ip、pod名称
 










