无法在本地种类集群中挂载本地主机路径

Cant mount local host path in local kind cluster

下面是我的kubernetes文件,我需要做两件事

  1. 需要挂载一个包含文件的文件夹
  2. 需要用启动脚本挂载文件

我的本地 /tmp/zoo 文件夹中的文件和我的 zoo 文件夹文件从未出现在 pod 内的 /bitnami/zookeeper 中。

下面是更新后的Service、Deployment、PVC和PV

kubernetes.yaml

apiVersion: v1
items:
- apiVersion: v1
  kind: Service
  metadata:
    annotations:
      kompose.service.type: nodeport
    creationTimestamp: null
    labels:
      io.kompose.service: zookeeper
    name: zookeeper
  spec:
    ports:
    - name: "2181"
      port: 2181
      targetPort: 2181
    selector:
      io.kompose.service: zookeeper
    type: NodePort
  status:
    loadBalancer: {}
- apiVersion: apps/v1
  kind: Deployment
  metadata:
    annotations:
      kompose.service.type: nodeport
    creationTimestamp: null
    name: zookeeper
  spec:
    replicas: 1
    selector:
      matchLabels:
        io.kompose.service: zookeeper
    strategy:
      type: Recreate
    template:
      metadata:
        creationTimestamp: null
        labels:
          io.kompose.service: zookeeper
      spec:
        containers:
        - image: bitnami/zookeeper:3
          name: zookeeper
          ports:
          - containerPort: 2181
          env:
          - name: ALLOW_ANONYMOUS_LOGIN
            value: "yes"
          resources: {}
          volumeMounts:
          - mountPath: /bitnami/zoo
            name: bitnamidockerzookeeper-zookeeper-data
        restartPolicy: Always
        volumes:
        - name: bitnamidockerzookeeper-zookeeper-data
          #hostPath:
            #path: /tmp/tmp1
          persistentVolumeClaim:
            claimName: bitnamidockerzookeeper-zookeeper-data
  status: {}

- apiVersion: v1
  kind: PersistentVolumeClaim
  metadata:
    creationTimestamp: null
    labels:
      io.kompose.service: bitnamidockerzookeeper-zookeeper-data
      type: local
    name: bitnamidockerzookeeper-zookeeper-data
  spec:
    accessModes:
    - ReadWriteOnce
    resources:
      requests:
        storage: 100Mi
  status: {}
- apiVersion: v1
  kind: PersistentVolume
  metadata:
    name: foo
  spec:
    storageClassName: manual
    claimRef:
      name: bitnamidockerzookeeper-zookeeper-data
    capacity:
      storage: 100Mi
    accessModes:
      - ReadWriteMany
    hostPath:
      path: /tmp/tmp1
  status: {}
kind: List
metadata: {}

有点困惑,如果你想使用节点上的文件路径作为 pod 的卷,你应该这样做:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on host
      path: /data
      # this field is optional
      type: Directory

但您需要确保 pod 将成为具有文件路径的同一节点的调度程序。

无法为服务分配卷。在 YAML 的第 4 行中,当它应该是“Pod”时指定“Service”,并且 Kubernetes 中使用的每个资源都必须有一个名称,您可以在元数据中添加它。那应该可以解决这个简单的问题。

apiVersion: v1
items:
- apiVersion: v1
  kind: Pod  #POD
  metadata:
    name: my-pod  #A RESOURCE NEEDS A NAME
    creationTimestamp: null
    labels:
      io.kompose.service: zookeeper
  spec:
    containers:
    - image: bitnami/zookeeper:3
      name: zookeeper
      ports:
      - containerPort: 2181
      env:
      - name: ALLOW_ANONYMOUS_LOGIN
        value: "yes"
      resources: {}
      volumeMounts:
      - mountPath: /bitnami/zookeeper
        name: bitnamidockerzookeeper-zookeeper-data
    restartPolicy: Always
    volumes:
    - name: bitnamidockerzookeeper-zookeeper-data
      persistentVolumeClaim:
        claimName: bitnamidockerzookeeper-zookeeper-data
  status: {}

现在,我不知道您使用的是什么,但 hostPath 仅适用于 Minikube 等本地集群。在生产中,情况发生了翻天覆地的变化。如果一切都是本地的,你需要在节点中有目录“/tmp/zoo”,注意不是在你的本地电脑上,而是在节点内。例如,如果你使用 minikube,那么你 运行 minikube ssh 进入节点并在那里复制“/tmp/zoo”。 kubernetes 官方文档中提供了一个很好的指南:https://kubernetes.io/docs/tasks/configure-pod-container/configure-persistent-volume-storage/

