From da22584bae1b6095cd615401b0d301c2d09deeb6 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Mon, 18 Dec 2023 14:50:28 -0800 Subject: [PATCH 1/3] Ignore the exit code of `modprobe` always The nature of `modprobe` in this image is that it works via `ip` hacks, but the exit code will always be non-zero because we don't have `/lib/modules` from the host. The effect of this was that everyone was using `iptables-legacy` (whether it was warranted for them to be doing so or not). --- 24/dind/dockerd-entrypoint.sh | 10 +++++++--- 25-rc/dind/dockerd-entrypoint.sh | 10 +++++++--- dockerd-entrypoint.sh | 10 +++++++--- 3 files changed, 21 insertions(+), 9 deletions(-) diff --git a/24/dind/dockerd-entrypoint.sh b/24/dind/dockerd-entrypoint.sh index c15a62417..9f892b053 100755 --- a/24/dind/dockerd-entrypoint.sh +++ b/24/dind/dockerd-entrypoint.sh @@ -148,10 +148,14 @@ if [ "$1" = 'dockerd' ]; then # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - if ! modprobe nf_tables; then + modprobe nf_tables || : + if ! iptables -nL > /dev/null 2>&1; then + # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi fi fi diff --git a/25-rc/dind/dockerd-entrypoint.sh b/25-rc/dind/dockerd-entrypoint.sh index c15a62417..9f892b053 100755 --- a/25-rc/dind/dockerd-entrypoint.sh +++ b/25-rc/dind/dockerd-entrypoint.sh @@ -148,10 +148,14 @@ if [ "$1" = 'dockerd' ]; then # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - if ! modprobe nf_tables; then + modprobe nf_tables || : + if ! iptables -nL > /dev/null 2>&1; then + # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi fi fi diff --git a/dockerd-entrypoint.sh b/dockerd-entrypoint.sh index c15a62417..9f892b053 100755 --- a/dockerd-entrypoint.sh +++ b/dockerd-entrypoint.sh @@ -148,10 +148,14 @@ if [ "$1" = 'dockerd' ]; then # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 # https://github.com/docker-library/docker/pull/437#issuecomment-1854900620 - if ! modprobe nf_tables; then + modprobe nf_tables || : + if ! iptables -nL > /dev/null 2>&1; then + # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi fi fi From d5d05eb749dad8d893b45d7e4a928e4dfe1f33f7 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Tue, 19 Dec 2023 10:25:51 -0800 Subject: [PATCH 2/3] Use `/proc/net/ip_tables_names` (and friends) to pre-detect whether we should use `iptables-legacy` --- 24/dind/dockerd-entrypoint.sh | 22 +++++++++++++++++++--- 25-rc/dind/dockerd-entrypoint.sh | 22 +++++++++++++++++++--- dockerd-entrypoint.sh | 22 +++++++++++++++++++--- 3 files changed, 57 insertions(+), 9 deletions(-) diff --git a/24/dind/dockerd-entrypoint.sh b/24/dind/dockerd-entrypoint.sh index 9f892b053..799204023 100755 --- a/24/dind/dockerd-entrypoint.sh +++ b/24/dind/dockerd-entrypoint.sh @@ -143,7 +143,20 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - if ! iptables -nL > /dev/null 2>&1; then + iptablesLegacy= + if ( + # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 + # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 + for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do + if b="$(cat "$f")" && [ -n "$b" ]; then + exit 0 + fi + done + exit 1 + ); then + # if we already have any "legacy" iptables rules, we should always use legacy + iptablesLegacy=1 + elif ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 @@ -153,11 +166,14 @@ if [ "$1" = 'dockerd' ]; then # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + iptablesLegacy=1 fi fi fi + if [ -n "$iptablesLegacy" ]; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/25-rc/dind/dockerd-entrypoint.sh b/25-rc/dind/dockerd-entrypoint.sh index 9f892b053..799204023 100755 --- a/25-rc/dind/dockerd-entrypoint.sh +++ b/25-rc/dind/dockerd-entrypoint.sh @@ -143,7 +143,20 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - if ! iptables -nL > /dev/null 2>&1; then + iptablesLegacy= + if ( + # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 + # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 + for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do + if b="$(cat "$f")" && [ -n "$b" ]; then + exit 0 + fi + done + exit 1 + ); then + # if we already have any "legacy" iptables rules, we should always use legacy + iptablesLegacy=1 + elif ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 @@ -153,11 +166,14 @@ if [ "$1" = 'dockerd' ]; then # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + iptablesLegacy=1 fi fi fi + if [ -n "$iptablesLegacy" ]; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/dockerd-entrypoint.sh b/dockerd-entrypoint.sh index 9f892b053..799204023 100755 --- a/dockerd-entrypoint.sh +++ b/dockerd-entrypoint.sh @@ -143,7 +143,20 @@ if [ "$1" = 'dockerd' ]; then # XXX inject "docker-init" (tini) as pid1 to workaround https://github.com/docker-library/docker/issues/318 (zombie container-shim processes) set -- docker-init -- "$@" - if ! iptables -nL > /dev/null 2>&1; then + iptablesLegacy= + if ( + # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 + # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 + for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do + if b="$(cat "$f")" && [ -n "$b" ]; then + exit 0 + fi + done + exit 1 + ); then + # if we already have any "legacy" iptables rules, we should always use legacy + iptablesLegacy=1 + elif ! iptables -nL > /dev/null 2>&1; then # if iptables fails to run, chances are high the necessary kernel modules aren't loaded (perhaps the host is using xtables, for example) # https://github.com/docker-library/docker/issues/350 # https://github.com/moby/moby/issues/26824 @@ -153,11 +166,14 @@ if [ "$1" = 'dockerd' ]; then # might be host has no nf_tables, but Alpine is all-in now (so let's try a legacy fallback) modprobe ip_tables || : if /usr/local/sbin/.iptables-legacy/iptables -nL > /dev/null 2>&1; then - # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) - export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + iptablesLegacy=1 fi fi fi + if [ -n "$iptablesLegacy" ]; then + # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) + export PATH="/usr/local/sbin/.iptables-legacy:$PATH" + fi uid="$(id -u)" if [ "$uid" != '0' ]; then From eb4c40e45daf9218a21526d0ebd076b627d0b882 Mon Sep 17 00:00:00 2001 From: Tianon Gravi Date: Tue, 19 Dec 2023 11:29:15 -0800 Subject: [PATCH 3/3] Add `DOCKER_IPTABLES_LEGACY` for letting users explicitly pick `iptables-legacy` via `--env DOCKER_IPTABLES_LEGACY=1` --- 24/dind/dockerd-entrypoint.sh | 11 ++++++++++- 25-rc/dind/dockerd-entrypoint.sh | 11 ++++++++++- dockerd-entrypoint.sh | 11 ++++++++++- 3 files changed, 30 insertions(+), 3 deletions(-) diff --git a/24/dind/dockerd-entrypoint.sh b/24/dind/dockerd-entrypoint.sh index 799204023..b11a1cffd 100755 --- a/24/dind/dockerd-entrypoint.sh +++ b/24/dind/dockerd-entrypoint.sh @@ -144,7 +144,15 @@ if [ "$1" = 'dockerd' ]; then set -- docker-init -- "$@" iptablesLegacy= - if ( + if [ -n "${DOCKER_IPTABLES_LEGACY+x}" ]; then + # let users choose explicitly to legacy or not to legacy + iptablesLegacy="$DOCKER_IPTABLES_LEGACY" + if [ -n "$iptablesLegacy" ]; then + modprobe ip_tables || : + else + modprobe nf_tables || : + fi + elif ( # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do @@ -174,6 +182,7 @@ if [ "$1" = 'dockerd' ]; then # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi + iptables --version # so users can see whether it's legacy or not uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/25-rc/dind/dockerd-entrypoint.sh b/25-rc/dind/dockerd-entrypoint.sh index 799204023..b11a1cffd 100755 --- a/25-rc/dind/dockerd-entrypoint.sh +++ b/25-rc/dind/dockerd-entrypoint.sh @@ -144,7 +144,15 @@ if [ "$1" = 'dockerd' ]; then set -- docker-init -- "$@" iptablesLegacy= - if ( + if [ -n "${DOCKER_IPTABLES_LEGACY+x}" ]; then + # let users choose explicitly to legacy or not to legacy + iptablesLegacy="$DOCKER_IPTABLES_LEGACY" + if [ -n "$iptablesLegacy" ]; then + modprobe ip_tables || : + else + modprobe nf_tables || : + fi + elif ( # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do @@ -174,6 +182,7 @@ if [ "$1" = 'dockerd' ]; then # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi + iptables --version # so users can see whether it's legacy or not uid="$(id -u)" if [ "$uid" != '0' ]; then diff --git a/dockerd-entrypoint.sh b/dockerd-entrypoint.sh index 799204023..b11a1cffd 100755 --- a/dockerd-entrypoint.sh +++ b/dockerd-entrypoint.sh @@ -144,7 +144,15 @@ if [ "$1" = 'dockerd' ]; then set -- docker-init -- "$@" iptablesLegacy= - if ( + if [ -n "${DOCKER_IPTABLES_LEGACY+x}" ]; then + # let users choose explicitly to legacy or not to legacy + iptablesLegacy="$DOCKER_IPTABLES_LEGACY" + if [ -n "$iptablesLegacy" ]; then + modprobe ip_tables || : + else + modprobe nf_tables || : + fi + elif ( # https://git.netfilter.org/iptables/tree/iptables/nft-shared.c?id=f5cf76626d95d2c491a80288bccc160c53b44e88#n420 # https://github.com/docker-library/docker/pull/468#discussion_r1442131459 for f in /proc/net/ip_tables_names /proc/net/ip6_tables_names /proc/net/arp_tables_names; do @@ -174,6 +182,7 @@ if [ "$1" = 'dockerd' ]; then # see https://github.com/docker-library/docker/issues/463 (and the dind Dockerfile where this directory is set up) export PATH="/usr/local/sbin/.iptables-legacy:$PATH" fi + iptables --version # so users can see whether it's legacy or not uid="$(id -u)" if [ "$uid" != '0' ]; then