1. 背景
客户私有化部署的时候容器需要挂载卷,但不支持nfs或openebs的方式,只能采取hostpath或者local pv的方式。通过hostpath方式挂卷,当pod重启进行重新调度的时候,不能保证pod和node之间的绑定,会导致数据出现丢失的问题,local pv的挂载方式能保证node和pod之前的绑定关系,从而真正的保证数据持久化。
2. HostPath 和 Local Persistent Volume 的区别
在Kubernetes中,有两种用于访问本地存储的主要方式:Local Persistent Volumes(PV)和 HostPath Volume。它们之间有一些关键区别:
1. **Local Persistent Volume (PV) 和 Persistent Volume Claim (PVC)**:
* **Local Persistent Volume (PV)**:
* `Local Persistent Volume` 是 Kubernetes 提供的一种存储抽象,用于表示集群节点上的本地存储资源。
* `Local PV` 允许你在集群中使用本地磁盘,并且具有一定的持久性,即使 Pod 重新启动或迁移到其他节点,数据也能保留在本地 PV 上。
* PV 是集群级别的资源,可以被多个 Pod 或多个命名空间中的 Pod 共享,但一次只能被一个 Pod 挂载(ReadWriteOnce 访问模式)。
* **Persistent Volume Claim (PVC)**:
* `Persistent Volume Claim` 是对 PV 的请求,它定义了 Pod 所需的存储大小和访问模式。
* PVC 是 Pod 级别的资源,每个 Pod 需要自己的 PVC,它可以请求与 PV 匹配的存储。
2. **HostPath Volume**:
* **HostPath Volume** 是一种直接将节点上的文件系统路径挂载到 Pod 中的存储卷。它不需要定义 PV 和 PVC,也不受 Kubernetes 存储系统的管理。
* 使用 HostPath Volume 可能会导致一些限制和不可预测性,因为它不提供数据的持久性和可移植性。如果 Pod 在不同的节点上重新调度,它将无法访问之前挂载的 HostPath。
3. 测试
本次测试通过部署nginx的statefulset测试,2个副本分别部署在两台node节点上
3.1 node节点打标签并创建hostpath文件夹
# 两个node执行
mkidr /data/localpv-test
kubectl label node df-idc-qa-001 use=nginx1 app=nginx
kubectl label node df-idc-qa-002 use=nginx2 app=nginx
3.2 创建Local Persistent Volume
# local-pv1 和 df-idc-qa-001 绑定
# local-pv2 和 df-idc-qa-002 绑定
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-1
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/localpv-test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: use
operator: In
values:
- nginx1
apiVersion: v1
kind: PersistentVolume
metadata:
name: local-pv-2
spec:
capacity:
storage: 10Gi
volumeMode: Filesystem
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Retain
storageClassName: local-storage
local:
path: /data/localpv-test
nodeAffinity:
required:
nodeSelectorTerms:
- matchExpressions:
- key: use
operator: In
values:
- nginx2
3.3 创建Storageclass
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: local-storage
provisioner: kubernetes.io/no-provisioner
volumeBindingMode: WaitForFirstConsumer
3.4 创建Statefulset
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: nginx-statefulset
spec:
replicas: 2
selector:
matchLabels:
app: nginx
serviceName: nginx-headless
template:
metadata:
labels:
app: nginx
spec:
containers:
- name: nginx-container
image: nginx:latest
ports:
- containerPort: 80
volumeMounts:
- name: "nginx-persistent-storage"
mountPath: /tmp
volumeClaimTemplates:
- metadata:
name: nginx-persistent-storage
spec:
accessModes: [ "ReadWriteOnce" ]
storageClassName: local-storage
resources:
requests:
storage: 1Gi