在单节点Kubernetes集群中,尝试操作PV和PVC

你好。
我是Class Act基础设施事业部的大塚。

上次,我学习了在Docker上创建卷以及将其挂载到容器的方法,并尝试了实际操作。下面是具体内容。

 

这次我想在Kubernetes上做类似于上面提到的事情。
我认为Kubernetes的优点在于可以在多节点上部署和管理Pod(容器),但是如果直接在多节点上操作可能会让人头脑混乱,所以我打算先在单节点的k8s集群上尝试一下,之后再逐步在多节点的k8s集群环境中进行操作。

环境

在Ubuntu 22.04上启动虚拟机。
正在安装microk8s并创建Kubernetes环境。

root@ansible-tower:~# kubectl get node -o wide
NAME            STATUS   ROLES    AGE   VERSION   INTERNAL-IP    EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
ansible-tower   Ready    <none>   23h   v1.26.4   192.168.2.35   <none>        Ubuntu 22.04.2 LTS   5.15.0-71-generic   containerd://1.6.15

用语 –

视频

持久卷(PV)是集群存储的一部分,由管理员或动态分配使用存储类来进行管理。它与节点一样是集群资源的一部分。PV是类似于卷的插件,但与使用PV的独立Pod具有不同的生命周期。

聚氯乙烯

持久卷索取(PVC)是由用户请求的存储资源。它类似于Pod。Pod消耗节点资源,而PVC消耗PV资源。Pod可以请求特定级别的CPU和内存资源。索取可以以特定的大小和访问模式(例如,ReadWriteOnce、ReadOnlyMany、ReadWriteMany)进行挂载。

 

我对此的理解是,在物理卷(PV)中创建一个大容量的存储空间,然后可以使用逻辑卷(PVC)来分割并利用它。我的理解如下:

名称未設定ファイル-ページ11 drawio

验证:尝试使用spec.persistentVolumeReclaimPolicy设置为”Delete”部署和使用PV和PVC。

首先,我们将准备PV。
这次准备的yaml文件如下所示。

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-vol
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce 
  persistentVolumeReclaimPolicy: Delete
  storageClassName: my-vol-class
  hostPath:
    path: /tmp/k8s-vol
    type: DirectoryOrCreate

我将简略地写下在yaml文件中所写的细节。

コンテンツ意味spec.accessModes:ReadWriteOnce1つのNodeからR/Wでマウントすることができる。このほかにReadOnlyManyやReadWriteManyがある
参考:Kubernetes: ReadWriteOnceとReadWriteOncePodの動作検証spec:persistentVolumeReclaimPolicy:DeletePVCが削除されるとPVも削除するような挙動にする。このほかにRetainなどもある。
参考:Kubernetes: ReadWriteOnceとReadWriteOncePodの動作検証spec.hostpath.path:/tmp/k8s-vol作成するPVをノードのどのディレクトリに作成するかを指定している。今回のyamlでは/tmp/k8s-vol配下に作ることになる。spec.hostpath.type:DirectoryOrCreatespec.hostpath.pathで指定したディレクトリが存在しない場合作成する
参考:KubernetesでHostPathを使う

我会部署它。
看起来已经完成了。

root@ansible-tower:~/yaml# kubectl create -f my-vol.yaml
persistentvolume/my-vol created

root@ansible-tower:~/yaml# kubectl get pv -o wide
NAME     CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS   REASON   AGE   VOLUMEMODE
my-vol   5Gi        RWO            Delete           Available           my-vol-class            6s    Filesystem

对于PV和后续提到的PVC,可以像pod一样进行描述。
以下是其结果。您可以在这里确认您在yaml中的写法。

root@ansible-tower:~/yaml# kubectl describe pv my-vol
Name:            my-vol
Labels:          <none>
Annotations:     <none>
Finalizers:      [kubernetes.io/pv-protection]
StorageClass:    my-vol-class
Status:          Available
Claim:
Reclaim Policy:  Delete
Access Modes:    RWO
VolumeMode:      Filesystem
Capacity:        5Gi
Node Affinity:   <none>
Message:
Source:
    Type:          HostPath (bare host directory volume)
    Path:          /tmp/k8s-vol
    HostPathType:  DirectoryOrCreate
Events:            <none>

在这个时间点,/tmp目录下没有被创建的节点。

root@ansible-tower:~/yaml# ls /tmp/
snap-private-tmp                                                                systemd-private-e9093ba59c54473c8be00fd9efae24cd-systemd-resolved.service-8TljcD   ubuntu-advantage
systemd-private-e9093ba59c54473c8be00fd9efae24cd-ModemManager.service-YQKnnw    systemd-private-e9093ba59c54473c8be00fd9efae24cd-systemd-timesyncd.service-NfUEnV
systemd-private-e9093ba59c54473c8be00fd9efae24cd-systemd-logind.service-VAqu3p  systemd-private-e9093ba59c54473c8be00fd9efae24cd-upower.service-oEMHBO

