在 Kubernetes 中,Pod 的存储通常通过 Volume 对象来管理。Volume 提供了一种在 Pod 生命周期内持久化数据的机制,并且可以跨容器共享。以下是对 Kubernetes Volume 的详细介绍,包括各种 Volume 类型和它们的用途:
一、Volume 基本概念
-
Volume:Kubernetes Volume 是一种在 Pod 中共享和持久化数据的机制。它可以被 Pod 内的一个或多个容器使用。Volume 绑定在 Pod 上,在 Pod 生命周期内存在。
-
Pod 生命周期与 Volume:Volume 的数据在 Pod 生命周期内保持持久。如果 Pod 被删除或重新调度到不同的节点,Volume 的数据仍然保留,除非指定的 Volume 类型与 Pod 生命周期绑定(如
emptyDir
)。
二、常见的 Volume 类型
- emptyDir: 临时目录,Pod重启时数据丢失。
- hostPath: 将宿主机的文件或目录挂载到Pod中。
- nfs: 使用NFS服务器共享存储。
- persistentVolumeClaim: 使用持久卷声明。
- configMap: 从ConfigMap中获取配置文件。
- secret: 从Secret中获取敏感数据。
- awsElasticBlockStore: AWS的EBS卷。
- azureDisk: Azure的磁盘。
- gcePersistentDisk: Google Cloud的持久磁盘。
1.emptyDir
数据的临时性:使用 emptyDir
时,请注意数据只在 Pod 生命周期结束时保留。因此,如果 Pod 被删除,emptyDir
中的数据也会丢失。
数据共享:在同一 Pod 中的多个容器可以共享同一个 emptyDir
卷,实现数据共享。
性能:emptyDir
卷通常提供较快的读写性能,但适用于中短期临时数据存储,不适合持久存储方案。
apiVersion: apps/v1 kind: Pod metadata: name: nginx-emptydir labels: app: myapp # Pod 的标签 spec: containers: - name: nginx image: harbor.hiuiu.com/nginx/nginx:1.21.5 # 使用的 NGINX 镜像 ports: - containerPort: 80 # 容器暴露的端口 volumeMounts: - mountPath: /cache # 容器内部的挂载路径 name: cache-volume # 绑定到的卷的名称 volumes: - name: cache-volume emptyDir: {} # 使用 emptyDir 卷,它会在 Pod 生命周期内被创建
#可做资源限制
emptyDir:
sizeLimit: 500Mi
#查询到pod所在的node和uid后,在目标文件夹下新建文件
cd /var/lib/kubelet/pods/2be38576-c950-44d8-b911-d9dbcf22bf10/volumes/kubernetes.io~empty-dir/cache-volume/
#删除pod后,node下的文件一起被删除 kubectl delete -f emptydir.yaml
2.hostPath
将宿主机的某个目录(或文件)挂载到容器中。Pod 内部的容器可以访问这个挂载目录。
宿主机路径必须存在:确保宿主机上的 /mnt/data 目录存在,Kubernetes 需要此目录来挂载。否则,Pod 将无法启动。
安全性:使用 hostPath 卷时要仔细考虑安全性问题。Pod 可能拥有对宿主机某些目录的直接访问权限,这可能导致数据泄露或其他安全风险。
数据一致性:hostPath 卷允许在多个 Pods 之间共享同一个目录或文件,但多 Pod 之间的并发访问可能会导致数据一致性问题,因此在使用时要考虑如何管理并发写操作。
局限性:hostPath
只在单个节点上有效。如果 Pod 被调度到不同的节点,hostPath
卷将不可用。
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deployment labels: app: nginx-dep spec: replicas: 10 # 指定运行5个副本 selector: matchLabels: app: nginx # 用于选择管理 pods 的标签 template: metadata: labels: app: nginx # Pod 的标签,标识此 Pod spec: containers: - name: nginx image: harbor.hiuiu.com/nginx/nginx:1.21.5 # 使用的 NGINX 镜像 ports: - containerPort: 80 # 暴露的容器端口 volumeMounts: - mountPath: /usr/share/nginx/html # 容器内的挂载路径 name: hostpath-volume # 绑定到的卷名称 volumes: - name: hostpath-volume hostPath: path: /data/host # 宿主机上挂载的路径,需要提前手动创建
type: DirectoryOrCreate --- apiVersion: v1 kind: Service metadata: name: my-nodeport spec: type: NodePort selector: app: nginx ports: - port: 80 targetPort: 80 nodePort: 30007
#node上分别创建index.html文件,通过访问service的ip加端口可以访问到pod
# 将容器中多个目录挂载到真机上
apiVersion: v1 kind: Pod metadata: name: pod-host-dir labels: app: pod-host-dir spec: containers: - name: host-dir-container image: harbor.hiuiu.com/nginx/nginx:1.21.5 volumeMounts: - mountPath: /usr/share/nginx/html name: nginx-volume - mountPath: /var/logs name: logs-volume - mountPath: /cache name: cache-volume volumes: - name: nginx-volume hostPath: path: /data/webs type: DirectoryOrCreate - name: logs-volume hostPath: path: /data/logs type: DirectoryOrCreate - name: cache-volume hostPath: path: /data/cache type: DirectoryOrCreate kubectl apply -f hostPash.yaml kubectl get pod -o wide kubectl exec -it pod-host-dir -- /bin/bash
3.NFS-Service
共享数据:多个 Pod 可以同时访问和修改同一个 NFS 文件系统,适合需要文件共享的应用场景。
灵活性:可以在不同的节点上使用,适合跨节点的存储需求。
可靠性:NFS 服务器的可靠性直接影响到 Pod 的数据访问。如果 NFS 服务器出现问题,所有依赖它的 Pod 可能会受到影响。
配置NFS
#node节点 apt-get install nfs-common -y #主节点 apt-get install nfs-kernel-server -y vim /etc/exports /data/disk *(rw,sync,no_root_squash,no_subtree_check) exports -arv systemctl restart nfs-kernel-server.service
配置yaml文件
apiVersion: apps/v1 kind: Deployment metadata: name: nginx-deploy spec: replicas: 5 selector: matchLabels: app: nginx template: metadata: labels: app: nginx spec: containers: - name: nginx image: harbor.hiuiu.com/nginx/nginx:1.21.5 imagePullPolicy: IfNotPresent ports: - containerPort: 80 volumeMounts: - mountPath: /usr/share/nginx/html # 挂载路径 name: nginx-volume # 关联的卷名 volumes: - name: nginx-volume # 卷名称 nfs: server: 192.168.100.204 # NFS 服务器 IP 地址 path: /data/disk # NFS 共享路径 readOnly: false strategy: #指定执行更新时的策略 type: RollingUpdate # 更新策略 rollingUpdate: maxSurge: 20% # 允许增加副本数 maxUnavailable: 50% # 允许不在线的副本数 --- apiVersion: v1 kind: Service metadata: name: nginx-nodeport spec: type: NodePort selector: app: nginx ports: - port: 90 targetPort: 80 nodePort: 30008
4.NFS-PV
创建NFS服务器创建联系文件夹
mkdir -p /data/volume/v{1..5} vim /etc/exports /data/volume/v1 *(rw,sync,no_root_squash,no_subtree_check) /data/volume/v2 *(rw,sync,no_root_squash,no_subtree_check) /data/volume/v3 *(rw,sync,no_root_squash,no_subtree_check) /data/volume/v4 *(rw,sync,no_root_squash,no_subtree_check) /data/volume/v5 *(rw,sync,no_root_squash,no_subtree_check) exportfs -arv systemctl restart nfs-kernel-server.service chmod 777 /data/volume/ -r
PV、PVC
Persistent Volume (PV) 是集群中的一块存储资源,类似于传统存储系统中的硬盘。PV 是由管理员预先配置的,它提供了一种抽象层,使应用程序可以请求持久化存储,而不需要直接管理底层存储。
Persistent Volume Claim (PVC) 是用户对存储资源的请求。PVC 请求特定的存储容量和访问模式,Kubernetes 系统会根据 PVC 的要求来绑定合适的 PV。
PV 和 PVC 的工作流程
-
PV 的定义:管理员创建 PV,指定其存储容量、访问模式和其他属性。PV 可能会绑定到具体的存储系统,如 NFS、iSCSI、Ceph、AWS EBS 等。
-
PVC 的创建:用户或应用程序创建 PVC,指定所需的存储容量和访问模式。
-
绑定:Kubernetes 控制器会根据 PVC 的要求寻找适合的 PV。如果找到符合条件的 PV,PVC 将与 PV 绑定,用户或应用程序可以通过 PVC 使用 PV 提供的存储资源。
-
使用:绑定后的 PVC 被挂载到 Pod 上,Pod 可以使用这个存储卷来保存数据。
PV 和 PVC 的访问模式
-
ReadWriteOnce (RWO):允许单个节点以读写模式挂载该存储卷。
-
ReadOnlyMany (ROX):允许多个节点以只读模式挂载该存储卷。
-
ReadWriteMany (RWX):允许多个节点以读写模式挂载该存储卷。
PVC和pv绑定: 自动匹配并绑定 # 控制平面中的控制回路监测新的 PVC 对象,寻找与之匹配的 PV (如果可能的话), 并将二者绑定到一起。如果找不到匹配的 PV 卷,PVC 申领会无限期地处于未绑定状态。 当与之匹配的 PV 卷可用时,PVC 申领会被绑定。
例如,即使某集群上制备了很多 50 Gi 大小的 PV 卷,也无法与请求 100 Gi 大小的存储的 PVC 匹配。当新的 100 Gi PV 卷被加入到集群时, 该 PVC 才有可能被绑定。 # Pod 将 PVC 申领当做存储卷来使用。集群会检视 PVC 申领,找到所绑定的卷, 并为 Pod 挂载该卷。对于支持多种访问模式的卷, 用户要在 Pod 中以卷的形式使用申领时指定期望的访问模式。 一旦用户有了申领对象并且该申领已经被绑定, 则所绑定的 PV 卷在用户仍然需要它期间一直属于该用户。 用户通过在 Pod 的 `volumes` 块中包含 `persistentVolumeClaim` 节区来调度 Pod,访问所申领的 PV 卷。
apiVersion: v1 kind: PersistentVolume metadata: name: v1 spec: capacity: storage: 3Gi accessModes: ["ReadOnlyMany"] nfs: path: /data/volume/v1 server: 192.168.100.204 --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: my-pvc spec: accessModes: ["ReadOnlyMany"] resources: requests: storage: 2Gi--- apiVersion: v1 kind: Pod metadata: name: pod-pvc labels: app: nginx spec: containers: - name: nginx image: harbor.hiuiu.com/nginx/nginx:1.21.5 imagePullPolicy: IfNotPresent ports: - containerPort: 80 volumeMounts: - name: nginx-html mountPath: /usr/share/nginx/html volumes: - name: nginx-html persistentVolumeClaim: claimName: my-pvc --- apiVersion: v1 kind: Service metadata: name: nginx-pvc spec: type: NodePort selector: app: nginx ports: - port: 90 targetPort: 80 nodePort: 30008
5.NFS-provisioner
创建一个sa账户(sa.yaml)
apiVersion: v1 kind: ServiceAccount metadata: name: nfs-provisioner
对sa授权
kubectl create clusterrolebinding nfs-provisioner-clusterrolebinding --clusterrole=cluster-admin --serviceaccount=default:nfs-provisioner
安装并配置NFS
#所有节点 apt-get install nfs-kernel-server nfs-common -y #主节点 vim /etc/exports /nfs/nfs_pro *(rw,sync,no_root_squash,no_subtree_check) exportfs -arv systemctl restart nfs-kernel-server.service
启动一个pod(nfs_provisioner.yaml)
apiVersion: apps/v1 kind: Deployment metadata: name: nfs-provisioner spec: replicas: 1 selector: matchLabels: app: myapp strategy: type: Recreate template: metadata: labels: app: myapp spec: serviceAccount: nfs-provisioner containers: - name: nfs-provisioner image: registry.cn-beijing.aliyuncs.com/mydlq/nfs-subdir-external-provisioner:v4.0.0 volumeMounts: - name: nfs-client-root mountPath: /persistentvolumes env: - name: PROVISIONER_NAME value: example.com/nfs - name: NFS_SERVER value: 192.168.100.204 - name: NFS_PATH value: /data/nfs_pro volumes: - name: nfs-client-root nfs: server: 192.168.100.204 path: /data/nfs_pro
创建一个StorageClass,动态PV(example_nfs.yaml)
apiVersion: storage.k8s.io/v1 kind: StorageClass metadata: name: nfs provisioner: example.com/nfs parameters: server: 192.168.100.204 path: /data/nfs_pro readOnly: "false"
创建PVC,通过StorageClass去实现(pvc.yaml)
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: test-claim1 spec: accessModes: ["ReadWriteMany"] resources: requests: storage: 1Gi storageClassName: nfs
创建测试用Pod(test.yaml)
apiVersion: v1 kind: Pod metadata: name: read-pod labels: app: myapp spec: containers: - name: read-pod image: harbor.hiuiu.com/nginx/nginx:1.21.5 ports: - containerPort: 80 volumeMounts: - name: nfs-pvc mountPath: /usr/share/nginx/html restartPolicy: Never volumes: - name: nfs-pvc persistentVolumeClaim: claimName: test-claim1
标签:存储,持久,name,nginx,PVC,nfs,PV,Pod From: https://www.cnblogs.com/hxqwe/p/18384458