docs: add k3s integration documentation#1371
Conversation
There was a problem hiding this comment.
Pull request overview
Adds a new documentation page for the CommunityToolkit.Aspire.Hosting.K3s integration and wires it into the integrations catalog, sidebar navigation, and integration grid icon set so it appears as a first-class integration on aspire.dev.
Changes:
- Add new
/integrations/compute/k3s/documentation page with C# and TypeScript AppHost examples. - Register the K3s integration in the site’s integration metadata (
aspire-integrations.json,integration-docs.json) so it’s discoverable and linkable. - Add a k3s icon and include it in the integration grid + sidebar topic list.
Reviewed changes
Copilot reviewed 5 out of 6 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| src/frontend/src/data/integration-docs.json | Adds doc route mapping for CommunityToolkit.Aspire.Hosting.K3s. |
| src/frontend/src/data/aspire-integrations.json | Adds K3s integration metadata (title/description/icon/tags/version). |
| src/frontend/src/content/docs/integrations/compute/k3s.mdx | New integration documentation page for running a local k3s cluster from AppHost. |
| src/frontend/src/components/IntegrationGrid.astro | Adds k3s icon mapping for the integration grid. |
| src/frontend/src/assets/icons/k3s-icon.svg | Adds the k3s icon asset. |
| src/frontend/config/sidebar/integrations.topics.ts | Adds “K3s” to the Compute integrations sidebar group. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
IEvangelist
left a comment
There was a problem hiding this comment.
Docs-accuracy review — k3s integration
Automated two-phase review (claims-vs-source + blind doc-tester).
Phase A source of truth: CommunityToolkit/Aspire @ main (SHA b9d40479805b74ea20b7dc57cb659d46e6f11c43), cross-checked against the microsoft/aspire public API surface (EndpointReferenceExpression) and the NuGet registration for CommunityToolkit.Aspire.Hosting.K3s.
Claims extracted: 34 non-narrative → 29 verified, 4 verified-with-nuance, 1 contradicted, 0 unverifiable.
Phase B (doc-tester, blind to source): served the PR head locally and exercised /integrations/compute/k3s/ (C# + TypeScript tabs) and the gallery — 1 critical, 2 warnings, 18 passed checks.
Verdict: 🔴 Request changes
- The C# sample under “Reach Aspire services from k3s pods” won’t compile (Phase A — inline comment).
- The documented
aspire add k3scommand fails at the CLI; the real friendly name iscommunitytoolkit-k3s(Phase B — inline comment).
The page is otherwise remarkably accurate: every AppHost API, parameter, default, container image, and behavior I checked matches the integration source, and the sidebar/gallery/data-file wiring is consistent.
Phase A — Claim verification
🔴 1 contradicted — see the inline comment on the WithHelmValue(..., .Property(EndpointProperty.Port)) sample.
✅ 29 verified + 4 verified-with-nuance — evidence (click to expand)
All paths below are in CommunityToolkit/Aspire src/CommunityToolkit.Aspire.Hosting.K3s/ @ b9d40479 unless noted.
Cluster APIs
AddK3sCluster(this IDistributedApplicationBuilder, [ResourceName] string name, int? apiServerPort = null, int? agentCount = null)—K3sBuilderExtensions.cs:61. Random API-server port + single-node defaults match the doc.WithK3sVersion(tag):288;WithPodSubnet(cidr)→--cluster-cidr:327/334;WithServiceSubnet(cidr)→--service-cidr:346/353;WithDisabledComponent(c)→--disable=<c>(repeatable):369/376;WithExtraArg(arg)→ raw arg onk3s server(repeatable):395/402.WithDataVolume(string? name = null)→ mounts/var/lib/rancher/k3s:423/438.WithAgentCount(int count):460; health check waits1 + countnodesReady(:453);0= single-node (:446-467).WithHelmImage(string? tag = null, string? image = null, string? registry = null)overridesalpine/helm:489;WithKubectlImage(tag?, image?, registry?)overridesalpine/kubectl:512— parameter order matches(tag?, image?, registry?).WithLifetime(ContainerLifetime)applies to cluster and agents:539-556.- Privileged flags injected automatically:
--privileged:152,--cgroupns=host:155, writable cgroup fs--volume=/sys/fs/cgroup:/sys/fs/cgroup:rw:156— matches the Prerequisites callout. - Images:
rancher/k3s(K3sContainerImageTags),alpine/helm(HelmContainerImageTags),alpine/kubectl(KubectlContainerImageTags).
Helm
AddHelmRelease([ResourceName] string name, string chart, string? repo = null, string? version = null, string @namespace = "default")—K3sBuilderExtensions.Helm.cs:56. Named-arg usage matches.- Runs
helm upgrade --install … --wait(:249/251, actual command also adds--timeout 10m). WithHelmValue(key, value):202;WithHelmValuesFile(path):164. Value precedence (files first, then--setoverrides; last-set wins) matches the doc’s ordered list (:158,:187).
Manifests
AddK8sManifest([ResourceName] string name, string path):49; runskubectl apply --server-side(Manifest.cs:185/187); auto-detects single file →-f, dir →-f,kustomization.yaml→-k(kustomize dir bind-mounted). Matches the mode table.
Service endpoints & injection
AddServiceEndpoint([ResourceName] string name, string serviceName, int servicePort, string @namespace = "default", string? scheme = null):71-77. In-process WebSocket port-forward bound to0.0.0.0:{allocatedPort}(:44,K3sInProcessPortForwarder.cs:13). Scheme inferenceservicePort is 443 or 8443 ? "https" : "http":87.- Injected env
services__{Name}__url(K3sServiceEndpointResource.cs:76); host URLslocalhost+host.docker.internal(:210/213);--add-host=host.docker.internal:host-gatewayinjected for containers:236. K3sClusterResource : ContainerResource, IResourceWithConnectionString(:21),ConnectionStringEnvironmentVariable => "KUBECONFIG"(:51); container kubeconfig at/tmp/k3s-kubeconfig.yaml(K3sFileHelpers.cs:32); host path.k3s/{name}/local/kubeconfig.yaml(:78/564).K3sServiceEndpointResource : … IResourceWithConnectionString(:29). Both resources implementIResourceWithConnectionString— matches the Kubeconfig-injection section.
Data files
- NuGet confirms id, version
13.4.1-beta.686, the exacticonUrl, and a superset of the listed tags.integration-docs.jsonmatch → /integrations/compute/k3s/, the sidebar entry, and theIntegrationGridicon are all consistent with the new page.
Verified-with-nuance
- TypeScript samples: every underlying C# method carries
[AspireExport], so the TS bindings are generated; the shapes (required params positional, trailing optionals as an options object) match the exported signatures and the integration README’s own TS sample. The generated.aspire/modules/aspire.mjsitself was not read. aspire add k3sfriendly name — flagged separately by Phase B (it fails at the CLI; see inline comment).- Default subnets
10.42.0.0/16/10.43.0.0/16are described as “k3s built-in” defaults — a k3s product fact; the methods only set the CIDR flags. - The
KubernetesClientConfiguration.BuildConfigFromConfigFile+new Kubernetes(config)snippet uses the externalKubernetesClientpackage; standard usage.
Phase B — Doc-tester report (blind-user perspective)
Served PR ref
pr-1371-review@b4f5f33onhttp://localhost:4323/. Routes exercised:/integrations/compute/k3s/,…?aspire-lang=csharp,…?aspire-lang=typescript,/integrations/gallery/?search=k3s.
Summary
| Category | Passed | Failed | Warnings |
|---|---|---|---|
| Content Accuracy | 5 | 0 | 2 |
| Code Examples | 2 | 0 | 1 |
| CLI Commands | 1 | 1 | 0 |
| Links | 10 | 0 | 0 |
Critical Issues
Issue 1 — Installation command uses the wrong exact Aspire integration name (/integrations/compute/k3s/#installation, CLI, Critical)
- Docs say:
aspire add k3s - What actually happens:
aspire add k3s --non-interactivefails becausek3sis not an exact friendly name. The gallery card for the same integration showsaspire add communitytoolkit-k3s, which succeeds.
aspire integration search k3s
Name: communitytoolkit-k3s
Package: CommunityToolkit.Aspire.Hosting.K3s
aspire add k3s --non-interactive
❌ No exact match was found for 'k3s'.
aspire add communitytoolkit-k3s --non-interactive
✅ The package CommunityToolkit.Aspire.Hosting.K3s::13.4.1-beta.686 was added successfully.
Recommended action: change the install snippets (both tabs) from aspire add k3s to aspire add communitytoolkit-k3s.
Warnings
- Examples are reference fragments, not a runnable first path (
#add-a-k3s-clusterand later): samples referenceProjects.MyOperator,Projects.MyApi,./deploy/podinfo-values.yaml, and./k8s/...without showing how to create them. Suggestion: add a short minimal runnable example, or explicitly label later samples as fragments. - Prerequisites may be thin for brand-new users (
#prerequisites): the page requires Docker Desktop/Podman and notes privileged containers, but doesn’t explain how to verify the runtime can run privileged Linux containers. Suggestion: add a short verification note/link.
Passed Checks
- k3s page loads; sidebar lists K3s under Compute and marks it current.
- Gallery search shows the
CommunityToolkit.Aspire.Hosting.K3scard; card icon renders and links to/integrations/compute/k3s/. - Page icon renders with alt text
k3s logo. - C# and TypeScript tab routes render code blocks correctly.
- Callouts render (Note, Privileged containers, Caution).
- Internal links/anchors resolve with no 404s; Previous/Next resolve to Docker and Kubernetes.
aspire add communitytoolkit-k3s --non-interactivesuccessfully adds the package.
Knowledge Gaps
- Placeholder projects/files (
Projects.MyOperator,Projects.MyApi, Helm values, manifests) must already exist — not explained on the page; new users may copy samples and fail immediately. - Privileged Linux container runtime readiness — Windows/macOS users may not know how to verify Docker Desktop is configured for privileged k3s containers.
Phase A read source code; Phase B (doc-tester) was blind to source and used only the rendered local site + the aspire CLI. Line-anchored comments follow.
| .WithHelmValue("database.port", | ||
| postgres.GetEndpoint("tcp").Property(EndpointProperty.Port)); |
There was a problem hiding this comment.
Phase A · 🔴 contradicted — this C# sample won't compile.
WithHelmValue has a single overload — WithHelmValue(this IResourceBuilder<HelmReleaseResource> builder, string key, string value) (CommunityToolkit/Aspire @ main, src/CommunityToolkit.Aspire.Hosting.K3s/K3sBuilderExtensions.Helm.cs:202).
postgres.GetEndpoint("tcp").Property(EndpointProperty.Port) returns an EndpointReferenceExpression (microsoft/aspire, src/Aspire.Hosting/ApplicationModel/EndpointReference.cs), which implements IValueProvider/IManifestExpressionProvider/IExpressionValue but has no implicit conversion to string. Passing it to the string value parameter is a compile error (CS1503), so this snippet does not build as written.
Note: this is copied verbatim from the integration README (lines 247–249), so the same bug exists upstream.
Suggested fix: pass a string (e.g. a literal port), or resolve the endpoint to a string value before calling WithHelmValue.
| <TabItem id="csharp" label="C#"> | ||
|
|
||
| ```bash title="Terminal" | ||
| aspire add k3s |
There was a problem hiding this comment.
Phase B · 🔴 critical (doc-tester, verified at the CLI) — aspire add k3s fails.
aspire integration search k3s reports the friendly name communitytoolkit-k3s. Running the documented command fails:
aspire add k3s --non-interactive
❌ No exact match was found for 'k3s'.
The correct command succeeds:
aspire add communitytoolkit-k3s --non-interactive
✅ The package CommunityToolkit.Aspire.Hosting.K3s::13.4.1-beta.686 was added successfully.
Change aspire add k3s → aspire add communitytoolkit-k3s here and in the TypeScript tab (line 69).
Adding docs for: CommunityToolkit.Aspire.Hosting.K3s