前言

今天发现小伙伴把mysql的pod部署到了default命名空间下,而且已经用了好久,而恰巧我们清理k8s空间,就把他pod删了,小伙伴很恼火,哈哈哈哈~

default命名空间禁止部署业务pod,幸好pvc还在,那如何把default命名空间下的的pvc复制到别的namespace下呢,其中有一个比较简单的办法。

复制过程

使用该方法复制PVC的前提条件

1、集群中的CSI支持卷快照功能,我这里用rook-ceph block存储,且你的k8s集群有volumesnapshotclasses,可通过以下命令查询:

kubectl get volumesnapshotclasses.snapshot.storage.k8s.io

2.此外集群中部署了csi-snapshotter

满足以上两点即代表你可以利用我的方法跨namespace复制pvc。(另外我的k8s版本为:1.20.12)

复制过程用一张图表示:

下面详细解释下复制过程:

(1)通过源PVC创建一个VolumeSnapshot对象。

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: j-mysql-test
spec:
  volumeSnapshotClassName: rook-ceph-block
  source:
    persistentVolumeClaimName: wy-mysql-pvc # 源pvc名称

(2)第一步创建完后,会自动生成VolumeSnapshotContent对象

kubectl get volumesnapshotcontents.snapshot.storage.k8s.io | grep j-mysql-test

#返回结果
snapcontent-281e6771-f5dd-495d-be46-3b46144c24b0   true         21474836480    Delete           rook-ceph.rbd.csi.ceph.com   rook-ceph-block       j-mysql-test                                   28h

(3)手动创建一个新的VolumeSnapshotContent指向第二步创建的VolumeSnapshotContent中的

先查询(2)步自动创建出来的Snapshot Handle:

kubectl describe volumesnapshotcontents.snapshot.storage.k8s.io snapcontent-281e6771-f5dd-495d-be46-3b46144c24b0 | grep "Snapshot Handle:"

#返回结果
 Snapshot Handle:  0001-0009-rook-ceph-0000000000000004-04e34373-99fe-11ec-a1cc-62a9b1ac58bf

根据旧的VolumeSnapshotContent中的Snapshot Handle创建一个新的VolumeSnapshotContent:

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshotContent
metadata:
  name: j-mysql-test-vsc
spec:
  deletionPolicy: Delete
  driver: rook-ceph.rbd.csi.ceph.com
  source:
    snapshotHandle: 0001-0009-rook-ceph-0000000000000004-04e34373-99fe-11ec-a1cc-62a9b1ac58bf
  volumeSnapshotRef:
    name: j-mysql-test
    namespace: whh

其中定义了一个新的VolumeSnapshot,也就是volumeSnapshotRef的内容,此时它还不存在。

查询执行状态:

kubectl get volumesnapshotcontents.snapshot.storage.k8s.io | grep j-mysql
#返回
j-mysql-test-vsc                                   true         0              Delete           rook-ceph.rbd.csi.ceph.com                         j-mysql-test                                   5d17h
snapcontent-281e6771-f5dd-495d-be46-3b46144c24b0   true         21474836480    Delete           rook-ceph.rbd.csi.ceph.com   rook-ceph-block       j-mysql-test                                   5d17h

可以看到有两个VolumeSnapshotContent,第一个是手动新建的,第二个是源PVC自动创建的VolumeSnapshotContent。

(4)创建一个新的VolumeSnapshot

apiVersion: snapshot.storage.k8s.io/v1
kind: VolumeSnapshot
metadata:
  name: j-mysql-test
  namespace: whh
spec:
  source:
    volumeSnapshotContentName: j-mysql-test-vsc

上面的namespace和name的值指向的就是第(3)步骤中定义的新的VolumeSnapshot

查询执行状态:

kubectl get volumesnapshot -n whh | grep j-mysql
#返回结果
j-mysql-test            true                     j-mysql-test-vsc               0                             j-mysql-test-vsc               5d17h          5d17h

注意第二个值一定要为“true”才能接着往下执行。

(6)根据新的volumesnapshot创建一个新的pvc

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: rbd-pvc-restore-test
  namespace: whh
spec:
  storageClassName: rook-ceph-block
  dataSource:
    name: j-mysql-test
    kind: VolumeSnapshot
    apiGroup: snapshot.storage.k8s.io
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 20Gi

查看执行结果:

kubectl get pvc -n whh | grep rbd-pvc
#返回
rbd-pvc-restore-test   Bound    pvc-90449d6e-87f3-4c5e-9fcd-ff2dc7936bd6   20Gi       RWO            rook-ceph-block   4d14h

如果显示PVC为 Bound 状态,代表pvc跨namespace复制成功。

(7)用新建的pvc绑定新的实例,我这里是mysql

查看绑定状态:

 kubectl get po -n whh
NAME                               READY   STATUS              RESTARTS   AGE
jumpserver-mysql-0                 0/1     ContainerCreating   0          4s

因为状态是“ContainerCreating”,我们describe一下看看有啥问题(由于我的pv已经复制成功,无法再次模拟ContainerCreating状态问题),假如里面有个告警可以先不用管,PV越大复制的时间越长,可耐心等一下

总结

这里跨namespace复制pvc用到的知识点: volumesnapshot、volumesnapshotcontent。小伙伴可到官网学习:

Volume Snapshots | Kubernetes

Logo

K8S/Kubernetes社区为您提供最前沿的新闻资讯和知识内容

更多推荐