docs(troubleshooting): add WSL2 DNS troubleshooting for install preflight and sandbox data plane - #1260
docs(troubleshooting): add WSL2 DNS troubleshooting for install preflight and sandbox data plane#1260Tantanovo wants to merge 5 commits into
Conversation
…ight and sandbox data plane Two DNS problems are specific to WSL2 and are not covered in the current docs: 1. online-install.sh preflight exits 3 because a default Ubuntu-on-WSL install has neither resolvectl nor NetworkManager. The generic prerequisite is documented in self-build-deploy.md, but quickstart.md lists WSL as supported without mentioning it, and the error names the command rather than the systemd-resolved package that ships it. 2. After a successful install the control plane works but the data plane fails with 'Name or service not known', because WSL regenerates /etc/resolv.conf on every start and discards the CoreDNS nameserver written by dns-host-route-up.sh, which breaks wildcard resolution for *.cube.app. Both were reproduced and fixed on a real single-node v0.6.0 deployment on Ubuntu 24.04.4 (WSL2). Adds bilingual pages and index entries. Signed-off-by: Tantanovo <1348215719@qq.com>
|
|
||
| ### Problem 1: install `systemd-resolved` to provide `resolvectl` | ||
|
|
||
| ```bash |
There was a problem hiding this comment.
The address mapping here is inverted relative to the implementation. In deploy/one-click/scripts/systemd/dns-host-route-up.sh, /etc/resolv.conf is only written on the dnsmasq paths — and always with the dummy-link IP: write_host_resolv_conf "${RESOLVED_COREDNS_BIND_ADDR}" (line 270), where RESOLVED_COREDNS_BIND_ADDR defaults to 169.254.254.53 (env.example:177). 127.0.0.54 (DEFAULT_COREDNS_BIND_ADDR, env.example:176) is CoreDNS's internal bind address: on the dnsmasq path it appears only in the forwarder rule server=/cube.app/127.0.0.54#53, never in resolv.conf. And on the systemd-resolved path the script does not touch /etc/resolv.conf at all — it routes ~cube.app via resolvectl domain cube-dns0 '~cube.app' (line 168).
The repo's own deploy/one-click/README.md (lines 444–445) confirms the client entry point is the same dummy-link IP on both paths: "cat /etc/resolv.conf should show nameserver 169.254.254.53 on both paths."
So the client-facing nameserver is 169.254.254.53 in both cases; 127.0.0.54 should be described only as CoreDNS's internal bind that dnsmasq forwards cube.app queries to. As written, a reader on the dnsmasq fallback path would write a loopback address into resolv.conf, which is unreachable from inside Docker containers — the exact problem the dummy link was introduced to solve. The same text needs fixing in the zh file (lines 92–94).
|
|
||
| ```bash | ||
| cat /etc/resolv.conf | ||
| ``` |
There was a problem hiding this comment.
Same correction as in the Root Cause section: on the dnsmasq fallback path the installer still points /etc/resolv.conf at 169.254.254.53 (the dummy-link IP), not 127.0.0.54. The latter is only CoreDNS's internal bind used by dnsmasq's server=/cube.app/127.0.0.54#53 forwarder. Recommend rewording to: "on both the systemd-resolved path and the dnsmasq fallback path the client entry is 169.254.254.53." (zh file line 148 likewise.)
| - Cube Sandbox version: v0.6.0 (`cubemastercli` `8721dd15`, built 2026-07-24) | ||
| - Deployment mode: one-click, single node (control + compute on the same host) | ||
| - Host OS / kernel: Ubuntu 24.04.4 LTS on WSL2, `6.18.33.2-microsoft-standard-WSL2`, glibc 2.39 | ||
| - Related components: `online-install.sh` preflight, CoreDNS (`cube-sandbox-coredns`), CubeProxy, `scripts/systemd/dns-host-route-up.sh` |
There was a problem hiding this comment.
This script lives at deploy/one-click/scripts/systemd/dns-host-route-up.sh, not scripts/systemd/dns-host-route-up.sh (in the installed tree it is /usr/local/services/cubetoolbox/scripts/systemd/dns-host-route-up.sh, per the ExecStart of deploy/one-click/systemd/cube-sandbox-dns.service). Same wrong path recurs at line 117 of this file, and in the zh file at lines 51 and 92.
Review:
|
The bot review correctly caught two factual errors in both languages: 1. Client-facing nameserver is 169.254.254.53 on BOTH DNS backends. dns-host-route-up.sh writes /etc/resolv.conf only on the dnsmasq paths and always with the dummy-link address (RESOLVED_COREDNS_BIND_ADDR); 127.0.0.54 (DEFAULT_COREDNS_BIND_ADDR) is only CoreDNS's internal loopback bind that dnsmasq forwards cube.app queries to, and never appears in /etc/resolv.conf. The previous text inverted this mapping. 2. Script path is deploy/one-click/scripts/systemd/dns-host-route-up.sh, not scripts/systemd/dns-host-route-up.sh. Also adopted the non-blocking suggestions: on the systemd-resolved path the installer does not rewrite resolv.conf (routing lives on the cube-dns0 dummy link, which WSL also tears down on restart), and the restart notes now mention the dummy link/forwarder rule loss. Signed-off-by: Tantanovo <1348215719@qq.com>
|
Thanks for the review — both blocking issues are confirmed and fixed in
Also adopted the two non-blocking suggestions:
|
| ```bash | ||
| # 1. tell WSL to leave resolv.conf alone | ||
| sudo tee -a /etc/wsl.conf >/dev/null <<'EOF' | ||
|
|
There was a problem hiding this comment.
Minor (non-blocking): tee -a appends unconditionally. If a WSL user already has a [network] section in /etc/wsl.conf (common for memory/swap or hostname settings), this appends a second [network] block, and duplicate INI sections can silently fail to apply or behave unpredictably. Consider adding a one-line note: "If /etc/wsl.conf already has a [network] section, merge generateResolvConf = false into it instead of appending."
| # 2. resolv.conf is usually a symlink into /run, so remove it before writing | ||
| sudo rm -f /etc/resolv.conf | ||
| sudo tee /etc/resolv.conf >/dev/null <<'EOF' | ||
| nameserver 169.254.254.53 |
There was a problem hiding this comment.
Minor (non-blocking): 223.5.5.5 is AliDNS. It's a fine default for the China audience this repo targets, but for WSL users elsewhere it can be slow or blocked by enterprise networks. Consider noting it's an example ("use any upstream resolver that works on your network, e.g. 223.5.5.5"), since the repo's own dns-host-route-up.sh picks up the host's existing upstream automatically rather than hardcoding one.
| ```bash | ||
| # wildcard sandbox domain must resolve | ||
| dig +short +tcp +timeout=3 foo.cube.app @169.254.254.53 | ||
|
|
There was a problem hiding this comment.
Minor (non-blocking): dig is not installed by default on Ubuntu — it requires the dnsutils/bind9-dnsutils package. This exact command is consistent with deploy/one-click/README.md, but since this is a troubleshooting page for users who just hit a DNS failure, consider adding a note to install dnsutils first (or swap the first check for getent hosts foo.cube.app, which needs no extra package, like the second check already does).
1. Note that generateResolvConf belongs inside an existing [network] section if /etc/wsl.conf already has one, so 'tee -a' does not create a duplicate. 2. Mark 223.5.5.5 as an example upstream and point out that the installer's own write_host_resolv_conf reuses the host's existing upstream, whereas this file is written by hand. 3. Note that dig ships in dnsutils / bind9-dnsutils, which Ubuntu does not install by default, and lead with a getent check that needs no extra package. Signed-off-by: Tantanovo <1348215719@qq.com>
|
All three suggestions adopted in
Thanks for the thorough verification against the base tree — the |
| ```bash | ||
| sudo apt-get update | ||
| sudo apt-get install -y systemd-resolved | ||
| sudo systemctl enable --now systemd-resolved |
There was a problem hiding this comment.
Consider adding a WSL-specific prerequisite here: systemctl enable --now systemd-resolved only works if systemd is actually PID 1 in the distro — WSL2 requires [boot] / systemd=true in /etc/wsl.conf (plus a wsl --shutdown) for that. Without it, systemctl fails with "System has not been booted with systemd", yet the page's own verification below (command -v resolvectl) would still pass misleadingly, because it only checks that the binary exists — and then the install proceeds past the preflight but fails later at the resolvectl dns step when systemd-resolved's D-Bus isn't up.
Suggest verifying with resolvectl status (or systemctl is-active systemd-resolved) instead of command -v. Please mirror this note in the zh page (docs/zh/guide/troubleshooting/wsl-dns.md).
…hutdown The page said the dummy link and host routing are lost on restart but did not say how to rebuild them, which is the part a reader actually needs. - Give the Corefile path (/usr/local/services/cubetoolbox/coredns/Corefile, TOOLBOX_ROOT from scripts/systemd/common.sh) instead of just saying the address can be confirmed from the running Corefile. - Add the recovery sequence: remount XFS, start cube-sandbox-control.target, then restart cube-sandbox-coredns.service and cube-sandbox-dns.service if *.cube.app still fails, and verify with 'ip addr show cube-dns0'. - Explain the restart order: cube-sandbox-dns.service is Type=oneshot and declares Requires=/BindsTo= on cube-sandbox-coredns.service, so CoreDNS has to be listening first. Signed-off-by: Tantanovo <1348215719@qq.com>
|
Pushed The restart notes said the dummy link and host routing are lost after
This is the sequence I actually used to recover the deployment after a WSL restart, so it is verified rather than inferred from the unit files alone. |
| stuck on WSL anyway: | ||
|
|
||
| - A default Ubuntu-on-WSL install has **neither**. `systemd-resolved` is not | ||
| installed, and NetworkManager is not present, so the first branch fails. |
There was a problem hiding this comment.
Small factual nit on the packaging attribution: on Debian/Ubuntu (and RPM-based distros), the resolvectl binary is shipped by the systemd package, not by systemd-resolved — the systemd-resolved package provides the systemd-resolved daemon and depends on systemd. So apt-get install -y systemd-resolved still fixes Problem 1 correctly (it pulls in systemd → resolvectl appears), but the claim "the command is shipped by the systemd-resolved package" is slightly off. Suggest wording like "the command is provided by the systemd package, which systemd-resolved depends on". The zh page (docs/zh/guide/troubleshooting/wsl-dns.md, "这个命令是由 systemd-resolved 包提供的") carries the same wording and would need the same tweak.
| `online-install.sh` stops immediately with: | ||
|
|
||
| ```text | ||
| [online-install] ERROR: DNS setup requires resolvectl or NetworkManager. |
There was a problem hiding this comment.
Consider adding apt install systemd-resolved in error message instead.
There was a problem hiding this comment.
Done in 3f566e9.
Covered all three sites that reject a host for missing DNS tooling, so the hint shows up regardless of which path fails:
install.sh:232(check_dns_preflight)online-install.sh:295(NetworkManager not loaded)online-install.sh:299(no systemctl at all)
The error now reads:
[online-install] ERROR: DNS setup requires resolvectl or NetworkManager. resolvectl is provided by the systemd-resolved package: apt install systemd-resolved (or dnf install systemd-resolved).
Two follow-on edits since the page quotes this error verbatim: both language versions now match the new text, and the note about the package name being absent is scoped to releases predating this change rather than stated as current behaviour.
…t error The preflight names the resolvectl command but not the package that ships it, and 'apt install resolvectl' does not exist, so the next step is not obvious. Per review feedback on TencentCloud#1260, put the install hint in the error itself rather than only in the troubleshooting page. Covers all three sites that reject a host for missing DNS tooling: install.sh:232 (check_dns_preflight) and online-install.sh:295,299. The troubleshooting page quotes this error verbatim in both languages, so both copies are updated to match, and the note about the package name being absent is scoped to releases predating this change. Signed-off-by: Tantanovo <1348215719@qq.com>
|
|
||
| - A default Ubuntu-on-WSL install has **neither**. `systemd-resolved` is not | ||
| installed, and NetworkManager is not present, so the first branch fails. | ||
| - The message names the *command* `resolvectl`, which is shipped by the |
There was a problem hiding this comment.
Minor accuracy note on package attribution (also present in the new install.sh/online-install.sh messages and the zh version): on Debian/Ubuntu the resolvectl binary actually ships in the systemd package — the systemd-resolved package provides the daemon/service (and pulls in systemd). On RHEL 9 / OpenCloudOS 9 there is often no systemd-resolved package at all, so dnf install systemd-resolved can itself fail, recreating the exact "next step is not obvious" dead-end this PR is fixing. Consider pointing at the resolver rather than over-attributing the binary, e.g. "install/enable the systemd-resolved resolver (apt install systemd-resolved; otherwise NetworkManager + dnsmasq)".
| - If `/etc/wsl.conf` already contains a `[network]` section, put | ||
| `generateResolvConf = false` inside it rather than appending a second | ||
| section. | ||
| - Keep an upstream resolver as the second entry. With only the CoreDNS address, |
There was a problem hiding this comment.
Minor: "With only the CoreDNS address, *.cube.app resolves but general internet resolution breaks" is stated as absolute, but it only holds while the CoreDNS/dnsmasq stack is down. When the stack is running, CoreDNS (systemd-resolved path) and dnsmasq (dnsmasq path) both forward non-cube.app queries to the preserved upstream snapshot, so general resolution keeps working. The advice itself is right for the WSL-restart window this page is about — consider wording like "if the Cube Sandbox DNS services are not running yet (e.g. right after a WSL restart), only-the-CoreDNS-address leaves no general resolution until they come back" so it doesn't read as unconditional. Same phrasing appears in the zh version.
What
Adds a bilingual troubleshooting page for two DNS problems that are specific to WSL2, requested by @fslongjin.
docs/guide/troubleshooting/wsl-dns.mddocs/zh/guide/troubleshooting/wsl-dns.mdquickstart.mdlists WSL as a supported platform, and #311 covers the XFS loopback workaround, but neither of the two DNS failures below is documented anywhere. Both were hit while bringing up v0.6.0 on WSL2 for #644.The two problems
1. Preflight exits 3 before anything is downloaded
online-install.shrequiresresolvectlor a loadedNetworkManager. A default Ubuntu-on-WSL install has neither.The generic prerequisite is documented in
self-build-deploy.md("DNS routing:systemd-resolved(preferred) orNetworkManager + dnsmasq"), so this is not a missing requirement — it is a discoverability gap:quickstart.mdlists WSL as supported but its requirements table only mentions glibc and XFS.resolvectl, while the command is shipped by thesystemd-resolvedpackage.apt install resolvectldoes not exist, so the next step is not obvious.Fix:
apt-get install -y systemd-resolved && systemctl enable --now systemd-resolved.2. Install succeeds, sandbox is created, but
run_codecannot resolveThe control plane is fine because it goes through
127.0.0.1:3000. The data plane needs wildcard resolution for*.cube.app, and WSL regenerates/etc/resolv.confon every start, discarding the CoreDNS nameserver written bydns-host-route-up.sh.This one is the more valuable of the two for a troubleshooting page: the error mentions neither DNS nor
cube.app, and it can appear on a deployment that worked yesterday, because the trigger is a WSL restart rather than a config change.Fix requires both steps — either alone does not survive a restart:
/etc/wsl.conf→[network]/generateResolvConf = false/etc/resolv.confis usually a symlink into/run/..., sormit before writing; point the first nameserver at CoreDNS and keep an upstream resolver as a fallback (with only the CoreDNS address,*.cube.appresolves but general internet resolution breaks).The page also notes which CoreDNS address applies to which backend (
169.254.254.53on thesystemd-resolvedpath,127.0.0.54on thednsmasqfallback), points to the two DNS-free alternatives already in the repo (path-based access andexamples/e2b-dev-sidecar), and lists the two pieces of state that do not survivewsl --shutdown(the loopback XFS mount andresolv.conf).Environment used for verification
cubemastercli8721dd15, built 2026-07-24)6.18.33.2-microsoft-standard-WSL2/data/cubeletreflink=1Deployment screenshots and logs from that run are attached to #1238 (14 systemd units active, template
READY, guest kernel6.6.1199vs host6.18.33.2).Checklist
docs/guide/troubleshooting/index.mdanddocs/zh/guide/troubleshooting/index.md_template.mdsection structure (Symptom / Environment / Root Cause / Resolution / References)title,author,date,tags,lang)online-install.shsnippet matches upstream (marked as an excerpt)Happy to adjust the wording, section split, or file placement if you would prefer this merged into
deployment.mdinstead of a standalone page.