配置 Pod 使用持久卷进行存储
此页面向您展示如何配置 Pod 以使用 PersistentVolumeClaim 进行存储。以下是该过程的摘要
您作为集群管理员创建了一个由物理存储支持的 PersistentVolume。您不会将卷与任何 Pod 关联。
您现在担任开发人员/集群用户角色,创建一个 PersistentVolumeClaim,该 PersistentVolumeClaim 会自动绑定到合适的 PersistentVolume。
您创建一个使用上述 PersistentVolumeClaim 进行存储的 Pod。
在您开始之前
您需要拥有一个只有一个节点的 Kubernetes 集群,并且 kubectl 命令行工具必须配置为与您的集群通信。如果您还没有单节点集群,可以使用 Minikube 创建一个。
熟悉 持久卷 中的材料。
在您的节点上创建一个 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。
创建一个持久卷
在本练习中,您将创建一个 hostPath 持久卷。Kubernetes 支持 hostPath 用于在单节点集群上进行开发和测试。hostPath 持久卷使用节点上的文件或目录来模拟网络连接存储。
在生产集群中,您不会使用 hostPath。相反,集群管理员会配置网络资源,例如 Google Compute Engine 持久磁盘、NFS 共享或 Amazon Elastic Block Store 卷。集群管理员还可以使用 StorageClass 来设置 动态供应。
以下是 hostPath 持久卷的配置文件
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 gibibytes 的大小和 ReadWriteOnce
的访问模式,这意味着该卷可以由单个节点以读写方式安装。它为持久卷定义了 StorageClass 名称 manual
,该名称将用于将 PersistentVolumeClaim 请求绑定到此持久卷。
注意
此示例出于简单起见使用了ReadWriteOnce
访问模式。对于生产使用,Kubernetes 项目建议使用 ReadWriteOncePod
访问模式。创建持久卷
kubectl apply -f https://k8s.io/examples/pods/storage/pv-volume.yaml
查看有关持久卷的信息
kubectl get pv task-pv-volume
输出显示持久卷的 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,该 PersistentVolumeClaim 请求至少 3 gibibytes 的卷,该卷可以为最多一个节点提供读写访问权限。
以下是 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,它会将声明绑定到卷。
再次查看持久卷
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 绑定到您的持久卷 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 http://localhost/
输出显示您写入 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 会导致权限被拒绝错误。为了减少与用户的协调需求,管理员可以为 PersistentVolume 添加注释,其中包含 GID。然后,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 中的所有容器,与 Pod 安全上下文中指定的 GID 相同。每个 GID(无论它源自 PersistentVolume 注释还是 Pod 的规范)都会应用于每个容器中运行的第一个进程。