Cannot connect to RDS from inside a docker container, I can from the host, and I can from a local docker container - amazon-web-services

I have an ec2 instance with docker compose installed, running a single container. I have the same setup replicated locally on my machine.
using nc -v **host** 5432 results in:
From my machine > success
From inside a docker container running on my machine > success
From inside the ec2 instance > success
From inside a docker container running on the ec2 > Host is unreachable
I'm guessing there's something I'm missing in the ec2's docker config if anyone can point me in the right direction.
This is the docker_boot.service file
Description=docker boot
After=docker.service
[Service]
Type=oneshot
RemainAfterExit=yes
WorkingDirectory=/home/ubuntu/metabase
ExecStart=sudo /usr/bin/docker-compose -f /home/ubuntu/metabase/docker-compose.yml up -d --remove-orphans
[Install]
WantedBy=multi-user.target

The reason behind this is your Docker container is trying to resolve your RDS DNS using public DNS rather than private one.
For a quick workaround, I think you can nslookup your RDS DNS and take 1 of its IPv4 addresses. Then, use that single IPv4 as your host.
nslookup <ID>.rds.amazonaws.com
For a clean workaround, you need to adjust your Docker container DNS configuration into your VPC internal DNS IPv4 address. Using --dns, you can quickly adjust this and you can add more DNS if your application is trying to reach other services as well.
docker run --name app --dns=169.254.169.253 -p 80:5000 -d app
References:
https://docs.docker.com/config/containers/container-networking/
https://docs.aws.amazon.com/vpc/latest/userguide/vpc-dns.html

Related

I cannot reach from a browser to ec2 instance in AWS

I wrote a very simple spring-boot application and packed it in Docker.
The content of docker file is:
FROM openjdk:13
ADD target/HelloWorld-1.0-SNAPSHOT.jar HelloWorld.jar
EXPOSE 8085
ENTRYPOINT ["java", "-jar", "HelloWorld.jar"]
I pushed it to docker hub.
I created a new EC2 instance on aws. Then I connected to it and typed the following commands:
sudo yum update -y
sudo yum install docker -y
sudo service docker start
sudo docker run -p 80:8085 ****/docker-hello-world
The last command gave many messages on the screen that said that spring-boot application is running.
Looks great. However, when I opened my browser and typed: "http://ec2-54-86-87-68.compute-1.amazonaws.com/" (public DNS of EC2 machine).
I got "This site can’t be reached".
Do you know what I did wrong?
Edit: security groups that regard this machine are "default" and the following group that I defined:
Inside the EC2 machine, I typed:"curl localhost:8085" and got:
"curl: (52) Empty reply from server"
Ensure that your port's inbound traffic is enabled for your local IP address in your ec2 instance security group configuration
https://docs.aws.amazon.com/AWSEC2/latest/UserGuide/ec2-security-groups.html#adding-security-group-rule
Have you allowed inbound traffic for port 8085 in your security group configuration? That should be the first thing to check.
I found the solution.
It was port issues.
Instead of running
sudo docker run -p 80:8085 ****/docker-hello-world
I had to run:
sudo docker run -p 8085:8080 ****/docker-hello-world
This command says: "take the application that runs on port 8080 in the application and put it on port 8085 on docker".
I opened the browser and browsed to: "http://ec2-18-207-188-57.compute-1.amazonaws.com:8085/hello" and got the response I expected.

ssh to docker container hosted on EC2

I want to run a docker container on EC2 and also I need to ssh into the container for debugging purposes. I have 2 ports open for ssh 22 and 8022 on my EC2 instance(security group applied). The problem is when I want to bind 22 port of my docker container to port 8022 then it tells address already in use. And the address is used by sshd program. If I kill the process then I cant ssh to the instance from my localhost. How can I overcome this deadlock?
As mentioned in the comments, you don't need to start ssh inside the container in order to go inside the container. You can use the docker exec command to go inside the container after you ssh into the EC2 instance by running:
docker exec -it <container-name> bash
If you still want to ssh into the container directly, then you need to do the following:
Start the container and map port 22 inside to a free port outside;
docker run -p 2222:22 ...
After starting the container, exec into it and install ssh if not yet installed, and start the ssh service using something like systemctl start sshd
ssh into the container, by using the ec2 instance IP and the mapped port
ssh <container-user>#<ec2-instance-ip> -p 2222
This will connect to the ec2 instance and redirect you into the container due to the port mapping.

