创建一个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的创建
1、requests:最小的申请值,limits:容器最大使用上限
2、requests 必须小于limits,小于limits 20%-30%(良性)
3、limits尽量不要超过宿主机实际物理配置,不然限制没意义
4、requests会影响pod调度,必须有节点能够满足该配置pod才能运行
5、requests只是一个预留性质,并非实际占用
requests值设置太大,会发生什么现象?节点资源空闲
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 =
例如: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
nodeAffinity:
节点亲和类似于nodeSelector,可以根据节点上的标签来约束Pod可以调度到哪些节点。
相比nodeSelector
• 匹配有更多的逻辑组合,不只是字符串的完全相等,支持的操作
符有:In、 NotIn、 Exists、 DoesNotExist、 Gt、 Lt
• 调度分为软策略和硬策略,而不是硬性要求
• 硬(required):必须满足
• 软(preferred):尝试满足,但不保证
编辑
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
编辑
编辑
第二步:
如果希望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 -o wide
查看调度失败原因: kubectl describe pod
节点CPU/内存不足
有污点,没容忍
没有匹配到节点标签
1、多个pod副本如何统一对外提供服务?
增加负载均衡器
2、pod短暂的,如何保障这一组pod的准确性?
可以指定pod ip、pod名称