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:
/tmp/assets
sur le nœud existe, il est vide/app/<app-name>/public
à l'intérieur du conteneur de l'application est également videEn 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"}
[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.
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: {}
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?
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é. 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
Kubernetes a ses propres types de volume et ceux-ci sont les types de volume les plus utilisés:
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.
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.
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.