2

Objective: Assign fixed IP address to Docker container (Unifi Controller instance).

History: I fetched the unifi controller image from Docker Hub to my Synology Docker host. The container of the unifi controller runs properly if I attach it to the network of the host (not the default bridge). That blocks though multiple ports I need for other services (in the future). Thus it would be much easier to assign that unifi container with it's own designated IP --> 192.168.2.2 (than changing all the ports).

I guess that is a cinch to deal with for most in here.

Indications of my misconception:

  • I created my own network in the Synology Docker GUI (with the subnet 192.168.2.0/23 and gateway 192.168.2.1)
  • I assigned it to a new unifi-controller container instance.
  • The GUI suggests to map the host ports with "auto" to the container ports, which indicates me that I do NOT understand completly the network concept of Docker. Because if I'm able to set an individual IP, why should it allow to map host ports (to container ports)?

Questions:

  • Why can I not assign a fixed IP to the container in the GUI?
  • What am I conceptually missing?
  • If not in the GUI, how can I accomplish it over SSH/Bash?
2

SOLUTION APPROACH

The approach is to create a macvlan. This will create a virtual adapter, that is allowed to lease an IP address from the subnet defined.

1) Activate Promiscous Mode

For the virtual adapter one must enable promiscuous mode in the network. For Unifi controllers, do a SSH to your gateway and set:

ifconfig [interface] promisc

Some network gateways/controllers have set promiscuous mode by default. Continue with step 2 before you're wasting time to find that out.

2) Create macvlan

Then one can create the macvlan.

$ docker network create -d macvlan \
  --subnet=192.168.2.0/23 \
  --ip-range=192.168.2.5/25 \
  --gateway=192.168.2.1 \
  --aux-address="my-router=192.168.2.10" \
  -o parent=eth0 unifinet
  • Limiting the IP range: use --ip-range to scope the possible IPs to lease.

  • Avoiding certain IPs: The --aux-address marks my Synology host, which should never ever battle for that IP address (It's marked in the unifi controller's DHCP service as a fixed IP anyways).

  • the -o parent is your network interface you want to attach your macvlan. In my case unifinet.

Check with docker network ls if the macvlan has been properly created.

NETWORK ID          NAME                DRIVER              SCOPE
c49094a4c914        bridge              bridge              local
b2315de1aa7e        host                host                local
c124eda0f9d2        none                null                local
a60da50f0d12        unifinet            macvlan             local

3) Start Docker Container

While you define the image (--name UnifiController jacobalberty/unifi) assign the freshly created macvlan (--network unifinet) to the container (UnifiController). It will grab the latest image respectively the latest Unifi Controller version available from Docker Hub.

docker run -dit --network unifinet --name UnifiController jacobalberty/unifi

Verify if the container has been assigned to the network in the container section of the JSON config.

sudo docker network inspect unifinet.

[
    {
        "Name": "unifinet",
        "Id": "a60da50f0d1229d1a3c76210141e0c81567c17daf6c2b49d4f1c83d5ec9f02b3",
        "Created": "2019-10-04T14:39:37.377311991+02:00",
        "Scope": "local",
        "Driver": "macvlan",
        "EnableIPv6": false,
        "IPAM": {
            "Driver": "default",
            "Options": {},
            "Config": [
                {
                    "Subnet": "192.168.2.0/24",
                    "Gateway": "192.168.2.1"
                }
            ]
        },
        "Internal": false,
        "Attachable": false,
        "Ingress": false,
        "ConfigFrom": {
            "Network": ""
        },
        "ConfigOnly": false,
        "Containers": {
            "b819bf1d6f3af459825a1a7b58f9a44e15e6e09489e7bf50653ed8e1e176fd73": {
                "Name": "UnifiController",
                "EndpointID": "41a048034ad63e48b46b58aed65661c9eaa2bf6937d3eebacefde4478ad26cce",
                "MacAddress": "02:42:c0:a8:02:02",
                "IPv4Address": "192.168.2.2/24",
                "IPv6Address": ""
            }
        },
        "Options": {
            "parent": "eth0"
        },
        "Labels": {}
    }
]

The IP 192.168.2.2 is assigned. The container workes properly and stable.

4) Optional/Reminder

If the IP was not assigned respectively one cannot connect to it for any service, the follow up on the promiscious mode setting as described in Step 1.

4
  • Is this possible when the container is launched by kubernetes?
    – LLlAMnYP
    Oct 5 '19 at 8:09
  • @LLlAMnYP I see no reason why that should not be the case if you keep the macvlan up and assign it to the container. I bet it works. But that is merely an assumption. Let us know.
    – feder
    Oct 6 '19 at 12:21
  • Well, the intended question is more like "how to do this in practice". The internet usually responds vaguely with something like "use the macvlan cni driver", but I haven't found a proper detailed description so far.
    – LLlAMnYP
    Oct 6 '19 at 14:29
  • 1
    @LLlAMnYP I hear you. I'll check at work. I'm certain rather sooner than later I run into this - and then I'll document it. Since I strongly believe it's consequent to allocate an IP address to every single service one has. This fosters the decoupling and isolation of service even more than just sharing an IP and the set services on ports. Of course, that decision depends on your network setup (available IPs), number of services, etc.
    – feder
    Oct 6 '19 at 15:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.