配置 Pod 以使用持久卷进行存储
此页面向您展示如何配置 Pod 使用 PersistentVolumeClaim 进行存储。以下是该过程的总结
您作为集群管理员,创建由物理存储支持的 PersistentVolume。您不将该卷与任何 Pod 关联。
您现在担任开发人员/集群用户的角色,创建一个会自动绑定到合适的 PersistentVolume 的 PersistentVolumeClaim。
您创建一个 Pod,该 Pod 使用上述 PersistentVolumeClaim 进行存储。
开始之前
在您的节点上创建一个 index.html 文件
打开一个 shell 连接到集群中的单个节点。如何打开 shell 取决于您如何设置集群。例如,如果您使用的是 Minikube,可以通过输入 minikube ssh
来打开连接到节点的 shell。
在节点的 shell 中,创建一个 /mnt/data
目录
# This assumes that your Node uses "sudo" to run commands
# as the superuser
sudo mkdir /mnt/data
在 /mnt/data
目录中,创建一个 index.html
文件
# This again assumes that your Node uses "sudo" to run commands
# as the superuser
sudo sh -c "echo 'Hello from Kubernetes storage' > /mnt/data/index.html"
注意
如果您的节点使用sudo
以外的工具进行超级用户访问,您通常可以通过将 sudo
替换为其他工具的名称来使其正常工作。测试 index.html
文件是否存在
cat /mnt/data/index.html
输出应为
Hello from Kubernetes storage
您现在可以关闭与节点的 shell 连接。
创建一个 PersistentVolume
在本练习中,您将创建一个 _hostPath_ PersistentVolume。Kubernetes 支持在单节点集群上进行开发和测试使用 hostPath。hostPath PersistentVolume 使用节点上的文件或目录来模拟网络连接的存储。
在生产集群中,您不会使用 hostPath。相反,集群管理员将配置网络资源,例如 Google Compute Engine 持久磁盘、NFS 共享或 Amazon Elastic Block Store 卷。集群管理员还可以使用 StorageClasses 来设置动态配置。
以下是 hostPath PersistentVolume 的配置文件
apiVersion: v1
kind: PersistentVolume
metadata:
name: task-pv-volume
labels:
type: local
spec:
storageClassName: manual
capacity:
storage: 10Gi
accessModes:
- ReadWriteOnce
hostPath:
path: "/mnt/data"
配置文件指定该卷位于集群节点的 /mnt/data
。该配置还指定了 10 吉比字节的大小和 ReadWriteOnce
的访问模式,这意味着该卷可以由单个节点以读写方式挂载。它为 PersistentVolume 定义了StorageClass 名称 manual
,它将用于将 PersistentVolumeClaim 请求绑定到此 PersistentVolume。
注意
此示例为简单起见使用了ReadWriteOnce
访问模式。对于生产用途,Kubernetes 项目建议改用 ReadWriteOncePod
访问模式。创建 PersistentVolume
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
查看有关 PersistentVolume 的信息
kubectl get pv task-pv-volume
输出显示 PersistentVolume 的 STATUS
为 Available
。这意味着它尚未绑定到 PersistentVolumeClaim。
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Available manual 4s
创建 PersistentVolumeClaim
下一步是创建一个 PersistentVolumeClaim。Pod 使用 PersistentVolumeClaim 来请求物理存储。在本练习中,您将创建一个 PersistentVolumeClaim,该请求至少需要 3 吉比字节的卷,并且每次最多为一个节点提供读写访问。
以下是 PersistentVolumeClaim 的配置文件
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: task-pv-claim
spec:
storageClassName: manual
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 3Gi
创建 PersistentVolumeClaim
kubectl apply -f https://k8s.io/examples/pods/storage/pv-claim.yaml
创建 PersistentVolumeClaim 后,Kubernetes 控制平面会查找满足该声明要求的 PersistentVolume。如果控制平面找到具有相同 StorageClass 的合适 PersistentVolume,则会将该声明绑定到该卷。
再次查看 PersistentVolume
kubectl get pv task-pv-volume
现在输出显示 STATUS
为 Bound
。
NAME CAPACITY ACCESSMODES RECLAIMPOLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 10Gi RWO Retain Bound default/task-pv-claim manual 2m
查看 PersistentVolumeClaim
kubectl get pvc task-pv-claim
输出显示 PersistentVolumeClaim 已绑定到您的 PersistentVolume task-pv-volume
。
NAME STATUS VOLUME CAPACITY ACCESSMODES STORAGECLASS AGE
task-pv-claim Bound task-pv-volume 10Gi RWO manual 30s
创建一个 Pod
下一步是创建一个使用您的 PersistentVolumeClaim 作为卷的 Pod。
以下是 Pod 的配置文件
apiVersion: v1
kind: Pod
metadata:
name: task-pv-pod
spec:
volumes:
- name: task-pv-storage
persistentVolumeClaim:
claimName: task-pv-claim
containers:
- name: task-pv-container
image: nginx
ports:
- containerPort: 80
name: "http-server"
volumeMounts:
- mountPath: "/usr/share/nginx/html"
name: task-pv-storage
请注意,Pod 的配置文件指定了一个 PersistentVolumeClaim,但未指定 PersistentVolume。从 Pod 的角度来看,该声明是一个卷。
创建 Pod
kubectl apply -f https://k8s.io/examples/pods/storage/pv-pod.yaml
验证 Pod 中的容器是否正在运行;
kubectl get pod task-pv-pod
获取连接到 Pod 中正在运行的容器的 shell
kubectl exec -it task-pv-pod -- /bin/bash
在您的 shell 中,验证 nginx 是否正在从 hostPath 卷提供 index.html
文件
# Be sure to run these 3 commands inside the root shell that comes from
# running "kubectl exec" in the previous step
apt update
apt install curl
curl https://127.0.0.1/
输出显示您写入 hostPath 卷上的 index.html
文件的文本
Hello from Kubernetes storage
如果您看到该消息,则说明您已成功配置 Pod 以使用 PersistentVolumeClaim 中的存储。
清理
删除 Pod、PersistentVolumeClaim 和 PersistentVolume
kubectl delete pod task-pv-pod
kubectl delete pvc task-pv-claim
kubectl delete pv task-pv-volume
如果您还没有打开与集群中节点的 shell 连接,请以您之前的方式打开一个新的 shell。
在您的节点的 shell 中,删除您创建的文件和目录
# This assumes that your Node uses "sudo" to run commands
# as the superuser
sudo rm /mnt/data/index.html
sudo rmdir /mnt/data
您现在可以关闭与节点的 shell 连接。
在两个地方挂载相同的持久卷
apiVersion: v1
kind: Pod
metadata:
name: test
spec:
containers:
- name: test
image: nginx
volumeMounts:
# a mount for site-data
- name: config
mountPath: /usr/share/nginx/html
subPath: html
# another mount for nginx config
- name: config
mountPath: /etc/nginx/nginx.conf
subPath: nginx.conf
volumes:
- name: config
persistentVolumeClaim:
claimName: test-nfs-claim
您可以在 nginx 容器上执行 2 次卷挂载
- 用于静态网站的
/usr/share/nginx/html
- 用于默认配置的
/etc/nginx/nginx.conf
访问控制
使用组 ID (GID) 配置的存储仅允许使用相同 GID 的 Pod 写入。不匹配或缺少 GID 会导致权限被拒绝错误。为了减少与用户协调的需要,管理员可以使用 GID 注释 PersistentVolume。然后,该 GID 会自动添加到使用该 PersistentVolume 的任何 Pod。
如下使用 pv.beta.kubernetes.io/gid
注释
apiVersion: v1
kind: PersistentVolume
metadata:
name: pv1
annotations:
pv.beta.kubernetes.io/gid: "1234"
当 Pod 使用带有 GID 注释的 PersistentVolume 时,带注释的 GID 将以与 Pod 的安全上下文中指定的 GID 相同的方式应用于 Pod 中的所有容器。每个 GID,无论是源自 PersistentVolume 注释还是 Pod 的规范,都将应用于每个容器中运行的第一个进程。