您的 YAML 中存在一些潜在问题。

首先,PersistentVolume 的 accessModes 与 PersistentVolumeClaim 不匹配。解决该问题的一种方法是在 PersistentVolume 的 accessModes 中同时列出 ReadWriteManyReadWriteOnce

那么,PersistentVolume 没有指定 storageClassName。因此,如果您将 StorageClass 配置为集群上的默认 StorageClass(您可以使用 kubectl get sc 看到这一点),它将自动动态配置 PersistentVolume,而不是使用您声明的 PersistentVolume。所以你需要指定一个storageClassName。 StorageClass 不必真实存在(因为我们使用的是静态配置而不是动态配置)。

接下来PersistentVolume中的claimRef需要提到PersistentVolumeClaim的Namespace。提醒一下:PersistentVolumes 是集群资源,因此它们没有命名空间;但是 PersistentVolumeClaims 与装载它们的 Pod 属于同一个命名空间。

还有一点就是bitnami图片中Zookeeper数据使用的路径是/bitnami/zookeeper,不是/bitnami/zoo.

您还需要在该卷中初始化权限,因为默认情况下,只有 root 具有写入权限,并且 Zookeeper 在这里以非根用户身份运行,并且不会对 data 子目录.

这是一个更新的 YAML,解决了所有这些问题。我还重写了 YAML 以使用 YAML 多文档语法(资源由 --- 分隔)而不是 kind: List 语法,并且我删除了很多未使用的字段(如空 status: 字段和并非绝对必要的标签)。它适用于我的 KinD 集群,我希望它也适用于您的情况。

如果你的集群只有一个节点,这会工作正常,但如果你有多个节点,你可能需要稍微调整一下以确保卷绑定到特定节点(我添加了一个注释掉 YAML 中的 nodeAffinity 部分,但您可能还必须更改绑定模式——我现在只有一个单节点集群来测试它;但是 Kubernetes 文档和博客对此有丰富的详细信息; 也有关于此绑定模式的详细信息。

最后一件事:在这种情况下,我认为使用 StatefulSet 可能更有意义。它不会产生巨大差异,但会更清楚地表明意图(Zookeeper 是有状态服务)并且在一般情况下(超出本地 hostPath 卷)它会避免让两个 Zookeeper Pods 同时访问该卷.

apiVersion: v1
kind: Service
metadata:
  name: zookeeper
spec:
  ports:
  - name: "2181"
    port: 2181
    targetPort: 2181
  selector:
    io.kompose.service: zookeeper
  type: NodePort
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: zookeeper
spec:
  replicas: 1
  selector:
    matchLabels:
      io.kompose.service: zookeeper
  template:
    metadata:
      labels:
        io.kompose.service: zookeeper
    spec:
      initContainers:
      - image: alpine
        name: chmod
        volumeMounts:
        - mountPath: /bitnami/zookeeper
          name: bitnamidockerzookeeper-zookeeper-data
        command: [ sh, -c, "chmod 777 /bitnami/zookeeper" ]
      containers:
      - image: bitnami/zookeeper:3
        name: zookeeper
        ports:
        - containerPort: 2181
        env:
        - name: ALLOW_ANONYMOUS_LOGIN
          value: "yes"
        volumeMounts:
        - mountPath: /bitnami/zookeeper
          name: bitnamidockerzookeeper-zookeeper-data
      volumes:
      - name: bitnamidockerzookeeper-zookeeper-data
        persistentVolumeClaim:
          claimName: bitnamidockerzookeeper-zookeeper-data
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: bitnamidockerzookeeper-zookeeper-data
spec:
  storageClassName: manual
  accessModes:
  - ReadWriteOnce
  resources:
    requests:
      storage: 100Mi
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name: tmp-tmp1
spec:
  storageClassName: manual
  claimRef:
    name: bitnamidockerzookeeper-zookeeper-data
    namespace: default
  capacity:
    storage: 100Mi
  accessModes:
    - ReadWriteMany
    - ReadWriteOnce
  hostPath:
    path: /tmp/tmp1
  #nodeAffinity:
  #  required:
  #    nodeSelectorTerms:
  #      - matchExpressions:
  #        - key: kubernetes.io/hostname
  #          operator: In
  #          values:
  #          - kind-control-plane