Kubernetes: La ruta de montaje del archivo configmap da como resultado un error de comando no encontrado

Creado en 23 abr. 2017  ·  10Comentarios  ·  Fuente: kubernetes/kubernetes

¿Es esta una solicitud de ayuda? (En caso afirmativo, debe utilizar nuestra guía de resolución de problemas y los canales de asistencia de la comunidad, consulte http://kubernetes.io/docs/troubleshooting/): No

¿Qué palabras clave buscó en los problemas de Kubernetes antes de presentar este? (Si ha encontrado duplicados, debe responder allí): comando no encontrado configmap kubernetes


¿Es este un INFORME DE ERROR o una SOLICITUD DE FUNCIÓN? (elige uno): ERROR

Versión de Kubernetes (use kubectl version ):
Versión del cliente: v1.6.1 GitCommit: "b0b7a323cc5a4a2019b2e9520c21c7830b7f708e"
Versión del servidor: v1.6.0 GitCommit: "fff5156092b56e6bd60fff75aad4dc9de6b6ef37

Medio ambiente :

  • Proveedor de nube o configuración de hardware :
  • SO (por ejemplo, de / etc / os-release): el host es ubuntu 16.04
  • Kernel (por ejemplo, uname -a ): el host es Linux dev1 4.4.0-72-generic # 93-Ubuntu SMP Vie 31 de marzo 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU / Linux
  • Instalar herramientas :
  • Otros : Ejecutando desde dentro de la versión de minikube: v0.18.0

Que paso :
Cuando intento crear una implementación con un archivo de mapa de configuración que está montado en el mismo directorio que el punto de entrada, el contenedor no se inicia con el siguiente error
"Respuesta de error del demonio: comando contenedor '/app/app.sh' no encontrado o no existe".
La especificación del pod incluye un mapa de configuración que se monta en el mismo directorio que el punto de entrada

Parece que la secuencia de comandos del punto de entrada se pierde después de montar el volumen para el mapa de configuración en el mismo directorio
Si monte el archivo configmap en un subdirectorio, todo funciona como se esperaba

Qué esperabas que sucediera :
Esperaba que el archivo de mapa de configuración se creara en el directorio sin afectar el contenido del directorio existente, que en este caso contiene un script de punto de entrada

Cómo reproducirlo (de la forma más mínima y precisa posible):

Archivo Docker: tenga en cuenta el punto de entrada

FROM busybox:latest

RUN        mkdir /app
COPY       app.sh /app

ENTRYPOINT ["/app/app.sh"]

Script de punto de entrada - bucle infinito

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

archivo de implementación y mapa de configuración de k8s

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 

Cuando ejecuto kubectl apply -d k8s.yaml y miro el pod, puedo ver el siguiente error

rpc error: code = 2 desc = failed to start container "f9e0112c80ebba568d4b508f99ffb053bf1ae5a4f095ce7f45bff5f38900b617": Respuesta de error del demonio: El comando de contenedor '/app/app.sh' no se encuentra o no existe.

Cualquier otra cosa que necesitemos saber :
Si cambio el mountPath para el volumen a cualquier otro directorio, funciona como se esperaba

Probé esto directamente con la ventana acoplable en mi host (17.03.0-ce) y funcionó como se esperaba

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

Comentario más útil

@pmcgrath

Echa un vistazo aquí .

parece que entiendo tu problema. Tengo la misma pregunta antes, pero en realidad hay una respuesta en su situación.

Para resumir su caso, tiene un mapa de configuración ( settings.json: blahblah ) y desea montarlo en una carpeta /app . Entonces, a continuación, encontrará lo que necesita saber:

  1. Una vez que monte un volumen (no importa si es configmap u otros), anula el mountPath , por lo que en su caso, la carpeta /app solo contendrá settings.json .
  2. Sé que no es lo que esperabas, por lo que debes especificar el mountPath: /app/settings.json , solo de esa manera, el contenido original en las carpetas /app no se verá afectado.
  3. bueno, cuando haces el segundo paso, recuerdas que configmap es en realidad una lista de pares clave-valor, solo necesitas una de las claves (aunque en realidad solo tienes una), por lo que debes indicarle a los montajes de volumen que use una subruta de su mapa de configuración.

Esto es algo que obtendrás eventualmente:

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

Todos 10 comentarios

@pmcgrath

Echa un vistazo aquí .

parece que entiendo tu problema. Tengo la misma pregunta antes, pero en realidad hay una respuesta en su situación.

Para resumir su caso, tiene un mapa de configuración ( settings.json: blahblah ) y desea montarlo en una carpeta /app . Entonces, a continuación, encontrará lo que necesita saber:

  1. Una vez que monte un volumen (no importa si es configmap u otros), anula el mountPath , por lo que en su caso, la carpeta /app solo contendrá settings.json .
  2. Sé que no es lo que esperabas, por lo que debes especificar el mountPath: /app/settings.json , solo de esa manera, el contenido original en las carpetas /app no se verá afectado.
  3. bueno, cuando haces el segundo paso, recuerdas que configmap es en realidad una lista de pares clave-valor, solo necesitas una de las claves (aunque en realidad solo tienes una), por lo que debes indicarle a los montajes de volumen que use una subruta de su mapa de configuración.

Esto es algo que obtendrás eventualmente:

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

@ zhouhaibing089
Gracias por la respuesta, funciona según tu sugerencia, agradezco la explicación

Me complace cerrar este problema.
Palmadita

Como referencia, la mención original de esta solución parece estar aquí: https://github.com/kubernetes/kubernetes/issues/23748#issuecomment -230390309

Parece que falta la documentación para esto, lo que hace que este caso sea bastante confuso / engañoso, y los documentos de proyección también parecen hacerlo más engañoso; no estoy seguro si falta porque las actualizaciones automáticas aparentemente no funcionan según ese problema

El requisito de que el nombre del archivo se especifique tanto en mountPath como en subPath es contrario a la intuición.

La solución proporcionada por @ zhouhaibing089 funciona, pero el contenido del archivo montado en subPath no se actualiza si lo editamos en el ConfigMap similar.

En mi opinión, esto no está _ realmente_ resuelto. Debería haber una opción para agregar cada clave en lugar de sobrescribir.

Algo como:

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...
    }

Así que eso...

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

... mantiene el default.conf y cualquier otro artefacto de la imagen de Docker, pero aumenta con example*.conf

Repetir la misma información en subPath es simplemente _icky_.

+1 en la opción append: true @leebenson .

De acuerdo con la respuesta de @leebenson : ¿alguien puede explicar de dónde viene la opción append: true ?

no me funciona, tengo:

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

Además, no está presente en los documentos de la API para el montaje de volumen:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

De acuerdo con la respuesta de @leebenson : ¿alguien puede explicar de dónde viene la opción append: true ?

no me funciona, tengo:

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

Además, no está presente en los documentos de la API para el montaje de volumen:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

no existe, es una sugerencia. uno bueno para el caso de uso.

Intenté usar este método, pero obtuve un error del sistema de archivos de solo lectura cuando apliqué el statefulset. ¿Alguien sabe cómo arreglar eso?
(Estoy sobrescribiendo un archivo existente, que contiene configuraciones para elasticsearch, mensaje de error real -> /usr/share/elasticsearch/bin/run.sh: line 28: ./config/elasticsearch.yml: Read-only file system )

¿Fue útil esta página
0 / 5 - 0 calificaciones