当前位置:   article > 正文

【K8S系列】深入解析K8S中PV 和PVC

pv 和pvc

在 Kubernetes 中,PV(持久卷)和 PVC(持久卷声明)之间的关系是一种动态匹配和绑定关系,用于实现 Pod 与存储资源的解耦。

一、概念介绍

1.1 PV(持久卷)

  • PV 是集群中的一块网络存储,它独立于 Pod 存在。PV 可以是各种存储系统,如云提供商的存储、NFS、iSCSI、本地存储等。
  • 管理员负责创建 PV,并配置其细节,如容量、访问模式(ReadWriteOnce、ReadOnlyMany、ReadWriteMany)、存储类别等。
  • PV 有自己的生命周期,它的状态包括可用(Available)、绑定(Bound)、释放(Released)、回收(Retained)等状态。

1.2 PVC(持久卷声明)

  • PVC 是对 PV 的请求,它定义了 Pod 对存储的需求。在创建 Pod 时,可以通过 PVC 来请求存储资源。
  • PVC 可以指定所需的存储容量、访问模式等参数,但通常不需要指定具体的 PV,而是通过标签选择器来动态匹配 PV。
  • PVC 的存在使得 Pod 与具体的存储实现解耦,提高了可移植性。

1.3 关系

  • PVC 与 PV 之间是一种声明与提供的关系。PVC 声明了对存储资源的需求,而 PV 则是提供这些资源的实际载体。
  • 当 PVC 被创建时,Kubernetes 会尝试将其与满足其要求的 PV 进行绑定。匹配的过程是根据 PVC 的标签选择器和 PV 的标签进行匹配,只有匹配成功的 PV 才能被绑定到 PVC。
  • 一旦绑定成功,Pod 可以通过 PVC 访问 PV 提供的存储资源。
  • 如果没有合适的 PV 可以绑定,PVC 将处于 Pending 状态,直到有合适的 PV 可用为止。

总之,PV 和 PVC 之间的关系是一种动态的匹配和绑定关系,它们使得 Pod 与存储资源的具体实现解耦,提高了灵活性和可移植性。

二、示例介绍

下面通过一个简单的示例来说明 PV 和 PVC 的关系。

假设我们有一个 Kubernetes 集群,并且我们想要创建一个 Pod,这个 Pod 需要使用一个持久卷来存储数据。我们将按照以下步骤进行操作:

2.1 创建 PV(持久卷)

首先,我们需要创建一个 PV,它可以是任何一种存储系统,比如 NFS。

  1. apiVersion: v1
  2. kind: PersistentVolume
  3. metadata:
  4. name: example-pv
  5. spec:
  6. capacity:
  7. storage: 1Gi
  8. volumeMode: Filesystem
  9. accessModes:
  10. - ReadWriteOnce
  11. persistentVolumeReclaimPolicy: Retain
  12. nfs:
  13. path: /path/to/nfs/volume
  14. server: nfs-server-ip

2.2 创建 PVC(持久卷声明)

接下来,我们创建一个 PVC,用于声明对 PV 的需求。

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4. name: example-pvc
  5. spec:
  6. accessModes:
  7. - ReadWriteOnce
  8. resources:
  9. requests:
  10. storage: 1Gi

2.3 Pod 使用 PVC

最后,我们创建一个 Pod,并将 PVC 与 Pod 关联起来,以便 Pod 可以访问 PV 提供的存储资源。

  1. apiVersion: v1
  2. kind: Pod
  3. metadata:
  4. name: example-pod
  5. spec:
  6. containers:
  7. - name: example-container
  8. image: nginx
  9. volumeMounts:
  10. - name: data
  11. mountPath: /data
  12. volumes:
  13. - name: data
  14. persistentVolumeClaim:
  15. claimName: example-pvc

2.4 总结

在这个示例中,创建了一个 PV,它代表了一个 NFS 挂载点,然后创建了一个 PVC,声明了对 1GB 存储的需求。

最后,创建了一个 Pod,并将 PVC 与 Pod 关联起来,Pod 可以通过 PVC 访问 PV 提供的存储资源。

这样,PV 和 PVC 就建立了关系,Pod 可以使用 PVC 来访问持久卷提供的存储空间。

三、项目示例

假设我们有一个需求:我们想在 Kubernetes 中运行一个 WordPress 应用程序,并且希望 WordPress 的数据持久化存储在一个持久卷中。

3.1 创建 PV(持久卷)

首先,我们创建一个 PV,用于存储 WordPress 的数据。

  1. apiVersion: v1
  2. kind: PersistentVolume
  3. metadata:
  4. name: wordpress-pv
  5. spec:
  6. capacity:
  7. storage: 5Gi
  8. volumeMode: Filesystem
  9. accessModes:
  10. - ReadWriteOnce
  11. hostPath:
  12. path: /mnt/data

在这个示例中,我们使用了 hostPath 来定义一个本地存储的 PV。

3.2 创建 PVC(持久卷声明)

然后,我们创建一个 PVC,用于声明对 PV 的需求。

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4. name: wordpress-pvc
  5. spec:
  6. accessModes:
  7. - ReadWriteOnce
  8. resources:
  9. requests:
  10. storage: 5Gi

3.3 部署 WordPress Pod

