Forked from g3rv4/gist:8ba1ef17b4355bb43c6219a9acb7a400
Created
September 13, 2024 03:29
-
-
Save simhaonline/a3d5eecf356b0abe510a8c150706d9f7 to your computer and use it in GitHub Desktop.
Assigning public IPv6 addresses to containers, with a /64 range
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Then, I used the actual server range... Hetzner assigns a /64 IPv6 range. We have to tell Docker the network new containers are going to have, and we also have to specify the network ranges new networks will have (docker compose creates them). | |
If the server has been assigned the `2001:0db8:2a01:4f8::/64` range, that means it can control all the addresses from `2001:0db8:2a01:04f8:0000:0000:0000:0000` to `2001:0db8:2a01:04f8:ffff:ffff:ffff:ffff`. That's... a lot of addresses. The server is using `2001:0db8:2a01:4f8::1` (or `2001:0db8:2a01:04f8:0000:0000:0000:0001`). | |
Now, each docker network needs at least an /80 range so that it can generate ip addresses from mac addresses. | |
So what I'm going to do is: | |
1. Set `2001:0db8:2a01:4f8:1000::/68` as the default network range. It means the default network will have addresses from `2001:0db8:2a01:04f8:1000:0000:0000:0000` to `2001:0db8:2a01:04f8:1fff:ffff:ffff:ffff` | |
2. Add a default address pool that's `2001:0db8:2a01:4f8:2000::/68`, but so that new networks take /80 ranges. In a /68 range there are 4096 /80 ranges, so that's more networks that I'll need. | |
Another small detail: if you don't specify the dns on daemon.json, it won't use the host's information when running in a docker swarm (it's not needed if you don't use a swarm though). | |
Now, this code is very hacky. I couldn't find a reliable way of manipulating IPv6 ranges on bash so instead of requiring another tool, I'm just doing something that works for my use case. | |
``` | |
ipv6_with_prefix=$(ip -6 addr show eth0 | grep "scope global" | awk '{print $2}' | head -n1) | |
IFS="/" read -ra ADDR <<< "$ipv6_with_prefix" | |
ipv6=${ADDR[0]} | |
length=${ADDR[1]} | |
if (( length != 64 )); then | |
echo "Error: Prefix length is not 64" | |
exit 1 | |
fi | |
ipv6_68_default="${ipv6%%::*}:1000::/68" | |
ipv6_68_new_networks="${ipv6%%::*}:2000::/68" | |
# Generate /etc/docker/daemon.json | |
cat <<EOF | sudo tee /etc/docker/daemon.json >/dev/null | |
{ | |
"ipv6": true, | |
"fixed-cidr-v6": "$ipv6_68_default", | |
"experimental": true, | |
"ip6tables": true, | |
"default-address-pools":[ | |
{"base": "172.31.0.0/16", "size": 24}, | |
{"base": "$ipv6_68_new_networks", "size": 80} | |
], | |
"dns": ["2a00:1098:2c::1", "2a01:4f9:c010:3f02::1", "2a00:1098:2b::1"] | |
} | |
EOF | |
sudo systemctl restart docker | |
``` |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment