当前位置: 首页 > 知识库问答 >
问题:

kubernetes - rancher-desktop with k3s 如何做基于hostpath的本地持久化?

上官培
2024-04-15

rancher-desktop with k3s 如何做基于hostpath的本地持久化?

我希望用rancher-desktop,搭配k3s,在我的mac上部署一个postgres,并且创建数据库所需的文件我希望持久化到一个我指定的路径/Users/<username>/Workspaces/postgres/pg_data
但持久化到我的Mac上这个需求始终不能解决,每次rancher-desktop都是自己创建了一个映射到lima虚拟机内的/var/lib/rancher/k3s/storage/pv,但是我如果把rancher-desktop with k3s换成Docker-desktop with k8s,就没有问题,可以顺利完成,yaml文件是一样的:

# 安装postgres# 定义一个命名空间apiVersion: v1kind: Namespacemetadata:  name: postgresd---# 定义配置apiVersion: v1kind: ConfigMapmetadata:  name: postgres-config  namespace: postgresddata:  POSTGRES_DB: postgres  MAX_CONNECTIONS: "10000"  LOG_MIN_DURATION_STATEMENT: "500ms"---# 定义存储卷apiVersion: v1kind: PersistentVolumemetadata:  name: postgres-data-pvspec:  capacity:    storage: 10Gi  # 根据实际需求设置存储容量  accessModes:    - ReadWriteOnce  persistentVolumeReclaimPolicy: Delete#  storageClassName: local-path  hostPath:    path: "/Users/hulei/Workspaces/postgres/pg_data"#  nodeAffinity:#    required:#      nodeSelectorTerms:#        - matchExpressions:#          - key: kubernetes.io/hostname#            operator: In#            values:#              - lima-rancher-desktop---# 定义用户名、密码等敏感信息apiVersion: v1kind: Secretmetadata:  name: postgres-secret  namespace: postgresdtype: Opaquedata:  postgres-user: cG9zdGdyZXM= # Base64编码的用户名,这里是"postgres"  postgres-password: U2VjdXJlUGFzc3dvcmQ= # Base64编码的密码,这里是"SecurePassword"---apiVersion: apps/v1kind: StatefulSetmetadata:  name: postgres-statefulset  namespace: postgresdspec:  replicas: 1  selector:    matchLabels:      app: postgres  serviceName: postgres-serive  template:    metadata:      labels:        app: postgres    spec:      containers:        - name: postgresd          image: postgres:16.2-alpine3.19          ports:            - containerPort: 5432              name: postgresd-port          env:            - name: POSTGRES_USER              valueFrom:                secretKeyRef:                  name: postgres-secret                  key: postgres-user            - name: POSTGRES_PASSWORD              valueFrom:                secretKeyRef:                  name: postgres-secret                  key: postgres-password            - name: POSTGRES_DB              valueFrom:                configMapKeyRef:                  name: postgres-config                  key: POSTGRES_DB          volumeMounts:            - name: postgres-data              mountPath: /var/lib/postgresql/data              subPath: data  volumeClaimTemplates:    - metadata:        name: postgres-data      spec:        accessModes: [ "ReadWriteOnce" ]        resources:          requests:            storage: 5Gi#        storageClassName: local-path---# 定义将5432端口映射到kind cluster  5432端口的serviceapiVersion: v1kind: Servicemetadata:  namespace: postgresd  name: postgres-servicespec:  selector:    app: postgres  ports:  - port: 5432    targetPort: 5432  type: ClusterIP

我想知道如何在rancher-desktop中实现基于hostpath的本地持久化?

在我的mac上运行上述yaml文件后,kubectl get pv 总是得到如下结果:
image.png

k3s会自己创建一个pv,不会用我创建的pv,这是为什么?

共有3个答案

乜心思
2024-04-15

image.png
你本地应该已经配置了一个叫local-path的默认storageClass,可以通过命令kubectl get storageclass 确认,因为这个storageClass的存在,所以会自动创建pvc;

你要pvc和pv绑定那你应该使用volumeName: xxx 指定pvc和pv关联,类似你下面这个配置。

  volumeClaimTemplates:    - metadata:        name: postgres-data      spec:        accessModes: [ "ReadWriteOnce" ]        resources:          requests:            storage: 5Gi        volumeName: postgres-data-pv
凌联
2024-04-15

本地测试了一下,使用MacOS上的OrbStack模拟的k8s环境,实现应该和rancher-desktop差不多。

