Is swarm required for using multi-host networking feature using overlay in docker
Yes, it is possible: see "Lab 6: Docker Networking".
The key part of an overlay network is the discovery service, like for instance Consul.
An overlay network requires a key-value store.
The store maintains information about the network state which includes discovery, networks, endpoints, ip-addresses, and more. Engine supports Consul, etcd, and ZooKeeper (Distributed store) key-value store stores.
The article "Docker Networks: Discovering Services on an Overlay" lay some criticisms about the current service discovery tools which are not built for individual container registration or discovery.
Overlay uses KV stores under the covers to model the network topology and enable cross-host container to container communication. It does not provide SRV record resolution.
The rub is that in an overlay network every container has its own IP address.
So, the only way you could make this work is by running Consul agents inside of every container on the network that contributes a service. That is certainly not transparent to the developer, or compatible with off-the-shelf images.
Multi Host : Docker Networking
Those networks are bridge networks that only exist on a single docker host. Containers assigned to only these networks will not be able to talk to containers on other hosts.
Multi-host networking is done with an "overlay" network and will show up with that driver instead of "bridge". The overlay driver relies on a global key/value store, such as consul, etcd, and it's now built into swarm with the raft backend. Assigning IP's is done by referencing this global key/value store so they should always be unique.
For more details, see: https://docs.docker.com/engine/userguide/networking/get-started-overlay/
What is overlay network and how does DNS resolution work?
Q. How does the docker overlay driver work?
I would recommend this good reference for understanding docker swarm network overlay, and more globally, Docker's architecture.
This states that:
Docker uses embedded DNS to provide service discovery for containers running on a single Docker Engine and tasks running in a Docker Swarm. Docker Engine has an internal DNS server that provides name resolution to all of the containers on the host in user-defined bridge, overlay, and MACVLAN networks.
Each Docker container ( or task in Swarm mode) has a DNS resolver that forwards DNS queries to Docker Engine, which acts as a DNS server.
So, in multi-host docker swarm mode
, with this example setup :
In this example there is a service of two containers called
myservice
. A second service (client
) exists on the same network. Theclient
executes twocurl
operations for docker.com andmyservice
.These are the resulting actions:
- DNS queries are initiated by
client
fordocker.com
andmyservice
.- The container's built-in resolver intercepts the DNS queries on
127.0.0.11:53
and sends them to Docker Engine's DNS server.myservice
resolves to the Virtual IP (VIP) of that service which is internally load balanced to the individual task IP addresses. Container names resolve as well, albeit directly to their IP addresses.docker.com
does not exist as a service name in the mynet network and so the request is forwarded to the configured default DNS server.
Back to your question:
How can I connect to an external mongodb server form cluster?
For your external mongodb
(let's say you have a DNS for that mongodb.mydomain.com
), you are in the same situation as the client
in above architecture, wanting to connect to docker.com
, except that you certainly don't wan't to expose that mongodb.mydomain.com
to the entire web, so you may have declared it in your internal cluster DNS server.
Then, how to tell docker engine to use this internal DNS server to resolve mongodb.mydomain.com
?
You have to indicate in your docker service
task that you want to use an internal DNS server, like so:
docker service create \
--name myservice \
--network my-overlay-network \
--dns=10.0.0.2 \
myservice:latest
The important thing here is --dns=10.0.0.2
. This will tell the Docker engine to use the DNS server at 10.0.0.2:53
as default if it can not resolve the DNS name in the VIP.
Finally, when you say :
I cannot connect to external mongodb server from my docker swarm cluster. As I understand this is because of cluster uses overlay network driver. Am I right?
I would say no, as there is a built in method in docker engine
to forward unknown DNS name coming from overlay network
to the DNS server you want.
Hope this helps!
Docker Swarm Overlay Network Not Working Between Nodes
it seems this problem was because of the nodes being not being able to connect to each other on the required ports.
TCP port 2377 for cluster management communications
TCP and UDP port 7946 for communication among nodes
UDP port 4789 for overlay network traffic
before you open those ports.
a better and simpler solution is to use the docker image portainer/agent
. like the documentation says,
The Portainer Agent is a workaround for a Docker API limitation when using the Docker API to manage a Docker environment.
https://portainer.readthedocs.io/en/stable/agent.html
i hope this helps anyone else experiencing this problem.
Related Topics
Apache Cgi in User Directory "End of Script Output Before Headers"
Why Kernel Needs Virtual Addressing
On-The-Fly Output Redirection, Seeing The File Redirection Output While The Program Is Still Running
Fork() and Stdout/Stderr to The Console from Child Processes
Self Updating Bash Script from Github
Why The Size of an Empty Directory in Linux Is 4Kb
Why Is The Close Function Is Called Release in 'struct File_Operations' in The Linux Kernel
Executing Exe or Bat File on Remote Windows Machine from *Nix
How to Keep Directory Structure with Aria2
When Using Cpan in Linux Ubuntu Should I Run It Using Sudo/As Root or as My Default User
Bash Loop Through Directory Including Hidden File
Why Does Pages Allocation with Order of 10 or 11 Using _Get_Free_Pages() Usually Fail
How to Convert Dynamically Linked Application to Statically One
How to Open Another File in Background Vim from Bash Command-Line