web-dev-qa-db-fra.com

Comment imiter '--volumes-from' dans Kubernetes

Je recherche un modèle permettant de partager des volumes entre deux conteneurs s'exécutant sur le même module dans Kubernetes.

Mon cas d'utilisation est le suivant: J'ai une application Ruby on Rails s'exécutant à l'intérieur d'un conteneur docker . L'image du menu fixe contient des actifs statiques dans le répertoire /app/<app-name>/public et je dois accéder à ces actifs à partir du conteneur nginx qui s'exécute parallèlement au même cosse.

Dans le menu fixe 'Vanilla', j'aurais utilisé l'indicateur --volumes-from pour partager ce répertoire:

docker run --name app -v /app/<app-dir>/public <app-image>
docker run --volumes-from app nginx

Après avoir lu cette documentation: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md J'ai essayé ceci (seules les entrées pertinentes présentées):

spec:
  containers:
    - image: <app-image>
      name: <app-name>
      volumeMounts:
        - mountPath: /app/<app-name>/public
          name: assets
    - image: nginx
      name: nginx
      volumeMounts:
        - mountPath: /var/www/html
          name: assets
          readOnly: true
    volumes:
      - name: assets
        hostPath:
          path: /tmp/assets

Mais:

  • Même si /tmp/assets sur le nœud existe, il est vide
  • /app/<app-name>/public à l'intérieur du conteneur de l'application est également vide

En guise de solution de contournement, je vais essayer de renseigner le répertoire partagé lorsque le conteneur d'applications est activé (simplement cp /app/<app-name>/public/* dans le répertoire partagé), mais je n'aime vraiment pas cette idée.

Question: comment imiter --volumes-from dans Kubernetes, ou s’il n’existe pas de contrepartie directe, comment puis-je partager des fichiers d’un conteneur à l’autre dans le même pod?

apiVersion: v1beta3

Client Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}
Server Version: version.Info{Major:"0", Minor:"17", GitVersion:"v0.17.0", GitCommit:"82f8bdac06ddfacf493a9ed0fedc85f5ea62ebd5", GitTreeState:"clean"}
40
cthulhu

[update-2016-8] Dans la dernière version de Kubernetes, vous pouvez utiliser une fonctionnalité très agréable nommée init-container pour remplacer la partie postStart de ma réponse ci-dessous, qui assurera l'ordre du conteneur.

enter image description here

NOTE: initContainer est toujours une fonctionnalité bêta, de sorte que la version de travail de ce yaml est en réalité: http://kubernetes.io/docs/user-guide/production-pods/ # manipulation-initialisation } _, veuillez noter la partie pod.beta.kubernetes.io/init-containers.

--- réponse originale commence ---

En fait, vous pouvez. Vous devez utiliser un gestionnaire de cycle de vie du conteneur pour contrôler les fichiers/répertoires que vous souhaitez partager avec d'autres conteneurs. Comme:

---
apiVersion: v1
kind: Pod
metadata:
    name: server
spec:
    restartPolicy: OnFailure
    containers:
    - image: resouer/sample:v2
      name: war
      lifecycle:
        postStart:
          exec:
            command:
              - "cp"
              - "/sample.war"
              - "/app"
      volumeMounts:
      - mountPath: /app
        name: hostv1 
    - name: peer
      image: busybox
      command: ["tail", "-f", "/dev/null"]
      volumeMounts:
      - name: hostv2
        mountPath: /app/sample.war
    volumes:
    - name: hostv1
      hostPath:
          path: /tmp
    - name: hostv2
      hostPath:
          path: /tmp/sample.war

S'il vous plaît vérifier mon Gist pour plus de détails:

_ { https://Gist.github.com/resouer/378bcdaef1d9601ed6aa } _

Et bien sûr, vous pouvez utiliser emptyDir. Ainsi, war container peut partager son conteneur /sample.war à peer sans le répertoire/app de mess peer.

Si nous pouvons tolérer que/app soit remplacé, ce sera beaucoup plus simple:

---
apiVersion: v1
kind: Pod
metadata:
  name: javaweb-2
spec:
  restartPolicy: OnFailure
  containers:
  - image: resouer/sample:v2
    name: war
    lifecycle:
      postStart:
        exec:
          command:
            - "cp"
            - "/sample.war"
            - "/app"
    volumeMounts:
    - mountPath: /app
      name: app-volume
  - image: resouer/mytomcat:7.0
    name: Tomcat
    command: ["sh","-c","/root/Apache-Tomcat-7.0.42-v2/bin/start.sh"]
    volumeMounts:
    - mountPath: /root/Apache-Tomcat-7.0.42-v2/webapps
      name: app-volume
    ports:
    - containerPort: 8080
      hostPort: 8001 
  volumes:
  - name: app-volume
    emptyDir: {}
34
harryz

La réponse est - pour l'instant - vous ne pouvez pas. Voici quelques fils de discussion issus des problèmes de Kubernetes:

Cependant, puis-je vous suggérer de choisir un autre modèle qui pourrait mieux fonctionner? 

  1. Si vos actifs sont verrouillés au moment de la mise en production du conteneur, vous pouvez utiliser quelque chose comme gitRepo Volume, qui le copierait dans une emptyDir au moment de la mise en production, ce qui signifierait que vous n’auriez pas à déplacez le contenu dans all, il suffit de le télécharger directement dans le répertoire partagé. 
  2. Si vos ressources sont verrouillées au moment où le conteneur Est créé, il est probablement préférable de les copier à ce moment-là, à l'aide de la commande COPY.
  3. Si vous voulez vraiment vous en tenir à la façon dont vous le faites, vous devez copier le contenu dans le volume emptyDir, qui est conçu pour exactement ce que vous recherchez (moins le besoin de le copier).

Les volumes NFS [1] peuvent également résoudre votre problème, mais peuvent être trop complexes.

De plus, je recommanderais que ces deux services existent dans des modules différents, afin que vous puissiez les faire évoluer séparément. Vous pouvez créer un noeud final de service pour communiquer entre eux si vous en avez besoin.

[1] https://github.com/GoogleCloudPlatform/kubernetes/blob/master/examples/nfs/nfs-web-pod.yaml

9
aronchick

Kubernetes a ses propres types de volume et ceux-ci sont les types de volume les plus utilisés:

  1. emptyDir
  2. secret
  3. gitRepo
  4. hostPath (similaire à --volumes-from)
  5. config Maps
  6. stockage persistant (disques de stockage fournis par les plates-formes cloud)

Vous pouvez trouver plus d'informations sur les volumes kubernets ici - https://kubernetes.io/docs/concepts/storage/volumes/

un exemple de volume hostpath:

apiVersion: v1
kind: Pod
metadata:
  name: test-pd
spec:
  containers:
  - image: k8s.gcr.io/test-webserver
    name: test-container
    volumeMounts:
    - mountPath: /test-pd
      name: test-volume
  volumes:
  - name: test-volume
    hostPath:
      # directory location on Host
      path: /data
      # this field is optional
      type: Directory

hostpath monte le répertoire hôte/nœud dans le répertoire du conteneur. Plusieurs conteneurs d'un pod peuvent utiliser des volumes différents ou identiques.Vous devez le mentionner dans chaque conteneur. pod, vous devriez éviter d'utiliser hostPath.

1
shubham_asati

Nouvelle mise à jour du future:

Il existe maintenant un plug-in FlexVol pour les volumes Docker: https://github.com/dims/docker-flexvol

Au moment de la rédaction de cet article, FlexVol est toujours une fonctionnalité alpha, donc attention.

1
coderanger

Si vous utilisez Docker v17.0.5 ou une version ultérieure, vous pouvez utiliser une génération en plusieurs étapes pour copier des fichiers de l’un de vos conteneurs vers l’autre au cours de la génération. C’est un excellent guide sur les fonctionnalités avancées disponibles à https://medium.com/@tonistiigi/advanced-multi-stage-build-patterns-6f741b852fae

La façon dont je l’ai utilisée pour copier les actifs statiques de mon conteneur principal dans le proxy Nginx est:

ARG API_BACKEND_CONTAINER="api:backend"
FROM $API_BACKEND_CONTAINER as source

FROM nginx:mainline-Alpine

ARG NGINX_ROOT=/usr/share/nginx/html/
COPY --from=source  /var/share/api/static/ ${NGINX_ROOT}

Le grand avantage est que, parce que le API_BACKEND_CONTAINER est un argument de construction, je suis en mesure de transmettre la balise de la dernière version de l'API.

0
Vinay Anantharaman