简体   繁体   English

如何在Kubernetes中将卷安装到Pod

[英]How to mount a volume to a pod in Kubernetes

I'm trying to change my express server deployment from Deployment to Statefulsets in my Kubernetes cluster. 我正在尝试将我的Express服务器部署从Kubernetes集群中的Deployment更改为Statefulsets。 After I added the volumeMounts to the yaml file, I gets the following error from the pod's log: 将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

My previous files: 我以前的文件:

Dockerfile Docker文件

FROM node:10.16-alpine

WORKDIR /usr/src/app

COPY package*.json ./

RUN npm install

COPY . .

CMD [ "npm", "start" ]

Service yaml file 服务Yaml文件

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

deployment yaml file 部署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'

My current file: 我当前的文件:

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 file 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

I think the package.json file might be deleted when I added the volume mount. 我认为在添加卷装载时,可能会删除package.json文件。

What is the proper way to mount the volume to my pod? 将卷安装到吊舱的正确方法是什么?

From the comment discussion, your use case is to handle users' uploaded files. 在评论讨论中,您的用例是处理用户上传的文件。

You should not use a PV for this use case, for various reasons. 出于各种原因,您不应为此用途使用PV。 One reason is that your two StatefulSet replicas will have different volumes mounted, so if a user uploads a file and that request gets handled by one replica, and then later they try to view their file and that request is handled by the other replica, it won't be there. 原因之一是您的两个StatefulSet副本将装载不同的卷,因此,如果用户上载文件,并且该请求由一个副本处理,然后稍后他们尝试查看其文件,而该请求由另一个副本处理,则它不会在那里。 Consider using a blobstore service like S3, Google Cloud Filestore, Minio, etc. This will require a bit more code for you to write, and probably pull in some client libraries, but it's a better practice. 考虑使用blobstore服务,例如S3,Google Cloud Filestore,Minio等。这将需要更多代码来编写,并且可能会引入一些客户端库,但这是一种更好的做法。

For your edification, though you shouldn't use PVs for this use case, here's why it was causing the specific error you were seeing: You're mounting the volume to /usr/src/app so it's going to blow away whatever was at that place in the filesystem within the container, namely all your app source code you put there via the COPY commands when building your Docker image. 为了您的启发,尽管您不应该在此用例中使用PV,但这是为什么它导致您看到的特定错误的原因:您正在将卷挂载到/usr/src/app因此无论什么时候它都会消失容器中文件系统中的位置,即在构建Docker映像时通过COPY命令放置的所有应用程序源代码。 In the future when using PVs, be sure to mount the volume to a different path that won't blow away the files you've put there intentionally. 将来在使用PV时,请确保将卷安装到其他路径,以免损坏您故意放置的文件。

Your StatefulSet declaration seems ok. 您的StatefulSet声明似乎还可以。
However, as you're using a volumeClaimTemplates , have you declared a PersistentVolume before applying your configuration ? 但是,当您使用volumeClaimTemplates时 ,是否应用配置之前声明了PersistentVolume

In order to use a volumeClaimTemplate , you need to be in the situation described in the official documentation . 为了使用volumeClaimTemplate ,您需要处于官方文档中所述的情况。 Especially this sentence : 特别是这句话:

This tutorial assumes that your cluster is configured to dynamically provision PersistentVolumes. 本教程假定您的集群已配置为动态设置PersistentVolumes。 If your cluster is not configured to do so, you will have to manually provision two 1 GiB volumes prior to starting this tutorial 如果您的集群未配置为这样做,那么在开始本教程之前,您将必须手动配置两个1 GiB卷

This seems to be working fine: 这似乎工作正常:

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

But you are mounting over your application's working directory /usr/src/app . 但是,您正在安装应用程序的工作目录/usr/src/app Instead, mount the volume somewhere else like /usr/image . 而是将卷挂载到/usr/image

您正在迁移尚未创建的voulume image-server-vol

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM