Kubernetes: configmap-Datei-Mount-Pfad führt zum Fehler "Befehl nicht gefunden"

Erstellt am 23. Apr. 2017  ·  10Kommentare  ·  Quelle: kubernetes/kubernetes

Ist das eine Bitte um Hilfe? (Wenn ja, sollten Sie unseren Leitfaden zur Fehlerbehebung und die Community-Supportkanäle verwenden, siehe http://kubernetes.io/docs/troubleshooting/.): Nein

Nach welchen Schlüsselwörtern haben Sie in Kubernetes-Ausgaben gesucht, bevor Sie diese eingereicht haben? (Wenn Sie Duplikate gefunden haben, sollten Sie stattdessen dort antworten.): command not found configmap kubernetes


Ist dies ein FEHLERBERICHT oder eine FEATURE-ANFRAGE? (wählen Sie einen): BUG

Kubernetes-Version (verwenden Sie kubectl version ):
Client-Version: v1.6.1 GitCommit:"b0b7a323cc5a4a2019b2e9520c21c7830b7f708e"
Serverversion: v1.6.0 GitCommit:"fff5156092b56e6bd60fff75aad4dc9de6b6ef37

Umgebung :

  • Cloud-Anbieter oder Hardware-Konfiguration :
  • Betriebssystem (zB von /etc/os-release): Host ist Ubuntu 16.04
  • Kernel (zB uname -a ): Host ist Linux dev1 4.4.0-72-generic #93-Ubuntu SMP Fr 31. März 14:07:41 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux
  • Tools installieren :
  • Sonstiges : Ausführung innerhalb von Minikube-Version: v0.18.0

Was ist passiert :
Wenn ich versuche, eine Bereitstellung mit einer configmap-Datei zu erstellen, die im selben Verzeichnis wie der Einstiegspunkt gemountet ist, startet der Container nicht mit der folgenden Fehlermeldung
"Fehlerantwort vom Daemon: Container-Befehl '/app/app.sh' nicht gefunden oder existiert nicht."
Die Pod-Spezifikation enthält eine configmap, die in das gleiche Verzeichnis wie der Einstiegspunkt eingehängt wird

Scheint, dass das Einstiegspunkt-Skript verloren geht, nachdem das Volume für die Konfigurationszuordnung im selben Verzeichnis gemountet wurde
Wenn ich die configmap-Datei in ein Unterverzeichnis mounte, funktioniert alles wie erwartet

Was Sie erwartet haben, zu passieren :
Ich habe erwartet, dass die Konfigurationszuordnungsdatei im Verzeichnis erstellt wird, ohne den vorhandenen Verzeichnisinhalt zu beeinträchtigen, der in diesem Fall ein Einstiegspunktskript enthält

So reproduzieren Sie es (so minimal und genau wie möglich):

Docker-Datei - beachten Sie den Einstiegspunkt

FROM busybox:latest

RUN        mkdir /app
COPY       app.sh /app

ENTRYPOINT ["/app/app.sh"]

Einstiegspunktskript - Endlosschleife

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

k8s configmap und Bereitstellungsdatei

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 

Wenn ich kubectl apply -d k8s.yaml ausführe und mir den Pod ansehe, sehe ich den folgenden Fehler

rpc error: code = 2 desc = konnte den Container "f9e0112c80ebba568d4b508f99ffb053bf1ae5a4f095ce7f45bff5f38900b617" nicht starten: Fehlerantwort vom Daemon: Container-Befehl '/app/app.sh' nicht gefunden oder existiert nicht.

Was wir sonst noch wissen müssen :
Wenn ich den mountPath für das Volume in ein anderes Verzeichnis ändere, funktioniert es wie erwartet

Ich habe dies direkt mit Docker auf meinem Host (17.03.0-ce) getestet und es hat wie erwartet funktioniert

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

Hilfreichster Kommentar

@pmcgrath

Kasse hier .

anscheinend verstehe ich dein Problem. Ich habe die gleiche Frage schon einmal, aber es gibt tatsächlich eine Antwort in Ihrer Situation.

Um Ihren Fall zu beschreiben, haben Sie eine configmap ( settings.json: blahblah ) und möchten sie in einen Ordner /app mounten. Dann ist unten, was Sie wissen müssen:

  1. Sobald Sie ein Volume mounten (egal, ob es sich um configmap oder andere handelt), überschreibt es mountPath , so dass in Ihrem Fall der Ordner /app nur settings.json .
  2. Ich weiß, dass es nicht das ist, was Sie erwartet haben, also müssen Sie mountPath: /app/settings.json angeben, nur so wird der ursprüngliche Inhalt in den Ordnern /app nicht beeinflusst.
  3. Nun, wenn Sie den zweiten Schritt machen, erinnern Sie sich daran, dass configmap eigentlich eine Liste von Schlüssel-Wert-Paaren ist, Sie brauchen nur einen der Schlüssel (obwohl Sie tatsächlich auch nur einen haben), also müssen Sie den Volume-Mounts mitteilen Verwenden Sie einen Unterpfad von Ihrer configmap.

Dies ist etwas, das Sie schließlich erhalten:

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

Alle 10 Kommentare

@pmcgrath

Kasse hier .

anscheinend verstehe ich dein Problem. Ich habe die gleiche Frage schon einmal, aber es gibt tatsächlich eine Antwort in Ihrer Situation.

Um Ihren Fall zu beschreiben, haben Sie eine configmap ( settings.json: blahblah ) und möchten sie in einen Ordner /app mounten. Dann ist unten, was Sie wissen müssen:

  1. Sobald Sie ein Volume mounten (egal, ob es sich um configmap oder andere handelt), überschreibt es mountPath , so dass in Ihrem Fall der Ordner /app nur settings.json .
  2. Ich weiß, dass es nicht das ist, was Sie erwartet haben, also müssen Sie mountPath: /app/settings.json angeben, nur so wird der ursprüngliche Inhalt in den Ordnern /app nicht beeinflusst.
  3. Nun, wenn Sie den zweiten Schritt machen, erinnern Sie sich daran, dass configmap eigentlich eine Liste von Schlüssel-Wert-Paaren ist, Sie brauchen nur einen der Schlüssel (obwohl Sie tatsächlich auch nur einen haben), also müssen Sie den Volume-Mounts mitteilen Verwenden Sie einen Unterpfad von Ihrer configmap.

Dies ist etwas, das Sie schließlich erhalten:

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

@zhouhaibing089
Danke für die Antwort, funktioniert nach deinem Vorschlag, ich freue mich über die Erklärung

Gerne schließe ich dieses Thema
Klopfen

Als Referenz scheint die ursprüngliche Erwähnung dieser Lösung hier zu sein: https://github.com/kubernetes/kubernetes/issues/23748#issuecomment -230390309

Es sieht so aus, als ob die Dokumentation dafür fehlt, was diesen Fall ziemlich verwirrend / irreführend macht, und die Projektionsdokumentation scheint es auch irreführender zu machen - nicht sicher, ob sie fehlt, da automatische Updates anscheinend nicht gemäß diesem Problem funktionieren

Die Anforderung, dass der Dateiname sowohl unter mountPath als auch unter subPath ist nicht intuitiv.

Die von @zhouhaibing089 bereitgestellte Lösung funktioniert, aber der Inhalt der gemounteten Datei unter subPath wird nicht aktualisiert, wenn wir ihn in der ähnlichen ConfigMap bearbeiten.

IMO, das ist nicht _wirklich_ gelöst. Es sollte eine Option zum Anhängen jedes Schlüssels geben, anstatt ihn zu überschreiben.

Etwas wie:

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

So dass...

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

... behält das vorhandene default.conf und alle anderen Artefakte des Docker-Images bei, erweitert aber um example*.conf

Dieselben Informationen in subPath zu wiederholen ist nur _icky_.

+1 für die Option append: true von @leebenson .

Laut @leebenson Antwort: Kann jemand erklären, woher die Option append: true ?

Bei mir funktioniert es nicht, ich habe:

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

Außerdem ist es in den API-Dokumenten für die Volume-Bereitstellung nicht vorhanden:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

Laut @leebenson Antwort: Kann jemand erklären, woher die Option append: true ?

Bei mir funktioniert es nicht, ich habe:

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

Außerdem ist es in den API-Dokumenten für die Volume-Bereitstellung nicht vorhanden:
https://k8smeetup.github.io/docs/api-reference/v1.9/#volumemount -v1-core

es existiert nicht, es ist ein Vorschlag. eine gute für den anwendungsfall.

Ich habe versucht, diese Methode zu verwenden, aber ich habe einen schreibgeschützten Dateisystemfehler erhalten, als ich das Statefulset angewendet habe. Weiß jemand, wie man das beheben kann?
(Ich überschreibe eine vorhandene Datei, die Einstellungen für Elasticsearch enthält, aktuelle Fehlermeldung --> /usr/share/elasticsearch/bin/run.sh: line 28: ./config/elasticsearch.yml: Read-only file system )

War diese Seite hilfreich?
0 / 5 - 0 Bewertungen