存储卷,简称卷,卷是pod的一部分,卷在pod创建时创建,删除pod时卷也会被销毁,卷可以为pod中的所有容器使用,前提是所有容器都将卷挂载到容器里,卷可以挂载到容器的文件系统中的任意位置。一个pod可以定义多个不同类型的卷,一个容器也可以使用不同类型的多个卷。pod需要设置卷来源(spec.volume)和挂载点(spec.containers.volumeMounts)两个信息后才可以使用相应的Volume。
几种常用的卷
emptyDir类型的Volume在Pod分配到Node上时被创建,Kubernetes会在Node上自动分配一个目录,因此无需指定宿主机Node上对应的目录文件。 这个目录的初始内容为空,当Pod从Node上移除时,emptyDir中的数据会被永久删除。这个目录对应的是pod里的挂载目录。
【温馨提示】容器的crashing事件并不会导致emptyDir中的数据被删除。会随着Pod的结束而销毁。
使用场景:
【温馨提示】在使用tmpfs文件系统作为emptyDir的存储后端时,如果遇到node节点重启,则emptyDir中的数据也会全部丢失。同时,你编写的任何文件也都将计入Container的内存使用限制。
【示例】
apiVersion: v1
kind: Pod
metadata:
name: test-pod
spec:
containers:
- image: busybox
name: test-emptydir
command: [ "sleep", "3600" ]
volumeMounts:
- mountPath: /opt/emptyDir
name: data-volume
volumes:
- name: data-volume
emptyDir: {}
可以进入到容器中查看下实际的卷挂载结果:
kubectl exec -it test-pod -c test-emptydir /bin/sh
df -h
hostPath类型则是映射node文件系统中的文件或者目录到pod里,与宿主机目录映射。在使用hostPath类型的存储卷时,也可以设置type字段,支持的类型有文件、Directory、File、Socket、CharDevice和BlockDevice。不适用于生产环境,为什么说不适合在生产环境中使用呢?有以下节点原因:
使用场景:
注意事项:
【示例】
apiVersion: v1
kind: Pod
metadata:
name: test-pod2
spec:
containers:
- image: busybox
name: test-hostpath
command: [ "sleep", "3600" ]
volumeMounts:
- mountPath: /test-data
name: test-volume
volumes:
- name: test-volume
hostPath:
# directory location on host
path: /opt/test-hostpath
# this field is optional
type: Directory
我们登录到容器中,进入挂载的/test-data目录中,创建个测试文件。
kubectl exec -it test-pod2 -c test-hostpath /bin/sh
echo 'test' > /test-data/test.log
我们在运行该pod的node节点上,可以看到如下的文件和内容:
# 先查看pod调度到哪个node节点上
kubectl get pods -owide
在local-168-182-112节点上查看
cat /opt/test-hostpath/test.log
【温馨提示】在使用hostPath volume卷时,即便pod已经被删除了,volume卷中的数据还在!
使用场景:
关于PV和PVC的介绍,可以参考我之前的文章:Kubernetes(k8s)五种控制器详解
kind: StorageClass
apiVersion: storage.k8s.io/v1
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
【 注意】到这里volumeBindingMode字段的值是WaitForFirstConsumer。这种bindingmode意味着:kubernetes的pv控制器会将这类pv的binding延迟,直到有一个使用了对应pvc的pod被创建出来且该pod被调度完毕。这时候才会将pv和pvc进行binding,并且这时候pv的选择会结合调度的node和pv的nodeaffinity。
手动创建两PV:local-pv-1、local-pv-2分别绑定两主机存储,如绑定主机名的本地卷如下:
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-1
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/k8s-install/StorageClass-local/test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- local-168-182-111
local-pv-2
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-2
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
volumeMode: Filesystem
local:
path: /data/k8s-install/StorageClass-local/test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: kubernetes.io/hostname
operator: In
values:
- local-168-182-112
kubernetes.io/hostname是node的标签,这个标签是自带的,当然也可以自定义,查看标签/自定义标签:
kubectl get node -o wide --show-labels
# 自定义标签
kubectl label nodes k8s-node1 team=a
local-pvc-1
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-pvc-1
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-storage
volumeName: local-pv-1
volumeMode: Filesystem
local-pvc-2
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: local-pvc-2
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
storageClassName: local-storage
volumeName: local-pv-2
volumeMode: Filesystem
【温馨提示】PVC与PV是一对一,pod与PVC可以一对多,volumeName如果不指定具体PV,PVC则会自动绑定空闲的PV
apiVersion: extensions/v1
kind: StatefulSet
metadata:
labels:
app: local-volume-test
name: local-volume-test
spec:
replicas: 1
selector:
matchLabels:
app: local-volume-test
template:
metadata:
labels:
app: local-volume-test
spec:
containers:
- image: busybox
name: local-volume-test
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "while true; do sleep 2; echo $(date) $(hostname)>> /mnt/test/test.log; done" ]
volumeMounts:
- name: local-data
mountPath: /mnt/test
volumes:
- name: local-data
persistentVolumeClaim:
claimName: local-pvc-1
注意:
【温馨提示】如果调度的是master节点且master不可调度,会导致pod起不来
上面是手动创建pvc,其实一般我们会配置pvc模板,自动创建pvc,将上面的改造如下:
apiVersion: extensions/v1
kind: StatefulSet
metadata:
labels:
app: local-volume-test
name: local-volume-test
spec:
replicas: 1
selector:
matchLabels:
app: local-volume-test
template:
metadata:
labels:
app: local-volume-test
spec:
containers:
- image: busybox
name: local-volume-test
imagePullPolicy: IfNotPresent
command: [ "/bin/sh", "-c", "while true; do sleep 2; echo $(date) $(hostname)>> /mnt/test/test.log; done" ]
volumeMounts:
- name: local-data
mountPath: /mnt/test
volumeClaimTemplates: #pvc的模板
- metadata:
name: local-data
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: "local-storage" #存储类名
resources:
requests:
storage: 1Gi
# 不同版本可能不一样,先查看NoSchedule的标识
kubectl describe node local-168-182-110
kubectl taint nodes local-168-182-110 node-role.kubernetes.io/control-plane:NoSchedule-
CongfigMap、secret的介绍,可以参考我之前的文章:Kubernetes(k8s)ConfigMap详解及应用
k8s的本地存储卷介绍和简单使用就先到这里了,有疑问的小伙伴欢迎给我留言哦~
留言与评论(共有 0 条评论) “” |