Docker Administration: Docker Networking (ipvlan)

Background:

My home lab’s network is organized and controlled by IPs, access-lists, etc., via Cisco routers and switches, so I wanted my Docker host and containers to have static IP addresses and be within the same IP segment and add custom DNS records to my DNS servers to resolve to them. The Docker networking part is fairly straightforward, but what’s inconvenient is how Docker Desktop for Windows and WSL2 handle their networking part behind the scene. WSL2 gets its own vEthernet adapter with an IP in the 172.0.0.0 range and the containers get placed in a different 172.0.0.0 network segment and assigned with dynamic IPs and depending on how the Hyper-V and WSL2 backend handles the routing and switching, it’s rather difficult (if not impossible) to easily assign static IPs to the containers within the same IP segment as the host machine and make them part of the same subnet for easy access. After a couple of hours fiddling around with different solutions I basically gave up on it as it’s really not worth the time and efforts doing so, I opted to have a dedicated Hyper-V VM running Ubuntu Server as the Docker host.

Solution:

On an Ubuntu Server the networking part becomes straightforward.

Assuming that the Docker host VM has the IP address of 192.168.1.100/24 (this is the IP assigned to interface eth0). To find out what IP the eth0 interface is using, run:

ip address show eth0

Create an ipvlan network:

docker network create --driver ipvlan --subnet=192.168.1.0/24 --gateway=192.168.1.1 -o ipvlan_mode=l2 -o parent=eth0 docker_dev_net

And then we can create containers using this network and assign static IPs to them:

# Let's use ubuntu/mysql Docker image as an example:

docker run -dit --name MySQL_DEV --network docker_dev_net --ip 192.168.1.101 -p 3306:3306 -p 22:22 -e MYSQL_ROOT_PASSWORD=password ubuntu/mysql

# Make sure you add the corresponding DNS entries to your DNS server or router. e.g., on my Cisco router:

ip host MySQL_DEV.mydomain 192.168.1.101

After the containers are running, test the connection with PowerShell:

Test-NetConnection -ComputerName MySQL_DEV.mydomain -Port 3306