目录
2. key=value:effect 键名=数值:污点类型
污点taint
污点:一旦节点上有污点的标签,那么调度器在部署pod的时候会避开这些有污点标签的节点进行部署。
node-role.kubernetes.io/master:NoSchedule 键名:污点类型
污点的格式
1. key:effect 键名:污点类型
effect 指的是污点的类型
2. key=value:effect 键名=数值:污点类型
污点的类型
1. NoSchedule
表示节点上一旦有这个污点,调度器是不会把pod部署在该节点上的。
2. PreferNoSchedule
表示尽量避免把pod部署在该节点
3. NoExecute(驱逐)
表示调度器不仅不会把pod部署到该节点,而且会把该节点上的pod驱逐到其他节点上。
注:不是基于deployment创建的pod驱逐之后会被销毁
设置污点(主节点操作)
方式一:kubectl taint node node01 test1=1:NoSchedule
方式二:kubectl taint node node01 test1:NoSchedule
查看污点
kubectl describe nodes master01 查看污点
删除污点
kubectl taint node master01 node-role.kubernetes.io/master:NoSchedule- 删除污点
修改污点
kubectl taint node node01 test1=1:PreferNoSchedule --overwrite 修改污点
对master节点总结:
1. master节点一般情况下作为集群的调度者,尽量不部署pod。但是为了资源最大化,master也可以部署pod,这个时候可以把master节点设置污点类型 PreferNoSchedule。
2. 如果集群规模很小,也可以直接用来当节点进行pod部署,就是取消污点。
容忍tolerations
容忍:即使节点上有污点,调度器依然可以把pod部署在有污点的节点上。
语法:tolerations
类型:Equal 等于和 Exists 包含
Equal类型
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx:1.22
tolerations:
#容忍的语法
- key: "test1"
#指定键的名称
operator: "Equal"
#容忍里匹配的算法只有两个:Equal 等于;Exists 包含
#Equal匹配的污点格式必须是 test1=1:NoSchedule
value: "2"
effect: "NoSchedule"
#匹配污点的类型
NoExecute
tolerations:
#容忍的语法
- key: "test1"
#指定键的名称
operator: "Equal"
#容忍里匹配的算法只有两个:Equal 等于;Exists 包含
#Equal匹配的污点格式必须是 test1=1:NoSchedule
value: "2"
effect: "NoExecute"
#匹配污点的类型
tolerationSeconds: 10
#指定pod在这个节点上部署成功之后运行多久被驱逐
# tolerationSeconds: 10 使用这个字段必须是NoExecute
Exists类型
没有key 只有effect
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx
image: nginx:1.22
tolerations:
#容忍的语法
- operator: "Exists"
#使用Exists时,可以不指定key的时候,表示所有的节点只要是NoSchedule的标签都可以部署
effect: "NoSchedule"
只有key 没有effect
tolerations:
#容忍的语法
- key: "test1"
operator: "Exists"
不可调度cordon
cordon:直接标记节点为不可用的状态,调度器不会把pod部署到该节点
设置不可调度命令:kubectl cordon node02
查看是否是不可调度:kubectl get node
取消不可调度命令:kubectl uncordon node02
排水drain
drain:标记节点为不可调度,而且会把节点上的pod驱逐到其他节点。
设置排水命令:kubectl drain node02 --ignore-daemonsets --delete-local-data --force
--ignore-daemonsets:无视daemonsets部署的pod
--delete-local-data:如果被排水的节点上有本地的挂载点,它也会强制杀死该pod
--force:不是控制器创建的pod会被强制释放
恢复:kubectl uncordon node02
注:排水就排一次,排水跟驱逐类似。
问题:当排水或者驱逐之后,怎么样能让pod重新回到节点?
步骤:1. 污点类型驱逐必须要取消掉
2. 恢复排水的节点:kubectl uncordon node02
3. 重启:kubectl delete pod
数据卷
因为容器、pod的生命周期是有限的,一旦重启或者崩溃,数据会丢失,所以我们为了保证数据的完整,我们要实现pod内的容器和节点的挂载。
k8s的数据卷:volume
emptyDir 存储卷
pod分配给节点之前,首先创建emptyDir存储卷,只要运行在节点,数据卷会一直存在。但是这个emptyDir是空的。原因:这个数据卷不能和宿主机共享,一般用于pod内的容器之间共享。一旦pod重启,emptyDir存储卷的数据也会一起删除。
emptyDir存储卷使用场景:主要用于容器内部组件通信,不涉及敏感数据。
容器内部挂载
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#容器内的路径
- name : nginx2
image: nginx:1.22
volumeMounts:
- name: html
#这里的名称要和上面保持一致
mountPath: /data/
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
emptyDir: {}
#容器1的/usr/share/nginx/html和容器2/data/做挂载,数据卷是emptyDir,一旦重启pod数据会丢失。
kubectl logs -f pod名 -c 容器名 指定查看pod里容器的日志
kubectl exec -it pod名 -c 容器名 指定进入pod里的容器
hostPath 数据卷
hostPath:它是和节点进行挂载。就是当pod部署到节点时,就会和节点的指定目录进行挂载。
它的数据可以持久化,但是node节点如果格式化,数据也会消失。
使用场景:因为每个pod运行的服务不同,保留的数据要做区分,所以这个时候需要用hostPath,比如redis缓存数据库、kafka等等。
容器和节点挂载
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#pod的容器内的目录
- name : nginx2
image: nginx:1.22
volumeMounts:
- name: html
#这里的名称要和上面保持一致
mountPath: /data/
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
hostPath:
path: /opt/xy102
#节点的目录
type: DirectoryOrCreate
#此时容器1的/usr/share/nginx/html和容器2的/data/都会和节点的/opt/xy102进行挂载。因为pod会有pause底层容器,pause容器提供共享网络和共享挂载卷
此时,三个节点主机都会生成/opt/xy102/index.html文件,所以它们都共享到/opt/xy102/index.html。
注:挂载的时候如果节点目录为空,那么对应的容器目录也为空。
问题:如果pod里有多个容器,但是我只声明了一个挂载点,它们是否共享?
答:共享,因为pod会有pause底层容器,pause容器提供共享网络和共享挂载卷,也就是pod里面的所有容器共用一个ip地址,共用一个挂载点。
NFS共享存储卷
它使用的是NFS共享存储。也就是集群里的pod相当于客户端,另外一台服务器提供NFS共享。
此时,三个节点它们共享一个挂载点,所有的数据都在这一个挂载点。
应用场景:nginx的服务 或者 pod的数据是一致的。
首先需要再另外一台客户机提供NFS共享
在另外一台主机上操作
mkdir /opt/data1
chmod 777 /opt/data1
vim /etc/exports
/opt/data1 192.168.233.0/24(rw,no_root_squash)
systemctl restart rpcbind
systemctl restart nfs
showmount -e 检查一下
然后回到master01主机上 showmount -e 192.168.233.23(另一个客户机)
在master01主机上
apiVersion: apps/v1
kind: Deployment
metadata:
labels:
app: nginx1
name: nginx1
spec:
replicas: 3
selector:
matchLabels:
app: nginx1
template:
metadata:
labels:
app: nginx1
spec:
containers:
- name: nginx1
image: nginx:1.22
volumeMounts:
- name: html
mountPath: /usr/share/nginx/html
#pod的容器内的目录
- name : nginx2
image: nginx:1.22
volumeMounts:
- name: html
#这里的名称要和上面保持一致
mountPath: /data/
command: ["/bin/bash","-c","while true; do echo $(date) >> /data/index.html; sleep 2; done"]
volumes:
- name: html
nfs:
path: /opt/data1
#节点的目录
server: 192.168.233.23
#server可以使用ip地址,也可以使用主机名,但是主机名需要做映射
此时三个节点共享另一个客户机的data1目录
如果在这个data1目录创建一个文件,此时容器里面的目录也会有文件