Kubernetes: configmap 文件挂载路径导致找不到命令错误

创建于 2017-04-23  ·  10评论  ·  资料来源: kubernetes/kubernetes

这是请求帮助吗? (如果是,您应该使用我们的故障排除指南和社区支持渠道,请参阅 http://kubernetes.io/docs/troubleshooting/。):否

在提交这个问题之前,您在 Kubernetes 问题中搜索了哪些关键字? (如果您发现任何重复项,您应该在那里回复。): command not found configmap kubernetes


这是错误报告还是功能请求? (选择一项):BUG

Kubernetes 版本(使用kubectl version ):
客户端版本:v1.6.1 GitCommit:"b0b7a323cc5a4a2019b2e9520c21c7830b7f708e"
服务器版本:v1.6.0 GitCommit:"fff5156092b56e6bd60fff75aad4dc9de6b6ef37

环境:

  • 云提供商或硬件配置
  • 操作系统(例如来自 /etc/os-release):主机是 ubuntu 16.04
  • 内核(例如uname -a ):主机是 Linux dev1 4.4.0-72-generic #93-Ubuntu SMP Fri Mar 31 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
  • 安装工具
  • 其他:从 minikube 版本中运行:v0.18.0

发生了什么
当我尝试使用挂载到与入口点相同的目录中的 configmap 文件创建部署时,容器无法启动并出现以下错误
“来自守护进程的错误响应:未找到或不存在容器命令‘/app/app.sh’。”
pod 规范包括一个 configmap,它安装在与入口点相同的目录中

在同一目录中安装配置映射的卷后,入口点脚本似乎丢失了
如果我将 configmap 文件挂载到子目录中,则一切正常

你期望发生的事情
我希望在目录中创建配置映射文件而不影响现有目录内容,在这种情况下包含入口点脚本

如何重现它(尽可能少且精确):

Docker 文件 - 注意入口点

FROM busybox:latest

RUN        mkdir /app
COPY       app.sh /app

ENTRYPOINT ["/app/app.sh"]

入口点脚本 - 无限循环

#!/bin/sh
seq=1
while [[ true ]]; do
    echo "${seq} $(date) working"
    sleep .5s   
    let seq=$((seq + 1))
done

k8s configmap 和部署文件

apiVersion: v1
kind: ConfigMap
metadata:
  labels:
    product: k8s-demo
  name: demo
data:
  settings.json: |
    {
      "store": {
        "type": "InMemory",
    }

---
apiVersion: apps/v1beta1
kind: Deployment
metadata:
  labels:
    product: k8s-demo
  name: demo
spec:
  replicas: 1
  template:
    metadata:
      labels:
        app: demo
        product: k8s-demo
    spec:
      containers:
      - name: demo
        image: pmcgrath/shellloop:1
        imagePullPolicy: Always
        volumeMounts:
          - name: demo-config
            mountPath: /app
      volumes:
        - name: demo-config
          configMap:
            name: demo
            items:
              - key: settings.json
                path: settings.json 

当我运行 kubectl apply -d k8s.yaml 并查看 pod 时,我可以看到以下错误

rpc 错误:代码 = 2 desc = 无法启动容器“f9e0112c80ebba568d4b508f99ffb053bf1ae5a4f095ce7f45bff5f38900b617”:来自守护进程的错误响应:容器命令“/app found/app.sh”不存在。

还有什么我们需要知道的
如果我将卷的 mountPath 更改为任何其他目录,它会按预期工作

我确实在我的主机 (17.03.0-ce) 上直接使用 docker 进行了测试,并且它按预期工作

touch settings.json
docker container run -ti -v $(pwd)/settings.json:/app/settings.json pmcgrath/shellloop:1

最有用的评论

@pmcgrath

在这里结帐。

看来我明白你的问题了。 我以前也有同样的问题,但实际上在你的情况下有一个答案。

为了简要说明您的情况,您有一个 configmap( settings.json: blahblah ),并且想要挂载到/app文件夹中。 那么下面是你需要知道的:

  1. 一旦你挂载了一个卷(无论是 configmap 还是其他),它就会覆盖mountPath ,所以在你的情况下, /app文件夹将只包含settings.json
  2. 我知道这不是您所期望的,因此您必须指定mountPath: /app/settings.json ,只有这样, /app文件夹中的原始内容才不会受到影响。
  3. 好吧,当你做第二步时,你记得 configmap 实际上是一个键值对列表,你只需要一个键(尽管你实际上只有一个),所以你需要告诉卷安装使用您的 configmap 中的子路径。

这是你最终会得到的东西:

containers:
- volumeMounts:
  - name: demo-config
    mountPath: /app/settings.json
    subPath: settings.json
volumes:
- name: demo-config
  configMap:
    name: demo

所有10条评论

@pmcgrath

在这里结帐。

看来我明白你的问题了。 我以前也有同样的问题,但实际上在你的情况下有一个答案。

为了简要说明您的情况,您有一个 configmap( settings.json: blahblah ),并且想要挂载到/app文件夹中。 那么下面是你需要知道的:

  1. 一旦你挂载了一个卷(无论是 configmap 还是其他),它就会覆盖mountPath ,所以在你的情况下, /app文件夹将只包含settings.json
  2. 我知道这不是您所期望的,因此您必须指定mountPath: /app/settings.json ,只有这样, /app文件夹中的原始内容才不会受到影响。
  3. 好吧,当你做第二步时,你记得 configmap 实际上是一个键值对列表,你只需要一个键(尽管你实际上只有一个),所以你需要告诉卷安装使用您的 configmap 中的子路径。

这是你最终会得到的东西:

containers:
- volumeMounts:
  - name: demo-config
    mountPath: /app/settings.json
    subPath: settings.json
volumes:
- name: demo-config
  configMap:
    name: demo

@zhouhaibing089
感谢您的回复,根据您的建议工作,我感谢您的解释

我很高兴关闭这个问题

作为参考,此解决方案的原始提及似乎在这里: https :

看起来缺少有关此的文档,这使得这种情况相当混乱/具有误导性,并且投影文档似乎也使其更具误导性 - 不确定它是否丢失,因为自动更新显然无法按照该问题工作

mountPathsubPath下都指定文件名的要求是违反直觉的。

@zhouhaibing089提供的解决方案有效,但如果我们在类似的 ConfigMap 中对其进行编辑, subPath处的已挂载文件的内容不会更新。

IMO,这并没有_真的_解决。 应该有一个选项来附加每个键而不是覆盖。

就像是:

kind: ConfigMap
apiVersion: v1
metadata:
  name: nginx-conf
data:
  example1.conf: |
    server {
      server_name example1.com;
      # config here...
    }
  example2.conf: |
    server {
      server_name example2.com;
      # config here...
    }

以便...

- name: nginx-conf
  mountPath: /etc/nginx/conf.d
  append: true

... 保留现有的default.conf和 Docker 镜像的任何其他人工制品,但增加了example*.conf

在 subPath 中重复相同的信息只是 _icky_。

+1 @leebensonappend: true选项。

根据@leebenson 的回答:谁能解释一下append: true选项的来源?

它对我不起作用,我得到:

error: error validating "hdfs/21-namenode-statefulset.yaml": error validating data: ValidationError(StatefulSet.spec.template.spec.containers[1].volumeMounts[1]): unknown field "append" in io.k8s.api.core.v1.VolumeMount; if you choose to ignore these errors, turn validation off with --validate=false

此外,它不存在于卷挂载的 api 文档中:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

根据@leebenson 的回答:谁能解释一下append: true选项的来源?

它对我不起作用,我得到:

error: error validating "hdfs/21-namenode-statefulset.yaml": error validating data: ValidationError(StatefulSet.spec.template.spec.containers[1].volumeMounts[1]): unknown field "append" in io.k8s.api.core.v1.VolumeMount; if you choose to ignore these errors, turn validation off with --validate=false

此外,它不存在于卷挂载的 api 文档中:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

它不存在,这是一个建议。 一个很好的用例。

我尝试使用此方法,但在应用 statefulset 时出现只读文件系统错误。 有谁知道如何解决这个问题?
(我正在覆盖一个现有文件,其中包含弹性搜索设置、实际错误消息 --> /usr/share/elasticsearch/bin/run.sh: line 28: ./config/elasticsearch.yml: Read-only file system

此页面是否有帮助?
0 / 5 - 0 等级

相关问题

arun-gupta picture arun-gupta  ·  3评论

Seb-Solon picture Seb-Solon  ·  3评论

sanjana-bhat picture sanjana-bhat  ·  3评论

rhohubbuild picture rhohubbuild  ·  3评论

errordeveloper picture errordeveloper  ·  3评论