Stack of VM reverse traversal: reaching host port from a Docker container within a Vagrant machine - docker

We are implementing a CI infrastructure as Docker containers.
Development of the solution takes place on OS X machines:
The OS X physical machine (Host) has Vagrant installed on it, plus a service listening on localhost:2200.
On Host, we vagrant up a Linux machine (VM-a) on which we provision Docker.
On VM-a, we docker run a Linux container (VM-b). VM-b needs to interact with the service running on Host.
By way of well-documented port binding, we are able to reach any listening port on both VM-a and VM-b from the Host.
Yet, we cannot identify a way to have VM-b reach Host port 2200 on Host's localhost interface.
Is it possible to achieve such communication?
If so, how?

So, we found the "magic" interface on which to reach the Host from any VM, i.e. from booth VM-a and VM-b (nested in VM-a).
It is 10.0.2.2.

Related

How to get Docker Desktop to bind on a virtual interface

If I run Docker locally and I bind the containers' ports, I usually connect with them through localhost and not through the dynamically created IP address. I might start a MySQL container, bound with 3306:3306 and can then connect with it to localhost:3306.
If I am using a virtual machine in Windows to run Docker in (e.g. with VirtualBox), the VM has its own interface (e.g. VirtualBox Host-Only Network) which might have an IP address of 192.168.50.1. I can now connect to a MySQL container via 192.168.50.1:3306.
Using a different interface/network for my containers is useful during development because I free up my localhost ports for other things and many browsers treat localhost differently than it does other addresses.
However, Docker Desktop also has advantages over a VM:
Not having to manage the VM
Testcontainers out-of-the-box
Docker Desktop is nice
Should it not be possible to get Docker to bind to ports on a virtual interface instead of localhost, e.g. by creating a Windows virtual switch or even by using the existing VirtualBox network? And is it possible to do this for Docker Desktop (on Windows) for all containers by default?
This answer indicates there's an --ip option available when starting the Docker daemon, but:
Which IP address do I use here? The gateway is the only IP address that I have configured for a virtual switch.
What is the equivalent for Docker Desktop?

What's the host in Docker + Rancher context?

So I see host mentioned a few times in the docs. There's also networking_mode=host you can add in the yml file.
So what I assume the host is, is the machine the VM (Docker) is run on?
So if I set networking mode to host, the port mapping etc will be handled on my local machine. Where in the yml i could do 3001:3000 that'll map port 3001 to the container port of 3000. With networking mode host that mapping will be handled on my local machine.
Now, when we're hosting containers on rancher. And we set the networking_mode=host. What's host in that context? Is it the VM or ec2 or whatever that is running my rancher? Or the VM/ec2 that's running my host stack?
I can't grasp it from the docs.
A container runs on a single server, a.k.a host, running Docker.
Host can be either be a bare metal server, Virtual machine running on your laptop or an EC2 instance.
Rancher itself is a container running on a host. Now when you build a cluster, you can add the host that's running the Rancher container or you can choose to keep things isolated and start adding totally different hosts.
If you choose networking_mode=host, the container is using the host networking stack and if you don't the container gets it's own networking stack. When running in host networking mode, the application running inside the container binds directly to the host network interfaces, so there is no port mapping happening.
In case you are interested in more details, I have discussed a lot about networking in the first half of this talk: https://www.youtube.com/watch?v=GXq3FS8M_kw. Let me know if you have more questions.

Run docker container on localhost via VM

