【问题标题】:How to mount a volume to a pod in Kubernetes如何在 Kubernetes 中将卷挂载到 pod
【发布时间】:2019-08-24 00:32:09
【问题描述】:

我正在尝试在我的 Kubernetes 集群中将我的快速服务器部署从 Deployment 更改为 Statefulsets。将 volumeMounts 添加到 yaml 文件后,我从 pod 的日志中收到以下错误:

npm ERR! path /usr/src/app/package.json
npm ERR! code ENOENT
npm ERR! errno -2
npm ERR! syscall open
npm ERR! enoent ENOENT: no such file or directory, open '/usr/src/app/package.json'
npm ERR! enoent This is related to npm not being able to find a file.
npm ERR! enoent 

npm ERR! A complete log of this run can be found in:
npm ERR!     /root/.npm/_logs/2019-08-23T13_55_03_058Z-debug.log

我以前的文件:

Dockerfile

FROM node:10.16-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

CMD [ "npm", "start" ]

服务 yaml 文件

apiVersion: v1
kind: Service
metadata:
  name: image-server-cluster-ip-service
spec:
  type: ClusterIP
  selector:
    component: image-server
  ports:
  - port: 3001
    targetPort: 3001

部署yaml文件

apiVersion: apps/v1
kind: Deployment
metadata:
  name: image-server-deployment
spec:
  replicas: 1
  selector:
    matchLabels:
      component: image-server
  template:
    metadata:
      labels:
        component: image-server
    spec:
      containers:
      - name: image-server
        image: gcr.io/my-project/image-server:v0.0.10
        ports:
        - containerPort: 3001
        env:
          - name: MONGO_HOST
            value: mongo-cluster-ip-service
          - name: MONGO_PORT
            value: '27017'

我当前的文件:

headless service file

apiVersion: v1
kind: Service
metadata:
  name: image-server-cluster-ip-service
spec:
  clusterIP: None
  selector:
    component: image-server
  ports:
  - port: 3001
    targetPort: 3001

statefulsets yaml 文件

apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: image-server-deployment
spec:
  serviceName: "image-server-cluster-ip-service"
  replicas: 2
  selector:
    matchLabels:
      component: image-server
  template:
    metadata:
      labels:
        component: image-server
    spec:
      containers:
      - name: image-server
        image: gcr.io/my-project/image-server:v0.0.10
        ports:
        - containerPort: 3001
        env:
          - name: MONGO_HOST
            value: mongo-cluster-ip-service
          - name: MONGO_PORT
            value: '27017'
        volumeMounts:
          - mountPath: /usr/src/app
            name: image-server-vol
  volumeClaimTemplates:
    - metadata:
        name: image-server-vol
      spec:
        accessModes: ["ReadWriteOnce"]
        resources:
          requests:
            storage: 1Gi

我认为添加卷挂载时可能会删除 package.json 文件。

将卷安装到我的 pod 的正确方法是什么?

【问题讨论】:

  • 为什么首先需要挂载任何卷?
  • @AmitKumarGupta 我正在使用服务器来处理用户上传的文件。 AFAIK,如果我只是将这些文件保存在 Pod 中的本地文件系统中,而不是通过 PV 持久保存它们,那么一旦 Pod 被删除/重新启动,它们就会被删除。所以我也在尝试将这些文件映射到 PV。我对 k8s 很陌生,所以我不确定这是正确的方法。
  • 由于各种原因,您可能不应该在此用例中使用 PV。一个原因是您的两个 StatefulSet 副本将安装不同的卷,因此如果用户上传文件并且该请求由一个副本处理,然后他们尝试查看他们的文件并且该请求由另一个副本处理,它不会在那里。考虑使用像 S3 或 Minio 这样的 blobstore 服务。这将需要您编写更多代码,并且可能会引入一些客户端库,但这是一种更好的做法...
  • ... 另外,关于 PV,您将卷安装到 /usr/src/app,因此它将吹走容器内文件系统中该位置的所有内容,即您所有的应用程序源代码在构建 Docker 映像时通过 COPY 命令将其放在那里。如果有的话,请将卷挂载到其他路径,这样不会破坏您故意放在那里的文件。
  • 感谢您回答我的问题和我应该提出的问题。由于我使用的是 GCP,因此 S3 将不可用,我想我将不得不使用 Google Cloud Filestore 来完成这项工作。

标签: kubernetes volume


【解决方案1】:

从评论讨论中,您的用例是处理用户上传的文件。

出于各种原因,您不应在此用例中使用 PV。一个原因是您的两个 StatefulSet 副本将安装不同的卷,因此如果用户上传文件并且该请求由一个副本处理,然后他们尝试查看他们的文件并且该请求由另一个副本处理,它不会在那里。考虑使用 Blobstore 服务,如 S3、Google Cloud Filestore、Minio 等。这将需要您编写更多代码,并且可能会引入一些客户端库,但这是一种更好的做法。

为了您的启迪,尽管您不应该在此用例中使用 PV,但这就是导致您所看到的特定错误的原因:您将卷安装到 /usr/src/app 所以它会吹走任何东西该位置在容器内的文件系统中,即您在构建 Docker 映像时通过 COPY 命令放置的所有应用程序源代码。以后在使用 PV 时,请务必将卷挂载到其他路径,以免将您故意放在那里的文件吹走。

【讨论】:

    【解决方案2】:

    您的 StatefulSet 声明似乎没问题。
    但是,由于您使用的是 volumeClaimTemplates,您是否在应用配置之前声明了 PersistentVolume

    为了使用 volumeClaimTemplate,您需要处于official documentation 中描述的情况。尤其是这句话:

    本教程假设您的集群配置为动态供应 PersistentVolume。如果您的集群未配置为这样做,您必须在开始本教程之前手动配置两个 1 GiB 卷

    【讨论】:

    • PV 应该是动态配置的。
    【解决方案3】:

    这似乎工作正常:

        volumeMounts:
          - mountPath: /usr/src/app
            name: image-server-vol
    

    但是您正在安装应用程序的工作目录/usr/src/app。相反,将卷安装在其他位置,例如 /usr/image

    【讨论】:

      【解决方案4】:

      您正在安装一个您尚未创建的卷镜像服务器卷

      【讨论】:

      • PV 是通过 volumeClaimTemplates 动态配置的。
      猜你喜欢
      • 2021-11-22
      • 2021-10-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-12-22
      • 2018-01-09
      • 2019-10-19
      相关资源
      最近更新 更多