{"id":126,"date":"2019-10-30T20:28:00","date_gmt":"2019-10-31T01:28:00","guid":{"rendered":"http:\/\/127.0.0.1:8080\/?p=126"},"modified":"2024-01-07T18:39:32","modified_gmt":"2024-01-07T23:39:32","slug":"docker-nftables-example-with-drone-ci-docker-runner","status":"publish","type":"post","link":"http:\/\/10.42.0.68:8080\/blog\/docker-nftables-example-with-drone-ci-docker-runner","title":{"rendered":"Docker + nftables: example with Drone CI \u2013 Docker Runner"},"content":{"rendered":"\n

<\/h1>\n\n\n\n

At this time, Docker isn’t compatible with nftables. This is how you can do with an example with Drone CI<\/a> (Docker Runner<\/a>).<\/p>\n\n\n\n\n\n\n\n

Docker fix for nftables (systemd way)<\/h1>\n\n\n\n

We need to fix docker.service<\/code> using a little fix to disable iptables and fix the IP range used by Docker<\/p>\n\n\n\n

mkdir \/etc\/systemd\/system\/docker.service.d\n\ncat << EOF > \/etc\/systemd\/system\/docker.service.d\/nftables-fix.conf\n[Service]\nExecStart=\nExecStart=\/usr\/bin\/dockerd -H fd:\/\/ --containerd=\/run\/containerd\/containerd.sock --iptables=false --fixed-cidr=172.17.0.0\/16\nEOF<\/code><\/pre>\n\n\n\n

We need the first ExecStart<\/strong><\/em> without anything to cancel the official ExecStart for docker.service<\/code>, I don’t replace this file.<\/p>\n\n\n\n

nftables rules<\/h1>\n\n\n\n

I transposed rules from iptables to nftables, you can optimize it and I’d like to read it.<\/p>\n\n\n\n

table ip nat {\n     chain PREROUTING {\n          fib daddr type local jump DOCKER\n     }\n     chain POSTROUTING {\n          oifname != \"docker0\" ip saddr 172.17.0.0\/16 masquerade\n          ip saddr 172.17.0.2 ip daddr 172.17.0.2 tcp dport 3000 masquerade\n     }\n     chain OUTPUT {\n          ip daddr != 127.0.0.0\/8 fib daddr type local jump DOCKER\n     }\n     chain DOCKER {\n          iifname \"docker0\" return\n          iifname != \"docker0\" ip daddr 127.0.0.1 tcp dport 3000 dnat to 172.17.0.2:3000\n     }\n}\n\ntable ip filter {\n     chain INPUT {\n          iifname \"docker0\" accept\n     }\n     chain FORWARD {\n          oifname \"docker0\" ct state established,related accept\n          oifname \"docker0\" jump DOCKER\n          iifname \"docker0\" oifname != \"docker0\" accept\n          iifname \"docker0\" oifname \"docker0\" accept\n          jump DOCKER-USER\n          jump DOCKER-ISOLATION-STAGE-1\n     }\n     chain DOCKER-USER {\n          return\n     }\n     chain DOCKER {\n          iifname != \"docker0\" oifname \"docker0\" ip daddr 172.17.0.2 tcp dport 3000 accept\n     }\n     chain DOCKER-ISOLATION-STAGE-1 {\n          iifname \"docker0\" oifname != \"docker0\" jump DOCKER-ISOLATION-STAGE-2\n          return\n     }\n     chain DOCKER-ISOLATION-STAGE-2 {\n          oifname \"docker0\" drop return\n     }\n}<\/code><\/pre>\n\n\n\n

How to start successfully the container<\/h1>\n\n\n\n

I use the easiest fix: fixed IP<\/p>\n\n\n\n

docker run -d --ip 172.17.0.2 \\\n-v \/var\/run\/docker.sock:\/var\/run\/docker.sock \\\n-e DRONE_RPC_PROTO=https \\\n-e DRONE_RPC_HOST=drone.lina.local \\\n-e DRONE_RPC_SECRET=MY_RPC_SECRET \\\n-e DRONE_RUNNER_CAPACITY=12 \\\n-e DRONE_RUNNER_NAME=runner1 \\\n-p 127.0.0.1:3000:3000 \\\n--restart always \\\n--name runner \\\ndrone\/agent<\/code><\/pre>\n\n\n\n

Right now, you have your Docker Runner running with success<\/p>\n\n\n\n

Conclusion<\/h1>\n\n\n\n

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.<\/p>\n\n\n\n

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.<\/p>\n","protected":false},"excerpt":{"rendered":"

At this time, Docker isn’t compatible with nftables. This is how you can do with an example with Drone CI (Docker Runner).<\/p>\n","protected":false},"author":1,"featured_media":82,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"saved_in_kubio":false,"footnotes":""},"categories":[14,9],"tags":[15,10],"_links":{"self":[{"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/posts\/126"}],"collection":[{"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/comments?post=126"}],"version-history":[{"count":1,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/posts\/126\/revisions"}],"predecessor-version":[{"id":127,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/posts\/126\/revisions\/127"}],"wp:featuredmedia":[{"embeddable":true,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/media\/82"}],"wp:attachment":[{"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/media?parent=126"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/categories?post=126"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/10.42.0.68:8080\/wp-json\/wp\/v2\/tags?post=126"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}