PVC将会被创建。
我们准备的yaml文件如下。

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc01-my-vol
spec:
  resources:
    requests:
      storage: 5Gi 
  accessModes:
  - ReadWriteOnce
  storageClassName: my-vol-class

根据yaml配置文件进行部署。
如果PVC的状态为Bound,则表示PV和PVC已经成功关联。

root@ansible-tower:~/yaml# kubectl create -f pvc01-my-vol.yaml
persistentvolumeclaim/pvc01-my-vol created

root@ansible-tower:~/yaml# kubectl get pv,pvc -o wide
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE   VOLUMEMODE
persistentvolume/my-vol   5Gi        RWO            Delete           Bound    default/pvc01-my-vol   my-vol-class            13s   Filesystem

NAME                                 STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE   VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol   Bound    my-vol   5Gi        RWO            my-vol-class   46s   Filesystem

我会查看PVC的描述以获得更多详细信息。

root@ansible-tower:~/yaml# kubectl describe pvc pvc01-my-vol
Name:          pvc01-my-vol
Namespace:     default
StorageClass:  my-vol-class
Status:        Bound
Volume:        my-vol
Labels:        <none>
Annotations:   pv.kubernetes.io/bind-completed: yes
               pv.kubernetes.io/bound-by-controller: yes
Finalizers:    [kubernetes.io/pvc-protection]
Capacity:      5Gi
Access Modes:  RWO
VolumeMode:    Filesystem
Used By:       <none>
名称未設定ファイル-ページ9 drawio

创建一个名为PostgreSQL的Pod,并将PVC挂载到/var/lib/postgresql/data目录下。
准备以下的YAML文件。

apiVersion: v1
kind: Pod
metadata:
  name: postgres01
spec:
  containers:
  - name: postgres01
    image: postgres:latest
    env:
    - name: POSTGRES_PASSWORD
      value: "postgres"
    volumeMounts:
    - mountPath: /var/lib/postgresql/data
      name: pvc01-my-vol
  volumes:
  - name: pvc01-my-vol
    persistentVolumeClaim:
      claimName: pvc01-my-vol

我要部署pod。

root@ansible-tower:~/yaml# kubectl create -f vol-postgresql01.yaml
pod/postgres01 created

root@ansible-tower:~/yaml# kubectl get pod -o wide
NAME         READY   STATUS    RESTARTS   AGE    IP           NODE            NOMINATED NODE   READINESS GATES
postgres01   1/1     Running   0          108s   10.1.108.9   ansible-tower   <none>           <none>

我会尝试查看Pod的详细信息,根据以下的输出,它似乎已经成功挂载了。

root@ansible-tower:~/yaml# kubectl describe pod postgres01
~中略~
Volumes:
  pvc01-my-vol:
    Type:       PersistentVolumeClaim (a reference to a PersistentVolumeClaim in the same namespace)
    ClaimName:  pvc01-my-vol
    ReadOnly:   false

在此时创建了/tmp/k8s-vol。
以下是实际确认的日志。自动创建了名为k8s-vol的目录,其下可以确认到PostgreSQL的数据存在于/tmp目录中。

root@ansible-tower:/# cd /tmp
root@ansible-tower:/tmp# ls
k8s-vol           systemd-private-7b30335e5c3847888ee14c9d4ae96fea-ModemManager.service-9JtOcV    systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-resolved.service-y1Y1GA
snap-private-tmp  systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-logind.service-f83oWV  systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-timesyncd.service-Mr4GTU
root@ansible-tower:/tmp/k8s-vol# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

我会在已部署的pod中进行确认。
/tmp/k8s-vol/的内容和之前一样。

root@ansible-tower:~# kubectl get pod
NAME         READY   STATUS    RESTARTS   AGE
postgres01   1/1     Running   0          7h13m
root@ansible-tower:~# kubectl exec -it postgres01 -- /bin/bash
root@postgres01:/# cd /var/lib/postgresql/data
root@postgres01:/var/lib/postgresql/data# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

我在pod侧创建数据,并确认节点侧是否能够看到。在pod中创建一个名为text.txt的空文件。

root@postgres01:/var/lib/postgresql/data# touch test.txt
root@postgres01:/var/lib/postgresql/data# ls -ltr test.txt
-rw-r--r-- 1 root root 0 May 10 21:15 test.txt

我会在节点端进行确认。看起来没什么问题。

root@ansible-tower:~# cd /tmp/k8s-vol/
root@ansible-tower:/tmp/k8s-vol# ls -ltr test.txt
-rw-r--r-- 1 root root 0 May 10 21:15 test.txt
名称未設定ファイル-ページ10 drawio (1)

首先,我们将删除装有PVC的Pod,以确认能否再利用。

root@ansible-tower:~# kubectl delete pod postgres01

root@ansible-tower:~# kubectl get pod,pv,pvc -o wide
NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE     VOLUMEMODE
persistentvolume/my-vol   5Gi        RWO            Delete           Bound    default/pvc01-my-vol   my-vol-class            7h31m   Filesystem

NAME                                 STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE     VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol   Bound    my-vol   5Gi        RWO            my-vol-class   7h31m   Filesystem

root@ansible-tower:~# ls /tmp/k8s-vol/
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts  test.txt
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

使用相同的 ymal 重新部署 pod。

root@ansible-tower:~/yaml# kubectl get pod,pv,pvc -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
pod/postgres01   1/1     Running   0          21s   10.1.108.10   ansible-tower   <none>           <none>

NAME                      CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                  STORAGECLASS   REASON   AGE     VOLUMEMODE
persistentvolume/my-vol   5Gi        RWO            Delete           Bound    default/pvc01-my-vol   my-vol-class            7h33m   Filesystem

NAME                                 STATUS   VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE     VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol   Bound    my-vol   5Gi        RWO            my-vol-class   7h33m   Filesystem

我会检查重新部署的pod中的/var/lib/postgresql/data文件夹,并确认是否存在text.txt。
从下面的日志中,我可以看出它是可以重新使用的。

root@ansible-tower:~/yaml# kubectl exec -it postgres01 -- /bin/bash
root@postgres01:/# cd /var/lib/postgresql/data/
root@postgres01:/var/lib/postgresql/data# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts  test.txt
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

删除pod和PVC。由于在创建PV时指定了Delete操作,所以应当同时删除PVC时也会删除PV。
从get命令没有任何输出来看,可以确认PVC和PV已经被同时删除。

root@ansible-tower:~# kubectl delete pod postgres0
persistentvolumeclaim "pvc01-my-vol" deleted

root@ansible-tower:~# kubectl get pod,pv,pvc
No resources found

/tmp文件夹下的内容也被删除了。

root@ansible-tower:~# cd /tmp
root@ansible-tower:/tmp# ls
snap-private-tmp                                                                systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-resolved.service-y1Y1GA
systemd-private-7b30335e5c3847888ee14c9d4ae96fea-fwupd.service-Srke4w           systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-timesyncd.service-Mr4GTU
systemd-private-7b30335e5c3847888ee14c9d4ae96fea-ModemManager.service-9JtOcV    systemd-private-7b30335e5c3847888ee14c9d4ae96fea-upower.service-LLEENP
systemd-private-7b30335e5c3847888ee14c9d4ae96fea-systemd-logind.service-f83oWV

验证:尝试使用”保留”作为spec.persistentVolumeReclaimPolicy在PV和PVC的部署以及使用。

以下是PV的yaml

apiVersion: v1
kind: PersistentVolume
metadata:
  name: my-vol-retain
spec:
  capacity:
    storage: 5Gi
  accessModes:
  - ReadWriteOnce
  persistentVolumeReclaimPolicy: Retain
  storageClassName: my-vol-retain-class
  hostPath:
    path: /tmp/my-vol-retain
    type: DirectoryOrCreate

进行部署

root@ansible-tower:~/yaml# kubectl create -f my-vol-retain.yaml
persistentvolume/my-vol-retain created

root@ansible-tower:~/yaml# kubectl get pv
NAME            CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS      CLAIM   STORAGECLASS          REASON   AGE
my-vol-retain   5Gi        RWO            Retain           Available           my-vol-retain-class            6s

PVC的yaml如下所示

apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: pvc01-my-vol-retain
spec:
  resources:
    requests:
      storage: 5Gi
  accessModes:
  - ReadWriteOnce
  storageClassName: my-vol-retain-class

部署

root@ansible-tower:~/yaml# kubectl create -f pvc01-my-vol-retain.yaml
persistentvolumeclaim/pvc01-my-vol-retain created

root@ansible-tower:~/yaml# kubectl get pv,pvc -o wide
NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS          REASON   AGE   VOLUMEMODE
persistentvolume/my-vol-retain   5Gi        RWO            Retain           Bound    default/pvc01-my-vol-retain   my-vol-retain-class            68s   Filesystem

NAME                                        STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS          AGE   VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol-retain   Bound    my-vol-retain   5Gi        RWO            my-vol-retain-class   10s   Filesystem

