2.16. 使用卷快照的持久性存储
OpenShift Container Platform 4.2 中已弃用卷快照。
本文介绍了如何使用 VolumeSnapshot 来防止 OpenShift Container Platform 中发生数据丢失。建议先熟悉持久性卷。
卷快照只是技术预览功能。技术预览功能不被红帽产品服务等级协议 (SLA) 支持,且可能在功能方面有缺陷。红帽不推荐在生产环境中使用它们。这些技术预览功能可以使用户提早试用新的功能,并有机会在开发阶段提供反馈意见。
有关红帽技术预览功能支持范围的详情,请参阅 https://access.redhat.com/support/offerings/techpreview/。
2.16.1. 关于快照
卷快照是集群中的一个存储卷的快照。外部快照控制器和置备程序支持使用 OpenShift Container Platform 集群中的功能,并通过 OpenShift Container Platform API 处理卷快照。
使用卷快照时,集群管理员能够:
- 为绑定到 PersistentVolumeClaim 的 PersistentVolume 创建快照。
- 列出现有的 VolumeSnapshot。
- 删除现有的 VolumeSnapshot。
- 从现有 VolumeSnapshot 创建新的 PersistentVolume。
支持的 PersistentVolume 类型:
- AWS Elastic Block Store (EBS)
- Google Compute Engine (GCE) Persistent Disk (PD)
2.16.2. 外部控制器和置备程序
控制器和置备程序提供卷快照功能。这些外部组件在集群中运行。
提供卷快照的两个外部组件:
- 外部控制器
- 创建、删除和报告有关卷快照的事件。
- 外部置备程序
- 从 VolumeSnapshot 创建新的 PersistentVolume。
外部控制器和置备程序服务以容器镜像形式分发,并可像平常一样在 OpenShift Container Platform 集群中运行。
2.16.2.1. 运行外部控制器和置备程序
集群管理员必须配置访问权限,以运行外部控制器和置备程序。
流程
允许容器管理 API 对象:
创建 ServiceAccount 和 ClusterRole:
apiVersion: v1 kind: ServiceAccount metadata: name: snapshot-controller-runner kind: ClusterRole apiVersion: rbac.authorization.k8s.io/v1 metadata: name: snapshot-controller-role rules: - apiGroups: [""] resources: ["persistentvolumes"] verbs: ["get", "list", "watch", "create", "delete"] - apiGroups: [""] resources: ["persistentvolumeclaims"] verbs: ["get", "list", "watch", "update"] - apiGroups: ["storage.k8s.io"] resources: ["storageclasses"] verbs: ["get", "list", "watch"] - apiGroups: [""] resources: ["events"] verbs: ["list", "watch", "create", "update", "patch"] - apiGroups: ["apiextensions.k8s.io"] resources: ["customresourcedefinitions"] verbs: ["create", "list", "watch", "delete"] - apiGroups: ["volumesnapshot.external-storage.k8s.io"] resources: ["volumesnapshots"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"] - apiGroups: ["volumesnapshot.external-storage.k8s.io"] resources: ["volumesnapshotdatas"] verbs: ["get", "list", "watch", "create", "update", "patch", "delete"]
作为集群管理员,提供
hostNetwork
安全 上下文约束 (SCC):# oc adm policy add-scc-to-user hostnetwork -z snapshot-controller-runner
此 SCC 控制对 Pod 正在使用的
snapshot-controller-runner
服务帐户的访问。通过 ClusterRoleBinding 绑定规则:
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: snapshot-controller roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: snapshot-controller-role subjects: - kind: ServiceAccount name: snapshot-controller-runner namespace: default 1
- 1
- 指定 snapshot-controller 所在的项目名称。
2.16.2.2. AWS 和 GCE 身份验证
为进行外部控制器和置备程序身份验证,云供应商可能需要管理员提供 Secret。
2.16.2.2.1. AWS 身份验证
如果外部控制器和置备程序部署在 Amazon Web Services (AWS) 中,AWS 必须能够使用访问密钥进行身份验证。
为向 Pod 提供凭证,集群管理员要创建一个新的 Secret:
apiVersion: v1 kind: Secret metadata: name: awskeys type: Opaque data: access-key-id: <base64 encoded AWS_ACCESS_KEY_ID> secret-access-key: <base64 encoded AWS_SECRET_ACCESS_KEY>
在为 awskeys
secret 生成 base64 值时,请删除结尾的换行符:
$ echo -n "<aws_access_key_id>" | base64 $ echo -n "<aws_secret_access_key>" | base64
下例展示了外部控制器和置备程序容器的 AWS 部署。两个 Pod 容器都使用 Secret 访问 AWS API。
kind: Deployment apiVersion: extensions/v1beta1 metadata: name: snapshot-controller spec: replicas: 1 strategy: type: Recreate template: metadata: labels: app: snapshot-controller spec: serviceAccountName: snapshot-controller-runner hostNetwork: true containers: - name: snapshot-controller image: "registry.redhat.io/openshift3/snapshot-controller:latest" imagePullPolicy: "IfNotPresent" args: ["-cloudprovider", "aws"] env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: awskeys key: access-key-id - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: awskeys key: secret-access-key - name: snapshot-provisioner image: "registry.redhat.io/openshift3/snapshot-provisioner:latest" imagePullPolicy: "IfNotPresent" args: ["-cloudprovider", "aws"] env: - name: AWS_ACCESS_KEY_ID valueFrom: secretKeyRef: name: awskeys key: access-key-id - name: AWS_SECRET_ACCESS_KEY valueFrom: secretKeyRef: name: awskeys key: secret-access-key
2.16.2.2.2. GCE 身份验证
对于 Google Compute Engine (GCE),无需使用 Secret 来访问 GCE API。
管理员可以按照下例所示进行部署:
kind: Deployment apiVersion: extensions/v1beta1 metadata: name: snapshot-controller spec: replicas: 1 strategy: type: Recreate template: metadata: labels: app: snapshot-controller spec: serviceAccountName: snapshot-controller-runner containers: - name: snapshot-controller image: "registry.redhat.io/openshift3/snapshot-controller:latest" imagePullPolicy: "IfNotPresent" args: ["-cloudprovider", "gce"] - name: snapshot-provisioner image: "registry.redhat.io/openshift3/snapshot-provisioner:latest" imagePullPolicy: "IfNotPresent" args: ["-cloudprovider", "gce"]
2.16.2.3. 管理快照用户
根据集群配置,可能需要允许非管理员用户操作 API 服务器上的 VolumeSnapshot 对象。这可以通过创建一个绑定到特定用户或组的 ClusterRole 来完成。
例如,假设用户“alice”需要使用集群中的快照。集群管理员完成下列步骤:
定义一个新的 ClusterRole:
apiVersion: v1 kind: ClusterRole metadata: name: volumesnapshot-admin rules: - apiGroups: - "volumesnapshot.external-storage.k8s.io" attributeRestrictions: null resources: - volumesnapshots verbs: - create - delete - deletecollection - get - list - patch - update - watch
通过创建一个 ClusterRoleBinding 绑定对象,将集群角色绑定到用户“alice”:
apiVersion: rbac.authorization.k8s.io/v1beta1 kind: ClusterRoleBinding metadata: name: volumesnapshot-admin roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: volumesnapshot-admin subjects: - kind: User name: alice
这只是 API 访问配置的一个示例。VolumeSnapshot 对象的行为与其他 OpenShift Container Platform API 对象类似。有关管理 API RBAC 的详情,请参阅 API 访问控制文档。
2.16.3. 创建和删除快照
与持久性卷声明 (PVC) 绑定到持久性卷 (PV) 来置备卷的方式类似,VolumeSnapshotData 和 VolumeSnapshot 用于创建卷快照。
卷快照必须使用受支持的 PersistentVolume 类型。
2.16.3.1. 创建快照
要获取 PV 快照,请基于 VolumeSnapshot 创建一个新的 VolumeSnapshotData 对象,如下例所示:
apiVersion: volumesnapshot.external-storage.k8s.io/v1 kind: VolumeSnapshot 1 metadata: name: snapshot-demo spec: persistentVolumeClaimName: ebs-pvc 2
根据 PV 类型,创建快照操作可能会经历若干阶段,由不同的 VolumeSnapshot 状态来体现:
- 创建新的 VolumeSnapshot 对象。
- 启动控制器。可能需要冻结快照的 PersistentVolume,并且暂停应用程序。
-
创建(“截取”)快照。快照的 PersistentVolume 可能会恢复正常运作,但快照本身还没有就绪(status=
True
,type=Pending
)。 - 创建新的 VolumeSnapshotData 对象,该对象代表实际快照。
-
快照已完成,且已可用(status=
True
,type=Ready
)。
用户负责确保数据一致性(停止 Pod 或应用程序,清除缓存,以及冻结文件系统等)。
如果出现错误,VolumeSnapshot 状态中会带有出错信息。
显示 VolumeSnapshot 状态:
$ oc get volumesnapshot -o yaml
此时会显示这个状态,如下例所示:
apiVersion: volumesnapshot.external-storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
clusterName: ""
creationTimestamp: 2017-09-19T13:58:28Z
generation: 0
labels:
Timestamp: "1505829508178510973"
name: snapshot-demo
namespace: default 1
resourceVersion: "780"
selfLink: /apis/volumesnapshot.external-storage.k8s.io/v1/namespaces/default/volumesnapshots/snapshot-demo
uid: 9cc5da57-9d42-11e7-9b25-90b11c132b3f
spec:
persistentVolumeClaimName: ebs-pvc
snapshotDataName: k8s-volume-snapshot-9cc8813e-9d42-11e7-8bed-90b11c132b3f
status:
conditions:
- lastTransitionTime: null
message: Snapshot created successfully
reason: ""
status: "True"
type: Ready
creationTimestamp: null
- 1
- 指定 snapshot-controller 所在的项目名称。
2.16.3.2. 恢复快照
PVC 用于恢复快照。但是,管理员必须先创建一个 StorageClass,以便从现有 VolumeSnapshot 恢复 PersistentVolume。
创建 StorageClass:
kind: StorageClass apiVersion: storage.k8s.io/v1 metadata: name: snapshot-promoter provisioner: volumesnapshot.external-storage.k8s.io/snapshot-promoter parameters: 1 encrypted: "true" type: gp2
- 1
- 如果您使用配置了
gp2 encryption
加密的 AWS EBS 存储,您必须设置encrypted
和type
参数。
创建 PVC:
apiVersion: v1 kind: PersistentVolumeClaim metadata: name: snapshot-pv-provisioning-demo annotations: snapshot.alpha.kubernetes.io/snapshot: snapshot-demo 1 spec: storageClassName: snapshot-promoter 2 accessModes: - ReadWriteOnce resources: requests: storage: 1Gi 3
创建一个新的 PersistentVolume 并绑定到 PersistentVolumeClaim。此过程可能需要几分钟,具体视 PV 类型而异。
2.16.3.3. 删除快照
删除 VolumeSnapshot:
$ oc delete volumesnapshot/<snapshot-name>
系统将自动删除绑定到 VolumeSnapshot 的 VolumeSnapshotData。