Skip to content

fix: add WSL2 support for local setup #1

Description

@zongqichen

Problem

The local setup (task gardener:local platform-mesh:local openmcp:local integrate) works on macOS but fails on WSL2 due to Docker bridge networking limitations and tool compatibility issues.

Root Cause

WSL2's Docker networking does not reliably forward UDP packets between containers on user-created bridge networks. Gardener's local setup assumes bind9 DNS at 172.18.255.53 is reachable from kind nodes — this works on macOS/native Linux but not on WSL2. All other issues are consequences of this networking limitation.


Issues & Fixes (6 total)

1. Gardener calico manifest remote fetch fails

File: hack/setup-gardener-local.sh

Symptom: make kind-up fails at kustomize:

dial udp 10.255.255.254:53: connect: resource temporarily unavailable

Cause: Kustomize fetches https://raw.githubusercontent.com/projectcalico/calico/v3.31.4/manifests/calico.yaml at build time. On WSL2, host DNS points to bind9 (10.255.255.254) which just started and is unreliable.

Fix: After cloning Gardener (before make kind-up), download calico manifest locally and patch the kustomization:

CALICO_BASE_DIR="$GARDENER_DIR/dev-setup/kind/calico/base"
CALICO_KUSTOMIZATION="$CALICO_BASE_DIR/kustomization.yaml"
if grep -q 'raw.githubusercontent.com' "$CALICO_KUSTOMIZATION" 2>/dev/null; then
    log "Patching calico: downloading manifest locally (avoids DNS issues on WSL2)..."
    CALICO_URL=$(grep 'raw.githubusercontent.com' "$CALICO_KUSTOMIZATION" | sed 's/^- //')
    curl -sL -o "$CALICO_BASE_DIR/calico.yaml" "$CALICO_URL"
    sed -i.bak "s|^- https://.*calico.yaml$|- calico.yaml|" "$CALICO_KUSTOMIZATION"
    rm -f "${CALICO_KUSTOMIZATION}.bak"
fi

2. Kind node cannot reach bind9 via Docker bridge

File: hack/setup-gardener-local.sh

Symptom: Calico and Gardener pods stuck in ImagePullBackOff:

dial tcp: lookup quay.registry-cache.local.gardener.cloud on 172.18.255.53:53: i/o timeout

Cause: On WSL2, Docker bridge inter-container UDP communication is unreliable. Kind nodes cannot query bind9 at 172.18.255.53. Additionally, IPv6 DNS entry fd00:ff::53 in the kind node's resolv.conf points to an address bind9 doesn't listen on.

Fix: After kind cluster creation, fix DNS and add /etc/hosts entries. This requires splitting make kind-up gardener-up into two steps:

if grep -qi microsoft /proc/version 2>/dev/null; then
    log "WSL2 detected: running kind-up and gardener-up separately..."
    pushd "$GARDENER_DIR" > /dev/null
    make kind-up
    popd > /dev/null

    log "WSL2: fixing kind node DNS and registry resolution..."
    docker exec gardener-local-control-plane bash -c '
        grep -v "fd00:ff::53" /etc/resolv.conf > /tmp/resolv.new
        echo "nameserver 8.8.8.8" >> /tmp/resolv.new
        cp /tmp/resolv.new /etc/resolv.conf
    '
    for container in registry registry-cache-quay registry-cache-gcr registry-cache-k8s registry-cache-europe-docker-pkg-dev; do
        IP=$(docker inspect "$container" --format "{{.NetworkSettings.Networks.kind.IPAddress}}" 2>/dev/null || true)
        [ -z "$IP" ] && continue
        case "$container" in
            registry) HOST="registry.local.gardener.cloud" ;;
            registry-cache-quay) HOST="quay.registry-cache.local.gardener.cloud" ;;
            registry-cache-gcr) HOST="gcr.registry-cache.local.gardener.cloud" ;;
            registry-cache-k8s) HOST="registry.registry-cache.local.gardener.cloud" ;;
            registry-cache-europe-docker-pkg-dev) HOST="europe-docker.registry-cache.local.gardener.cloud" ;;
        esac
        docker exec gardener-local-control-plane bash -c "echo '$IP $HOST' >> /etc/hosts"
    done
    docker exec gardener-local-control-plane bash -c '
        rm -rf /etc/containerd/certs.d/quay.io /etc/containerd/certs.d/gcr.io \
               /etc/containerd/certs.d/registry.k8s.io /etc/containerd/certs.d/europe-docker.pkg.dev
    '
    docker exec gardener-local-control-plane systemctl restart containerd
    log "Fixed kind node DNS ✓"

    pushd "$GARDENER_DIR" > /dev/null
    make gardener-up
    popd > /dev/null
else
    pushd "$GARDENER_DIR" > /dev/null
    make kind-up gardener-up
    popd > /dev/null
fi

3. Host DNS order breaks subsequent operations

File: hack/setup-gardener-local.sh

Symptom: Docker builds, git clone, curl fail intermittently:

Could not resolve host: github.com

Cause: Gardener's kind-up.sh sets /etc/resolv.conf to nameserver 10.255.255.254 (bind9 loopback). On WSL2 this address is unreliable.

Fix: After Gardener setup, ensure 8.8.8.8 is the primary nameserver:

if grep -qi microsoft /proc/version 2>/dev/null; then
    if ! head -1 /etc/resolv.conf | grep -q "8.8.8.8"; then
        log "WSL2: fixing host DNS order (8.8.8.8 first)..."
        sudo bash -c '
            EXISTING=$(grep "^nameserver" /etc/resolv.conf | grep -v "8.8.8.8" || true)
            SEARCH=$(grep "^search" /etc/resolv.conf || true)
            { echo "nameserver 8.8.8.8"; echo "$EXISTING"; [ -n "$SEARCH" ] && echo "$SEARCH"; } > /etc/resolv.conf
        '
    fi
fi

4. HTTPS registry incompatible with Helm OCI push

File: Taskfile.yml

Symptom: helm push fails:

Error: unexpected status from HEAD request to http://localhost:5002/...: 400 Bad Request

Cause: Helm (3.14+) always uses HTTP for oci:// push regardless of --ca-file. The HTTPS-only registry returns 400.

Fix: Switch to HTTP registry:

  • LOCAL_OCM_REPO: https://http://
  • local-registry task: remove TLS cert env vars and volume mount
  • openmcp:mirror-crossplane: remove --ca-file from helm push
  • openmcp:create-platform-cluster: hosts.toml use http://, remove ca line

5. wsl.exe not in PATH

Files: hack/integrate-openmcp-platform-mesh.sh, Taskfile.yml

Symptom:

Error: wsl.exe not found in WSL environment

Cause: Platform Mesh's WSL compatibility check requires wsl.exe at /mnt/c/Windows/System32/wsl.exe, not in default PATH.

Fix: Add WSL2 PATH detection at the top of scripts:

if grep -qi microsoft /proc/version 2>/dev/null; then
    [[ ":$PATH:" != *":/mnt/c/Windows/System32:"* ]] && export PATH="$PATH:/mnt/c/Windows/System32"
fi

6. Helm --force-conflicts removed in 3.15+

File: hack/integrate-openmcp-platform-mesh.sh

Symptom:

Error: unknown flag: --force-conflicts

Cause: Helm 3.15+ removed this flag. Three helm upgrade --install commands use it.

Fix: Remove --force-conflicts \ from all three helm commands (openmcp-init-operator, gardener-init-operator, openmcp-onboarding-ui). Note: kubectl apply --force-conflicts is valid and should NOT be changed.


Files to modify

File Changes
hack/setup-gardener-local.sh Calico prefetch (#1), split kind-up/gardener-up + DNS fix (#2), host DNS order (openmcp-project#3)
hack/integrate-openmcp-platform-mesh.sh WSL2 PATH detection (openmcp-project#5), remove helm --force-conflicts (openmcp-project#6)
Taskfile.yml HTTP registry (openmcp-project#4), WSL2 PATH for platform-mesh:local (openmcp-project#5)

Environment

  • WSL2 (kernel 6.6.87.2)
  • Docker 27.3.1
  • Helm 3.17.3
  • Kind 0.27.0

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions