天天看點

ACK叢集中雲盤資料卷的備份恢複方案

在阿裡雲ACK叢集中部署有狀态服務通常使用雲盤資料卷做資料存儲,雲盤本身提供了資料的備份(快照)恢複機制,但是如何将底層能力和K8S服務內建并靈活的提供給應用使用,是雲原生存儲服務需要解決的問題。K8S使用如下兩個特性來實作備份恢複能力:

通過VolumeSnapshot對象實作雲盤的備份(快照功能);

通過PVC中的DataSource功能實作資料的恢複(快照恢複);

由于VolumeSnapshot在K8S 1.16版本處于Alpha狀态,是以ACK叢集目前沒有預設部署快照功能,需要手動安裝插件才能使用;

K8S快照說明:

在Kubernetes中為了實作快照相關功能,通過CRD定義了下面3個相關資源類型:

VolumeSnapshotContent:描述存儲後端的快照執行個體,由系統管理者建立維護,無NameSpace;類比于PV概念;

VolumeSnapshot:聲明一個快照執行個體,由使用者建立維護,屬于特定NameSpace;類比于PVC概念;

VolumeSnapshotClass:定義一個快照類,描述建立快照使用的參數、Controller;類比于StorageClass概念;

快照資源綁定規則:

在使用Snapshot對象時,和pv、pvc一樣,VolumeSnapshot與VolumeSnapshotContent需要首先進行綁定;

VolumeSnapshot如果沒有靜态VolumeSnapshotContent可以綁定,則會建立動态VolumeSnapshotContent;

VolumeSnapshotContent 與 VolumeSnapshot 綁定是一對一;

删除VolumeSnapshotContent 同時會把後端的快照也删除;

1.卷快照模闆

下面是一個VolumeSnapshotClass定義模闆:

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
  name: default-snapclass
driver: diskplugin.csi.alibabacloud.com
parameters:
  forceDelete: "false"
deletionPolicy: Delete           

其中:

driver:定義了使用這個快照類的VolumeSnapshot所使用的controller;

deletionPolicy: 表示删除volumeSnapshot的時候,volumeSnapshotContent是否删除;

forceDelete: 表示是否允許在雲盤引用快照的時候删除快照(預設是不允許删除的,因為以快照為資料源建立雲盤時,建立過程會有時延,強制删除可能會造成資料丢失);

下面是一個VolumeSnapshot定義模闆:

apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: new-snapshot-demo
spec:
  volumeSnapshotClassName: default-snapclass
  source:
    persistentVolumeClaimName: disk-ssd-web-0           

persistentVolumeClaimName:定義使用哪個pvc作為快照源;

volumeSnapshotClassName:定義了打快照使用的快照類;

2.通過快照恢複資料

通過雲盤快照建立雲盤是阿裡雲雲盤提供的基礎功能。在容器服務中通過在pvc定義DataSource指定使用哪個快照,動态建立雲盤的時候即可實作使用快照建立雲盤;

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: disk-snapshot
spec:
  accessModes:
    - ReadWriteOnce
  storageClassName: alicloud-disk-ssd
  dataSource:
    name: new-snapshot-demo
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  resources:
    requests:
      storage: 20Gi           

storageClassName:定建立pv的存儲類,指向的disk controller需要支援DataSource特性;

dataSource:指定snapshot資源,說明建立雲盤會使用這個快照資料;

插件部署:

叢集準備:

部署csi-snapshotter前,您需要建立一個ACK 1.16版本叢集,并在建立叢集的時候選擇使用CSI插件;

叢集建立

部署CRD & Snapshot:

下載下傳snapshotter crd模闆:

https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/deploy/disk/snapshot/crd.yaml

下載下傳csi-snapshotter模闆:

https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/deploy/disk/snapshot/csi-snapshotter.yaml

部署插件:

$ kubectl apply -f crd.yaml
$ kubectl apply -f csi-snapshotter.yaml
           

部署完成後叢集中csi插件如下:

# kubectl get crd
NAME                                             CREATED AT
volumesnapshotclasses.snapshot.storage.k8s.io    2020-06-17T09:36:32Z
volumesnapshotcontents.snapshot.storage.k8s.io   2020-06-17T09:36:32Z
volumesnapshots.snapshot.storage.k8s.io          2020-06-17T09:36:32Z

# kubectl get pod -nkube-system |grep csi-snap
csi-snapshotter-d78f57d4d-rmjhp                     3/3     Running   0          54m           

使用:

下圖是一個使用示例流程圖,分成1、2、3三個步驟:

ACK叢集中雲盤資料卷的備份恢複方案

步驟1:建立原始應用,建立雲盤卷儲存資料;

步驟2:建立VolumeSnapshot,這時會自動建立VolumeSnapshotContent和存儲端的快照執行個體;

步驟3:建立新的應用,并配置PVC引用步驟2中建立的快照對象;

通過上述三步實作了:

備份:Volume1中的資料備份到Snapshot1;

恢複:Snapshot1的資料(Volume1的資料)恢複成Volume2卷;

建立VolumeSnapshotClass快照類:

下載下傳VolumeSnapshotClass模闆:

https://github.com/kubernetes-sigs/alibaba-cloud-csi-driver/blob/master/examples/disk/snapshot/snapshotclass.yaml
$ kubectl apply -f calss.yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshotClass
metadata:
  name: default-snapclass
driver: diskplugin.csi.alibabacloud.com
deletionPolicy: Delete           
# kubectl get VolumeSnapshotClass
NAME                AGE
default-snapclass   4h40m           

步驟1:建立原始應用并寫入資料:

$ kubectl apply -f sts.yaml
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: web
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      containers:
      - name: nginx
        image: nginx
        volumeMounts:
        - name: disk-ssd
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: disk-ssd
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: "alicloud-disk-snap"
      resources:
        requests:
          storage: 20Gi           

往pod中寫入資料:

# kubectl exec -ti web-0 touch /data/test
# kubectl exec -ti web-0 ls /data
lost+found  test           

步驟2:建立VolumeSnapshot:

$ kubectl apply -f snapshot.yaml
apiVersion: snapshot.storage.k8s.io/v1beta1
kind: VolumeSnapshot
metadata:
  name: new-snapshot-demo
spec:
  volumeSnapshotClassName: default-snapclass
  source:
    persistentVolumeClaimName: disk-ssd-web-0           

檢查叢集狀态,VolumeSnapshot、VolumeSnapshotContent建立完成,同時到ECS控制台檢視快照執行個體也建立完成:

# kubectl get volumesnapshots.snapshot.storage.k8s.io
NAME                AGE
new-snapshot-demo   36m

# kubectl get VolumeSnapshotContent
NAME                                               AGE
snapcontent-222d4dbb-beb4-49e5-8e11-ca6358c62123   36m           

步驟3:資料恢複

$ kubectl apply -f sts-snapshot.yaml
apiVersion: v1
kind: Service
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  ports:
  - port: 80
    name: web
  clusterIP: None
  selector:
    app: nginx
---
apiVersion: apps/v1beta2
kind: StatefulSet
metadata:
  name: web-restore
spec:
  selector:
    matchLabels:
      app: nginx
  serviceName: "nginx"
  replicas: 1
  template:
    metadata:
      labels:
        app: nginx
    spec:
      hostNetwork: true
      containers:
      - name: nginx
        image: nginx
        command: ["sh", "-c"]
        args: ["sleep 10000"]
        volumeMounts:
        - name: disk-ssd
          mountPath: /data
  volumeClaimTemplates:
  - metadata:
      name: disk-ssd
    spec:
      accessModes: [ "ReadWriteOnce" ]
      storageClassName: alicloud-disk-ssd
      resources:
        requests:
          storage: 20Gi
      dataSource:
        name: new-snapshot-demo
        kind: VolumeSnapshot
        apiGroup: snapshot.storage.k8s.io           

在volumeClaimTemplates定義中指定dataSource為VolumeSnapshot類型,且選擇步驟2建立的名字為new-snapshot-demo的VolumeSnapshot。

檢視容器資料,驗證是否恢複成功:

# kubectl exec -ti web-restore-0 ls /data
lost+found  test           

可見實作了資料的恢複。

本方案隻給出了建立一個快照并進行恢複的場景,後續我們會提供建立定時快照的方案。

繼續閱讀