Kubernetes 在部署内的容器之间共享卷
Kubernetes share volume between containers inside a Deployment
在发布这个问题之前,我遵循了这个答案,但它对我不起作用。
我有 2 个容器:
- node: 它的图像包含与应用程序相关的所有文件(在
/var/www
内)
- nginx: 它需要访问 node 图像中的文件(尤其是
/clientBuild
文件夹,我有所有资产)
节点图像里面是什么:
$ docker run node ls -l
> clientBuild/
> package.json
> ...
nginx.prod.conf
的一部分:
location ~* \.(jpeg|jpg|gif|png|ico|css|js|gz|map|json)$ {
include /etc/nginx/mime.types;
root /usr/local/nginx/html/clientBuild/;
}
以及部署设置:
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: pwa-app-production
labels:
app: MyApp
spec:
replicas: 1
template:
metadata:
name: app
labels:
app: MyApp
env: production
spec:
containers:
- name: nginx
image: nginx
command: [nginx, -c, /nginx.prod.conf, -g, 'daemon off;']
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/local/nginx/html
name: pwa-disk
readOnly: true
ports:
- name: nginx
containerPort: 80
initContainers:
- name: node
image: node
command: [npm, start]
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /var/www
name: pwa-disk
ports:
- name: app
containerPort: 3000
- name: api
containerPort: 3001
volumes:
- name: pwa-disk
emptyDir: {}
我首先尝试将两个图像放在同一个 containers
键中,但我得到了: /var/www/package.json not found
on npm start
然后我将它移到 initContainers
中,但现在我只注意到它失败了,但没有告诉我原因。查看日志也不显示任何详细信息。
请注意,当我删除音量部分时,npm start
有效。
我假设您的资产已经打包在 /var/www
的图像中。如果您在该路径上安装一个 emptyDir
卷,那么那里的所有内容都会被 emptyDir
卷的内容覆盖——最初什么都没有。这意味着您的所有资产都通过该挂载被删除 - 这就是您的节点服务器最有可能失败的原因。
您要做的是将 emptyDir
卷挂载到其他路径,比如 /data
。然后你用 cp -r /var/www/* /data
覆盖你的节点容器 cmd 以将资产复制到你的 pwa-disk
卷中。现在,您可以将此卷装载到您的 nginx 容器中。
我认为对 initContainers
的工作方式存在误解。它们旨在终止。它们 运行 BEFORE 启动任何其他容器 - 在您的 initContainers
成功终止之前,您的 pod 中没有其他容器启动。所以很可能您不想将节点服务器启动为 initContainer
。我猜你的节点服务器不应该终止,在这种情况下你的 nginx 容器将永远不会启动。相反,您可能希望在 containers
部分内将节点服务器与 nginx 一起声明。此外,您还将具有覆盖的 cmd (cp -r /var/www/* /data
) 的节点容器添加到 initContainers
部分,以将资产复制到卷。整个事情可能看起来像这样:
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: pwa-app-production
labels:
app: MyApp
spec:
replicas: 1
template:
metadata:
name: app
labels:
app: MyApp
env: production
spec:
containers:
- name: nginx
image: nginx
command: [nginx, -c, /nginx.prod.conf, -g, 'daemon off;']
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/local/nginx/html
name: pwa-disk
readOnly: true
ports:
- name: nginx
containerPort: 80
- name: node
image: node
command: [npm, start]
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
ports:
- name: app
containerPort: 3000
- name: api
containerPort: 3001
initContainers:
- name: assets
image: node
command: [bash, -c]
args: ["cp -r /var/www/* /data"]
imagePullPolicy: Always
volumeMounts:
- mountPath: /data
name: pwa-disk
volumes:
- name: pwa-disk
emptyDir: {}
在发布这个问题之前,我遵循了这个答案
我有 2 个容器:
- node: 它的图像包含与应用程序相关的所有文件(在
/var/www
内) - nginx: 它需要访问 node 图像中的文件(尤其是
/clientBuild
文件夹,我有所有资产)
节点图像里面是什么:
$ docker run node ls -l
> clientBuild/
> package.json
> ...
nginx.prod.conf
的一部分:
location ~* \.(jpeg|jpg|gif|png|ico|css|js|gz|map|json)$ {
include /etc/nginx/mime.types;
root /usr/local/nginx/html/clientBuild/;
}
以及部署设置:
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: pwa-app-production
labels:
app: MyApp
spec:
replicas: 1
template:
metadata:
name: app
labels:
app: MyApp
env: production
spec:
containers:
- name: nginx
image: nginx
command: [nginx, -c, /nginx.prod.conf, -g, 'daemon off;']
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/local/nginx/html
name: pwa-disk
readOnly: true
ports:
- name: nginx
containerPort: 80
initContainers:
- name: node
image: node
command: [npm, start]
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /var/www
name: pwa-disk
ports:
- name: app
containerPort: 3000
- name: api
containerPort: 3001
volumes:
- name: pwa-disk
emptyDir: {}
我首先尝试将两个图像放在同一个 containers
键中,但我得到了: /var/www/package.json not found
on npm start
然后我将它移到 initContainers
中,但现在我只注意到它失败了,但没有告诉我原因。查看日志也不显示任何详细信息。
请注意,当我删除音量部分时,npm start
有效。
我假设您的资产已经打包在 /var/www
的图像中。如果您在该路径上安装一个 emptyDir
卷,那么那里的所有内容都会被 emptyDir
卷的内容覆盖——最初什么都没有。这意味着您的所有资产都通过该挂载被删除 - 这就是您的节点服务器最有可能失败的原因。
您要做的是将 emptyDir
卷挂载到其他路径,比如 /data
。然后你用 cp -r /var/www/* /data
覆盖你的节点容器 cmd 以将资产复制到你的 pwa-disk
卷中。现在,您可以将此卷装载到您的 nginx 容器中。
我认为对 initContainers
的工作方式存在误解。它们旨在终止。它们 运行 BEFORE 启动任何其他容器 - 在您的 initContainers
成功终止之前,您的 pod 中没有其他容器启动。所以很可能您不想将节点服务器启动为 initContainer
。我猜你的节点服务器不应该终止,在这种情况下你的 nginx 容器将永远不会启动。相反,您可能希望在 containers
部分内将节点服务器与 nginx 一起声明。此外,您还将具有覆盖的 cmd (cp -r /var/www/* /data
) 的节点容器添加到 initContainers
部分,以将资产复制到卷。整个事情可能看起来像这样:
kind: Deployment
apiVersion: extensions/v1beta1
metadata:
name: pwa-app-production
labels:
app: MyApp
spec:
replicas: 1
template:
metadata:
name: app
labels:
app: MyApp
env: production
spec:
containers:
- name: nginx
image: nginx
command: [nginx, -c, /nginx.prod.conf, -g, 'daemon off;']
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
volumeMounts:
- mountPath: /usr/local/nginx/html
name: pwa-disk
readOnly: true
ports:
- name: nginx
containerPort: 80
- name: node
image: node
command: [npm, start]
resources:
limits:
memory: "500Mi"
cpu: "100m"
imagePullPolicy: Always
ports:
- name: app
containerPort: 3000
- name: api
containerPort: 3001
initContainers:
- name: assets
image: node
command: [bash, -c]
args: ["cp -r /var/www/* /data"]
imagePullPolicy: Always
volumeMounts:
- mountPath: /data
name: pwa-disk
volumes:
- name: pwa-disk
emptyDir: {}