No Internet Access In Docker Container When Connected to Cisco AnyConnect VPN - linux

I am connected to a corporate VPN and need to be able to run docker containers while the VPN is connected due to the fact that the container needs to be able to access corporate endpoints. However, when I am connected with AnyConnect VPN, docker has no internet access at all. Neither to our corporate endpoints or the internet.
I am running CentOS7 as my host operating system.
A simple way to reproduce this issue is to install a minimal linux distro, install AnyConnect VPN, connect to vpn and try to run the following docker container:
docker run -i -t ubuntu:14.04 /bin/bash
Once inside the container I try to ping google dns
[###]$ ping 8.8.8.8
There will be no response. If I disconnect from AnyConnect VPN and retry the above, I get a ping response.
How can I fix this issue?

Ping outside and internet access are different. You could access internet but could not ping as limit by your corporation network. I suggest running busybox
docker run -it --rm busybox
and check the dns setup inside
cat /etc/resolv.conf
From there you may see list of nameserver ip addresses. Now you could try to ping those to make sure they are reachable from inside. If not, you could try
traceroute 1.2.3.4
to see how far you could go from inside container, the first 2 lines should be ip of docker and the host machine, and then the ip of your corporation network
1 172.17.0.1 (172.17.0.1) 0.016 ms 0.011 ms 0.009 ms
2 10.1.249.4 (10.1.249.4) 38.487 ms 35.697 ms 35.558 ms
Usually it's problem of the nameserver generated inside /etc/resolv.conf
file. If it's the case, then you need to check /etc/resolv.conf
in the host machine and update the docker setup to generate the nameservers correctly inside container.

After you make a change to the network interfaces, you often need to restart the docker engine to rebuild all of the routes and iptables entries. With Linux and systemd, use:
systemctl restart docker

Related

How can I get the IP of the docker host on a Linux system from a docker container?

This question appears to have been asked many times, but the answers appear to be outdated, or just not work.
I'm on a Linux system without a RTC (a raspberry pi). My host runs an ntp daemon (ntpd), which checks the time online as soon as the host boots up, assuming it has internet, and sets the system clock.
The code inside my container needs to know if the host's system clock is accurate (has been updated since last boot).
On the host itself, this is very easy to do - use something like ntpdate -q 127.0.0.1. ntpdate connects to 127.0.0.1:123 over udp, and checks with the ntpd daemon if the clock is accurate (if it's been updated since last boot). This appears to be more difficult to do from within a container.
If I start up a container, and use docker container inspect NAME to see the container's IP, it shows me this:
"Gateway": "172.19.0.1",
"IPAddress": "172.19.0.6",
If I run ntpdate -q 172.19.0.1 within the container, this works. Unfortunately, 172.19.0.1 isn't a permanent IP for the host. It that subnet is already taken when the container is starting up, the subnet will change, so hardcoding this IP is a bad idea. What I need is an environment variable that always reflects the proper IP for the host.
Windows and MacOS versions of docker appear to set the host.docker.internal hostname within containers, but Linux doesn't. Some people recommend setting this in the /etc/hosts file of the host, but then you're just hardcoding the IP, which again, can change.
I run my docker container with a docker-compose.yml file, and apparently, on new versions of docker, you can do this:
extra_hosts:
- "host.docker.internal:host-gateway"
I tried this, and this works. Sort of. Inside my container, host.docker.internal resolves to 172.17.0.1, which is IP of the docker0 interface on the host. While I can ping host.docker.internal from within the container, using ntpdate -q host.docker.internal or ntpdate -q 172.17.0.1 doesn't work.
Is there a way to make host.docker.internal resolve to the proper gateway IP of the host from within the container? In my example, 172.19.0.1.
Note: Yes, I can use code within the container to check what the container's gateway is with netstat or similar, but then I need to complicate my code, making it figure out the IP of the NTP server (the docker host). I can probably also pass the docker socket into the container, and try to get the docker host's IP through that, but that seems super hackey, and an unnecessary security issue.
The best solution I've found is to use the ip command from the iproute2 package, look for the default route and use the gateway address for it.
ip route | awk '/default/ {print $3}'
if you want it in an environment variable, you can set it in an entrypoint script with
export HOST_IP_ADDRESS=$(ip route | awk '/default/ {print $3}')

Docker cannot access mariadb server

I am newbie on docker.
I want to migrate my nodejs app to docker, and existing database already installed on server (172.17.2.1). I set mariadb host 172.17.2.1 on my nodejs config.
After that, I created an images and run with :
docker run -p 3009:3009 -d my-node
actually its already running, but when I tested to open by browser, I got an error that my app cannot connect to 172.17.2.1 (connecting to database).
I try to create bridge IP (172.17.2.135) and make a same subnet, but still got a same error.
My images on docker inside doesn't know 172.17.2.1 on my LAN.
Please help me,
I use windows 10 environment
You have two options to allow your container to reach an external server:
Run your docker container on your host network:
docker run -p 3009:3009 --network host -d my-node
This way your container will be able to reach anything reachable from your machine
create a network bridge: in this case docker will route the traffic from the container to the external server. the bridge IP can't be your docker machine IP as you tried to do.

Connect to host mongodb from docker container

So I want to connect to my mongodb running on my host machine (DO droplet, Ubuntu 16.04). It is running on the default 27017 port on localhost.
I then use mup to deploy my Meteor app on my DO droplet, which is using docker to run my Meteor app inside a container. So far so good.
A standard mongodb://... connection url is used to connect the app to the mongodb.
Now I have the following problem:
mongodb://...#localhost:27017... obviously does not work inside the docker container, as localhost is not the host's localhost.
I already read many stackoverflow posts on this, I already tried using:
--network="host" - did not work as it said 0.0.0.0:80 is already in use or something like that (nginx proxy)
--add-host="local:<MY-DROPLET-INTERNET-IP>" and connect via mongodb://...#local:27017...: also not working as I can access my mongodb only from localhost, not from the public IP
This has to be a common problem!
tl;dr - What is the proper way to expose the hosts localhost inside a docker container so I can connect to services running on the host? (including their ports, e.g. 27017).
I hope someone can help!
You can use: 172.17.0.1 as it is the default host ip that the containers can see. But you need to configure Mongo to listen to 0.0.0.0.
From docker 18.03 onwards the recommendation is to connect to the special DNS name host.docker.internal
For previous versions you can use DNS names docker.for.mac.localhost or docker.for.windows.localhost.
change the bindIp from 127.0.0.1 to 0.0.0.0 in /etc/mongod.conf. Then it will work
or start mongod on ubuntu with a flag to bind all ip address as a temporary workaround (dev/learning purposes)
$ mongod --bind_ip_all
Tried 100500 variants for Windows (using docker desktop), but without any result...
Unfortunately, currently, Windows (at least docker desktop) is not supporting --net=host
Quoted from: https://docs.docker.com/network/network-tutorial-host/#prerequisites
The host networking driver only works on Linux hosts, and is not supported on Docker for Mac, Docker for Windows, or Docker EE for Windows Server.
You can try to use https://docs.docker.com/toolbox/

Run dnsmasq as DHCP server from inside a Docker container

I'm trying to get dnsmasq to operate as a DHCP server inside a Docker container, issuing DHCP addresses to machines on the host's physical network. I'm using the Alpine Linux 6MB container from https://hub.docker.com/r/andyshinn/dnsmasq/.
It works fine as a DNS server on port 53 on the host machine, however there is nothing listening on port 67/udp, which is where I'm expecting DHCP to be. I use
dhcping 192.168.2.2, but get "no answer". telnet 192.168.2.2 67 returns "Connection refused".
My dnsmasq.conf file in the container looks like this:
interface=eth0
user=root
domain-needed
bogus-priv
no-resolv
local=/mydomain.io/
no-poll
server=8.8.8.8
server=8.8.4.4
no-hosts
addn-hosts=/etc/dnsmasq_static_hosts.conf
expand-hosts
domain=mydomain.io
dhcp-range=192.168.2.10,192.168.2.250,255.255.255.0,192.168.2.255,5m
# Have windows machine release on shutdown
dhcp-option=vendor:MSFT,2,1i
# No default route
dhcp-option=3
The host machine has a static address of 192.168.2.2.
I start the container like this:
docker run -d --name dns -p 192.168.2.2:67:67/udp -p 192.168.2.2:53:53/udp sitapati/dns
There is no firewall on this machine, which is running Ubuntu 16.04.
Things I've thought of/tried:
is it because eth0 in the container has an address on a completely different subnet? (docker inspect tells me it's 172.17.0.2 on the bridged interface)
does it need to use --net host? I tried that, and it still didn't work.
Yes, the container will have its own interfaces on a virtual subnet (the docker0 bridge network). So it will be trying to offer addresses on that subnet.
Using --net host worked for me, I got the DHCP server working using something like the following command:
docker run --name dnsmasq2 -t -v /vagrant/dnsmasq.conf:/opt/dnsmasq.conf -p 67:67/udp --net host centos
--net host ensures that the container appears to using the host's networking stack rather than its own.
dnsmasq -q -d --conf-file=/opt/dnsmasq.conf --dhcp-broadcast
I also needed to add the --dhcp-broadcast flag to dnsmasq within the container to get it to actually broadcast DHCPOFFER messages on the network. For some reason, dnsmasq was trying to unicast the DHCPOFFER messages, and it was using ARP to try to get an address that had not yet been assigned.

Multiple docker containers, IP addresses, VM, OSX

I am running docker on OSX via boot2docker. I am using docker remotely, via the API.
I create several images of a web server. Docker assigns different IP address to each container, like 172.17.0.61. Each web server is running on port 8080.
Inside VM, I can ping the server on this address.
How can I map these different container IP addresses (from VM) to the same one in VM, but on different port? E.G.
<local.ip>:9001 -> 172.17.0.61:8080
<local.ip>:9002 -> 172.17.0.62:8080
where local.ip may be either ip from boot2docker or anything else.
Possible solution is to define port bindings when creating container and bind each container to a different port. However, I would like to avoid that, since this config becomes part of the container, and only exist because running on OSX. If I do all this above on linux, we would not have this issue.
How to map inner containers to different ports?
Publishing ports is the right solution. You have the same problem whether you're running remotely or locally, just the IP address changes.
For example, say I start the following web servers:
$ docker run -d -p 8000:80 nginx
$ docker run -d -p 8001:80 nginx
From inside the VM (run boot2docker ssh), I can then run curl localhost:8000 or curl localhost:8001 to reach the website. This is the normal way of working with Docker on Linux. From the Mac command line, it becomes curl $(boot2docker ip):8000 because of the VM, but we've not done anything different with regards to starting the web servers because of boot2docker.

Resources