I have a database running in a docker container. It does not publish mariadb's port 3306.
Now I want to remotely log in to the docker host, connect to the container and access the database from my laptop
laptop ---> dockerhost ---> container
in order to access the database with gUI tools like DbVisualizer.
The idea is to open a connection with socat, but I'm stuck. Basically something like:
socat TCP4-LISTEN:3306 EXEC:'ssh dockerhost sudo docker exec container "socat - TCP:localhost:3306"'
The last attempt failed with "Unexpected exception encountered during query." in DbVisualizer and "2019/09/10 12:19:54 socat[17462] E write(6, 0x7f9985803c00, 114): Broken pipe" in the shell.
The command was (broken for readability):
socat TCP4-LISTEN:3306,forever,reuseaddr,fork \
exec:'
ssh dockerhost \
sudo docker exec container "
socat STDIO TCP:localhost:3306,forever,reuseaddr,fork
"
'
I hope someone can pinpoint what I do wrong or tell me how I can achieve my goal.
Delete and restart your container with a docker run -p or Docker Compose ports: option that will make it visible outside of Docker space. (You're storing the actual database data in a volume, right? On restart it will keep using the data from the volume.)
If you're comfortable with the container being accessed directly from off-host, then you can use an ordinary port invocation -p 3306:3306 and then reach it using dockerhost as the host name and the first port number as the port number.
If you still want to require the ssh tunnel, you can cause the port to be bound to the Docker host's localhost interface, and then use ssh port forwarding.
dockerhost$ docker run -p 127.0.0.1:3306:3306 -v ... mysql
laptop$ ssh -L 3306:localhost:3306 dockerhost
laptop$ mysql -h 127.0.0.1
docker exec in many ways is equivalent to ssh root#... and is not the normal way to interact with a network-accessible service.
Related
I have a local MySQL server, that listens to the port 3306 on 127.0.0.1 (not 0.0.0.0!) and though accessible only from my local machine.
I want to run a docker or podman (rootless) container and allow it to connect to my MySQL server.
What I practically trying to do is to pass SSH-Option -L/-R port tunnel option to docker run or podman run, like so
$ docker run ... -L 3306:localhost:3306
or
$ docker run ... -R 3306:localhost:3306
(depending from which point of view you see this tunnel being established)
I tried to use --add-host=host.docker.internal:host-gateway option, but it requires me to make MySQL listen to 0.0.0.0:3306 and I don't want to do it due to security reasons.
My question: How can I create a tunnel between my 127.0.0.1:3306 and to some port within the container?
I want to create a docker container from one machine (suppose having centos) machine and then access that container from another machine(may be centos or mac). How can we do that? Is it possible with macvlan networking? If yes , what are steps? If not, what is the way?
Depends from what is your final goal. Following are some approaches (depending on what you want to achieve as final goal):
Manage container and execute bash in the container on a remote host:
Easiest way is to use the environment variable DOCKER_HOST
export DOCKER_HOST=ssh://vagrant#192.168.5.178
docker exec -ti centos_remote /bin/bash
You can find more information in this answer https://stackoverflow.com/a/51897942/2816703
Use the container as a form of virtual machine on which user can ssh:
First you will need a container that is running the sshd. You will expose the port 22 on another port on the host network. Finally you will use the ssh with -p to connect that port. Here is a working example:
$ sudo docker run -d -P --name test_sshd rastasheep/ubuntu-sshd:14.04
$ sudo docker port test_sshd 22
0.0.0.0:49154
$ ssh root#localhost -p 49154
# The password is `root`
root#test_sshd $
or if you are on a remote machine, use the host IP address xxx.xxx.xxx.xxx, to connect to the container use:
$ ssh root#xxx.xxx.xxx.xxx -p 49154
# The password is `root`
Also you can pre-select a port (in this case port 22000) and test from the host.
~# docker run -d -p 22000:22 --name test_sshd rastasheep/ubuntu-sshd:14.04
~# ssh root#<ipaddress> -p 22000
Setup a network layer (L2/L3) between the hosts:
Using macvlan is one approach. Another approach is the ipvlan. In both cases, you are converting the host network adapter to a virtual router, after which you need to setup the routes. You can find detailed explanation on this link http://networkstatic.net/configuring-macvlan-ipvlan-linux-networking/
I've installed docker in a VM which is publicy available on internet. I've installed mongodb in a docker container in the VM.Mongodb is listening on 27017 port.
I've installed using the following steps
docker run -p 27017:27017 --name da-mongo -v ~/mongo-data:/data/db -d mongo
The port from container is redirected to the host using the -p flag. But the port 27017 is exposed on the internet. I don't want it to happen.
Is there any way to fix it?
Well, if you want it available for certain hosts then you need a firewall. But, if all you need is it working on localhost (your VM machine), then you don't need to expose/bind the port with the host. I suggest you to run the container without the -p option, then, run the following command:
docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' your_container_id_or_name
After that, it will display an IP, it is the IP of the container you've just ran (Yes, docker uses somewhat an internal virtual network connecting your containers and your host machine between them).
After that, you can connect to it using the IP and port combination, something like:
172.17.0.2:27017
When you publish the port, you can select which host interface to publish on:
docker run -p 127.0.0.1:27017:27017 --name da-mongo \
-v ~/mongo-data:/data/db -d mongo
That will publish the container port 27017 to host interface 127.0.0.1 port 27017. You can only add the interface to the host port, the container itself must still bind to 0.0.0.0.
I am trying to do this lab and type in the following command:
sudo docker run -it --name bdu_spark2 -P -p 4040:4040 -p 4041:4041 -p 8080:8080 -p 8081:8081 bigdatauniversity/spark2:latest /etc/bootstrap.sh -bash
But I get the following error. Is there a conflict between port 8080 of docker using it and other software trying to use it? I have restarted docker and made sure no other containers are running. Thanks for all the input.
Error response from daemon: Cannot start container 3c62472fe5f8481e5ee957550078f06106b45fc6bffe25669272e2ea924b5f36: failed to create endpoint bdu_spark2 on network bridge: Error starting userland proxy: listen tcp 0.0.0.0:8080: bind: address already in use
This is usually caused because another container is using 8080 port on your docker host.
You can see your running containers by running: $ sudo docker ps
Either stop the other container, or choose a different host port to map your container's 8080 to.
In my case doing this with MySQL, I didn't realize it was because I already had a native MySQL running on that port.
docker run --name db --detach --env="MYSQL_ROOT_PASSWORD=123" --publish=3306:3306 mysql:latest
I did a netstat --all --numeric --program --inet --timers | grep 3306 and noticed it gave me 1418/mysqld. Then I did a ps aux | grep mysql and noticed that was the same process number started by /usr/sbin/mysqld which was my local MySQL instance on my host, nothing to do with containers.
Double check nothing is using those ports, especially 8080, which is very common for stand alone web servers, like those that ship with IDEs.
If you are using that port, you can use the --publish option to specify the host port to be different but still use the same port on the container. i.e. --publish=8081:8080, hostport:containerport.
Running the following command fails:
sudo docker run -p unix:///tmp/file.sock:44444 -d image_name
Is something wrong with my port forwarding syntax or is a configuration like this not possible?
Docker's -p syntax won't take a unix socket:
-p=[] : Publish a container᾿s port to the host (format:
ip:hostPort:containerPort | ip::containerPort |
hostPort:containerPort)
One solution would be to:
Run your container without any -p specification, we'll name it "cont1" (--name cont1)
Run a second container which:
Bind mounts the unix socket (-v /tmp/file.sock:/tmp/file.sock) to have it accessible from within the container
Links to the first container (--link cont1:cont1) to be able to connect to it
Runs a tool such as socat to route traffic from the unix socket to the "cont1:4444" endpoint
I'm not a socat expert, but the address specification you'll need should look like this: UNIX-LISTEN:/tmp/file.sock,fork,reuseaddr TCP4:cont1:4444
The accepted answer is partially correct however since you can only link directories, which means you need to link the directory of the socket instead of the socket itself.
The following did it for me when I wanted to connect a postgres socket.
docker run -p 5432:5432 -v /run/postgresql:/run/postgresql -d --name postgres postgres
What this does is link the postgres socket file to your host system.