2a42da0495
* zh-trans: add storage-object-in-use-protection.md(recreation) add storage-object-in-use-protection.md * Update storage-object-in-use-protection.md
11 KiB
11 KiB
reviewers:
- msau42
- jsafrane
title: 保护使用的存储对象 content_template: templates/task
{{% capture overview %}}
Kubernetes 可以对被 Pod 持续使用的永久卷声明(PVCs)和绑定到 PVC 的永久卷(PVs)进行保护,以避免它们被用户不小心删除掉。
{{% /capture %}}
{{% capture prerequisites %}}
在下面列出的 Kubernetes 版本中,激活了在用存储对象的保护特性:
{{< feature-state for_k8s_version="v1.10" state="beta" >}}
{{< feature-state for_k8s_version="v1.11" state="stable" >}}
{{% /capture %}}
{{% capture steps %}}
在用存储对象的保护功能用于 PVC 的保护
下面的例子中使用了 GCE PD StorageClass, 但是类似的步骤可以在任意的卷类型上执行。
创建 StorageClass 以便提供存储:
apiVersion: storage.k8s.io/v1
kind: StorageClass
metadata:
name: slow
provisioner: kubernetes.io/gce-pd
parameters:
type: pd-standard
下面列出了验证场景。
场景1: PVC 没有被 Pod 使用
- 创建 PVC
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: slzc
spec:
accessModes:
- ReadWriteOnce
storageClassName: slow
resources:
requests:
storage: 3.7Gi
- 检查 PVC 设置了终结器
kubernetes.io/pvc-protection:
kubectl describe pvc slzc
Name: slzc
Namespace: default
StorageClass: slow
Status: Bound
Volume: pvc-bee8c30a-d6a3-11e7-9af0-42010a800002
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/gce-pd
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ProvisioningSucceeded 2m persistentvolume-controller Successfully provisioned volume pvc-bee8c30a-d6a3-11e7-9af0-42010a800002 using kubernetes.io/gce-pd
- 删除 PVC 并检查 PVC (当前未被某 Pod 使用)被成功删除。
场景 2: PVC 被 Pod 使用
- 再来一次,创建相同的 PVC。
- 创建一个 Pod ,并使用上面创建的 PVC:
kind: Pod
apiVersion: v1
metadata:
name: app1
spec:
containers:
- name: test-pod
image: k8s.gcr.io/busybox:1.24
command:
- "/bin/sh"
args:
- "-c"
- "date > /mnt/app1.txt; sleep 60 && exit 0 || exit 1"
volumeMounts:
- name: path-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: path-pvc
persistentVolumeClaim:
claimName: slzc
- 等到 Pod 的状态为
Running,即 PVC 变为在用状态。 - 删除被 Pod 使用的 PVC 并确认其没有被删除成功,但它的状态为
Terminating:
Name: slzc
Namespace: default
StorageClass: slow
Status: Terminating (since Fri, 01 Dec 2017 14:47:55 +0000)
Volume: pvc-803a1f4d-d6a6-11e7-9af0-42010a800002
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/gce-pd
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ProvisioningSucceeded 52s persistentvolume-controller Successfully provisioned volume pvc-803a1f4d-d6a6-11e7-9af0-42010a800002 using kubernetes.io/gce-pd
- 等到 Pod 的状态变为
Terminated(删除 Pod 或者等到它结束),紧接着确认 PVC 被删除掉了。
场景 3: Pod 开始使用正在停止状态(Terminating)的 PVC
- 再次创建相同的 PVC。
- 创建使用这个 PVC 的第一个 Pod:
kind: Pod
apiVersion: v1
metadata:
name: app1
spec:
containers:
- name: test-pod
image: k8s.gcr.io/busybox:1.24
command:
- "/bin/sh"
args:
- "-c"
- "date > /mnt/app1.txt; sleep 600 && exit 0 || exit 1"
volumeMounts:
- name: path-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: path-pvc
persistentVolumeClaim:
claimName: slzc
- 等到 Pod 状态为
Running,即 PVC 变为使用状态。 - 删除被 Pod 使用的 PVC 并确认其没有被删除成功,但它的状态为
Terminating:
Name: slzc
Namespace: default
StorageClass: slow
Status: Terminating (since Fri, 01 Dec 2017 14:47:55 +0000)
Volume: pvc-803a1f4d-d6a6-11e7-9af0-42010a800002
Labels: <none>
Annotations: pv.kubernetes.io/bind-completed=yes
pv.kubernetes.io/bound-by-controller=yes
volume.beta.kubernetes.io/storage-provisioner=kubernetes.io/gce-pd
Finalizers: [kubernetes.io/pvc-protection]
Capacity: 4Gi
Access Modes: RWO
Events:
Type Reason Age From Message
---- ------ ---- ---- -------
Normal ProvisioningSucceeded 52s persistentvolume-controller Successfully provisioned volume pvc-803a1f4d-d6a6-11e7-9af0-42010a800002 using kubernetes.io/gce-pd
- 创建使用这个 PVC 的第二个 Pod:
kind: Pod
apiVersion: v1
metadata:
name: app2
spec:
containers:
- name: test-pod
image: gcr.io/google_containers/busybox:1.24
command:
- "/bin/sh"
args:
- "-c"
- "date > /mnt/app1.txt; sleep 600 && exit 0 || exit 1"
volumeMounts:
- name: path-pvc
mountPath: "/mnt"
restartPolicy: "Never"
volumes:
- name: path-pvc
persistentVolumeClaim:
claimName: slzc
- 检查第二个 Pod 因为下面的警告而导致调度失败:
Warning FailedScheduling 18s (x4 over 21s) default-scheduler persistentvolumeclaim "slzc" is being deleted
- 等到两个 Pod 的状态为
Terminated或者Completed(删除 Pod 或者等待它们结束),紧接着检查 PVC 被删除掉了。
使用在用存储对象保护的功能来保护 PV
下面的示例使用了 HostPath PV。
下面列出了验证场景。
场景 1: PV 没有绑定到 PVC
- 创建 PV:
kind: PersistentVolume
apiVersion: v1
metadata:
name: task-pv-volume
labels:
type: local
spec:
capacity:
storage: 1Gi
accessModes:
- ReadWriteOnce
persistentVolumeReclaimPolicy: Delete
storageClassName: standard
hostPath:
path: "/tmp/data"
- 检查 PV 设置了终结器
kubernetes.io/pv-protection:
Name: task-pv-volume
Labels: type=local
Annotations: pv.kubernetes.io/bound-by-controller=yes
Finalizers: [kubernetes.io/pv-protection]
StorageClass: standard
Status: Terminating (lasts 1m)
Claim: default/task-pv-claim
Reclaim Policy: Delete
Access Modes: RWO
Capacity: 1Gi
Message:
Source:
Type: HostPath (bare host directory volume)
Path: /tmp/data
HostPathType:
Events: <none>
- 删除 PV 并检查该 PV(没有绑定到 PVC )被成功删除。
场景 2: PV 绑定了 PVC。
-
再次创建相同的 PV。
-
创建一个 PVC:
kind: PersistentVolumeClaim
apiVersion: v1
metadata:
name: task-pv-claim
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
- 等到 PV 和 PVC 相互绑定。
- 删除 PV 并确认该 PV 没有被删除掉,但它的状态是
Terminating:
NAME CAPACITY ACCESS MODES RECLAIM POLICY STATUS CLAIM STORAGECLASS REASON AGE
task-pv-volume 1Gi RWO Delete Terminating default/task-pv-claim standard 59s
- 删除 PVC 并确认 PV 也一同被删除了。
kubectl delete pvc task-pv-claim
persistentvolumeclaim "task-pv-claim" deleted
$ kubectl get pvc
No resources found.
$ kubectl get pv
No resources found.
{{% /capture %}}
{{% capture discussion %}}
{{% /capture %}}