One App -> Run Multiple Docker Instances on Single Ec2

I have an application , say an api , running as docker container on ec2.
As this container has dependency on the ec2 host ( port mapping) , i am unable to run more than one instance in a same machine.
I want to achieve a state where i have 5 hosts which are fronted with an elb and i should be able to run more than 1 instance of the container in all these hosts.
I am aware that i can achieve this state using ECS.
Can i do this with Ec2 , ELB and Docker?
-Thanks
There are multiple ways to do it
Use different port for each docker container
docker run -d -p 81:80 yourimage
docker run -d -p 82:80 yourimage
docker run -d -p 83:80 yourimage
docker run -d -p 84:80 yourimage
docker run -d -p 85:80 yourimage
And then you can put a nginx load balancer on port 80. See more details on http://nginx.org/en/docs/http/load_balancing.html
You need to use a config like below
http {
upstream myapp1 {
server 127.0.0.1:81;
server 127.0.0.1:82;
server 127.0.0.1:83;
server 127.0.0.1:84;
server 127.0.0.1:85;
}
server {
listen 80;
location / {
proxy_pass http://myapp1;
}
}
}
Use single node docker swarm manager
You can setup a single node docker swarm using below command
docker swarm init
And then on that machine run the below command
docker service create --name=myapp --replicase=5 -p 80:80 yourimage
This will create 5 load balanced container and publish them on port 80.
No ELB needed in both cases. And I doubt ELB works on same host + multi port scenario

How to Access AWS EC2 docker tomcat instance running inside jenkins docker instance from my local browser

I have a jenkins instance running inside a docker container that's listening on port 8181.
Example URL of the jenkins instance:
http://ec2-34-155-164-97.us-west-2.compute.amazonaws.com/
I have a tomcat docker instance that's listening on port 8383 running inside the jenkins docker container.
I can access jenkins instance from my local browser. Is there any possible way that I can access my docker tomcat instance from my local browser?
Here is my docker run command:
docker run -d -v /var/run/docker.sock:/var/run/docker.sock \ -v $(which docker):/usr/bin/docker -p 8181:8080 jenkins-dsl
Please provide your suggestions.
It sounds like your docker run command simply needs to expose the port that your nested tomcat server is running on.
To do this, you need to pass in -p argument into your command. The -p argument is for binding a host port to the docker container's port:
-p <host_port>:<container_port>
You can pass in as many -p arguments as you want to bind multiple ports.
So if the docker tomcat server is running on port 8383 within the Jenkins docker container, then you can do something like this:
-p 8383:8080
Full command example:
docker run -d -it -p 8383:8080 --name tomcatServer docker-tomcat
I would assume that this would allow you to access tomcat server using the example URL provided like so:
http://ec2-34-155-164-97.us-west-2.compute.amazonaws.com:8383
However, you'd have to ensure your AWS Security Group will allow traffic to port 8383.
EDIT: Updated answer to reflect the resolution we discussed in the comments.
Edited
I could able to launch tomcat by specifying the port in the URL and opening the port in EC2 instance.
http://ec2-34-155-164-97.us-west-2.compute.amazonaws.com:8383
Latest Docker installation guide for Tomcat clearly says you will get this error when you launch it for the first time
You can then go to http://localhost:8888 or http://host-ip:8888 in a browser (noting that it will return a 404 since there are no webapps loaded by default).
its because you do not have any apps in the default webapps folder of Tomcat. your latest Tomcat docker image has the default apps in the "webapps.dist" folder, you have to copy it to "webapps" folder. Do the Following commands
# docker exec -it tomcat-container /bin/bash
# cd webapps.dist
# cp -R * ../webapps
"tomcat-container" is your container name.
now refresh your browser you will get it. if not let me know

Docker Container/AWS EC2 Public DNS Refusing to Connect

I am unable to connect to my EC2 instance via its public dns on a browser, even though for security groups "default and "launch-wizard-1" port 80 is open for inbound and outbound traffic.
It may be important I note that I have a docker image that is running in the instance, one I launched with:
docker run -d -p 80:80 elasticsearch
I'm under the impression this forwards port 80 of the container to port 80 of the EC2 instance, correct?
The problem was that elasticsearch serves http over port 9200.
So the correct command was:
docker run -d -p 80:9200 elasticsearch
The command was run under root.