J'ai un fichier de guerre déployé en tant que conteneur Docker
sur linux ec2
. Mais quand j'essaye de frapper le http: // ec2-elastic-ip: 8080 / AppName
, je n'obtiens aucune réponse.
J'ai tout le groupe de sécurité code> règles entrantes configurées pour
http
et https
. Ce n'est donc pas un problème.
Débogage
J'ai essayé de déboguer par ssh-ing
l'instance Linux. Commande essayée curl localhost: 8080
, voici la réponse:
Docker machine "default" does not exist. Use "docker-machine ls" to list machines. Use "docker-machine create" to add a new one.
Essayé avec 127.0.0.1:8080
mais le même réponse.
La prochaine chose que j'ai faite a été de lister le conteneur Docker: docker ps
. J'obtiens:
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES <ID> <ecr>.amazonaws.com/<my>-registry:2019-05-16.12-17-02 "catalina.sh run" 24 minutes ago Up 24 minutes 0.0.0.0:32772->8080/tcp ecs-app-24-name
Maintenant, je me suis connecté à ce conteneur en utilisant docker exec -it
et j'ai essayé de vérifier les journaux tomcat qui montre clairement que ma guerre d'application est là et que tomcat a commencé.
J'ai déjà essayé de vérifier le docker-machine ip default
mais cela m'a donné une erreur:
curl: (7) Failed to connect to localhost port 8080: Connection refused
Je suis maintenant bloqué. Impossible de déboguer davantage. Le résultat que j'attends est d'accéder à l'application via l'URL ci-dessus.
Que faire? Est-ce que quelque chose ne va pas?
De plus, pour mentionner que toute l'infrastructure est gérée via terraform
. Je crée d'abord l'image de base, je copie la guerre dans les applications Web en utilisant DockerFile
, je pousse l'image de registre et enfin je fais une terraform apply
pour appliquer les modifications.
3 Réponses :
Assurez-vous qu'apache écoute sur toutes les adresses IP à l'intérieur du conteneur docker, pas seulement sur localhost. L'adresse IP doit être comme 0.0.0.0.
Si un service s'exécute dans docker et n'écoute que localhost, il ne peut être consulté que dans ce conteneur, pas depuis l'hôte.
Vous pouvez également essayez de démarrer apache avec le port 8080 et de lier le port docker 8080 avec le port hôte 8080
docker run apache -p 8080:8080
Comment pouvons-nous nous en assurer? Et dois-je le faire à chaque fois que je fais le déploiement?
Pouvez-vous spécifier quelle image Apache vous utilisez?
C'est un serveur Web. Matou.
docker exécuter -it --rm -p 8080: 8080 tomcat: 8.0
Actuellement, votre application fonctionne sur un port hôte aléatoire, c'est-à-dire 32772
, consultez la sortie docker ps
. Vous devez pouvoir accéder à votre application sur http: // ec2-ip: 32772
une fois que vous autorisez le port 32772
dans les groupes de sécurité.
Pour le faire fonctionner sur le port hôte 8080, vous devez lier / exposer le port hôte pendant l'exécution du docker -
$ docker run -p 8080: 8080 ......
Si vous êtes sur ECS, vous devriez idéalement utiliser un ALB & TG avec votre service.
Cependant, si vous n'utilisez pas ALB etc, vous pouvez essayer de donner un hostPort statique dans TD "hostPort": 8080
(je n'ai pas essayé cela). Si cela fonctionne correctement, vous devrez vous assurer de modifier la stratégie de déploiement en "pourcentage sain minimum = 0", sinon vous risquez de rencontrer des problèmes de conflit de port.
Dois-je le faire à chaque fois que je déploie?
oui, chaque fois que vous exécutez un nouveau conteneur. Pour faciliter les choses, vous pouvez utiliser docker compose
à l'avenir. Vous pouvez créer un alias pour ces commandes.
Je spécifie le port 8080
sur ma définition de tâche ecs dans terrafor infra. Cela ne devrait-il pas supposer que cela prenne cela à chaque fois?
C'est une question distincte. Vous pouvez utiliser des groupes cibles et définir le port d'hôte 0
pour vous assurer que votre ALB redirige vers le bon ensemble d'hôte: port. Vous définissez l'ALB dans la définition de service qui inturn prend en charge l'allocation de port sur l'hôte, etc.
C'est le but. Je n'utilise pas ALB. Spécification d'une adresse IP publique à ec2. Et le mappage de port est: "portMappings": [{"hostport": 0, "containerport": 8080}]
Il vous suffit de définir le port du conteneur lors de la création d'un service via terraform et d'utiliser le port hôte comme 0
dans la définition de la tâche.
Essayez de donner un hostPort statique dans TD "hostPort": 8080
. Je n'ai pas essayé ça. Si cela fonctionne correctement, vous devrez vous assurer que lors du déploiement, vous définissez la stratégie «pourcentage sain minimum = 0», sinon vous risquez de rencontrer des problèmes de conflit de port.
Quelle était l'erreur? Cependant, il semble que l'utilisation d'un ALB en face soit le meilleur pari pour le moment.
Je n'ai pas beaucoup de trafic, donc évitez ALB pour un coût supplémentaire. L'erreur est la même.
Si l'application a besoin d'un port réseau, vous devez EXPOSER celui-ci dans le fichier docker.
version: '1' services: web: build: ports: - "8080:8080" my_app: image: my_app
Au cas où vous auriez besoin que ce port soit mappé à un port spécifique sur le réseau, vous devez définir cela lorsque vous lancez le nouveau conteneur.
ports: - "8080:8080/tcp"
Si vous utilisez exécuter chaque image séparément, vous devez lier le port à chaque fois. Si vous ne voulez pas faire cela à chaque fois, vous pouvez utiliser docker-compose et y ajouter la directive ports.
docker run -p 8080:8080/tcp my_app
En supposant que vous ayez ajouté exposer dans le fichier docker, le fichier complet docker-compose.yml ressemblerait à ceci:
EXPOSE <port> [<port>/<protocol>...]
Ce n'est pas tout à fait exact. Vous n'avez pas à inclure une instruction EXPOSE
- vous devez l'ajouter pour la documentation.
l'application déployée à l'intérieur du conteneur est-elle supposée s'exécuter sur le port 32772? sinon, vous devez
EXPOSER
le port sur lequel l'application s'exécute dans le Dockerfile. Ensuite, lors de l'exécution de docker ou de docker-compose up, mappez le port-p 8080
Il devrait supposer fonctionner sur 8080. C'est ce que j'avais spécifié dans mes définitions de tâches du module
ecs
."portMappings": [{"hostport": 0, "containerport": 8080}]
alors dans votre Dockerfile, avez-vous
EXPOSE 8080
?Non. Le fichier Docker ajoute simplement, à partir de l'image de registre, un fichier war à `/ usr / local / tomcat / webapps '
alors c'est ce dont vous avez besoin :)
Exposez le port et liez-le également
$ docker run -p 8080: 8080
@workaround Je recherche une solution ponctuelle. Dois-je le lier à chaque fois que je fais un nouveau déploiement?
@roger_that Exécutez-vous votre conteneur en exécutant simplement l'image ou créez-vous un fichier de co-composition?
juste pour que nous soyons clairs à ce sujet. Dockerfile EXPOSE n'est que des métadonnées à des fins d'information - ce n'est pas une liaison en soi. Les hôtes Linux réfléchissent à ces informations sur l'image pour la liaison, mais les orchestrateurs (comme docker compose) doivent spécifier les liaisons et ne pas s'appuyer sur le comportement spécifique de cet hôte.