I'm new to Docker and Containers, and I'm trying to run a simple asp.net web app in a container but running into issues. My OS is Windows 10 Home, so I have to use the Docker Toolbox, which runs on a VM that only includes a basic Linux OS. When I spin up the container, it seems to start fine, but I can't view the app on the localhost.
$ docker run -p 8342:5000 -it jwarren:project
Hosting environment: Production
Content root path: /app
Now listening on: http://*:5000
Application started. Press Ctrl+C to shut down.
$ docker ps -a
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
98cc4aed7586 jwarren:project "dotnet run" 8 minutes ago Up 8 minutes 0.0.0.0:8342->5000/tcp naughty_brattain
I've tried several different recommendations that I found on the web, but none have helped so far. However, my knowledge of networking is very limited, so maybe I'm not fully understanding what needs to be done. I've tried accessing it with the default VM machine IP and the container IP. I understand that the port forwarding does not carry over to the container. Any assistance would be great, as this project is due on Tuesday, and this is the last road block before finishing.
I found the following post that was really helpful: How to connect to a docker container from outside the host (same network) [Windows]. Following the steps below worked perfectly:
Open Oracle VM VirtualBox Manager
Select the VM used by Docker
Click Settings -> Network Adapter 1 should (default?) be "Attached
to:NAT"
Click Advanced -> Port Forwarding Add rule: Protocol TCP, Host Port
8080, Guest Port 8080 (leave Host IP and Guest IP empty)
You should now be able to browse to your container via localhost:8080 and your-internal-ip:8080.
Started up the container (Dockerfile EXPOSES 5000):
docker run -p 8080:5000 -it jwarren:project
Was able to connect with http://localhost:8080
There are few things to consider when working with a VM networking.
Virtual Box has 3 types of networking options NAT, Bridged and Host Only.
NAT would allow your VM to access internet through your internet. But won't allow your HOST machine to access the VM
Host Only network will create a network where the VM can reach the host machine and the Host can reach the VM. No internet using this network
Bridged network will allow your VM to assign another IP from your Wifi router or the main network. This IP will allow VM to have net access as well as access to other machines on the network. This will allow even the host machine to reach the IP
Now in most cases when you want to run Docker inside a VM and access that VM using the host machine you want the VM to have both NAT and Host only bridges
Now accessing your app on port 8342 needs few things checked
seliunx, firewalld, ufw are disabled on your VM (or properly configured to allow the port)
Your VM has a host only network or bridged network
iptables -S should not show REJECT rules
Some VMs come pre-configure to only allow port 22 from external network. So you should try access the app on <hostonlyip>:8342 or <bridgedip>:8342.
If you want to test if the app is up or not you can do the following
docker inspect <containerid> | grep IPA
Get the IP from this and run the command
curl http://<containerip>:5000/
This command needs to be execute inside the VM and not on your machine. If this command doesn't work then your container is not listening on 5000. Sometimes app listen to only 127.0.0.1 inside the container. This means they will work only inside the container and not outside. The app inside the container needs to listen to 0.0.0.0
If nothing works you can try an ssh tunnel approach
ssh -L 8342:127.0.0.1:8342 user#<VMIP>
And then you should be able to access the app on localhost:8342

How do I give an own ip address to docker for Windows container?

I want to export the complete ip connectivity (UDP and TCP) from a docker container with a Linux app (ie give it's own ip address (in the same subnet as the host), that can be accessed from the host and from other physical machines on the network).
What do I need to configure in Windows, what in docker, what inside the container?
(NB: I don NOT want to expose ports as part of the host).
I finally solved the problem (for me) by installing Ubuntu in Virtual Box and using the docker containers from there. Not the most elegant solution but working on first try.

Allow a container running via docker-machine to connect with Mysql or XDEBUG port on parent OSX system without using an OSX DHCP assigned ip address?

I've got the following setup:
OSX running MySQL listening on all network adaptors at port 3306
XDEBUG enabled IDE listening on port 9000 on the base OSX system.
docker-machine host running on the OSX system with the host ip 192.168.99.100
A debian based docker container with a mysql client running on the docker host and HHVM running with xdebug looking to connect to some lucky remote host on port 9000.
The ip addresses change frequently on the OSX system due to being assigned via DHCP, so I want the docker container to be able to somehow be able to hit the mysql server regardless of what IP the native OSX network adaptors get assigned (without manually updating it). Also, I need a stable ip I can provide my HHVM server.ini file a remotes host for Xdebug.
With running a base system of linux this isn't an issue as the docker host and the actual native machine running docker are one-and-the-same. Also, there are several ways for a container to learn of the host's ip so the issue isn't hitting the docker host.
However, in OSX running docker-machine, the host ain't the native OSX system, but instead is a VM running in virtual box (assuming you're using the vb driver, and who the sam hill blazes isn't?).
The only thing I could think of was to port forward request on 3306 to the docker-machine host (192.168.99.100 which never changes) to the OSX's port 3306. Then have the container hit the docker-machine host for Mysql requests. IF this works, I could rinse and repeat for any port I port I need to link like xdebug on port 9000.
Does anyone know how to accomplish this or have another suggestion?
Figured a way out without needing to make any changes that provides a consistent ip to connect to on the base OSX system. Docker machine sets things up in such a way to make this possible.
Docker machine creates a virtualbox VM with 2 network adaptors, one set up as host-only, the other set as NAT. Don't know why it creates 2, but
The host-only adaptor provides the OSX an ip of 192.168.99.1 and the various VM's using it get addresses starting with 192.168.99.100. However, inside the VM network, you can't use the address 192.168.99.1 to hit ports on the parent OSX system (not sure why, but guessing host only intends to be only communication between the VMs).
The NAT network adaptor is set so the OSX get's the ip 10.0.2.2 and the VM get's 10.0.2.15. With a NAT, you can route to the OSX system at 10.0.2.2 from both the docker host VM and containers running on the host.
Since this 10.0.2.2 address for the OSX machine doesn't change (unless you screw with the virtual box networking settings) bingo, got what I need.

Resources