一、Pod亲和性
1.1 针对对象为Pod,目的是实现,新建Pod和目标Pod调度到一起,在同一个Node。
podAffinity 示例
apiVersion: v1
kind: Pod
metadata:
name: testpod01
namespace: prod
labels:
app: myapp01
env: test1
spec:
containers:
- name: testpod01
image: nginx:1.25.2
---
apiVersion: v1
kind: Pod
metadata:
name: testpod02
namespace: prod
labels:
app: myapp02
env: test2
spec:
affinity:
podAffinity:
requiredDuringSchedulingIgnoredDuringExecution: ##必须满足下面匹配规则
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01 ## app=myapp01, 上面的Pod是符合要求的
topologyKey: "kubernetes.io/hostname"
containers:
- name: testpod02
image: redis:6.2
应用YAML文件
# kubectl apply -f podAffinity.yaml
pod/testpod01 created
pod/testpod02 created
验证:
# kubectl get pod -n prod -o wide
二、Pod反亲和性
2.1 针对对象为Pod,目的是实现,新建Pod和目标Pod不能调度到一起,不在同一个Node。
podAntiAffinity示例
apiVersion: v1
kind: Pod
metadata:
name: testpod01
namespace: prod
labels:
app: myapp01
env: test1
spec:
containers:
- name: testpod01
image: nginx:1.25.2
---
apiVersion: v1
kind: Pod
metadata:
name: testpod02
namespace: prod
labels:
app: myapp02
env: test2
spec:
affinity:
podAntiAffinity:
requiredDuringSchedulingIgnoredDuringExecution: ##必须满足下面匹配规则
- labelSelector:
matchExpressions:
- key: app
operator: In
values:
- myapp01 ## app=myapp01, 上面的Pod是符合要求的
topologyKey: "kubernetes.io/hostname"
containers:
- name: testpod02
image: redis:6.2
应用YAML:
# kubectl apply -f podAntiAffinity.yaml
pod/testpod01 created
pod/testpod02 created
验证:
# kubectl get pod -n prod -o wide
三、污点与容忍度
污点(Taint)针对节点来说,和节点亲和性正好相对,节点清河性使Pod被吸引到一类特定的节点,而污点则使节点能够排斥一类特定的Pod。
容忍度(Toleration) 应用于Pod上,它用来允许调度器调度带有对应污点的节点。容忍度允许调度但是不保证调度:作为其功能的一部分,调度器也会评估其他参数。
污点和容忍度相互配合,可以避免Pod被分配到不合适的节点上。每个节点上都可以应用一个或多个污点,这表示对于那些不能容忍这些污点的Pod,是不会被该节点接受。
3.1 设置污点命令格式:
kubectl taint node [node] key-value:[effect]
说明:
其中[effect]可取值:[NoSchedule|PreferNoSchedule|NoExecute]
- NoSchedule:一定不能被调度,已经在运行中的Pod不受影响。
- PreferNoSchedule:尽量不要调度,实在没有节点可调度再调度到此节点。
- NoExecute:不仅不会调度,还会驱逐Node上已有的Pod。
清除污点格式:
kubectl taint node [node] key:[effect]-
示例:
kubectl taint node node-1-231 name=stage:NoSchedule
查看污点:
kubectl describe node [node] |grep -i taint -A 10
3.2 设置容忍度的几种规则:
1)完全匹配
tolerations:
- key: "taintKey" #和污点的key名字保持一致
operator: "Equal" #匹配类型,Equal表示匹配污点的所有值
value: "taintValue" #和污点key的值保持一致
effect: "NoSchedule" #污点类型
说明:
Pod的Toleration 声明中的key和effect需要与Taint的设置保持一直。
Operator如果设置为Equal,则key和value,要和Taint的设置保持一致。
2) 不完全匹配
tolerations:
- key: "taintKey" #和污点的key名字保持一致
operator: "Exists" #匹配类型,只要符合污点设置的key即可
effect: "NoSchedule" #污点的类型
说明:Operator 如果设置为Exists,则不需要指定value,只看key名字。
3)大范围匹配
tolerations:
- key: "taintKey" #和污点的key名字保持一致
operator: "Exists"
说明:如果省略effect,则需要只看key名字即可,不管Taint里的effect设置为什么都不会匹配到。
4)匹配所有
tolerations:
- operator: "Exists"
说明:如果省略key和effect,则匹配所有Taint, 在k8s中的daemonsets资源默认情况下是容忍所有污点的。
设置驱逐延缓时间设置
tolerations:
- key: "key1"
operator: "Equal"
value: "value1"
effect: "NoExecute"
tolerationSeconds: 3600
说明:如果Pod正在运行,那么Pod还将继续在节点运行3600秒,然后被驱逐。如果在此之前上述污点被删除,则Pod不会被驱逐。
Pod YAML示例:
apiVersion: v1
kind: Pod
metadata:
name: ng
namespace: prod
labels:
env: dev
spec:
containers:
- name: ng
image: nginx:1.25.2
tolerations:
- key: name
operator: Exists
effect: NoSchedule
应用YAML
# kubectl describe node node-1-23 |grep -i taint
Taints: <none>
Taints: <none>
Taints: <none>
# kubectl apply -f tolerations.yaml
pod/ng created
# kubectl get pod -n prod -o wide
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ng 1/1 Running 0 9s 10.244.154.15 node-1-233 <none> <none>
testpod01 1/1 Running 0 66m 10.244.154.12 node-1-233 <none> <none>
testpod02 1/1 Running 0 66m 10.244.167.144 node-1-231 <none> <none>
get3个node打污点
# kubectl taint node node-1-231 name1=prod:NoSchedule
node/node-1-231 tainted
# kubectl taint node node-1-232 name1=prod:NoSchedule
node/node-1-232 tainted
# kubectl taint node node-1-233 name1=prod:NoSchedule
node/node-1-233 tainted
# kubectl describe node node-1-23 |grep -i taint
Taints: name1=prod:NoSchedule
Taints: name1=prod:NoSchedule
Taints: name1=prod:NoSchedule
验证:
# kubectl apply -f tolerations.yaml
pod/ng created
# kubectl get pod -o wide -n prod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ng 0/1 Pending 0 28s <none> <none> <none> <none>
testpod01 1/1 Running 0 69m 10.244.154.12 node-1-233 <none> <none>
testpod02 1/1 Running 0 69m 10.244.167.144 node-1-231 <none> <none>
kubectl describe pod ng -n prod
# kubectl describe pod ng -n prod
Name: ng
Namespace: prod
Priority: 0
Service Account: default
Node: <none>
Labels: env=dev
Annotations: <none>
Status: Pending
IP:
IPs: <none>
Containers:
ng:
Image: nginx:1.25.2
Port: <none>
Host Port: <none>
Environment: <none>
Mounts:
/var/run/secrets/kubernetes.io/serviceaccount from kube-api-access-fjpwr (ro)
Conditions:
Type Status
PodScheduled False
Volumes:
kube-api-access-fjpwr:
Type: Projected (a volume that contains injected data from multiple sources)
TokenExpirationSeconds: 3607
ConfigMapName: kube-root-ca.crt
ConfigMapOptional: <nil>
DownwardAPI: true
QoS Class: BestEffort
Node-Selectors: <none>
Tolerations: name:NoSchedule op=Exists
node.kubernetes.io/not-ready:NoExecute op=Exists for 300s
node.kubernetes.io/unreachable:NoExecute op=Exists for 300s
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Warning FailedScheduling 56s default-scheduler 0/4 nodes are available: 1 node(s) had untolerated taint {node-role.kubernetes.io/control-plane: }, 3 node(s) had untolerated taint {name1: prod}. preemption: 0/4 nodes are available: 4 Preemption is not helpful for scheduling..
给node-1-231 加上name名称污点
# kubectl taint node node-1-231 name1=prod:NoSchedule-
node/node-1-231 untainted
# kubectl taint node node-1-231 name=prod:NoSchedule
node/node-1-231 tainted
# kubectl get pod -o wide -n prod
NAME READY STATUS RESTARTS AGE IP NODE NOMINATED NODE READINESS GATES
ng 1/1 Running 0 4m3s 10.244.167.146 node-1-231 <none> <none>
testpod01 1/1 Running 0 73m 10.244.154.12 node-1-233 <none> <none>
testpod02 1/1 Running 0 73m 10.244.167.144 node-1-231 <none> <none>
四、API资源对象PV和PVC
存储持久化相关的三个概念:
1)PersistentVolume(PV)
是对具体存储资源的描述,比如NFS、Ceph、GlusterFS等,通过PV可以访问到具体的存储资源
2)PersistentVolumeChaim(PVC)
Pod想要使用具体的存储资源需要对接到PVC,PVC会定义好Pod希望使用存储的属性,通过PVC再去申请合适的存储资源PV,匹配到合适的资源后PVC和PV会进行绑定,他们两者是一一对应的
3)StorageClass(SC)
PV可以手动创建,也可以自动创建,当PV需求量非常大时,如果靠手动创建PV非常麻烦,SC可以实现自动创建PV,并且将PVC和PV绑定
SC会定义两部分内容:
1)PV的属性,比如存储类型、大小
2)创建PV需要用到存储插件(provisioner),provisioner是实现自动创建PV的关键。
4.1 PV YAML示例
vim testpv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: testpv
spec:
storageClassName: test-storage
accessModes:
- ReadWriteOnce
capacity:
storage: 500Mi ##提供500Mi空间
hostPath:
path: /tmp/testpv/
说明:
storageClassName:定义存储类名称,PV和PVC中都会有改字段,目的是为了方便两者匹配绑定在一起
accessModes定义改pv的访问权限模式:
- ReadWriteOnce:存储卷可读可写,但是只能被一个节点上的Pod挂载
- ReadOnlyMany:存储卷只读不可写,可以被任意节点上的Pod多次挂载
- ReadWriteMany:存储卷可读可写,可以被任意节点上的Pod多次挂载
capacity:定义该存储大小
hostPath:定义该存储访问路径,这里指本地磁盘
4.2 PVC YAML示例
vim testpvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: testpvc
spec:
storageClassName: test-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 100Mi ##期望申请100Mi空间
应用pv和pvc的YAML
# kubectl apply -f testpv.yaml -f testpvc.yaml
persistentvolume/testpv created
persistentvolumeclaim/testpvc created
查看状态
# kubectl get pv,pvc
实验:
将testpvc的期望100Mi改为1000Mi,查看PV的STATUS
4.3 PV 和PVC匹配规则
PV创建好后,会等待PVC与其进行绑定,PVC一旦找到合适的PV就会绑定。如果有多个PV时,PVC又是如何匹配的?它有如下一些规则:
- 访问模式和存储类匹配:Kubernetes会筛选出访问模式(accessModes)和存储类(storageClassName)与PVC相匹配的PV。如果没有匹配的PV,PVC将保持未绑定状态。
- 资源大小:在满足访问模式和存储类匹配的PV中,Kubernetes会选择资源大小大于或等于PVC请求大小的PV
- 最佳匹配:在满足访问模式、存储类和资源大小的PV中,Kubernetes会选择资源大小最接近PVC请求大小的PV。如果有多个PV具有相同的资源小小,Kubernetes会选择其中一个进行绑定。
- 避免重复绑定:一个PV在任何时候只能被一个PVC绑定。一旦PV被绑定到一个PVC,它将不再可用于其他PVC。
五、本地存储
在6.1章节中的PV YAML示例,就是本地存储。本地存储类型的PV是Kubernetes中一种比较特殊的持久化存储,它允许将节点上的本地磁盘或目录用作PV。与其他PV类型(例如NFS、Ceph或云存储)不同,本地存储类型的PV直接使用节点上的存储资源,因此具有更低的延迟和更高的性能。
使用本地存储类型的PV时,需注意以下几个关键点:
- 节点特性:本地存储类型的PV与特定的节点绑定,因为它直接使用节点上的存储资源。这意味着当创建PV时,需要指定与之关联的节点。可以在PV的spec部分设置nodeAffinity来实现的。
nodeAffinity: ##定义节点亲和性
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- node-name
- 数据持久性:由于本地存储类型的PV与特定节点关联,当该节点发生故障时,存储在PV中的数据可能无法访问。因此,在使用本地存储类型的PV时,请确保采取适当的数据备份策略,以防止节点故障导致的数据丢失。
- 调度限制:Pod使用本地存储类型的Persistent Volume Claim(PVC)时,Kubernetes会尝试将Pod调度到关联PV的节点上。如果节点上的资源不足以运行Pod,Pod将无法启动。因此,在使用本地存储类型的PV时,请确保关联的节点有足够的资源来运行Pod。
- 回收策略:当PVC被删除时,PV的回收策略将决定如何处理关联的本地存储。对于本地存储类型的PV,建议使用Retain或Delete回收策略。Retain策略表示保留存储和数据,以便手动清理和管理;Delete策略表示删除存储和数据。需要注意的是,Recycle策略并不适用于本地存储类型的PV。
persistentVolumeReclaimPolicy: Retain
完整示例:
首先,确保在每个要使用本地存储的节点(node-1-231)上创建一个本地目录。例如在节点上创建/data/local-storage
mkdir -p /data/local-storage
然后创建一个PV资源配置文件
vim local-pv.yaml
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv
labels:
type: local
spec:
storageClassName: local-storage
capacity:
storage: 5Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
local:
path: /data/local-storage
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname #这是内置的节点标签,表示节点的主机名
operator: In
values:
- node-1-231 #只有node-1-231这个主机节点才满足要求
应用PV资源配置文件
# kubectl apply -f local-pv.yaml
persistentvolume/local-pv created
再创建一个PVC资源配置文件
vim local-pvc.yaml
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: local-pvc
spec:
storageClassName: local-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 5Gi
应用PVC资源配置文件
kubectl apply -f local-pvc.yaml
查看状态:
kubectl get pv
kubectl get pvc
Kubernetes会自动将PVC与PV绑定。创建好的PVC可以在Pod中使用,将本地存储挂载到容器中。 最后,创建一个Pod资源配置文件,例如local-pod.yaml:
apiVersion: v1
kind: Pod
metadata:
name: local-pod
spec:
containers:
- name: local-container
image: nginx:1.25.2
volumeMounts:
- name: local-storage
mountPath: /data
volumes:
- name: local-storage
persistentVolumeClaim:
claimName: local-pvc
应用Pod YAML文件
# kubectl apply -f local-pd.yaml
pod/local-pod created
测试:
进入pod写入测试文件1.txt
# kubectl exec -it local-pod -- bash
root@local-pod:/# cd /data/
root@local-pod:/data# echo "Hello Kubernetes!" >1.txt
root@local-pod:/data# cat 1.txt
Hello Kubernetes!
root@local-pod:/data#
在node-1-231节点验证1.txt文件内容
标签:node,kubectl,PV,PVC,API,Pod,local From: https://www.cnblogs.com/pythonlx/p/17780590.html