How to access each instance of same container from host machine - docker

I have three instance of same containerized app running on docker. So their port are same for all. I can access one of them using port forwarding at localhost:8080 but when I want to do same thing for other ones I got error. So I think, somehow I need to access each instance from different ip address to connect them from my docker host. How can I do that?

I figured out how to do that. In case of someone else wants to achive this behaviour, I am writing down here the solution.
First example, you have three same container from couchbase image and you want to connect them in couchbase ui like each of them is seperated node.
1- Firstly you should open network interface for each container you want to deploy. Run below command on terminal.
sudo ifconfig lo0 alias 172.18.0.2 netmask 0xff000000
sudo ifconfig lo0 alias 172.18.0.3 netmask 0xff000000
sudo ifconfig lo0 alias 172.18.0.4 netmask 0xff000000
2- IP adresses above will be static container ip addresses for each instance. To do that, you should create docker network.
docker network create -d bridge my-network --gateway 172.18.0.1 --subnet 172.18.0.0/24
3- Create containers from couchbase image.
docker run -d --name cb1 --network my-network --ip 172.18.0.2 -p 172.18.0.2:8091-8096:8091-8096 -p 172.18.0.2:11210-11211:11210-11211 couchbase
docker run -d --name cb2 --network my-network --ip 172.18.0.3 -p 172.18.0.3:8091-8096:8091-8096 -p 172.18.0.3:11210-11211:11210-11211 couchbase
docker run -d --name cb3 --network my-network --ip 172.18.0.4 -p 172.18.0.4:8091-8096:8091-8096 -p 172.18.0.4:11210-11211:11210-11211 couchbase
4- Then you can open one of couchbase ui in this browser and connect the other two container to cluster. For example, type 172.18.0.2:8091 in browser and connect the 172.18.0.3 and 172.18.0.4 containers.
5- I need this project for GoSDK. So for golang you can use "couchbase://172.18.0.2" connection string to connect your cluster.
Note: This ip addresses are choosen randomly, you can assign whatever you want.

Related

How can I set ConnectionStrings on Docker? [duplicate]

I'm now trying to assign a static IP 172.17.0.1 when a Docker container be started up.
I use port 2122 as the ssh port of this container so that I let this container listen port 2122.
sudo docker run -i -t -p 2122:2122 ubuntu
This command will run a Docker container with a random IP like 172.17.0.5, but I need to assign a specific IP to the container.
The following shell script is what I reference Docker documentation in advanced network settings.
pid=$(sudo docker inspect -f '{{.State.Pid}}' <container_name> 2>/dev/null)
sudo rm -rf /var/run/netns/*
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip link add A type veth peer name B
sudo brctl addif docker0 A
sudo ip link set A up
sudo ip link set B netns $pid
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link delete eth0
sudo ip netns exec $pid ip link set dev B name eth0
sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link set eth0 up
sudo ip netns exec $pid ip addr add 172.17.0.1/16 dev eth0
sudo ip netns exec $pid ip route add default via 172.17.42.1
This shell script will assign a static IP 172.17.0.1 and link to the world fine. But whenever I try to ssh to this container from my local, it didn't work. What's the problem possibly I met?
Easy with Docker version 1.10.1, build 9e83765.
First you need to create your own docker network (mynet123)
docker network create --subnet=172.18.0.0/16 mynet123
then, simply run the image (I'll take ubuntu as example)
docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash
then in ubuntu shell
ip addr
Additionally you could use
--hostname to specify a hostname
--add-host to add more entries to /etc/hosts
Docs (and why you need to create a network) at https://docs.docker.com/engine/reference/commandline/network_create/
For docker-compose you can use following docker-compose.yml
version: '2'
services:
nginx:
image: nginx
container_name: nginx-container
networks:
static-network:
ipv4_address: 172.20.128.2
networks:
static-network:
ipam:
config:
- subnet: 172.20.0.0/16
#docker-compose v3+ do not use ip_range
ip_range: 172.28.5.0/24
from host you can test using:
docker-compose up -d
curl 172.20.128.2
Modern docker-compose does not change ip address that frequently.
To find ips of all containers in your docker-compose in a single line use:
for s in `docker-compose ps -q`; do echo ip of `docker inspect -f "{{.Name}}" $s` is `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $s`; done
If you want to automate, you can use something like this example gist
Not a direct answer but it could help.
I run most of my dockerized services tied to own static ips using the next approach:
I create ip aliases for all services on docker host
Then I run each service redirecting ports from this ip into container so each service have own static ip which could be used by external users and other containers.
Sample:
docker run --name dns --restart=always -d -p 172.16.177.20:53:53/udp dns
docker run --name registry --restart=always -d -p 172.16.177.12:80:5000 registry
docker run --name cache --restart=always -d -p 172.16.177.13:80:3142 -v /data/cache:/var/cache/apt-cacher-ng cache
docker run --name mirror --restart=always -d -p 172.16.177.19:80:80 -v /data/mirror:/usr/share/nginx/html:ro mirror
...
I stumbled upon this problem during attempt to dockerise Avahi which needs to be aware of its public IP to function properly. Assigning static IP to the container is tricky due to lack of support for static IP assignment in Docker.
This article describes technique how to assign static IP to the container on Debian:
Docker service should be started with DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". I assume that br0 bridge is already configured.
Container should be started with --cap-add=NET_ADMIN --net=bridge
Inside container pre-up ip addr flush dev eth0 in /etc/network/interfaces can be used to dismiss IP address assigned by Docker as in following example:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
pre-up ip addr flush dev eth0
address 192.168.0.249
netmask 255.255.255.0
gateway 192.168.0.1
Container's entry script should begin with /etc/init.d/networking start. Also entry script needs to edit or populate /etc/hosts file in order to remove references to Docker-assigned IP.
This works for me.
Create a network with
docker network create --subnet=172.17.0.0/16 selnet
Run docker image
docker run --net selnet --ip 172.18.0.2 hub
At first, I got
docker: Error response from daemon: Invalid address 172.17.0.2: It does not belong to any of this network's subnets.
ERRO[0000] error waiting for container: context canceled
Solution: Increased the 2nd quadruple of the IP
[.18. instead of .17.]
You can set the IP while running it.
docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"
See my example at https://github.com/RvdGijp/mariadb-10.1-galera
You can access other containers' service by their name(ping apachewill get the ip or curl http://apache would access the http service) And this can be a alternative of a static ip.
If you want your container to have it's own virtual ethernet socket (with it's own MAC address), iptables, then use the Macvlan driver. This may be necessary to route traffic out to your/ISPs router.
https://docs.docker.com/engine/userguide/networking/get-started-macvlan

Assigning static IP on the host network to container

I need to run a docker container (hosting nginx), such that the container gets a static IP address on the host network. Example:
Suppose the host has IP 172.18.0.2/16 then I would like to give 172.18.0.3/16 to the docker container running on the host. I'd like the other physical machines in the host's network to be able to connect to the container at 172.18.0.3/16.
I have tried the solution described by: https://qiita.com/kojiwell/items/f16757c1f0cc86ff225b, (without vegrant) but it didn't help. I'm not sure about the --subnet option that needed to be supplied to the docker network create command.
As suggested in this post, I was trying to do:
docker network create \
--driver bridge \
--subnet=<WHAT TO SUPPLY HERE?> \
--gateway=<WHAT TO SUPPLY HERE?> \
--opt "com.docker.network.bridge.name"="docker1" \
shared_nw
# Add my host NIC to the bridge
brctl addif docker1 eth1
Then start the container as:
docker run --name myApp --net shared_nw --ip 172.18.0.3 -dt ubuntu
Somehow it did not work. I will appreciate if someone could point me to the right direction about how to set such a thing up. Grateful!
On your use-case the ipvlan docker network could work for you.
using your assumptions about the host ip address and mask, you could create the network like this:
docker network create -d ipvlan --subnet=172.18.0.1/16 \
-o ipvlan_mode=l2 my_network
Then run your docker container within that network and assign an IP address:
docker run --name myApp --net my_network --ip 172.18.0.3 -dt ubuntu
Note that any exposed port of that container will be available on the 172.18.0.3 ip address, but any other services on your host will not be reachable with that IP address.
You can find more info on ipvlan at the official docker documentation
The docker run -p option optionally accepts a bind-address part, which specifies a specific host IP address that will accept inbound connections. If your host is already configured with the alternate IP address, you can just run
docker run -p 172.18.0.3:80:8080 ...
and http://172.18.0.3/ (on the default HTTP port 80) will forward to port 8080 in the container.
Docker has a separate internal IP address space for containers, that you can almost totally ignore. You almost never need the docker network create --subnet option and you really never need the docker run --ip option. If you ran ifconfig inside this container you'd see a totally different IP address, and that would be fine; the container doesn't know what host ports or IP addresses (if any) it's associated with.

Docker for Mac: Host network and port publishing

I am running Docker for Mac. When I run
docker run -d --rm --name nginx -p 80:80 nginx:1.10.3
I can access Nginx on port 80 on my Mac. When I run
docker run -d --rm --name nginx --network host -p 80:80 nginx:1.10.3
I can not.
Is it possible to use both "--network host" and publish a port so that it is reachable from my Mac?
Alternatively, can I access Nginx from my Mac via the IP of the HyperKit VM?
Without the --network flag the container is added to the bridge network by default; which creates a network stack on the Docker bridge (usually the veth interface).
If you specify --network host the container gets added to the Docker host network stack. Note the container will share the networking namespace of the host, and thus all its security implications.
Which means you don't need to add -p 80:80, instead run...
docker run -d --rm --name nginx --network host nginx:1.10.3
and access the container on http://127.0.0.1
The following link will help answer the HyperKit question and the current limitations:
https://docs.docker.com/docker-for-mac/networking/
There is no docker0 bridge on macOS
Because of the way networking is implemented in Docker for Mac, you
cannot see a docker0 interface in macOS. This interface is actually
within HyperKit.

docker networking direct access to container

I try to migrate from multiple VM with static ip to container based solution.
Now I'm using VM with static ip:
I can ping and telnet my VMs telnet 10.48.0.10 5432 and telnet 10.48.0.11 5432
I want to create a single docker host that allows me to do the same :
It would be great if I can telnet 172.17.0.2 5432 and telnet 172.17.0.3 5432
I try to do it via docker because I want to manage the configuration.
What would be the proper way to do this ?
Should I use a TCP Proxy inside a container to manage this ?
The solution is pretty simple.
create a network and bind it to the host
docker network create --subnet=10.0.0.0/24 -o "com.docker.network.bridge.host_binding_ipv4"="0.0.0.0" mynet
then run a container on mynet network
docker run -ti --net=mynet --ip=10.0.0.30 busybox
Now from another computer if you add route to your docker host (192.168.2.156) for this subnet :
sudo route add -net 10.0.0.0 netmask 255.255.255.0 gw 192.168.2.156
You can ping your container (ping 10.0.0.30)
If you want to access the containers from your host or from any other server that can get your host, you will need to map each container to a different port in the host server.
docker run -d -p 54321:5432 my_app
docker run -d -p 54322:5432 my_app
So you will can telnet 10.200.0.1 54321 and telnet 10.200.0.1 54322

Assign static IP to Docker container

I'm now trying to assign a static IP 172.17.0.1 when a Docker container be started up.
I use port 2122 as the ssh port of this container so that I let this container listen port 2122.
sudo docker run -i -t -p 2122:2122 ubuntu
This command will run a Docker container with a random IP like 172.17.0.5, but I need to assign a specific IP to the container.
The following shell script is what I reference Docker documentation in advanced network settings.
pid=$(sudo docker inspect -f '{{.State.Pid}}' <container_name> 2>/dev/null)
sudo rm -rf /var/run/netns/*
sudo ln -s /proc/$pid/ns/net /var/run/netns/$pid
sudo ip link add A type veth peer name B
sudo brctl addif docker0 A
sudo ip link set A up
sudo ip link set B netns $pid
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link delete eth0
sudo ip netns exec $pid ip link set dev B name eth0
sudo ip netns exec $pid ip link set eth0 address 12:34:56:78:9a:bc
sudo ip netns exec $pid ip link set eth0 down
sudo ip netns exec $pid ip link set eth0 up
sudo ip netns exec $pid ip addr add 172.17.0.1/16 dev eth0
sudo ip netns exec $pid ip route add default via 172.17.42.1
This shell script will assign a static IP 172.17.0.1 and link to the world fine. But whenever I try to ssh to this container from my local, it didn't work. What's the problem possibly I met?
Easy with Docker version 1.10.1, build 9e83765.
First you need to create your own docker network (mynet123)
docker network create --subnet=172.18.0.0/16 mynet123
then, simply run the image (I'll take ubuntu as example)
docker run --net mynet123 --ip 172.18.0.22 -it ubuntu bash
then in ubuntu shell
ip addr
Additionally you could use
--hostname to specify a hostname
--add-host to add more entries to /etc/hosts
Docs (and why you need to create a network) at https://docs.docker.com/engine/reference/commandline/network_create/
For docker-compose you can use following docker-compose.yml
version: '2'
services:
nginx:
image: nginx
container_name: nginx-container
networks:
static-network:
ipv4_address: 172.20.128.2
networks:
static-network:
ipam:
config:
- subnet: 172.20.0.0/16
#docker-compose v3+ do not use ip_range
ip_range: 172.28.5.0/24
from host you can test using:
docker-compose up -d
curl 172.20.128.2
Modern docker-compose does not change ip address that frequently.
To find ips of all containers in your docker-compose in a single line use:
for s in `docker-compose ps -q`; do echo ip of `docker inspect -f "{{.Name}}" $s` is `docker inspect -f '{{range .NetworkSettings.Networks}}{{.IPAddress}}{{end}}' $s`; done
If you want to automate, you can use something like this example gist
Not a direct answer but it could help.
I run most of my dockerized services tied to own static ips using the next approach:
I create ip aliases for all services on docker host
Then I run each service redirecting ports from this ip into container so each service have own static ip which could be used by external users and other containers.
Sample:
docker run --name dns --restart=always -d -p 172.16.177.20:53:53/udp dns
docker run --name registry --restart=always -d -p 172.16.177.12:80:5000 registry
docker run --name cache --restart=always -d -p 172.16.177.13:80:3142 -v /data/cache:/var/cache/apt-cacher-ng cache
docker run --name mirror --restart=always -d -p 172.16.177.19:80:80 -v /data/mirror:/usr/share/nginx/html:ro mirror
...
I stumbled upon this problem during attempt to dockerise Avahi which needs to be aware of its public IP to function properly. Assigning static IP to the container is tricky due to lack of support for static IP assignment in Docker.
This article describes technique how to assign static IP to the container on Debian:
Docker service should be started with DOCKER_OPTS="--bridge=br0 --ip-masq=false --iptables=false". I assume that br0 bridge is already configured.
Container should be started with --cap-add=NET_ADMIN --net=bridge
Inside container pre-up ip addr flush dev eth0 in /etc/network/interfaces can be used to dismiss IP address assigned by Docker as in following example:
auto lo
iface lo inet loopback
auto eth0
iface eth0 inet static
pre-up ip addr flush dev eth0
address 192.168.0.249
netmask 255.255.255.0
gateway 192.168.0.1
Container's entry script should begin with /etc/init.d/networking start. Also entry script needs to edit or populate /etc/hosts file in order to remove references to Docker-assigned IP.
This works for me.
Create a network with
docker network create --subnet=172.17.0.0/16 selnet
Run docker image
docker run --net selnet --ip 172.18.0.2 hub
At first, I got
docker: Error response from daemon: Invalid address 172.17.0.2: It does not belong to any of this network's subnets.
ERRO[0000] error waiting for container: context canceled
Solution: Increased the 2nd quadruple of the IP
[.18. instead of .17.]
You can set the IP while running it.
docker run --cap-add=NET_ADMIN -dit imagename /bin/sh -c "/sbin/ip addr add 172.17.0.12 dev eth0; bash"
See my example at https://github.com/RvdGijp/mariadb-10.1-galera
You can access other containers' service by their name(ping apachewill get the ip or curl http://apache would access the http service) And this can be a alternative of a static ip.
If you want your container to have it's own virtual ethernet socket (with it's own MAC address), iptables, then use the Macvlan driver. This may be necessary to route traffic out to your/ISPs router.
https://docs.docker.com/engine/userguide/networking/get-started-macvlan

Resources