要实现数据的持久存储,可以通过 PersistentVolumes 和 PersistentVolumeClaims 来保存数据。
PersistentVolume(PV)是一块集群里由管理员手动提供,或 kubernetes 通过 StorageClass 动态创建的存储。 PersistentVolumeClaim(PVC)是一个满足对 PV 存储需要的请求。PersistentVolumes 和 PersistentVolumeClaims 是独立于 Pod 生命周期而在 Pod 重启,重新调度甚至删除过程中保存数据。
PV
PV是Kubernetes集群中的一种网络存储实现,跟Node一样,也是属于集群的资源。 PV跟Docker里的Volume(卷)类似,不过会有独立于Pod的生命周期。 使用kubectl get pv查看列表:
$ kubectl get pv
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
pvc-c115b166 20Gi RWO Delete Bound default/mysql-pv-claim hostpath 14m
PVC
PVC是用户的一个请求,跟Pod类似。Pod消费Node的资源,PVC消费PV的资源
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
mysql-pv-claim Bound pvc-c115b166 20Gi RWO hostpath 18m
示例
apiVersion: v1
kind: Service
metadata:
name: basic-mysql
labels:
app: basic
spec:
ports:
- port: 3306
selector:
app: basic
tier: mysql
type: LoadBalancer
---
apiVersion: v1
kind: PersistentVolume
metadata:
name: mysql-pv-volume
labels:
app: basic
spec:
storageClassName: mysql-storage
accessModes:
- ReadWriteOnce
capacity:
storage: 5Gi
hostPath:
path: "/d/dev/k8s/yaml/basic/data/mysql"
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: mysql-pv-claim
labels:
app: basic
spec:
storageClassName: mysql-storage
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 2Gi
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: basic-mysql
labels:
app: basic
spec:
selector:
matchLabels:
app: basic
tier: mysql
strategy:
type: Recreate
template:
metadata:
labels:
app: basic
tier: mysql
spec:
containers:
- image: mysql:8.0.26
name: mysql
env:
- name: MYSQL_ROOT_PASSWORD
value: liveapp3306
ports:
- containerPort: 3306
name: mysql
volumeMounts:
- name: mysql-persistent-storage
mountPath: "/var/lib/mysql"
volumes:
- name: mysql-persistent-storage
hostPath:
path: /run/desktop/mnt/host/d/v/data/mysql
type: DirectoryOrCreate
注意windows下需要添加
/run/desktop/mnt/host
为路径前缀,否则找不到地址hostpath 支持的 type 值如下:
DirectoryOrCreate 如果在给定路径上什么都不存在,那么将根据需要创建空目录,权限设置为 0755,具有与 Kubelet 相同的组和所有权。 Directory 在给定路径上必须存在的目录。 FileOrCreate 如果在给定路径上什么都不存在,那么将在那里根据需要创建空文件,权限设置为 0644,具有与 Kubelet 相同的组和所有权。 File 在给定路径上必须存在的文件。 Socket 在给定路径上必须存在的 UNIX 套接字。 CharDevice 在给定路径上必须存在的字符设备。 BlockDevice 在给定路径上必须存在的块设备。
kubectl logs basic-mysql-7fc5c87587-5f44z
2022-02-12 09:26:44+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 8.0.26-1debian10 started.
find: '/var/lib/mysql/': Operation not permitted
chown: changing ownership of '/var/lib/mysql/': Operation not permitted
出现这个问题是由于
/var/lib/mysql/
所映射的宿主机文件夹没有写权限您正在直接在主节点上创建 docker 容器。因此,您可以使用新创建的目录运行 docker 容器。但是当您启动 kubernetes yaml 文件时,它打算在工作节点上运行。由于您在主节点上创建目录,kubelet 无法在工作节点上找到目录并且失败。这就是为什么类型标志上的“DirectoryorCreate”值是一种解决方案