如何在 Kubernetes 中将卷挂载到 Pod
How to mount a volume to a pod in Kubernetes
我试图在我的 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
我以前的文件:
Docker 文件
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 的正确方法是什么?
您的 StatefulSet 声明似乎没问题。
但是,当您使用 volumeClaimTemplates 时,您是否在应用配置之前声明了 PersistentVolume ?
为了使用 volumeClaimTemplate,您需要处于 official documentation 中描述的情况。特别是这句话:
This tutorial assumes that your cluster is configured to dynamically provision 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
这似乎工作正常:
volumeMounts:
- mountPath: /usr/src/app
name: image-server-vol
但是您是在应用程序的工作目录上挂载 /usr/src/app
。相反,将卷安装在其他地方,如 /usr/image
。
您正在装载您尚未创建的卷 image-server-vol
根据评论讨论,您的用例是处理用户上传的文件。
出于各种原因,您不应在此用例中使用 PV。一个原因是您的两个 StatefulSet 副本将安装不同的卷,因此如果用户上传文件并且该请求由一个副本处理,然后他们稍后尝试查看他们的文件并且该请求由另一个副本处理,它不会在那里。考虑使用 S3、Google Cloud Filestore、Minio 等 blobstore 服务。这将需要您编写更多代码,并且可能会引入一些客户端库,但这是更好的做法。
为了您的启发,虽然您不应该在此用例中使用 PV,但它导致您看到的特定错误的原因如下:您正在将卷安装到 /usr/src/app
,所以它会爆炸删除容器内文件系统中那个位置的所有内容,即在构建 Docker 图像时通过 COPY
命令放置在那里的所有应用程序源代码。以后使用 PV 时,一定要将卷挂载到不同的路径,这样才不会破坏你故意放在那里的文件。
我试图在我的 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
我以前的文件:
Docker 文件
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 的正确方法是什么?
您的 StatefulSet 声明似乎没问题。
但是,当您使用 volumeClaimTemplates 时,您是否在应用配置之前声明了 PersistentVolume ?
为了使用 volumeClaimTemplate,您需要处于 official documentation 中描述的情况。特别是这句话:
This tutorial assumes that your cluster is configured to dynamically provision 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
这似乎工作正常:
volumeMounts:
- mountPath: /usr/src/app
name: image-server-vol
但是您是在应用程序的工作目录上挂载 /usr/src/app
。相反,将卷安装在其他地方,如 /usr/image
。
您正在装载您尚未创建的卷 image-server-vol
根据评论讨论,您的用例是处理用户上传的文件。
出于各种原因,您不应在此用例中使用 PV。一个原因是您的两个 StatefulSet 副本将安装不同的卷,因此如果用户上传文件并且该请求由一个副本处理,然后他们稍后尝试查看他们的文件并且该请求由另一个副本处理,它不会在那里。考虑使用 S3、Google Cloud Filestore、Minio 等 blobstore 服务。这将需要您编写更多代码,并且可能会引入一些客户端库,但这是更好的做法。
为了您的启发,虽然您不应该在此用例中使用 PV,但它导致您看到的特定错误的原因如下:您正在将卷安装到 /usr/src/app
,所以它会爆炸删除容器内文件系统中那个位置的所有内容,即在构建 Docker 图像时通过 COPY
命令放置在那里的所有应用程序源代码。以后使用 PV 时,一定要将卷挂载到不同的路径,这样才不会破坏你故意放在那里的文件。