How does the Docker assign MAC addresses to containers? - docker

When I start new containers, Docker automatically assigns some MAC address to them. I am curious if there is a pattern to this assignment. Can the MAC address be changed?
$ docker network inspect bridge
"Containers": {
"3386a527aa08b37ea9232cbcace2d2458d49f44bb05a6b775fba7ddd40d8f92c": {
"EndpointID": "647c12443e91faf0fd508b6edfe59c30b642abb60dfab890b4bdccee38750bc1",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
},
"94447ca479852d29aeddca75c28f7104df3c3196d7b6d83061879e339946805c": {
"EndpointID": "b047d090f446ac49747d3c37d63e4307be745876db7f0ceef7b311cbba615f48",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
}

Docker start assigning always the same mac 02:42:ac:11:00:02 for the first container and then is increasing by one each mac for each different container.
Not sure why they are using that mac address. It seems 02:42:ac doesn't match any real vendor in oui databases. Look at the official documentation about this. They say:
The MAC address is generated using the IP address allocated to the container to avoid ARP collisions, using a range from 02:42:ac:11:00:00 to 02:42:ac:11:ff:ff
Anyway, you can set any mac address on container generation using --mac-address parameter on the docker run command. For example doing a command like this docker run -ti --mac-address 00:00:00:00:00:11 ubuntu:trusty
Hope it helps.

If you look at the MAC address of the container interface(s), you can see that the last 4 octets are the hex representation of the IPv4 address. This part is prefixed by 02:42:
For example:-
The docker generated MAC address of the container interface with IPv4 address 172.19.0.6 would be 02:42:ac:13:00:06

Related

Docker - Xdebug debug PHP CLI script (VS Code)

This question is regarding getting Xdebug to work with a CLI PHP script hosted inside a web-server Docker instance.
I have docker containers : web-server, varnish-cache, nginx-proxy.
I am able to successfully debug a Magento 2 web-page via browser with this VS Code Launch config:
This is with the new XDebug v3 which removed alot of v2 configuration settings
Client (Windows 10) IP (my laptop) : 192.168.1.150, Host (Ubuntu 20.04) IP: 192.168.1.105, hosting with Docker containers IP: 172.100.0.2-5
VS Code launch:
"name": "(Magento 2) Listen for XDebug on 192.168.1.5/105",
"type": "php",
"request": "launch",
"port": 9099,
"stopOnEntry": false, // Set to true to test any script on entry
"log": false,
// Remember to update remote_connect_back or remote_host
// inside xdebug PHP configuration.
// When using CLI debugging - rather use remote_host,
// because remote_connect_back = 1 does not work with CLI
// Server -> Local
"pathMappings": {
"/var/www/html/": "${workspaceRoot}",
},
"xdebugSettings": {
"max_children": 10000,
"max_data": 10000,
"show_hidden": 1
}
},
XDebug configuration (PHP 7.3)
zend_extension=xdebug.so
xdebug.log=/var/log/apache2/xdebug.log
xdebug.idekey=VSCODE
xdebug.client_port=9099
xdebug.client_discovery_header=HTTP_X_REAL_IP
xdebug.discover_client_host=On
; fallback for CLI - use client_host
xdebug.client_host=172.100.0.2
xdebug.start_with_request=yes
xdebug.mode=debug
Docker network:
docker inspect network magento2-network-frontend:
"Containers": {
"6538a93fbe811fbbd9646d4ce089e1b686b508862ed86f6afaac1b600043a1e5": {
"Name": "redis-cache-magento2.3.5",
"EndpointID": "d27bfbff61765cf2b840e98d43ec7a378e182baa7007dabde4bab5a41734fa2a",
"MacAddress": "02:42:ac:64:00:05",
"IPv4Address": "172.100.0.5/16",
"IPv6Address": ""
},
"7c7ba745db17d6d6a100901ed1e3fe38a3d26a97e086edc155254a7d41033bcf": {
"Name": "web-server-apache2-magento2-3-5",
"EndpointID": "9b81f6b7ff2292eba6fb68af209f1d5c958bea3ee0d505512862f225ed8e57be",
"MacAddress": "02:42:ac:64:00:02",
"IPv4Address": "172.100.0.2/16",
"IPv6Address": ""
},
"7f208ecce2aafdf182e4616ef2e8b043f3b8245018c299aae06c1acf4fc0d029": {
"Name": "varnish-cache-magento2-3-5",
"EndpointID": "e1c4e3f9e792b7dfd2cebfbb906bd237795820639a80ab8f530f0c8418257611",
"MacAddress": "02:42:ac:64:00:03",
"IPv4Address": "172.100.0.3/16",
"IPv6Address": ""
},
"dc599fa93b09650b70f8f95333caecc8f9db18cd19b17be57d84196e91f54c2a": {
"Name": "nginx-proxy-magento2-3-5",
"EndpointID": "7b8396af676d9af51b098d09f20d9e73ef83f4b085cb5f7195ea234aae7ed91d",
"MacAddress": "02:42:ac:64:00:04",
"IPv4Address": "172.100.0.4/16",
"IPv6Address": ""
}
The CLI command: _as can be seen it's a Magento 2 bin/magento migrate:data command from within the hosting Apache2 Web-server Docker container. (IP shown above is then : 172.100.0.2)
rm var/migration* && bin/magento migrate:data /var/www/html/app/code/ModuleOverrides/Magento_DataMigrationTool/etc/opensource-to-opensource/1.7.0.2/config.localboth.host_restoredb.xml
No debug breakpoints will work in my VS Code on Windows 10 Client (IP 192.168.1.150) because I am calling the script from within the container 172.100.0.2.
The log file /var/log/apache2/xdebug.log confirms something along this line:
Could not connect to debugging client. Tried: 172.100.0.2:9099 (fallback through xdebug.client_host/xdebug.client_port) :-(
So, since I have no idea how to run a CLI script from Windows 10 client and only from within Docker container, how/what can I do to get this CLI script to connect to Xdebug?
Additional information (if needed)
Magento 2 has CLI capability bin/magento [command] - and the command I am trying to debug is part of the data-migration-tool which is failing to import attributes correctly. No-one has a 100% working solution on the github repo for this particular issue - so I want to try and dig deeper to try and find a solution. Also, the tool is only a CLI tool, no web-ui option.
You need to set Xdebug's xdebug.client_host to the IP address of your IDE, which you indicated is 192.168.1.150.
You also need to turn off xdebug.discover_client_host, as that would try to use the internal Docker network IP (172.100.0.2), which is not where your IDE is listening on.
Remember: Xdebug makes a connection to the IDE, not the other way around.

Docker internals using IP address from the user’s IP address pool

Docker version 18.09.0, build 4d60db4
OS VERSION : Centos 7
Problem statement : -
I have a master machine and a worker machine on the same LAN. Both are connected by the docker-machine utility. The worker machine is expected to run 3 zookeeper standalone containers. I have created a docker overlay network, on my master machine, using -
docker network create --attachable --subnet 200.184.152.0/24 --gateway 200.184.152.254 --driver overlay my network
I want to bind zookeeper container with fixed IP address as follows : -
zoo1 : 200.184.152.2
zoo2: 200.184.152.3
zoo3: 200.184.152.4
After moving to the shell of the worker machine by using the command :
eval $(docker-machine env worker-1)
I run zookeeper’s first instancezoo1: 200.184.152.2. It successfully runs.
Then I try to run second Zookeeper instance zoo2: 200.184.152.3, but it fails to give a network error.
Then I inspect the network using docker network inspect my-network on worker machine and in the containers section it shows the results : -
"Containers": {
"1a2471c777c907dc05bb0f23e819919354669de699f862e4fdc093293d145b31": {
"Name": "zoo1",
"EndpointID": "8bb5eebd1cacf36dc7cdad7fc3d72c45047c66b455c568cc9e8911d2121fd8d6",
"MacAddress": "02:42:c8:b8:98:02",
"IPv4Address": "200.184.152.2/24",
"IPv6Address": ""
},
"lb-my-network": {
"Name": "my-network-endpoint",
"EndpointID": "8f747b26e921ee1543631b758b7dfaf8c7e820c47a95849608dc3568f9957e79",
"MacAddress": "02:42:c8:b8:98:03",
"IPv4Address": "200.184.152.3/24",
"IPv6Address": ""
}
},
This lb-my-network is using IP address required by my components, because of this the entire automatic deployment fails. The worst is, the IP address of lb-my-network changes it keeps clashing with IP address of other containers.
Is this expected? If yes, then how can I deploy a number of containers using automation when docker is using IP addresses randomly from the pool reserved by user’s logic.
In the documentation, it is stated that the docker needs three address for it’s working, a network address, a broadcast address, and a gateway address, so 253 addresses can be used by the user in /24 subnet. But here the lb-my-network is using IP address from the pool being expected to be used by user’s containers.
Help will be appreciated.

Docker - connect from HOST to container

I am using Docker for Windows with created bridge network:
"bridge":"none" (daemon.json)
docker network create --subnet 192.168.23.1/24 --gateway 192.168.23.1 --driver bridge my-network
... and container with Jenkins image.
When I configure connection between Jenkins (container) and Gitlab ("internet") everything is working fine. But when I am creating Webhook in Gitlab I have to enter URL of Jenkins. I was trying with localhost and IP obtained from IPAddress property:
"Networks": {
"my-network": {
"IPAMConfig": null,
"Links": null,
"Aliases": [
"jenkins",
"dff5dcb7c95a"
],
"NetworkID": "xxx",
"EndpointID": "yyy",
"Gateway": "192.168.23.1",
"IPAddress": "192.168.23.2",
"IPPrefixLen": 24,
"IPv6Gateway": "",
"GlobalIPv6Address": "",
"GlobalIPv6PrefixLen": 0,
"MacAddress": "zzz",
"DriverOpts": null
}
}
.. but both options have been not working.
Question: How to determine correct URL?
How to connect from HOST to my container? Is it correct approach? What issues should I know to resolve following problems in the future?
Thanks for help :)
If you are running your Gitlab-instance also in a Docker-container you just need to add the Gitlab-container to the same Docker-network.
If your Gitlab-instance is really in the internet, you can not solve this with localhost or any local IP-adress. You need to:
find out your public IP-adress, maybe use dynDNS to get a fix domain if you have a dynamic IP
open a port on your router and configure your firewall
open a port on your local windows firewall
need to find out on which port jenkins is waiting for the webhooks from GitLab
map this port to the docker-container by using
--p <docker-internal-port>:<docker-external-port>
If you would provide some more information about your network infrastruture, the answer could be clearer.

How can one refer to the hostname of a docker network ip?

For example on localhost we just refer to localhost:port to connect to a process running on the port port on the local machine. Is there a way to refer to the network the container is running on so we don't have to worry and hard-code what is the ip of a specific container/service. For instance if we want to connect to the postgresql database we would just write bridge1:5432.
EDIT : #fly2matrix suggested to use the named container solution but it didn't work, docker network inspect bridge returns
...
"Containers": {
"2375b29321dc4a5947f8b63b46fe1c955f43fb1fbca64bb2adce3503380dda37": {
"Name": "somepostgres",
"EndpointID": "398ec0e792b836ceb5dd5d2e448e813047f9157ad90283b448e40eaf3f4f5b66",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"a72fbb333e2d8cd3b7b78205795456fadc44678348ccedc58a78510cd273505b": {
"Name": "pizz",
"EndpointID": "2e7aa30844a632f4d42e3d0cfa16003dfd1d86aef85e63d16c83b3a71601e134",
"MacAddress": "02:42:ac:11:00:02",
"IPv4Address": "172.17.0.2/16",
"IPv6Address": ""
}
},
My containers are on the same boat but if I try to connect to somepostgres:5432 from pizz container it just says 'unknown host'.
Try using named containers ,
#>docker run -d -it --name "container-name" {image-name}:{tag}
and other container can reach this container using name container-name of required containers.
Additionally you can also use --link option to link containers (internally it will create an entry in /etc/hosts to create alias dns name)

Access docker bridge using docker exec

first of all, I'm a totally n00b in docker, but I got into a project that are actually running in docker, so I've been reading about it.
My problem is, I have to inspect my development environment in a mobile device(iOS). I tried to access by my docker ip because this is what I basically do in my computer. After a few failed attempts I noticed that I've to access with the docker network bridge instead of docker host(the default).
I already have defined my docker bridge( I think its default), but i have no idea how to run my server with this network, can you guys help me?
A few important notes:
I'm using MAC OS X El capitan ( 10.11.1 )
The device and the mac are in the same wi-fi network and i can access using regularly localhost outside docker.
My following steps to run my server is:
cd gsat_grupo_5/docker && docker-compose -p gsat_grupo_5 up -d
docker exec -it gsatgrupo5_web_1 bash
python manage.py runserver 0.0.0.0:8000
When I run docker ps my output is:
My docker bridge output:
{
"Name": "bridge",
"Id": "1b3ddfda071096b16b92eb82590326fff211815e56344a5127cb0601ab4c1dc8",
"Scope": "local",
"Driver": "bridge",
"EnableIPv6": false,
"IPAM": {
"Driver": "default",
"Options": null,
"Config": [
{
"Subnet": "172.17.0.0/16",
"Gateway": "172.17.0.1"
}
]
},
"Internal": false,
"Containers": {
"565caba7a4397a55471bc6025d38851b1e55ef1618ca7229fcb8f8dfcad68246": {
"Name": "gsatgrupo5_mongo_1",
"EndpointID": "471bcecbef0291d42dc2d7903f64cba6701f81e003165b6a7a17930a17164bd6",
"MacAddress": "02:42:ac:11:00:05",
"IPv4Address": "172.17.0.5/16",
"IPv6Address": ""
},
"5e4ce98bb19313272aabd6f56e8253592518d6d5c371d270d2c6331003f6c541": {
"Name": "gsatgrupo5_thumbor_1",
"EndpointID": "67f37d27e86f4a53b05da95225084bf5146261304016809c99c7965fc2414068",
"MacAddress": "02:42:ac:11:00:03",
"IPv4Address": "172.17.0.3/16",
"IPv6Address": ""
},
"a0b62a2da367e720d3a55deb7377e517015b06ebf09d153c6355b8ff30cc9977": {
"Name": "gsatgrupo5_web_1",
"EndpointID": "52687cc252ba36825d9e6d8316d878a9aa8b198ba2603b8f1f5d6ebcb1368dad",
"MacAddress": "02:42:ac:11:00:06",
"IPv4Address": "172.17.0.6/16",
"IPv6Address": ""
},
"b3286bbbe9259648f15e363c8968b64473ec0a9dfe1b1a450571639b8fa0ef6f": {
"Name": "gsatgrupo5_mysql_1",
"EndpointID": "53290cb44cf5ed8322801d2dd0c529518f7d414b3c5d71cb6cca527767dd21bd",
"MacAddress": "02:42:ac:11:00:04",
"IPv4Address": "172.17.0.4/16",
"IPv6Address": ""
}
},
"Options": {
"com.docker.network.bridge.default_bridge": "true",
"com.docker.network.bridge.enable_icc": "true",
"com.docker.network.bridge.enable_ip_masquerade": "true",
"com.docker.network.bridge.host_binding_ipv4": "0.0.0.0",
"com.docker.network.bridge.name": "docker0",
"com.docker.network.driver.mtu": "1500"
},
"Labels": {}
}
]
If there's some another smart approach to access my environment in my mobile device I'm listening.
I've to access with the docker network bridge instead of docker host(the default).
Unless you have a protocol that does something odd, like connecting back out to the device from the server, normally accessing <macip>:8000 from your device would be enough. Can you test the service from any other computers?
If you do require direct access the container network, that's a bit harder when using a Mac...
Docker for Mac doesn't support direct access to the Linux virtual machines bridge networks where your containers run.
Docker Toolbox runs a VirtualBox VM with the boot2docker vm image. It would be possible to use this but it's a little harder to apply custom network config to the VM that is setup and run via the docker-machine tools.
Plain Virtualbox is probably your best option, running your own VM with Docker installed.
Add two bridged network interfaces to the VM in Virtualbox. One for the VM and one for the the container, so they can both be available on your main network.
The first interface is for the host. It should pick up an address from DHCP like normal and Docker will then be available on your normal network.
The second bridged interface can be attached to your docker bridge and then the containers on that bridge will be on your home network.
On pre v1.10 versions of docker Pipework can be used to physically mapped an interface in to the container.
There is some specific VirtualBox interface setup required for both methods to make sure all this works.
Vagrant
Vagrant might make the VM setup a bit easier and repeatable.
$ mkdir dockervm
$ cd dockervm
$ vagrant init debian/jessie64
Vagrantfile network config:
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
config.vm.network "public_network", bridge: "en1: Wi-Fi (AirPort)"
config.vm.provider "virtualbox" do |v|
v.customize ['modifyvm', :id, '--nictype1', 'Am79C973']
v.customize ['modifyvm', :id, '--nicpromisc1', 'allow-all']
v.customize ['modifyvm', :id, '--nictype2', 'Am79C973']
v.customize ['modifyvm', :id, '--nicpromisc2', 'allow-all']
end
Note that this VM will have 3 interfaces. The first interface is for Vagrant to use as a management address and should be left as is.
Start up
$ vagrant up
$ vagrant ssh

Resources