At this time, Docker isn’t compatible with nftables. This is how you can do with an example with Drone CI (Docker Runner).
Docker fix for nftables (systemd way)
We need to fix docker.service
using a little fix to disable iptables and fix the IP range used by Docker
mkdir /etc/systemd/system/docker.service.d
cat << EOF > /etc/systemd/system/docker.service.d/nftables-fix.conf
[Service]
ExecStart=
ExecStart=/usr/bin/dockerd -H fd:// --containerd=/run/containerd/containerd.sock --iptables=false --fixed-cidr=172.17.0.0/16
EOF
We need the first ExecStart without nothing to cancel the official ExecStart for docker.service
, I don’t replace this file.
nftables rules
I transposed rules from iptables to nftables, you can optimize it and I’ll like to read it.
table ip nat {
chain PREROUTING {
fib daddr type local jump DOCKER
}
chain POSTROUTING {
oifname != "docker0" ip saddr 172.17.0.0/16 masquerade
ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3000 masquerade
}
chain OUTPUT {
ip daddr != 127.0.0.0/8 fib daddr type local jump DOCKER
}
chain DOCKER {
iifname "docker0" return
iifname != "docker0" ip daddr 127.0.0.1 tcp dport 3000 dnat to 172.17.0.2:3000
}
}
table ip filter {
chain INPUT {
iifname "docker0" accept
}
chain FORWARD {
oifname "docker0" ct state established,related accept
oifname "docker0" jump DOCKER
iifname "docker0" oifname != "docker0" accept
iifname "docker0" oifname "docker0" accept
jump DOCKER-USER
jump DOCKER-ISOLATION-STAGE-1
}
chain DOCKER-USER {
return
}
chain DOCKER {
iifname != "docker0" oifname "docker0" ip daddr 172.17.0.2 tcp dport 3000 accept
}
chain DOCKER-ISOLATION-STAGE-1 {
iifname "docker0" oifname != "docker0" jump DOCKER-ISOLATION-STAGE-2
return
}
chain DOCKER-ISOLATION-STAGE-2 {
oifname "docker0" drop return
}
}
How to start successfully the container
I use the easiest fix: fixed IP
docker run -d --ip 172.17.0.2 \
-v /var/run/docker.sock:/var/run/docker.sock \
-e DRONE_RPC_PROTO=https \
-e DRONE_RPC_HOST=drone.lina.local \
-e DRONE_RPC_SECRET=MY_RPC_SECRET \
-e DRONE_RUNNER_CAPACITY=12 \
-e DRONE_RUNNER_NAME=runner1 \
-p 127.0.0.1:3000:3000 \
--restart always \
--name runner \
drone/agent
Right now, you have your Docker Runner running with success
Conclusion
It’s strange to use fixed IP where Docker is for “automated” and “magic” deployment but it’s the only way to use it with nftables.
It’s a fix for now and I’m impatient to migrate from Docker to Podman (used to run Drone Server) but I need to wait, not my CI/CD.