Skip to content

Commit 95eac83

Browse files
committed
fix(helm-e2e): rewrite kubeconfig server when running inside a container
When helm-k3s-local.sh runs inside a Docker container that mounts the host's docker socket (e.g., a GitHub Actions `container:` job), k3d creates the cluster on the host's daemon and publishes the API server on `0.0.0.0:<port>` of the host. From inside the CI container that address is unreachable, so kubectl (and helm OpenAPI validation) fail with 'dial tcp 0.0.0.0:<port>: connect: connection refused'. After merging the kubeconfig, detect that we're in a container via /.dockerenv and rewrite the server URL to the default-route gateway (which routes to the docker host on standard sibling-container setups). The API cert isn't signed for the gateway IP, so also mark the cluster insecure-skip-tls-verify and clear the embedded CA — CI-only path; the local-dev case where 0.0.0.0 already works is unchanged.
1 parent d663a7f commit 95eac83

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

tasks/scripts/helm-k3s-local.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,34 @@ merge_kubeconfig() {
114114
rm -f "${tmp}"
115115

116116
kubectl --kubeconfig="${KUBECONFIG_TARGET}" config use-context "$(k3d_context_name)"
117+
118+
# When this script runs inside a container (e.g., a GitHub Actions
119+
# `container:` job mounting /var/run/docker.sock), k3d publishes the API
120+
# server on the host's `0.0.0.0:<port>` but `0.0.0.0` from inside the
121+
# container is not the host. Rewrite the server URL to the default-route
122+
# gateway, which routes to the docker host. The API server cert is signed
123+
# for `0.0.0.0` / `127.0.0.1` and won't have the gateway IP as a SAN, so
124+
# mark the cluster insecure-skip-tls-verify (CI-only path; local dev keeps
125+
# the default secure setup).
126+
if [[ -f /.dockerenv ]]; then
127+
local context old_server new_server host_addr
128+
context="$(k3d_context_name)"
129+
old_server=$(kubectl --kubeconfig="${KUBECONFIG_TARGET}" config view --raw \
130+
-o "jsonpath={.clusters[?(@.name=='${context}')].cluster.server}")
131+
if [[ "${old_server}" == https://0.0.0.0:* ]]; then
132+
host_addr=$(ip route show default 2>/dev/null | awk '/default/ {print $3; exit}')
133+
if [[ -n "${host_addr}" ]]; then
134+
new_server="${old_server//0.0.0.0/${host_addr}}"
135+
echo "Inside container; rewriting kubeconfig server ${old_server} -> ${new_server} (insecure-skip-tls-verify)."
136+
kubectl --kubeconfig="${KUBECONFIG_TARGET}" config unset \
137+
"clusters.${context}.certificate-authority-data" >/dev/null 2>&1 || true
138+
kubectl --kubeconfig="${KUBECONFIG_TARGET}" config set-cluster "${context}" \
139+
--server="${new_server}" --insecure-skip-tls-verify=true >/dev/null
140+
else
141+
echo "warning: running inside a container but could not detect a default-route gateway; kubectl may fail to reach the API server." >&2
142+
fi
143+
fi
144+
fi
117145
}
118146

119147
apply_base_manifests() {

0 commit comments

Comments
 (0)