2015-05-29 10 views
33

Sto cercando un modello che permetta di condividere i volumi tra due contenitori in esecuzione sullo stesso pod in Kubernetes.Come imitare "--volumes-from" in Kubernetes

Il mio caso d'uso è: Ho un'applicazione Ruby on Rails in esecuzione all'interno di un container. L'immagine della finestra mobile contiene risorse statiche nella directory /app/<app-name>/public e ho bisogno di accedere a tali risorse dal contenitore nginx che si trova a fianco nello stesso contenitore.

In 'vanilla' finestra mobile avrei usato --volumes-from bandiera a condividere questa directory:

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

Dopo aver letto questo documento: https://github.com/GoogleCloudPlatform/kubernetes/blob/master/docs/volumes.md Ho provato questo (solo le voci rilevanti presentate):

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 

Ma:

  • Anche se /tmp/assets sul nodo esiste, è vuota
  • /app/<app-name>/public all'interno del contenitore app è anche vuoto

Per aggirare il problema sarò cerco di popolare la directory condivisa quando il contenitore applicazione è alto (semplicemente cp /app/<app-name>/public/* alla directory condivisa), ma non mi piace davvero questa idea.

Domanda: come per imitare --volumes-from in kubernetes, o se non v'è alcuna controparte, Come posso condividere i file da un contenitore ad un altro in esecuzione nello stesso 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"} 

risposta

28

[update-2016-8] In ultima release kubernetes, è possibile utilizzare una caratteristica molto piacevole di nome init-container per sostituire la parte postStart nella mia risposta qui sotto, che farà in modo che il ordine del contenitore.

enter image description here

NOTA: initContainer è ancora una caratteristica beta così la versione di questo lavoro YAML è in realtà come: http://kubernetes.io/docs/user-guide/production-pods/#handling-initialization, si prega di notare la parte pod.beta.kubernetes.io/init-containers.

--- risposta originale cominciare ---

In realtà, è possibile. È necessario utilizzare il gestore del ciclo di vita del contenitore per controllare quali file/dir si desidera condividere con altri contenitori. Come:

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

prego il mio succo per maggiori dettagli:

https://gist.github.com/resouer/378bcdaef1d9601ed6aa

E, naturalmente, è possibile utilizzare emptyDir. Pertanto, il contenitore war può condividere il suo /sample.war nel contenitore peer senza la directory di app/peer di mess.

Se possiamo tollerare/app stato sovrascritto, sarà molto più semplice:

--- 
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: {} 
+0

La risposta di @aronchick è stata preziosa, ma la risposta è la migliore per il mio caso d'uso, quindi accetto, grazie. – cthulhu

+0

Qui vedo alcuni problemi: 1. Cosa succede quando due pod funzionano sullo stesso nodo? 2. Che cosa accadrà in un aggiornamento continuo? Quando due diverse versioni di pod vengono eseguite sullo stesso nodo, si sovrascrivono reciprocamente. – Alex

+1

@Alex Io uso solo hostDir, ad esempio, puoi usare emptyDIr, quindi non ci sarà alcun problema di sovrascrittura. Guarda il mio succo che ho postato. – harryz

9

La risposta è - per ora - non si può. Ecco un paio di thread di discussione dalle questioni kubernetes:

Tuttavia, mi permetto di suggerire che si dispone di un disegno alternativo che potrebbe funzionare meglio?

  1. Se le risorse sono bloccate nel punto del contenitore di andare in diretta, si potrebbe usare qualcosa come gitRepo del volume che copiarlo in una emptyDir al punto di andare in diretta, e significherebbe che non farebbe devi spostare il contenuto intorno a tutto, basta scaricarlo direttamente nella directory condivisa.
  2. Se le risorse sono bloccate nel punto di costruzione del contenitore , è probabilmente meglio copiarle in quel punto, utilizzando il comando COPIATRICE.
  3. Se si desidera attenersi al modo in cui lo si fa, è necessario copiare il contenuto nel volume emptyDir, progettato esattamente per quello che si sta cercando (meno la mancanza di doverlo copiare in).

Anche i volumi NFS [1] possono risolvere il problema, ma possono essere eccessivamente complessi.

Inoltre, consiglierei che questi due servizi esistano in diversi pod, quindi è possibile ridimensionarli separatamente. È possibile creare un endpoint del servizio per comunicare tra loro se necessario.

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

1

Ulteriori aggiornamento dal futuro:

V'è ora un plugin FlexVol per i volumi Docker: https://github.com/dims/docker-flexvol

Al momento della scrittura, FlexVol è ancora una caratteristica alfa, tuttavia, quindi caveat emptor.