I have many existing docker containers that are run using network=host parameter (configured at "docker run -D <params>"). I have a requirement to switch to another network type. I would prefer to make the transition as simple as possible. Further, since most of the services running on these containers are listening on specific ports, and since users calling these services already have clients created that call these endpoints, I have a need to choose a docker network solution that does not require the users to change how they currently call the endpoints.
For instance, if the user currently makes a call like:
curl -X POST "ourCurrentHost:8099/rest/endpointA?user=jsmith
, I want that to remain unchanged if possible. I am thinking that this may be possible by defining my own docker bridge network. I see very basic examples of creating such a network, like:
$ docker network create --driver bridge my_isolated_bridge_network
, and then you can run a container you want on that network by configuring at runtime like:
$ docker run --net=my_isolated_bridge_network --name=my_psql_db postgres
However, much less obvious to me is how to bridge this network to the underlying network of the host server the container is running on (I assume this is what is needed so that the client calls can remain unchanged).
Another consideration is that some of my containers make calls to other containers running on the host server network (i.e. the network my containers were running on before I had to switch away from network=host).
Also, I have not been using docker compose up until now either, but just CLI. I would rather continue doing that for now as well.
I am not certain how I should proceed. I would be grateful for any ideas/suggestions. Thank you.
CodePudding user response:
Given the assumption that your container does not need to communicate to anything on the host system, the transition is very painless.
If your container has listened before on port 8099 and used the host network, i.e.
docker run --network host myimage
All you have to do is to publish that port and not use the host network.
docker run --publish 8099:8099 myimage
Any request that is able to reach your server on port 8099 will hit that container on the published port. Exactly like it was before when using the host network.
It may be, that you need to configure your firewall or iptables to allow this kind of traffic. Depending on your setup, it can be disallowed. You need to allow traffic from and to a network interface called docker0
. You can find some related documentation here, https://docs.docker.com/network/iptables/.
Docker networks are for communication between containers and, in case of docker swarm, also to handle ingress traffic. You are not using swarm so that last point is out of question. Containers that should be able to communicate have to be joined on a shared bridge network and should use the container names as hostname to communicate to.
docker network create intercom
docker run --network intercom --name myapp --detach traefik/whoami
docker run --network intercom curimages/curl http://myapp
If you need to communicate to other services on the host system which are not containers, you have to add a flag when starting the container,
docker run --add-host host.docker.internal:host-gateway myimage
Then you can use host.docker.internal
to communicate to the host system.
That said, usually we want to expose a unified interface to clients via DNS or URL and not publish too many ports. In the long run, it would be a good idea to look into a reverse proxy for your containers. This proxy could be reachable on the standard ports 80 and 443. It could look at the host and or path header to determine to which container the request should get proxied.