最后,我们创建一个 WordPress 的 Deployment,并将 PVC 与 Deployment 关联起来。

  1. apiVersion: apps/v1
  2. kind: Deployment
  3. metadata:
  4. name: wordpress
  5. spec:
  6. replicas: 1
  7. selector:
  8. matchLabels:
  9. app: wordpress
  10. template:
  11. metadata:
  12. labels:
  13. app: wordpress
  14. spec:
  15. containers:
  16. - name: wordpress
  17. image: wordpress:latest
  18. ports:
  19. - containerPort: 80
  20. volumeMounts:
  21. - name: wordpress-persistent-storage
  22. mountPath: /var/www/html
  23. volumes:
  24. - name: wordpress-persistent-storage
  25. persistentVolumeClaim:
  26. claimName: wordpress-pvc

在这个示例中,创建了一个 Deployment 来运行 WordPress,将 PVC 与 Deployment 关联起来,并将 PVC 中的持久卷挂载到 WordPress 容器的 /var/www/html 目录下。

通过这个示例,我们可以看到 PV 和 PVC 的关系:PVC 声明了对持久卷的需求,而 PV 则提供了实际的存储资源。Pod 使用 PVC 来访问 PV 提供的存储资源,从而实现了数据持久化。

四、拓展

部署 WordPress 在 Kubernetes 上完整的步骤:

4.1 创建 MySQL 数据库

首先,我们需要创建一个 MySQL 数据库,WordPress 需要一个数据库来存储数据。

  1. apiVersion: v1
  2. kind: Secret
  3. metadata:
  4. name: mysql-secret
  5. type: Opaque
  6. data:
  7. mysql-root-password: base64_encoded_password
  8. mysql-password: base64_encoded_password
  9. ---
  10. apiVersion: v1
  11. kind: PersistentVolumeClaim
  12. metadata:
  13. name: mysql-pv-claim
  14. spec:
  15. accessModes:
  16. - ReadWriteOnce
  17. resources:
  18. requests:
  19. storage: 1Gi
  20. ---
  21. apiVersion: apps/v1
  22. kind: Deployment
  23. metadata:
  24. name: mysql
  25. spec:
  26. replicas: 1
  27. selector:
  28. matchLabels:
  29. app: mysql
  30. template:
  31. metadata:
  32. labels:
  33. app: mysql
  34. spec:
  35. containers:
  36. - name: mysql
  37. image: mysql:5.7
  38. env:
  39. - name: MYSQL_ROOT_PASSWORD
  40. valueFrom:
  41. secretKeyRef:
  42. name: mysql-secret
  43. key: mysql-root-password
  44. - name: MYSQL_PASSWORD
  45. valueFrom:
  46. secretKeyRef:
  47. name: mysql-secret
  48. key: mysql-password
  49. ports:
  50. - containerPort: 3306
  51. volumeMounts:
  52. - name: mysql-persistent-storage
  53. mountPath: /var/lib/mysql
  54. volumes:
  55. - name: mysql-persistent-storage
  56. persistentVolumeClaim:
  57. claimName: mysql-pv-claim

4.2 创建 WordPress

接下来,我们需要创建 WordPress 应用程序,并连接到 MySQL 数据库。

  1. apiVersion: v1
  2. kind: PersistentVolumeClaim
  3. metadata:
  4. name: wordpress-pv-claim
  5. spec:
  6. accessModes:
  7. - ReadWriteOnce
  8. resources:
  9. requests:
  10. storage: 1Gi
  11. ---
  12. apiVersion: apps/v1
  13. kind: Deployment
  14. metadata:
  15. name: wordpress
  16. spec:
  17. replicas: 1
  18. selector:
  19. matchLabels:
  20. app: wordpress
  21. template:
  22. metadata:
  23. labels:
  24. app: wordpress
  25. spec:
  26. containers:
  27. - name: wordpress
  28. image: wordpress:latest
  29. env:
  30. - name: WORDPRESS_DB_HOST
  31. value: "mysql:3306"
  32. - name: WORDPRESS_DB_NAME
  33. value: "wordpress"
  34. - name: WORDPRESS_DB_USER
  35. value: "root"
  36. - name: WORDPRESS_DB_PASSWORD
  37. valueFrom:
  38. secretKeyRef:
  39. name: mysql-secret
  40. key: mysql-password
  41. ports:
  42. - containerPort: 80
  43. volumeMounts:
  44. - name: wordpress-persistent-storage
  45. mountPath: /var/www/html
  46. volumes:
  47. - name: wordpress-persistent-storage
  48. persistentVolumeClaim:
  49. claimName: wordpress-pv-claim

4.3 创建 Service

最后,我们需要创建 Service 来公开 WordPress 应用程序。

  1. apiVersion: v1
  2. kind: Service
  3. metadata:
  4. name: wordpress
  5. spec:
  6. selector:
  7. app: wordpress
  8. ports:
  9. - protocol: TCP
  10. port: 80
  11. targetPort: 80
  12. type: LoadBalancer

以上步骤创建了一个 WordPress 应用程序,并将其连接到一个 MySQL 数据库。

WordPress 的数据和 MySQL 的数据都被持久化存储。

最后,通过 Service,WordPress 应用程序可以通过外部 IP 地址访问。

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/606093
推荐阅读
相关标签
  

闽ICP备14008679号