.claude/skills/nginx-to-higress-migration/SKILL.md
Migrate from ingress-nginx to Higress in Kubernetes environments. Use when (1) analyzing existing ingress-nginx setup (2) reading nginx Ingress resources and ConfigMaps (3) installing Higress via helm with proper ingressClass (4) identifying unsupported nginx annotations (5) generating WASM plugins for nginx snippets/advanced features (6) building and deploying custom plugins to image registry. Supports full migration workflow with compatibility analysis and plugin generation.
npx skillsauth add alibaba/higress nginx-to-higress-migrationInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Automate migration from ingress-nginx to Higress in Kubernetes environments.
Before you begin: Higress does NOT support the following nginx annotations:
nginx.ingress.kubernetes.io/server-snippetnginx.ingress.kubernetes.io/configuration-snippetnginx.ingress.kubernetes.io/http-snippetThese annotations will be silently ignored, causing functionality loss!
Pre-migration check (REQUIRED):
kubectl get ingress -A -o yaml | grep -E "snippet" | wc -lIf count > 0, you MUST plan WASM plugin replacements before migration. See Phase 6 for alternatives.
kubectl get ingress -A -o yaml > ingress-backup.yaml
kubectl get ingress -A -o yaml | grep "nginx.ingress.kubernetes.io" | sort | uniq -c
# Check for ingress-nginx installation
kubectl get pods -A | grep ingress-nginx
kubectl get ingressclass
# List all Ingress resources using nginx class
kubectl get ingress -A -o json | jq '.items[] | select(.spec.ingressClassName=="nginx" or .metadata.annotations["kubernetes.io/ingress.class"]=="nginx")'
# Get nginx ConfigMap
kubectl get configmap -n ingress-nginx ingress-nginx-controller -o yaml
Run the analysis script to identify unsupported features:
./scripts/analyze-ingress.sh [namespace]
Key point: No Ingress modification needed!
Higress natively supports nginx.ingress.kubernetes.io/* annotations - your existing Ingress resources work as-is.
See references/annotation-mapping.md for the complete list of supported annotations.
Unsupported annotations (require built-in plugin or custom WASM plugin):
nginx.ingress.kubernetes.io/server-snippetnginx.ingress.kubernetes.io/configuration-snippetnginx.ingress.kubernetes.io/lua-resty-waf*For these, check references/builtin-plugins.md first - Higress may already have a plugin!
Higress natively supports nginx.ingress.kubernetes.io/* annotations. Install Higress alongside nginx for safe parallel testing.
# 1. Get current nginx ingressClass name
INGRESS_CLASS=$(kubectl get ingressclass -o jsonpath='{.items[?(@.spec.controller=="k8s.io/ingress-nginx")].metadata.name}')
echo "Current nginx ingressClass: $INGRESS_CLASS"
# 2. Detect timezone and select nearest registry
# China/Asia: higress-registry.cn-hangzhou.cr.aliyuncs.com (default)
# North America: higress-registry.us-west-1.cr.aliyuncs.com
# Southeast Asia: higress-registry.ap-southeast-7.cr.aliyuncs.com
TZ_OFFSET=$(date +%z)
case "$TZ_OFFSET" in
-1*|-0*) REGISTRY="higress-registry.us-west-1.cr.aliyuncs.com" ;; # Americas
+07*|+08*|+09*) REGISTRY="higress-registry.cn-hangzhou.cr.aliyuncs.com" ;; # Asia
+05*|+06*) REGISTRY="higress-registry.ap-southeast-7.cr.aliyuncs.com" ;; # Southeast Asia
*) REGISTRY="higress-registry.cn-hangzhou.cr.aliyuncs.com" ;; # Default
esac
echo "Using registry: $REGISTRY"
# 3. Add Higress repo
helm repo add higress https://higress.io/helm-charts
helm repo update
# 4. Install Higress with parallel-safe settings
# Note: Override ALL component hubs to use the selected registry
helm install higress higress/higress \
-n higress-system --create-namespace \
--set global.ingressClass=${INGRESS_CLASS:-nginx} \
--set global.hub=${REGISTRY}/higress \
--set global.enableStatus=false \
--set higress-core.controller.hub=${REGISTRY}/higress \
--set higress-core.gateway.hub=${REGISTRY}/higress \
--set higress-core.pilot.hub=${REGISTRY}/higress \
--set higress-core.pluginServer.hub=${REGISTRY}/higress \
--set higress-core.gateway.replicas=2
Key helm values:
global.ingressClass: Use the same class as ingress-nginxglobal.hub: Image registry (auto-selected by timezone)global.enableStatus=false: Disable Ingress status updates to avoid conflicts with nginx (reduces API server pressure)nginx.ingress.kubernetes.io/* annotations⚠️ Note: After nginx is uninstalled, you can enable status updates:
helm upgrade higress higress/higress -n higress-system \
--reuse-values \
--set global.enableStatus=true
In Kind or local Kubernetes clusters, the LoadBalancer service will stay in PENDING state. Use one of these methods:
Option 1: Port Forward (Recommended for testing)
# Forward Higress gateway to local port
kubectl port-forward -n higress-system svc/higress-gateway 8080:80 8443:443 &
# Test with Host header
curl -H "Host: example.com" http://localhost:8080/
Option 2: NodePort
# Patch service to NodePort
kubectl patch svc -n higress-system higress-gateway \
-p '{"spec":{"type":"NodePort"}}'
# Get assigned port
NODE_PORT=$(kubectl get svc -n higress-system higress-gateway \
-o jsonpath='{.spec.ports[?(@.port==80)].nodePort}')
# Test (use docker container IP for Kind)
curl -H "Host: example.com" http://localhost:${NODE_PORT}/
Option 3: Kind with Port Mapping (Requires cluster recreation)
# kind-config.yaml
kind: Cluster
apiVersion: kind.x-k8s.io/v1alpha4
nodes:
- role: control-plane
extraPortMappings:
- containerPort: 30080
hostPort: 80
- containerPort: 30443
hostPort: 443
After Higress is running, generate a test script covering all Ingress routes:
# Generate test script
./scripts/generate-migration-test.sh > migration-test.sh
chmod +x migration-test.sh
# Get Higress gateway address
# Option A: If LoadBalancer is supported
HIGRESS_IP=$(kubectl get svc -n higress-system higress-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Option B: If LoadBalancer is NOT supported, use port-forward
kubectl port-forward -n higress-system svc/higress-gateway 8080:80 &
HIGRESS_IP="127.0.0.1:8080"
# Run tests
./migration-test.sh ${HIGRESS_IP}
The test script will:
⚠️ Only proceed after all tests pass!
Choose your cutover method based on infrastructure:
Option A: DNS Switch
# Update DNS records to point to Higress gateway IP
# Example: example.com A record -> ${HIGRESS_IP}
Option B: Layer 4 Proxy/Load Balancer Switch
# Update upstream in your L4 proxy (e.g., F5, HAProxy, cloud LB)
# From: nginx-ingress-controller service IP
# To: higress-gateway service IP
Option C: Kubernetes Service Switch (if using external traffic via Service)
# Update your external-facing Service selector or endpoints
Before writing custom plugins, check if Higress has a built-in plugin that meets your needs!
Higress provides many built-in plugins. Check references/builtin-plugins.md for the full list.
Common replacements for nginx features:
| nginx feature | Higress built-in plugin |
|---------------|------------------------|
| Basic Auth snippet | basic-auth |
| IP restriction | ip-restriction |
| Rate limiting | key-rate-limit, cluster-key-rate-limit |
| WAF/ModSecurity | waf |
| Request validation | request-validation |
| Bot detection | bot-detect |
| JWT auth | jwt-auth |
| CORS headers | cors |
| Custom response | custom-response |
| Request/Response transform | transformer |
| nginx snippet pattern | Higress solution |
|----------------------|------------------|
| Custom health endpoint (location /health) | WASM plugin: custom-location |
| Add response headers | WASM plugin: custom-response-headers |
| Request validation/blocking | WASM plugin with OnHttpRequestHeaders |
| Lua rate limiting | key-rate-limit plugin |
When nginx snippets or Lua logic has no built-in equivalent:
cd plugin-dir
go mod tidy
GOOS=wasip1 GOARCH=wasm go build -buildmode=c-shared -o main.wasm ./
If you don't have an image registry, install Harbor:
./scripts/install-harbor.sh
# Follow the prompts to install Harbor in your cluster
If you have your own registry:
# Build OCI image
docker build -t <registry>/higress-plugin-<name>:v1 .
docker push <registry>/higress-plugin-<name>:v1
apiVersion: extensions.higress.io/v1alpha1
kind: WasmPlugin
metadata:
name: custom-plugin
namespace: higress-system
spec:
url: oci://<registry>/higress-plugin-<name>:v1
phase: UNSPECIFIED_PHASE
priority: 100
See references/plugin-deployment.md for detailed plugin deployment.
# nginx snippet
more_set_headers "X-Custom: value";
→ Use headerControl annotation or generate plugin with proxywasm.AddHttpResponseHeader().
# nginx snippet
if ($request_uri ~* "pattern") { return 403; }
→ Generate WASM plugin with request header/path check.
# nginx snippet with Lua
access_by_lua_block { ... }
→ Generate WASM plugin implementing the logic.
See references/snippet-patterns.md for common patterns.
Before traffic switch, use the generated test script:
# Generate test script
./scripts/generate-migration-test.sh > migration-test.sh
chmod +x migration-test.sh
# Get Higress gateway IP
HIGRESS_IP=$(kubectl get svc -n higress-system higress-gateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
# Run all tests
./migration-test.sh ${HIGRESS_IP}
The test script will:
Only proceed with traffic cutover after all tests pass!
Symptoms: Ingress shows Ready, but curl returns 404
Check:
kubectl get ingress <name> -o yaml | grep ingressClassName
kubectl logs -n higress-system -l app=higress-controller --tail=100
kubectl run test --rm -it --image=curlimages/curl -- \
curl http://<service>.<namespace>.svc
Symptoms: Path not being rewritten, backend receives original path
Solution: Ensure use-regex: "true" is also set:
annotations:
nginx.ingress.kubernetes.io/rewrite-target: /$2
nginx.ingress.kubernetes.io/use-regex: "true"
Symptoms: nginx snippet features not working after migration
Cause: Higress does not support snippet annotations (by design, for security)
Solution:
Symptoms: HTTPS not working or certificate errors
Check:
kubernetes.io/tls
kubectl get secret <secret-name> -o yaml
kubectl get ingress <name> -o jsonpath='{.spec.tls}'
# View Higress controller logs
kubectl logs -n higress-system -l app=higress-controller -c higress-core
# View gateway access logs
kubectl logs -n higress-system -l app=higress-gateway | grep "GET\|POST"
# Check Envoy config dump
kubectl exec -n higress-system deploy/higress-gateway -c istio-proxy -- \
curl -s localhost:15000/config_dump | jq '.configs[2].dynamic_listeners'
# View gateway stats
kubectl exec -n higress-system deploy/higress-gateway -c istio-proxy -- \
curl -s localhost:15000/stats | grep http
Since nginx keeps running during migration, rollback is simply switching traffic back:
# If traffic was switched via DNS:
# - Revert DNS records to nginx gateway IP
# If traffic was switched via L4 proxy:
# - Revert upstream to nginx service IP
# Nginx is still running, no action needed on k8s side
Only after traffic has been fully migrated and stable:
# 1. Monitor Higress for a period (recommended: 24-48h)
# 2. Backup nginx resources
kubectl get all -n ingress-nginx -o yaml > ingress-nginx-backup.yaml
# 3. Scale down nginx (keep for emergency rollback)
kubectl scale deployment -n ingress-nginx ingress-nginx-controller --replicas=0
# 4. (Optional) After extended stable period, remove nginx
kubectl delete namespace ingress-nginx
tools
Develop Higress WASM plugins using Go 1.24+. Use when creating, modifying, or debugging Higress gateway plugins for HTTP request/response processing, external service calls, Redis integration, or custom gateway logic.
development
Deploy and configure Higress AI Gateway for OpenClaw integration. Use when: (1) User wants to deploy Higress AI Gateway, (2) User wants to configure OpenClaw to use more model providers, (3) User mentions 'higress', 'ai gateway', 'model gateway', 'AI网关', (4) User wants to set up model routing or auto-routing, (5) User needs to manage LLM provider API keys.
data-ai
生成 Higress 项目每日报告,追踪 issue/PR 动态,沉淀问题处理经验,驱动社区问题闭环。用于生成日报、跟进 issue、记录解决方案。
tools
Configure automatic model routing using the get-ai-gateway.sh CLI tool for Higress AI Gateway. Use when: (1) User wants to configure automatic model routing, (2) User mentions 'route to', 'switch model', 'use model when', 'auto routing', (3) User describes scenarios that should trigger specific models, (4) User wants to add, list, or remove routing rules.