Docker for Windows: cannot assign requested address - windows

How can I setup a multi-host running Docker 1.12 on Hyper-V?
I can easily assign a 127.x.x.x ip, but I would like to assign e.g. 10.240.0.x.
This is my docker-compose.yaml:
version: '2'
services:
nginx:
image: nginx:lastest
ports:
- "127.0.0.100:80:80"
If I try to assign 10.240.0.100 I get this error:
Error starting userland proxy: listen tcp 10.240.0.100:80: bind: cannot assign requested address
What am I missing? Do I have to configure Windows to support these addresses?

Is this using Docker for Windows? With that, you're limited to binding stuff to localhost on the host.
If you want to test a multi-node swarm on your machine, you need to set up a separate set of VMs:
> docker-machine create -d hyperv --hyperv-virtual-switch "Better New Virtual Switch" master
> docker-machine create -d hyperv --hyperv-virtual-switch "Better New Virtual Switch" worker1
> docker-machine create -d hyperv --hyperv-virtual-switch "Better New Virtual Switch" worker2
Init swarm:
> docker-machine inspect --format '{{ json .Driver.IPAddress }}' master
"192.168.202.112"
> docker-machine ssh master docker swarm init --advertise-addr 192.168.202.112
To add a worker to this swarm, run the following command:
docker swarm join \
--token SWMTKN-1-4k5ljcmxs1d9q14lth4tfbg868lf8eqi5alxtvgo7s1ptyrhlu-3ihz3bfmx5622vei1smzetudf \
192.168.202.112:2377
Add the workers:
> docker-machine ssh worker1 docker swarm join --token SWMTKN-1-4k5ljcmxs1d9q14lth4tfbg868lf8eqi5alxtvgo7s1ptyrhlu-3ihz3bfmx5622vei1smzetudf 192.168.202.112:2377
> docker-machine ssh worker2 docker swarm join --token SWMTKN-1-4k5ljcmxs1d9q14lth4tfbg868lf8eqi5alxtvgo7s1ptyrhlu-3ihz3bfmx5622vei1smzetudf 192.168.202.112:2377
SSH into the master and go to town (or use it from the host):
> docker-machine ssh master
> docker node ls
ID HOSTNAME STATUS AVAILABILITY MANAGER STATUS
aojoo2h0uuj5hv1c9xajo67o2 worker1 Ready Active
eqt1yd8x52gph3axjkz8lxl1z * master Ready Active Leader
Details here: https://github.com/docker/for-mac/issues/67#issuecomment-242239997

Related

How do I retrieve the IP of a windows host from a docker container?

I am trying to obtain the true IP address of a windows host running a docker container, not the ip address of the bridge. Windows system is using WSL
The following works on a linux host, but not on a windows host.
Create a simple container:-
docker run --rm -d --network host --name test alpine tail -f /dev/null
connect into the container:-
docker exec -it test /bin/sh
run ifconfig
On Linux I can see the true host IP address listed (10.0.0.2)
On windows the host ip address isnt present, but other adapters are.

Multipass VM not reachable via specific http ports from host

I'm running an Ubuntu VM with multipass hyperkit do run microk8s. Within the VM all things checkout and available with skaffold/kubectl port forwarding. For instance:
$ multipass list
Name State IPv4 Image
microk8s-vm Running 192.168.64.2 Ubuntu 20.04 LTS
10.0.1.1
172.17.0.1
10.1.254.64
Port forwarding service/my-app in namespace default, remote port 80 -> 127.0.0.1:4503
Within the VM:curl localhost:4503 ✅
From the host: curl 192.168.64.2:4503🛑
I know the VM is reachable on port 80 because curl 192.168.64.2 returns default ngnix not found page. FWIW I never installed ngnix and the service doesn't seem to be running /cannot turn it off.
I've been at this for a day and I'm stumped. I even tried the Vbox driver and manually configured a bridge adapter. I even created my own adapter...
$ multipass exec -- microk8s-vm sudo bash -c "cat > /etc/netplan/60-bridge.yaml" <<EOF
network:
ethernets:
enp0s8: # this is the interface name from above
dhcp4: true
dhcp4-overrides: # this is needed so the default gateway
route-metric: 200 # remains with the first interface
version: 2
EOF
$ multipass exec microk8s-vm sudo netplan apply
How can I reach this VM from the host?
You cant access your pod ip /portlike this.
If you want to access your pods port over the nodes ip address, you need to define a service type NodePort and then use ipaddressOfNode:NodePort.
curl http://ipaddressOfNode:NodePort
With port-forward you must use the localhost of your host system.
kubectl port-forward svc/myservice 8000:yourServicePort
then
curl http://localhost:8000

Can't run kubectl in docker container from a host machine installed Minikube "The connection to the server 127.0.0.1:32768 was refused"

I want to have a container that can access and run kubectl command on my host machine. Here is what I have:
I have installed Kubernetes and Minikube on my host machine.
I used this docker container: helm-kubectl link
This is the command I run my docker:
docker run -it -v ~/.kube:/root/.kube -v ~/.minikube:/Users/xxxx/.minikube dtzar/helm-kubectl
Inside the container, when I checked the cluster, I can see the context has loaded my minikube, However, I can't run another kubectl command due to the reason "The connection to the server 127.0.0.1:32768 was refused - did you specify the right host or port?".
bash-5.0# kubectl config get-contexts
CURRENT NAME CLUSTER AUTHINFO NAMESPACE
docker-desktop docker-desktop docker-desktop
docker-for-desktop docker-desktop docker-desktop
* minikube minikube minikube
bash-5.0# kubectl get all
The connection to the server 127.0.0.1:32768 was refused - did you specify the right host or port?
I have checked my Kubenetes config at ~/.kube and the port is 32768.
- cluster:
certificate-authority: /Users/xxx/.minikube/ca.crt
server: https://127.0.0.1:32768
name: minikube
I have tried port -p 32768 or --expose 32768 but no luck. So anyone can help this?
Thanks zerkms! It works with --network host

How could I ping my docker container from my host

I have created a ubuntu docker container on my mac
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
5d993a622d23 ubuntu "/bin/bash" 42 minutes ago Up 42 minutes 0.0.0.0:123->123/tcp kickass_ptolemy
I set port as 123.
My container IP is 172.17.0.2
docker inspect 5d993a622d23 | grep IP
"LinkLocalIPv6Address": "",
"LinkLocalIPv6PrefixLen": 0,
"SecondaryIPAddresses": null,
"SecondaryIPv6Addresses": null,
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"IPAMConfig": null,
"IPAddress": "172.17.0.2",
"IPPrefixLen": 16,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
On my Mac I try to ping my container,
Ping 172.17.0.2, I got Request timeout for icmp_seq 0....
What should I do? So my local machine can ping the container I installed. Did I missing some app installation on my container, which is a plain ubuntu system?
You can't ping or access a container interface directly with Docker for Mac.
The current best solution is to connect to your containers from
another container. At present there is no way we can provide routing
to these containers due to issues with OSX that Apple have not yet
resolved. we are tracking this requirement, but we cannot do anything
about it at present.
Docker Toolbox/VirtualBox
When running Docker Toolbox, Docker Machine via VirtualBox or any VirtualBox VM (like a Vagrant definition) you can setup a "Host-Only Network" and access the Docker VMs network via that.
If you are using the default boot2docker VM, don't change the existing interface as you will stop a whole lot of Docker utilities from working, add a new interface.
You will also need to setup routing from your Mac to the container networks via your VM's new IP address. In my case the Docker network range is 172.22.0.0/16 and the Host Only adapter IP on the VM is 192.168.99.100.
sudo route add 172.22.0.0/16 192.168.99.100
Adding a permanent route to osx is bit more complex
Then you can get to containers from your Mac
machost:~ ping -c 1 172.22.0.2
PING 172.22.0.2 (172.22.0.2): 56 data bytes
64 bytes from 172.22.0.2: icmp_seq=0 ttl=63 time=0.364 ms
--- 172.22.0.2 ping statistics ---
1 packets transmitted, 1 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.364/0.364/0.364/0.000 ms
Vagrant + Ansible setup
Here's my running config...
Vagrant.configure("2") do |config|
config.vm.box = "debian/contrib-buster64"
config.vm.hostname = "docker"
config.vm.network "private_network", ip: "10.7.7.7", hostname: true
config.vm.provider "virtualbox" do |vb|
vb.gui = false
vb.memory = "4000"
vb.cpus = "4"
end
config.vm.provision "ansible" do |ansible|
ansible.verbose = "v"
ansible.playbook = "tasks.yaml"
end
end
The ansible tasks.yaml to configure a fixed network.
- hosts: all
become: yes
vars:
ansible_python_interpreter: auto_silent
docker_config:
bip: 10.7.2.1/23
host: ["tcp://10.7.7.7:2375"]
userland-proxy: false
tasks:
- ansible.builtin.apt:
update_cache: yes
force_apt_get: yes
pkg:
- bridge-utils
- docker.io
- python3-docker
- python-docker
- iptables-persistent
- ansible.builtin.hostname:
name: docker
- ansible.builtin.copy:
content: "{{ docker_config | to_json }}"
dest: /etc/docker/daemon.json
- ansible.builtin.lineinfile:
line: 'DOCKER_OPTS="{% for host in docker_config.host %} -H {{ host }} {% endfor %}"'
regexp: '^DOCKER_OPTS='
path: /etc/default/docker
- ansible.builtin.systemd:
name: docker.service
state: restarted
- ansible.builtin.iptables:
action: insert
chain: DOCKER-USER
destination: 10.7.2.0/23
in_interface: eth1
out_interface: docker0
jump: ACCEPT
- ansible.builtin.shell: iptables-save > /etc/iptables/rules.v4
Add the route for the docker bridge network via the VM to the mac
$ sudo /sbin/route -n -v add -net 10.7.2.0/23 10.7.7.7
Then set DOCKER_HOST=10.7.7.7 in the environment to use the new VM.
$ export DOCKER_HOST=10.7.7.7
$ docker run --name route_test --rm -d node:14-slim node -e "require('http').createServer((req, res) => {
res.writeHead(200, {'Content-Type':'text/plain'})
res.end('hello')
}).listen(3000)"
$ docker container inspect route_test -f '{{ .NetworkSettings.Networks.bridge.IPAddress }}'
$ curl http://10.7.2.3:3000
hello
$ docker rm -f route_test
You don't get volumes mapped from the host to the vm, but as a bonus it uses a lot less cpu than the Docker 2.5.x release.
As an alternative, if your container has a bash shell incorporated, you can access it through
docker exec -it <CONTAINER ID> bash
and then you can ping your virtual ip
It works in this scenario:
Windows host
Linux VM installed on Windows host
Docker container installed on Linux VM host
Now you have to note this. Containers are in a isolated network but connected to the internet throught your Docker container host adapter.So you have to tell kernel linux to be available in your network then in your Linux VM:
# sysctl net.ipv4.conf.all.forwarding=1
# sudo iptables -P FORWARD ACCEPT
Now in you Windows host you have to add a route for our container network:
route add "Docker container network" "Linux VM IP" for example
# route add 172.17.0.0/16 192.168.1.20
setup:
PC-A a is docker host, PC-B is a another PC in the network. To ping/access docker's container from PC-B, run the below iptables-rules in the host.
iptables -A FORWARD -i docker0 -o eth0 -j ACCEPT
iptables -A FORWARD -i eth0 -o docker0 -j ACCEPT
note: eth0 is host's interface and docker0 is docker's virtual default bridge.
Now add route in PC-B
route add -net <dockerip> netmask <net mask> gw <docker's host>
ping/access container services directly.
Let's say you have W-> windows machine, L-Linux Vbox VM (eth0,eth1) and docker app (using port 8989) running on this L-Linux Vbox VM. Provider does not have to Vbox anyway or W-> a win.You want to type http://app:8989 on your browser.There are two methods afak; easy way to run vagrant automatically or manually configure Vbox VM with port forwarding through "Host-only Adapter" which is actually eth1; normally eth0 is Vbox's default reserved 10.0.2.15 IP assignment.Or on command prompt on win/lin/mac through "VBoxManage" command you can set up networks or automate through scripts.
webtier.vm.network "forwarded_port", guest: 8989, host: 8989
run docker app
sudo docker run -p 8989:8989 ...
on windows explorer(W-> windows machine) browse your app
http://app:8989
You still can not ping "172.17.0.2" which is docker container IP in this situation from W-> windows machine.This could run cross-platform win/lin/mac.You might want to look into Vbox Manual and Vagrant Manual, particularly networks.
It is possible to run the containers of interest in one and the same network with an additional container with OpenVPN server, so that you can see containers over VPN connection from the host:
Use docker network create --subnet=172.19.0.0/24 my-net to create a network where containers will see each other.
Attach containers to it using --net my-net parameter for docker run.
Run an additional container with OpenVPN in the same network. This time you need a port mapping for VPN connection -p 1194:1194/udp.
Use OpenVPN client on the host to connect to this network with containers to ping them.
Also, you may need to comment out redirect-gateway instruction in OpenVPN client config file and add push "route 172.19.0.0 255.255.255.0" to (and remove other pushes from) the server config file.

How to access web page served by nginx web server running in docker container

We are trying to use docker to run nginx but for some reason I'm unable to access the nginx web server running inside the docker container.
We have booted a Docker Container using the following Dockerfile: https://github.com/dwyl/learn-docker/blob/53cca71042482ca70e03033c66d969b475c61ac2/Dockerfile
(Its a basic hello world using nginx running on port 8888)
To run the container we used:
docker run -it ubuntu bash
we determined the Container's IP address using the docker inspect command:
docker inspect --format '{{ .NetworkSettings.IPAddress }}' a9404c168b21
which is: 172.17.0.11
when I try to visit the container's IP address and the nginx port in a browser http://172.17.0.11:8888/ we get ERR_CONNECTION_TIMED_OUT
or using curl:
curl 172.17.0.11:8888
curl: (7) Failed to connect to 172.17.0.11 port 8888: Connection refused
To attempt to solve this we googled extensively but suspect we might be asking the "wrong" questions...
You shouldn't be trying to hit the IP address of the container, you should be using the IP address of the host machine.
What you are missing is the mapping of the port of the host machine to the port of the container running the nginx server.
Assuming that you want to use port 8888 on the host machine, you need a parameter such as this to map the ports:
docker run ... -p 8888:8888 ...
Then you should be able to access you server at http://<HOST_MACHINE_IP>:8888
EDIT: There is another gotcha if you are running on a Mac. To use Docker on a Mac it's common to use boot2docker but boot2docker adds in another layer. You need determine the IP address of the boot2docker container and use that instead of localhost to access nginx.
$ boot2docker ip
The VM's Host only interface IP address is: <X.X.X.X>
$ wget http://<X.X.X.X>:8888
...
Connecting to <X.X.X.X>:8888... connected.
HTTP request sent, awaiting response... 200 OK
Reference: https://viget.com/extend/how-to-use-docker-on-os-x-the-missing-guide
EDIT: ... or with docker-machine the equivalent command would be docker-machine ip <machine-name> where <machine-name> is likely to be "default".
You may need to check if your container is running:
docker ps ( you should have an active container)
If no container is active:
docker run -p 80:80 -it /bin/bash
you will then be on your image terminal
start nginx - sudo service nginx start
ctrl p + ctrl q to quit docker without exiting the container
if you are on mac and using boot2docker you cannot use localhost to check your running nginx
so use boot2docker ip
browse using the boot2docker ip

Resources