具体测试了一下,主要修改

  1. 这里取消注释了 storageClassName ,指定了之后,后面的pve才能工作

    apiVersion: v1kind: PersistentVolumemetadata:  name: postgres-data-pvspec:  capacity: storage: 10Gi  # 根据实际需求设置存储容量  accessModes: - ReadWriteOnce  persistentVolumeReclaimPolicy: Delete  storageClassName: local-path  hostPath: path: "/Users/hy/Projects/kubernetes/sf/data"
  2. 这里指定一下 volumeName

    apiVersion: apps/v1kind: StatefulSetmetadata:  name: postgres-statefulset  namespace: postgresdspec:  replicas: 1  selector: matchLabels:   app: postgres  serviceName: postgres-serive  template:    ...  volumeClaimTemplates: - metadata:     name: postgres-data   spec:     accessModes: [ "ReadWriteOnce" ]     resources:       requests:         storage: 5Gi     volumeName: postgres-data-pv

持久化正常:
image.png


补充一下可能的原因,我猜测原因可能是两个k8s环境的storageClass实现不一样,看了一下用了local-path的storageClass默认就是会自动创建出pv。

这里OrbStack默认使用的也是rancher.io/local-path,所以直接就能复现一样的问题。


OrbStack默认使用的是 local-path ,完整的yaml:

# 定义一个命名空间apiVersion: v1kind: Namespacemetadata:  name: postgresd---# 定义配置apiVersion: v1kind: ConfigMapmetadata:  name: postgres-config  namespace: postgresddata:  POSTGRES_DB: postgres  MAX_CONNECTIONS: "10000"  LOG_MIN_DURATION_STATEMENT: "500ms"---# 定义存储卷apiVersion: v1kind: PersistentVolumemetadata:  name: postgres-data-pvspec:  capacity:    storage: 10Gi  # 根据实际需求设置存储容量  accessModes:    - ReadWriteOnce  persistentVolumeReclaimPolicy: Delete  storageClassName: local-path  hostPath:    path: "/Users/hy/Projects/kubernetes/sf/data"---# 定义用户名、密码等敏感信息apiVersion: v1kind: Secretmetadata:  name: postgres-secret  namespace: postgresdtype: Opaquedata:  postgres-user: cG9zdGdyZXM= # Base64编码的用户名,这里是"postgres"  postgres-password: U2VjdXJlUGFzc3dvcmQ= # Base64编码的密码,这里是"SecurePassword"---apiVersion: apps/v1kind: StatefulSetmetadata:  name: postgres-statefulset  namespace: postgresdspec:  replicas: 1  selector:    matchLabels:      app: postgres  serviceName: postgres-serive  template:    metadata:      labels:        app: postgres    spec:      containers:        - name: postgresd          image: postgres:16.2-alpine3.19          ports:            - containerPort: 5432              name: postgresd-port          env:            - name: POSTGRES_USER              valueFrom:                secretKeyRef:                  name: postgres-secret                  key: postgres-user            - name: POSTGRES_PASSWORD              valueFrom:                secretKeyRef:                  name: postgres-secret                  key: postgres-password            - name: POSTGRES_DB              valueFrom:                configMapKeyRef:                  name: postgres-config                  key: POSTGRES_DB          volumeMounts:            - name: postgres-data              mountPath: /var/lib/postgresql/data              subPath: data  volumeClaimTemplates:    - metadata:        name: postgres-data      spec:        accessModes: [ "ReadWriteOnce" ]        resources:          requests:            storage: 5Gi        volumeName: postgres-data-pv  #        storageClassName: local-path---# 定义将5432端口映射到kind cluster  5432端口的serviceapiVersion: v1kind: Servicemetadata:  namespace: postgresd  name: postgres-servicespec:  selector:    app: postgres  ports:  - port: 5432    targetPort: 5432  type: ClusterIP
公冶浩慨
2024-04-15

