web-dev-qa-db-fra.com

Chaque image Docker doit-elle contenir un JDK?

Je suis donc très nouveau dans Docker. Permettez-moi d'expliquer le contexte de la question.

  1. J'ai 10 à 20 applications de micro-service Spring Boot, chacune fonctionnant sur des ports différents sur ma machine locale.

  2. Mais pour migrer vers Docker, sur la base de mon apprentissage, chacun des services doit être dans un conteneur Docker différent afin de déployer rapidement ou de faire des copies.

  3. Pour chaque conteneur Docker, nous devons créer une nouvelle image Docker.

  4. Chaque image Docker doit contenir un JRE pour que l'application Spring Boot s'exécute. Il est d'environ 200 Mo maximum. Cela signifie que chaque image de docker est, disons, 350 Mo au maximum. D'un autre côté, sur mon PC local, je n'ai qu'un seul JRE de 200 Mo et chaque application ne prend que quelques Mo d'espace.

  5. Sur cette base, j'aurais besoin de 600 Mo sur mon système local, mais j'aurais besoin de 7 Go pour toutes les images Docker.

Cette approche est-elle correcte? Faut-il ajouter "OpenJDK" de DockerHub à chaque image?

Pourquoi la taille de l'image est-elle grande même si le PC cible peut déjà avoir le JDK?

18
SamwellTarly

Votre compréhension n'est pas correcte.

Les images Docker sont formées de couches; voir le diagramme suivant:

Lorsque vous installez un JRE dans votre image, supposons que sa somme de contrôle soit 91e54dfb1179 dans l'image suivante, il occupera vraiment votre disque.

Mais, si tous vos conteneurs sont tous basés sur la même image et ajoutent des choses différentes, dit votre application de microservice différente à la couche mince R/W, tous les conteneurs partageront le 91e54dfb1179, ce ne sera donc pas la relation n * m.

Vous devez faire attention à utiliser la même image de base pour toutes les applications Java autant que possible, et ajouter des éléments différents à la couche mince R/W.

Enter image description here

27
atline

Les autres réponses couvrent assez bien la superposition de Docker, donc je veux juste ajouter des détails pour vos questions

Cette approche est-elle correcte? Faut-il ajouter "OpenJDK" de DockerHub à chaque image?

Oui. S'il n'est pas dans l'image, il ne sera pas dans le conteneur. Vous pouvez cependant économiser de l'espace disque en réutilisant autant de couches que possible. Essayez donc d'écrire votre Dockerfile de "Le moins susceptible de changer" à "Le plus susceptible de changer". Ainsi, lorsque vous créez votre image, plus vous voyez souvent "Utilisation du cache", mieux c'est.

Pourquoi la taille de l'image est-elle grande même si le PC cible peut déjà avoir le JDK?

Docker veut aussi peu que possible faire avec l'hôte. Docker ne veut même pas traiter avec l'hôte. La première chose qu'il fait est de créer un VM pour se cacher. Les images Docker supposent que la seule chose que l'hôte donnera est un ram, un disque et des CPU vides. Donc, chaque image Docker doit également contenir la sienne OS/noyau. (C'est ce que fait votre FROM initial, choisir une image de système d'exploitation de base à utiliser) Donc, votre taille d'image finale est en fait OS + tools + app. La taille de l'image est un peu trompeuse cependant, car c'est la somme de tous couches, qui sont réutilisées à travers les images.

(Implicite) Chaque application/micro-service doit-il être dans son propre conteneur?

Idéalement, oui. En convertissant votre application en un module isolé, il est plus facile de remplacer/équilibrer la charge de ce module.

En pratique, peut-être pas (pour vous). Spring Boot n'est pas un framework léger. En fait, c'est un cadre pour module-izing votre code (Exécution efficace d'un système de contrôle de module à l'intérieur d'un système de contrôle de module). Et maintenant, vous voulez en héberger 10 à 20? Cela ne fonctionnera probablement pas sur un seul serveur. Docker forcera Spring Boot à se charger en mémoire par application; et les objets ne peuvent pas être réutilisés à travers les modules maintenant, ils doivent donc être multi-instanciés aussi! Et si vous êtes limité à 1 serveur de production, la mise à l'échelle horizontale n'est pas une option. (Vous aurez besoin d'environ 1 Go de HEAP (RAM) par Spring Boot, le kilométrage est très basé sur votre base de code). Et avec 10-20 applications, la refactorisation pour rendre l'application plus légère pour le déploiement de Docker peut ne pas être réalisable/dans le budget. Sans oublier que si vous ne pouvez pas exécuter localement une configuration minimale pour les tests (RAM insuffisante), les efforts de développement seront beaucoup plus "amusants".

Docker n'est pas un marteau en or. Essayez-le, évaluez vous-même les avantages et les inconvénients et décidez si les avantages en valent la peine pour vous et votre équipe.

4
Tezra

réponse de Lagom est super, mais je voudrais ajouter que la taille des conteneurs Docker devrait être aussi petite que raisonnablement possible pour faciliter le transfert et le stockage.

Par conséquent, il existe de nombreux conteneurs basés sur la distribution Alpine Linux , qui sont vraiment petits. Essayez de les utiliser si possible.

De plus, n'ajoutez pas tous les outils imaginables à votre conteneur, par ex. vous pouvez souvent vous passer de wget ...

2
Christian Sauer