pod的yaml内容如下

apiVersion: v1
kind: Pod
metadata:
  name: postgres01
spec:
  containers:
  - name: postgres01
    image: postgres:latest
    env:
    - name: POSTGRES_PASSWORD
      value: "postgres"
    volumeMounts:
    - mountPath: /var/lib/postgresql/data
      name: pvc01-my-vol-retain
  volumes:
  - name: pvc01-my-vol-retain
    persistentVolumeClaim:
      claimName: pvc01-my-vol-retain

部署中

root@ansible-tower:~/yaml# kubectl create -f vol-retain-postgresql01.yaml
pod/postgres01 created

root@ansible-tower:~/yaml# kubectl get pod,pv,pvc -o wide
NAME             READY   STATUS    RESTARTS   AGE   IP            NODE            NOMINATED NODE   READINESS GATES
pod/postgres01   1/1     Running   0          24s   10.1.108.11   ansible-tower   <none>           <none>

NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS          REASON   AGE     VOLUMEMODE
persistentvolume/my-vol-retain   5Gi        RWO            Retain           Bound    default/pvc01-my-vol-retain   my-vol-retain-class            5m12s   Filesystem

NAME                                        STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS          AGE     VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol-retain   Bound    my-vol-retain   5Gi        RWO            my-vol-retain-class   4m14s   Filesystem

在pod中创建一个名为test.txt的文件,并将其放置在/var/lib/postgresql/data目录下。

root@ansible-tower:~/yaml# kubectl exec -it postgres01 -- /bin/bash
root@postgres01:/# cd /var/lib/postgresql/data/
root@postgres01:/var/lib/postgresql/data# touch test.txt
root@postgres01:/var/lib/postgresql/data# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts  test.txt
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

确认主机上的/tmp/my-vol-retain目录中存在数据。

root@ansible-tower:~# cd /tmp/my-vol-retain/
root@ansible-tower:/tmp/my-vol-retain# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts  test.txt
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

我们将确认即使删除了pod和PVC,它们也不会自动删除。

root@ansible-tower:~/yaml# kubectl get pod,pv,pvc -o wide
NAME             READY   STATUS    RESTARTS   AGE     IP            NODE            NOMINATED NODE   READINESS GATES
pod/postgres01   1/1     Running   0          3m22s   10.1.108.11   ansible-tower   <none>           <none>

NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS   CLAIM                         STORAGECLASS          REASON   AGE     VOLUMEMODE
persistentvolume/my-vol-retain   5Gi        RWO            Retain           Bound    default/pvc01-my-vol-retain   my-vol-retain-class            8m10s   Filesystem

NAME                                        STATUS   VOLUME          CAPACITY   ACCESS MODES   STORAGECLASS          AGE     VOLUMEMODE
persistentvolumeclaim/pvc01-my-vol-retain   Bound    my-vol-retain   5Gi        RWO            my-vol-retain-class   7m12s   Filesystem

root@ansible-tower:~/yaml# kubectl delete pod postgres01
pod "postgres01" deleted
root@ansible-tower:~/yaml# kubectl delete pvc pvc01-my-vol-retain

可以确认还有剩余光伏电量,并且从主机上也确认还留有数据。

root@ansible-tower:~/yaml# kubectl get pod,pv,pvc -o wide
NAME                             CAPACITY   ACCESS MODES   RECLAIM POLICY   STATUS     CLAIM                         STORAGECLASS          REASON   AGE   VOLUMEMODE
persistentvolume/my-vol-retain   5Gi        RWO            Retain           Released   default/pvc01-my-vol-retain   my-vol-retain-class            25m   Filesystem

root@ansible-tower:~/yaml# cd /tmp/my-vol-retain/
root@ansible-tower:/tmp/my-vol-retain# ls
base    pg_commit_ts  pg_hba.conf    pg_logical    pg_notify    pg_serial     pg_stat      pg_subtrans  pg_twophase  pg_wal   postgresql.auto.conf  postmaster.opts  test.txt
global  pg_dynshmem   pg_ident.conf  pg_multixact  pg_replslot  pg_snapshots  pg_stat_tmp  pg_tblspc    PG_VERSION   pg_xact  postgresql.conf       postmaster.pid

要再利用这个可能需要花一点功夫呢。

1. 删除 PersistentVolume。删除 PV 后,与外部基础设施(如 AWS EBS、GCE PD、Azure Disk、Cinder 等)关联的存储组件仍然存在。
2. 手动清理与存储组件相关的数据。
3. 如果要手动删除相关存储组件或者希望重新使用相同的存储组件,则需创建新的 PersistentVolume 定义与其一起使用。

 

广告
将在 10 秒后关闭
bannerAds