在 Rancher Desktop 中使用 k3s 实现基于 hostPath 的本地持久化时,你需要确保几个关键步骤被正确执行。下面是一些可能的解决步骤和注意事项:

  1. 确认路径可访问性

    • 确保你指定的路径 /Users/<username>/Workspaces/postgres/pg_data 在你的 Mac 上是存在的,并且 Rancher Desktop 有权访问这个路径。
    • 如果路径不存在,你需要先创建它。如果权限不足,你可能需要调整文件或文件夹的权限。
  2. 检查 hostPath 配置

    • 确保你的 PersistentVolume 配置中的 hostPath 字段正确指向了你希望使用的本地路径。
    • 在 hostPath 中使用绝对路径,并确保路径的格式正确。
  3. 节点亲和性(Node Affinity)

    • 在你的 PersistentVolume 配置中,你可以尝试添加节点亲和性(Node Affinity)来确保你的 PV 只被绑定到正确的节点上。由于 Rancher Desktop 使用 Lima 虚拟机作为节点,你需要确保 PV 被绑定到这个节点。
    • 示例中的 nodeAffinity 部分是被注释掉的,你可以尝试取消注释并调整以匹配你的环境。
  4. StatefulSet 配置

    • 确保你的 StatefulSet 配置中的 volumeMounts 和 volumeClaimTemplates 部分正确引用了你的 PV 和 PVC。
    • 检查 StatefulSet 是否能够正确创建并挂载 PV。
  5. 检查 PV 和 PVC 状态

    • 运行 kubectl get pvkubectl get pvc 来检查 PersistentVolume 和 PersistentVolumeClaim 的状态。确保 PVC 已经成功绑定到了你创建的 PV。
  6. 查看事件和日志

    • 使用 kubectl describe pv <your-pv-name>kubectl describe pvc <your-pvc-name> 来查看 PV 和 PVC 的详细信息和事件。这可能会提供为什么 PV 没有被正确使用的线索。
  7. Rancher Desktop 设置

    • 检查 Rancher Desktop 的设置,确保没有与存储或路径映射相关的特殊配置干扰你的 hostPath 设置。
  8. 更新 YAML 配置

    • 如果以上步骤都无法解决问题,尝试简化你的 YAML 配置,只保留必要的部分,并逐步添加其他配置以确定问题所在。

如果以上步骤都不能解决问题,可能需要更深入地检查 Rancher Desktop 和 k3s 的文档,或者考虑在 Rancher Desktop 的社区论坛或 k3s 的 GitHub 仓库中寻求帮助。有时候,特定的环境配置或软件版本可能会导致预期之外的行为,因此查看官方文档和社区支持可能是解决问题的关键。

 类似资料:
  • 本地持久化卷允许用户通过标准 PVC 接口以简单便携的方式访问本地存储。PV 中包含系统用于将 Pod 安排到正确节点的节点亲和性信息。 一旦配置了本地卷,外部静态配置器(provisioner)可用于帮助简化本地存储管理。请注意,本地存储配置器与大多数配置器不同,并且尚不支持动态配置。相反,它要求管理员预先配置每个节点上的本地卷,并且这些卷应该是: Filesystem volumeMode(默

  • RKE是一款经过CNCF认证的开源Kubernetes发行版,可以在Docker容器内运行。它通过删除大部分主机依赖项,并为部署、升级和回滚提供一个稳定的路径,从而解决了Kubernetes最常见的安装复杂性问题。除此之外,RKE支持多种平台运行,比如MacOS、linux、windows。 Kubernetes自动化运维 借助RKE,Kubernetes可以完全独立于您正在运行的操作系统和平台,

  • 我正在尝试使用静态配置在本地kubernetes中挂载postgrsql毅力卷。这是我创建的pv、pvc和pod的yaml文件 我的卷位于 /var/lib/pgsql/9.3/data,但我的pod失败了,我不想将Mount tPath的位置更改为 /var/lib/pgsql/9.3/data/backup 你能建议yaml文件中的任何覆盖选项吗 我不想在这里创建新名称的文件夹。 如果我改变了

  • 我有一个Kubernetes pod(让我们称之为POD-A),我希望它使用某个配置文件来使用k8s API执行一些操作。配置文件将是一个YAML或JSON,由POD中的应用程序解析。 配置文件由云上的应用服务器托管,它的最新版本可以根据触发器提取。配置文件包含k8s集群中所有部署的配置细节,并将用于使用POD-A中的k8s API更新部署。 现在我想的是将这个配置文件保存在配置映射中,每次拉出一

  • 我找到的最接近的答案是这样的。 但我想知道的是,Dockerfile卷命令会被Kubernetes完全忽略吗?或者数据将被持久化到两个地方?一个用于docker卷(在主机中哪个豆荚运行),另一个是Kubernetes的PV? 之所以这样问,是因为我从docker hub部署了一些容器,其中包含VOLUME命令。同时,我也把PVC贴在我的豆荚上。我在考虑是否会在节点中创建本地卷(docker卷,而不