Is that possible to have multiple IPs on eth0 in a Docker container?
I would like having 5 IPs on eth0 in a Docker container interface. I am using "ip" utility. Executing ip address add 172.20.0.200/16 dev eth0 in the container give "Operation not permited.
I tried manually log to the container as root user using "sudo exec
-u root ..".
I have even tried apt-install sudo in the container. Result is same "Operation not permitted"
I have found the answer. There must be added --cap-add option
docker run --cap-add=NET_ADMIN image
But as I understand docker know nothing about static IPs since docker network inspect shows only one IP. Hence think of using custom network
I'm having a problem building Docker images on my corporate network. I'm just getting started with Docker, so I have the following Dockerfile for a hello-world type app:
# DOCKER-VERSION 0.3.4
FROM centos:6.4
# Enable EPEL for Node.js
RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
# Install Node.js and npm
RUN yum install -y npm
# Bundle app source
ADD . /src
# Install app dependencies
RUN cd /src; npm install
EXPOSE 8080
CMD ["node", "/src/index.js"]
This works fine when I build it on my laptop at home, on my own wireless network. It pulls down the requisite dependencies and builds the image correctly.
However, when I'm on my corporate network at work, this same docker build fails when trying to pull down the RPM from download.fedoraproject.org, with this error message:
Step 2 : RUN rpm -Uvh http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm
---> Running in e0c26afe9ed5
curl: (5) Couldn't resolve proxy 'some.proxy.address'
error: skipping http://download.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm - transfer failed
On my corporate network, I can access that URL just fine from my laptop. But once Docker is trying to build the container, all of a sudden it can't resolve at all. This behavior is the same for a variety of external resources (apt-get, etc.): They all can resolve just fine on my laptop on the corporate network, but Docker can't resolve them.
I don't have the network know-how to figure out what's going on here. Does anyone know why this strange behaviour would be occurring when building Docker containers?
I was able to figure out the issue. On Ubuntu, Docker sets the DNS servers for container to Google's servers at 8.8.8.x. As I understand it, this is a workaround on Ubuntu due to the fact that Ubuntu sets /etc/resolv.conf to be 127.0.0.1.
Those Google servers weren't accessible from behind our firewall, which is why we couldn't resolve any URLs.
The fix is to tell Docker which DNS servers to use. This fix depends on how you installed Docker:
Ubuntu Package
If you have the Ubuntu package installed, edit /etc/default/docker and add the following line:
DOCKER_OPTS="--dns <your_dns_server_1> --dns <your_dns_server_2>"
You can add as many DNS servers as you want to this config. Once you've edited this file you'll want to restart your Docker service:
sudo service docker restart
Binaries
If you've installed Docker via the binaries method (i.e. no package), then you set the DNS servers when you start the Docker daemon:
sudo docker -d -D --dns <your_dns_server_1> --dns <your_dns_server_2> &
I advise changing the DNS settings of the Docker daemon. You can set the default options for the docker daemon by creating a daemon configuration file at /etc/docker/daemon.json. Set DNS server according to your host machine, e.g. my DNS server is 10.0.0.2:
{"dns": ["10.0.0.2", "8.8.8.8"] }
Then you need just restart docker service:
sudo service docker restart
Step-by-step explanation is available here Fix Docker's networking DNS config
The following steps works for me ( for both docker build and docker run command). My linux version is Ubuntu 14.04.
Identify DNS using following command.
nm-tool | grep DNS
This result DNS:192.168.1.1 in my case
Create entry in /etc/default/docker.io. My current entry looks like this
DOCKER_OPTS="--dns 8.8.8.8 --dns 8.8.4.4 --dns 192.168.1.1"
Restart docker service
sudo service docker.io restart
For any Linux distribution working with SystemD (Ubuntu 16, RHEL 7...), the path will be displayed with the following command:
$ systemctl status docker
● docker.service - Docker Application Container Engine
Loaded: loaded (/lib/systemd/system/docker.service; enabled; vendor preset: enabled)
Active: active (running) since Wed 2016-06-29 08:10:33 PDT; 2min 34s ago
Docs: https://docs.docker.com
Main PID: 1169 (dockerd)
Tasks: 19
Memory: 85.0M
CPU: 1.779s
CGroup: /system.slice/docker.service
├─1169 /usr/bin/dockerd --dns 172.18.20.11 --dns 172.20.100.15 --dns 8.8.8.8 --dns 8.8.4.4 -H fd://
└─1232 docker-containerd -l unix:///var/run/docker/libcontainerd/docker-containerd.sock --shim docker-containerd-shim --met
The path would be /lib/systemd/system/docker.service. Add the DOCKER_OPTS values, which can have any of the --dns, in the line where the daemon is started.
cat /lib/systemd/system/docker.service | grep dns
ExecStart=/usr/bin/dockerd --dns 172.18.20.11 --dns 172.20.100.15 --dns 8.8.8.8 --dns 8.8.4.4 -H fd://
Docker (at least >=1.13, probably earlier) on Mac and Windows allow you configure the DNS in Preferences -> Daemon -> Advanced:
The following config sets two corporate DNS servers (use your own values here) with fallback to Google public DNS servers.
Specify your DNS to the Docker daemon.
First of all get your DNS address
$ nmcli dev show | grep 'IP4.DNS'
IP4.DNS[1]: 10.0.0.2
Test if the problem is really with the DNS by launching a docker container forcing this new DNS
$ docker run --dns 10.0.0.2 <image_name> <command_name>
If this solves the problem, you can apply this fix for all the docker daemons in the following way
Edit or create a file /etc/docker/daemon.json
Add the following line to this file
{
"dns": ["10.0.0.2", "8.8.8.8"]
}
Restart docker
$ sudo service docker restart
A very nice guide for doing ALL this process can be found here.
https://development.robinwinslow.uk/2016/06/23/fix-docker-networking-dns/
Solution without restarting Docker service
It is possible to modify the DNS settings for a single Docker image without affecting other docker build calls (and without restarting the Docker service) by overriding the resolv.conf at build time:
FROM ubuntu:18.04
RUN echo "nameserver 123.123.123.123" > /etc/resolv.conf && apt update
Replace the IP 123.123.123.123 with the one which is used within your corporate network (use nmcli dev show | grep 'IP4.DNS' to get the currently used DNS server).
Downsides:
This does not affect any other line from the Dockerfile. Hence, you have to prefix every line with the fix, if it depends on DNS resolution
On my Ubuntu 16.04 machine, sometimes, Google's DNS do not work for building Docker images.
cat /etc/docker/daemon.json
{"dns": [""8.8.8.8"] }
I have to manually find out my Service Providers DNS using the following command
nmcli device show <interfacename> | grep IP4.DNS
125.22.47.102
and add it to my daemon.json as show below
cat /etc/docker/daemon.json
{"dns": ["125.22.47.102","8.8.8.8"] }
restart docker
sudo service docker restart
(PS nm-tool is deprecated from Ubuntu 15.04)
Updated info September 2021
Inspired by Jason's answer; setting DNS server in the JSON didn't work for me in the current version, but there's now another place to set it:
When you turn on the toggle, the 8.8.8.8 is already there, so I just left it and it works well enough for me in my dev environment. I didn't research it but if wanted, there may be a way to add a list, perhaps separated by commas/semicolons/spaces etc.
I have a docker container which has NVM installed by default. when I try to install any version of node, or running command nvm ls-remote it fails to connect to it's server every time.
the message is:
Version '6.11.2' not found - try nvm ls-remote to browse available versions.
this error occurs just in this network I am joining to.
it is my /etc/resolve.conf file content:
# Dynamic resolv.conf(5) file for glibc resolver(3) generated by resolvconf(8)
# DO NOT EDIT THIS FILE BY HAND -- YOUR CHANGES WILL BE OVERWRITTEN
search SAD.UM.AC.IR
nameserver 8.8.8.8
nameserver 8.8.4.4
result of docker network ls command is:
NETWORK ID NAME DRIVER SCOPE
dc8cffbb2789 bridge bridge local
5efb2b5fb44e host host local
8c19a2b28c14 none null local
It is just a network problem!! Is there any thing to solve this??
Finally after a discussion with #TarunLalwani, I find what is wrong in this case. The problem is that my container does not use my host machine internet, so it has no internet access. I use this command when I run the container:
docker run -it -v somewhere/:/somewhere --net=host -p 8585:8585 --name test docker-image
--net=host added to command.
Apologies for asking two unrelated questions.
what is the best way of accessing the host machine of the docker container (i.e. I am trying to access a kafka instance running on the host, from my docker container so that I can publish some messages)
when I run docker run ..... on an image which I've modified that may have an issue/syntax error, it will naturally not start - is there a log file anywhere that I would be able to take a look at to debug the issue. (this question is somewhat related to the 1st question, since I did what was suggested on another post, but the image is still not starting)
This is an ongoing discussion on what to use and what not, I don't really know what is best. Using the docker run --net="host" is pretty easy but can be dangerous. See From inside of a Docker container, how do I connect to the localhost of the machine?.
Use docker logs containerid or lookup the raw data in /var/lib/docker/containers/containerid/ for Ubuntu.
You should have no problem connecting to the host using the local lan interface ip address. Suppose you have a host with ip 192.168.0.1:
docker run --rm -ti ubuntu bash
ping 192.168.0.1
should give you a response.
You can use docker logs to see the standard output of your container.
Im a trying to deploy my application using Docker and came across an issue that restarting named containers assigns a different IP to container. Maybe explaining what I am doing will better explain the issue:
Postgres runs inside a separate container named "postgres"
$ PG_ID=$(docker run --name postgres postgres/image)
My webapp container links to postgres container
$ APP_ID=$(docker run --link postgres:postgres webapp/image)
Linking postgres container image to webapp container inserts in webapp container a hosts file entry with the IP of the postgres container. This allows me to point to postgres db within my webapp using postgres:5432 (I am using Django btw). This all works well except if for some reason postgres crashes.
Before I manually stop postgres process to simulate postgres process crashing I verify IP of postgres container:
$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.73
Now to simulate crash I stop postgres container:
$ docker stop $PG_ID
If now I restart postgres by using
$ docker start $PG_ID
the ip of the container changes:
$ docker inspect --format "{{.NetworkSettings.IPAddress}}" $PG_ID
172.17.0.74
Therefore the IP which points to postgres container in webapp container is no longer correct. I though that by naming container docker assigns a name to it with specific configs so that you can reliably link between containers (both network and volumes). If the IP changes this seems to defeat the purpose.
If I have to restart my webapp process each time I postgres restarts, this does not seem any better than just using a single container to run both processes. Then I can use supervisor or something similar to keep both of them running and use localhost to link between processes.
I am still new to Docker so am I doing something wrong or is this a bug in docker?
2nd UPDATE: maybe you already discovered this, but as workaround, I plan to map the service to share the database to the host interface (ej: with -p 5432:5432), and connect the webapps to the host IP (the IP of the docker0 interface: in my Ubuntu and CentOS, the IP is 172.17.42.1). If you restart the postgres container, the conteiner's IP will change, but I wil be accesible using 172.17.42.1:5432. The downside is that you are exposing that port to all the containers, and loose the fine-grained mapping that --link gives you.
--- OLD UPDATES:
CORRECTION: Docker will map 'postgres' to the container's IP in the /etc/hosts files, on the webapp container. So, in the webapp container, you can ping 'postgres', and it will be mapped to the IP.
1st UPDATE: I've seen that Docker generates and mounts /etc/hosts, /etc/resolv.conf, etc. to have always the correct information, but this does not apply when the linked container is restarted. So, I've assumed (wrongly) that Docker would update the hosts files.
-- ORIGINAL (wrong) response:
Add --hostname=postgres-db (you can use anythin, I'm using something different than 'postgres' to avoid confussion with the container name):
$ docker run --name postgres --hostname postgres-db postgres/image
Docker will map 'postgres-db' to the container's IP (check the contents of /etc/hosts on the webapp container).
This will allow you run 'ping postgres-db' from the webapp container. If the IP changes, Dockers will update /etc/hosts for you.
In the Django app, use 'postgres-db' instead of the IP (or whatever you use for --hostname of the container with PostgreSql).
Bye!
Horacio
According to https://docs.docker.com/engine/reference/commandline/run/, it should be possible to assign a static IP for your container -- at the time of container creation -- using the --ip option:
Example:
docker run -itd --ip 172.30.100.104 --name postgres postgres/image
....where 172.30.100.104 is a free IP address on a custom bridge/overlay network.
This should then retain the same IP address even if postgres container crashes/restarts.
Looks like this was released in Docker Engine v 1.10 or greater, therefore if you have a lower version, you have to upgrade first.
As of Docker 1.0 they implemented a stronger sense of linked containers. Now you can use the container instance name as if it were the host name.
Here is a link
I found a link that better describes your problem. And while that question was answered I wonder whether or not this ambassador pattern might not solve the problem... this assumes that the ambassador is more reliable than the services that link.