From 29739ec5c91d9e440334b70a8422fe67144aa10b Mon Sep 17 00:00:00 2001 From: Jinpei Su Date: Tue, 21 Jul 2026 04:00:38 +0000 Subject: [PATCH 1/2] docs(ecosystem): add Alauda support for Nacos installation guide S2 install guide for Alauda support for Nacos v3.0.1 (chart-wrap, standalone + embedded). Covers Marketplace/OperatorHub install, empty-spec deploy, NodePort console access, config + naming validation, install-form knobs, persistence, and known limitations (chart appVersion follow, cluster-mode peer-finder amd64-only, production Auth Token override). factory:auto markers for version/limitation slots kept in sync with components/nacos on later releases. Co-Authored-By: Claude Opus 4.8 (1M context) --- .../nacos/Nacos_Installation_Guide.md | 266 ++++++++++++++++++ 1 file changed, 266 insertions(+) create mode 100644 docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md diff --git a/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md b/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md new file mode 100644 index 000000000..3f914a739 --- /dev/null +++ b/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md @@ -0,0 +1,266 @@ +--- +products: + - Alauda Application Services +kind: + - Solution +ProductsVersion: + - '4.1,4.2,4.3' +id: TBD +--- + + + +# Alauda support for Nacos — Installation Guide + +## Overview + +**Alauda support for Nacos** is the Alauda Application Services (S2, certified) packaging of +[Nacos](https://nacos.io/) — Alibaba's platform for dynamic service discovery, configuration +management, and service management — listed on the Alauda Cloud marketplace and installable from the +ACP OperatorHub. + +Because the upstream community OLM bundle for Nacos is abandoned, this plugin is delivered in +**chart-wrap** mode: the official `nacos-group/nacos-k8s` Helm chart is wrapped by an +operator-sdk helm-operator and shipped as an OLM Operator. You install the Operator from the +Marketplace, then create a single `Nacos` custom resource; the Operator runs `helm install` under +the hood and manages the resulting Nacos `StatefulSet` and `Service`. An empty `spec` gives you a +ready-to-use **standalone** Nacos with **embedded** storage. + +This guide describes how to install **Alauda support for Nacos** from the ACP Marketplace, bring up a +standalone Nacos instance, reach its console, and validate configuration management and service +discovery end to end. + +### Supported Versions + + +| Item | Version | +|------|---------| +| ACP | 4.1, 4.2, 4.3 | +| Architectures | amd64 (x86_64), arm64 | +| Alauda support for Nacos (bundle) | v3.0.1 | +| Nacos server (operand) | v3.0.1 (`docker.io/nacos/nacos-server:v3.0.1`, multi-arch) | +| Upstream chart | `nacos-group/nacos-k8s` `/helm` @ `1b98fe67a4b2` (appVersion 3.0.1) | + + +> **Networking:** this release supports both IPv4 and IPv6 (single-stack and dual-stack) clusters — +> every architecture × IP-stack combination is covered by the release e2e matrix. + +## Prerequisites + +- An ACP cluster at one of the supported versions above, and `cluster-admin` access to the target + workload cluster. +- The **Alauda support for Nacos** plugin available in your cluster's OperatorHub. If it is not yet + uploaded, an administrator can push it with the `violet` CLI (downloaded from **App Store > + App Onboarding**, matching the target platform version): + ```bash + violet push .tgz \ + --platform-address="https://" \ + --platform-username="" --platform-password="" \ + --clusters="" + ``` +- `kubectl` configured against the target cluster. + +## Install Alauda support for Nacos + +1. In the ACP Console, go to **Administrator > Marketplace > OperatorHub**, select the target cluster, + find **Alauda support for Nacos**, and click **Install**. +2. Keep the default channel (`alpha`), choose the target namespace, and confirm the installation. The + platform creates a `Subscription` and approves the `InstallPlan`. + +### Verify the Operator + +```bash +# The CSV should reach the Succeeded phase +kubectl -n get csv | grep nacos-operator + +# The operator controller Deployment should be Available +kubectl -n get deploy | grep nacos-operator +``` + +Expected: the CSV `nacos-operator.v3.0.1` reaches phase `Succeeded`, and the operator's +controller-manager Deployment shows `1/1` ready. + +## Quick Start: Deploy a Standalone Nacos + +Set variables used in the commands below: + +```bash +export NAMESPACE=nacos-demo +kubectl create namespace ${NAMESPACE} +``` + +### 1. Create the Nacos instance + +An empty `spec` deploys standalone Nacos with embedded storage. The chart's standalone Service +`nacos-cs` is type `NodePort`, so no extra object is needed to reach it. + +```yaml +apiVersion: nacos-operator.alauda.io/v1 +kind: Nacos +metadata: + name: nacos + namespace: nacos-demo +spec: {} # -> global.mode=standalone, nacos.storage.type=embedded, service.type=NodePort +``` + +```bash +kubectl apply -f nacos.yaml +``` + +### 2. Wait for Nacos to become Ready + +The Operator reconciles the CR into a Nacos `StatefulSet` (release name `nacos`) plus the `nacos-cs` +Service. Wait for the pod to become Ready: + +```bash +kubectl -n ${NAMESPACE} rollout status statefulset/nacos --timeout=300s +kubectl -n ${NAMESPACE} get pods,svc +``` + +Expected: the `nacos-0` pod is `1/1` Running and a `nacos-cs` Service exists exposing these ports: + +| Port | Name | Purpose | +|------|------|---------| +| 8848 | http | Nacos server — SDK, config & naming client open-API | +| 8080 | console | Web console + `/v3/console/health/readiness` | +| 9848 / 9849 | — | gRPC client-rpc / raft-rpc | +| 9080 | mcp | MCP endpoint | + +### 3. Reach the console (NodePort) + +```bash +# console node port (8080 is auto-assigned; the server 8848 port is pinned to 30000) +CONSOLE_PORT=$(kubectl -n ${NAMESPACE} get svc nacos-cs \ + -o jsonpath='{.spec.ports[?(@.name=="console")].nodePort}') +NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}') +echo "Console: http://${NODE_IP}:${CONSOLE_PORT}/" + +# readiness endpoint +curl -s "http://${NODE_IP}:${CONSOLE_PORT}/v3/console/health/readiness" # -> 200 +``` + +### 4. Validate configuration management and service discovery + +Run an in-cluster probe against the `nacos-cs` Service on the server port `8848` (the v1 client +open-APIs stay open in the default topology). Publish and read back a config, then register and list +a service instance: + +```bash +kubectl -n ${NAMESPACE} run probe --rm -it --restart=Never \ + --image=curlimages/curl:latest -- sh +``` + +Inside the probe container: + +```sh +SVC=nacos-cs.nacos-demo.svc.cluster.local:8848 + +# (A) publish a config -> "true", then read it back +curl -s -X POST "http://$SVC/nacos/v1/cs/configs" \ + -d 'dataId=demo.properties&group=DEFAULT_GROUP&content=key=value' +curl -s "http://$SVC/nacos/v1/cs/configs?dataId=demo.properties&group=DEFAULT_GROUP" +# -> key=value + +# (B) register a service instance -> "ok", then list it +curl -s -X POST "http://$SVC/nacos/v1/ns/instance" \ + -d 'serviceName=demo-svc&ip=10.0.0.1&port=8080' +curl -s "http://$SVC/nacos/v1/ns/instance/list?serviceName=demo-svc" +# -> JSON with hosts[] containing 10.0.0.1:8080 +``` + +## Configuration via the Install Form + +The wrapped CR spec mirrors the upstream chart `values.yaml`. The install form (driven by the plugin's +spec descriptors) exposes the main knobs; you can also set them directly on the CR `spec`: + +| Group | CR path | Notes | +|-------|---------|-------| +| Topology | `global.mode`, `nacos.replicaCount` | `standalone` (default) or `cluster` | +| Storage | `nacos.storage.type`, `nacos.storage.db.*` | `embedded` (default) or external `mysql` | +| Persistence | `persistence.enabled`, `persistence.data.storageClassName`, `persistence.data.resources.requests.storage` | retain embedded data across restarts | +| Service | `service.type`, `service.nodePort` | `NodePort` (default) or `ClusterIP` + your own Gateway/Ingress | +| Resources | `resources.requests.cpu`, `resources.requests.memory` | server container requests | +| Security | `nacos.authToken` | **override in production** — see below | + +> [!IMPORTANT] +> Nacos server 3.x enables its auth plugin by default and initializes the JWT signing key from the +> configured auth token, which must base64-decode to **≥ 32 bytes**. The chart default (`nil`) crashes +> the container on startup, so this plugin ships a **public placeholder** auth token to make the empty +> `spec` boot. **In production you must override `nacos.authToken`** (install form **Auth Token**, or +> `spec.nacos.authToken`) with your own value. Note that the v1 client open-APIs (`/nacos/v1/cs`, +> `/nacos/v1/ns`) remain open in this configuration — the token only initializes the auth plugin — which +> matches upstream community-chart behavior. + +### Persistence (optional) + +Standalone + embedded storage uses an `emptyDir` by default, so embedded (Derby) data does not survive +a pod restart. To retain it, enable persistence with a StorageClass: + +```yaml +apiVersion: nacos-operator.alauda.io/v1 +kind: Nacos +metadata: {name: nacos, namespace: nacos-demo} +spec: + persistence: + enabled: true + data: + storageClassName: + resources: {requests: {storage: 5Gi}} +``` + +## Known Limitations + + +- **First release follows the chart-declared server version (3.0.1).** The official + `nacos-group/nacos-k8s` chart declares `appVersion: 3.0.1`; newer upstream server versions (3.2.x) + are tracked by the factory's oss-watch bot and picked up on a later chart bump. This plugin + version-follows the chart as a unit. +- **Cluster mode on arm64 is not covered in this release.** The chart's `peer-finder` init image + (`nacos/nacos-peer-finder-plugin:1.1`) is **amd64-only**, and it is rendered only when + `global.mode: cluster`. Standalone (the default) does not use it. Cluster-mode-on-arm awaits a + multi-arch peer-finder in a future release. +- **Production must override the default Auth Token** (see the Security note above) — the shipped + placeholder is public. + + +## Cleanup + +```bash +kubectl delete nacos nacos -n nacos-demo +kubectl delete namespace nacos-demo +# Uninstall the Operator from Administrator > Marketplace > OperatorHub > Installed, or: +kubectl -n delete subscription nacos-operator +kubectl -n delete csv nacos-operator.v3.0.1 +``` + +## FAQ + +**Q: The Nacos pod is in `CrashLoopBackOff` right after install.** +Check the logs for `IllegalArgumentException: the length of secret key must ... >= 32 bytes`. That +means `nacos.authToken` was set to an invalid (too-short / `nil`) value. Use the shipped default or a +value that base64-decodes to at least 32 bytes. + +**Q: The Nacos pod is stuck in `ImagePullBackOff`.** +The plugin rewrites the operand reference to `docker.io/nacos/nacos-server` so the platform image +allowlist can match and rewrite it to the in-cluster registry. On an air-gapped cluster, ensure the +`sync-images` step mirrored `nacos-server:v3.0.1` to the platform registry and that the ImageWhiteList +rewrite is in effect. + +**Q: My embedded config disappeared after a pod restart.** +Standalone + embedded storage uses an `emptyDir` by default. Enable `persistence` with a StorageClass +(see [Persistence](#persistence-optional)) to retain data across restarts. + +**Q: How do I expose the console outside the cluster without NodePort?** +Set `spec.service.type: ClusterIP` and place your own Gateway/Ingress in front of the `nacos-cs` +Service (console on port 8080, server on 8848). + +**Q: How do I upgrade Nacos?** +Upgrade the Operator to the new version from the Marketplace; it reconciles the `Nacos` CR to the +matching chart/operand version. Version-following upgrades are handled by the factory's version-follow +pipeline. From 26f7712d16aa12b71d99ebf03a27a4ffe92fba2e Mon Sep 17 00:00:00 2001 From: Jinpei Su Date: Tue, 21 Jul 2026 04:11:18 +0000 Subject: [PATCH 2/2] =?UTF-8?q?docs(ecosystem/nacos):=20address=20review?= =?UTF-8?q?=20=E2=80=94=20scope=20claims,=20air-gap-safe=20probes?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex review (PR #812), 5 should-fix: 1. Networking claim scoped to the actual e2e matrix (4.3 amd64/IPv6, 4.2/4.1 arm64/IPv4) instead of 'every arch x IP-stack / dual-stack'. 2. NodePort console: bracket IPv6 node IPs; curl now prints the HTTP status (-o /dev/null -w '%{http_code}') to match the asserted 200. 3. Config/naming probes: exec into the nacos pod (ships curl) instead of an external curlimages/curl image — works on air-gapped/IPv6-only clusters and still traverses the nacos-cs Service; localhost fallback note added. 4. Rollout timeout 300s -> 600s + a ~10min cold-start/PVC note. 5. Cluster mode made explicit: requires replicaCount>=3 + external MySQL, standalone-focused validation, arm64 cluster is a known limitation. Shell mechanics of changed commands verified locally (IPv6 bracketing, curl status-code form). Cluster live-verify not practical (e2e envs air-gapped/cleaned). Co-Authored-By: Claude Opus 4.8 (1M context) --- .../nacos/Nacos_Installation_Guide.md | 74 +++++++++++-------- 1 file changed, 44 insertions(+), 30 deletions(-) diff --git a/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md b/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md index 3f914a739..0b12c33bf 100644 --- a/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md +++ b/docs/en/solutions/ecosystem/nacos/Nacos_Installation_Guide.md @@ -48,8 +48,9 @@ discovery end to end. | Upstream chart | `nacos-group/nacos-k8s` `/helm` @ `1b98fe67a4b2` (appVersion 3.0.1) | -> **Networking:** this release supports both IPv4 and IPv6 (single-stack and dual-stack) clusters — -> every architecture × IP-stack combination is covered by the release e2e matrix. +> **Networking:** this release is validated on both IPv4 and IPv6 clusters. The release e2e matrix +> covered ACP 4.3 on amd64/IPv6 and ACP 4.2 + 4.1 on arm64/IPv4; other architecture × IP-stack +> combinations (including dual-stack) are expected to work but were not exercised in this release. ## Prerequisites @@ -119,10 +120,14 @@ The Operator reconciles the CR into a Nacos `StatefulSet` (release name `nacos`) Service. Wait for the pod to become Ready: ```bash -kubectl -n ${NAMESPACE} rollout status statefulset/nacos --timeout=300s +kubectl -n ${NAMESPACE} rollout status statefulset/nacos --timeout=600s kubectl -n ${NAMESPACE} get pods,svc ``` +> The first rollout can take several minutes — Nacos server 3.x has a slow cold start, and when +> persistence is enabled the PVC must bind first. Allow up to ~10 minutes before treating a +> not-yet-Ready pod as a failure. + Expected: the `nacos-0` pod is `1/1` Running and a `nacos-cs` Service exists exposing these ports: | Port | Name | Purpose | @@ -139,41 +144,47 @@ Expected: the `nacos-0` pod is `1/1` Running and a `nacos-cs` Service exists exp CONSOLE_PORT=$(kubectl -n ${NAMESPACE} get svc nacos-cs \ -o jsonpath='{.spec.ports[?(@.name=="console")].nodePort}') NODE_IP=$(kubectl get nodes -o jsonpath='{.items[0].status.addresses[?(@.type=="InternalIP")].address}') -echo "Console: http://${NODE_IP}:${CONSOLE_PORT}/" -# readiness endpoint -curl -s "http://${NODE_IP}:${CONSOLE_PORT}/v3/console/health/readiness" # -> 200 +# Bracket the host if it is an IPv6 address (IPv6-only / air-gapped clusters) +case "$NODE_IP" in *:*) HOST="[$NODE_IP]" ;; *) HOST="$NODE_IP" ;; esac +echo "Console: http://${HOST}:${CONSOLE_PORT}/" + +# readiness endpoint — prints the HTTP status (expect 200) +curl -s -o /dev/null -w '%{http_code}\n' "http://${HOST}:${CONSOLE_PORT}/v3/console/health/readiness" ``` ### 4. Validate configuration management and service discovery -Run an in-cluster probe against the `nacos-cs` Service on the server port `8848` (the v1 client -open-APIs stay open in the default topology). Publish and read back a config, then register and list -a service instance: +Exercise the v1 client open-APIs (which stay open in the default topology) against the `nacos-cs` +Service on the server port `8848`. The Nacos pod already ships `curl`, so run the probes with +`kubectl exec` **inside** the pod — this needs no external probe image, which matters on air-gapped / +IPv6-only clusters where an image like `curlimages/curl` cannot be pulled. Curling the Service DNS +from inside the pod also exercises the `nacos-cs` Service routing, not just `localhost`: ```bash -kubectl -n ${NAMESPACE} run probe --rm -it --restart=Never \ - --image=curlimages/curl:latest -- sh -``` +POD=nacos-0 +SVC="nacos-cs.${NAMESPACE}.svc.cluster.local:8848" -Inside the probe container: - -```sh -SVC=nacos-cs.nacos-demo.svc.cluster.local:8848 - -# (A) publish a config -> "true", then read it back -curl -s -X POST "http://$SVC/nacos/v1/cs/configs" \ +# (A) publish a config -> "true", then read it back -> key=value +kubectl -n ${NAMESPACE} exec ${POD} -- curl -s -X POST \ + "http://${SVC}/nacos/v1/cs/configs" \ -d 'dataId=demo.properties&group=DEFAULT_GROUP&content=key=value' -curl -s "http://$SVC/nacos/v1/cs/configs?dataId=demo.properties&group=DEFAULT_GROUP" -# -> key=value +kubectl -n ${NAMESPACE} exec ${POD} -- curl -s \ + "http://${SVC}/nacos/v1/cs/configs?dataId=demo.properties&group=DEFAULT_GROUP" -# (B) register a service instance -> "ok", then list it -curl -s -X POST "http://$SVC/nacos/v1/ns/instance" \ +# (B) register a service instance -> "ok", then list it -> hosts[] with 10.0.0.1:8080 +kubectl -n ${NAMESPACE} exec ${POD} -- curl -s -X POST \ + "http://${SVC}/nacos/v1/ns/instance" \ -d 'serviceName=demo-svc&ip=10.0.0.1&port=8080' -curl -s "http://$SVC/nacos/v1/ns/instance/list?serviceName=demo-svc" -# -> JSON with hosts[] containing 10.0.0.1:8080 +kubectl -n ${NAMESPACE} exec ${POD} -- curl -s \ + "http://${SVC}/nacos/v1/ns/instance/list?serviceName=demo-svc" ``` +> [!NOTE] +> If the pod-to-own-Service-ClusterIP path does not converge (some CNIs lack hairpin support), +> substitute `localhost:8848` for the Service DNS in the commands above to confirm Nacos itself is +> healthy while you investigate the routing. + ## Configuration via the Install Form The wrapped CR spec mirrors the upstream chart `values.yaml`. The install form (driven by the plugin's @@ -181,8 +192,8 @@ spec descriptors) exposes the main knobs; you can also set them directly on the | Group | CR path | Notes | |-------|---------|-------| -| Topology | `global.mode`, `nacos.replicaCount` | `standalone` (default) or `cluster` | -| Storage | `nacos.storage.type`, `nacos.storage.db.*` | `embedded` (default) or external `mysql` | +| Topology | `global.mode`, `nacos.replicaCount` | `standalone` (default) or `cluster`. **Cluster mode requires `nacos.replicaCount` ≥ 3 and external MySQL storage** (see Storage), and is subject to the limitations below | +| Storage | `nacos.storage.type`, `nacos.storage.db.*` | `embedded` (default; standalone only) or external `mysql` (`nacos.storage.db.{host,port,name,username,password}`) — required for cluster mode | | Persistence | `persistence.enabled`, `persistence.data.storageClassName`, `persistence.data.resources.requests.storage` | retain embedded data across restarts | | Service | `service.type`, `service.nodePort` | `NodePort` (default) or `ClusterIP` + your own Gateway/Ingress | | Resources | `resources.requests.cpu`, `resources.requests.memory` | server container requests | @@ -221,10 +232,13 @@ spec: `nacos-group/nacos-k8s` chart declares `appVersion: 3.0.1`; newer upstream server versions (3.2.x) are tracked by the factory's oss-watch bot and picked up on a later chart bump. This plugin version-follows the chart as a unit. -- **Cluster mode on arm64 is not covered in this release.** The chart's `peer-finder` init image +- **Release validation is standalone-focused; cluster mode is not exercised in this release.** + Cluster mode (`global.mode: cluster`) requires `nacos.replicaCount` ≥ 3 **and** external MySQL + storage (embedded storage is standalone-only), and the release e2e covered the standalone topology. +- **Cluster mode on arm64 is a known limitation.** The chart's `peer-finder` init image (`nacos/nacos-peer-finder-plugin:1.1`) is **amd64-only**, and it is rendered only when - `global.mode: cluster`. Standalone (the default) does not use it. Cluster-mode-on-arm awaits a - multi-arch peer-finder in a future release. + `global.mode: cluster`. Standalone (the default) does not use it, so it is unaffected. + Cluster-mode-on-arm awaits a multi-arch peer-finder in a future release. - **Production must override the default Auth Token** (see the Security note above) — the shipped placeholder is public.