diff --git a/config/manager/kustomization.yaml b/config/manager/kustomization.yaml index b87dd66..631b39f 100644 --- a/config/manager/kustomization.yaml +++ b/config/manager/kustomization.yaml @@ -2,4 +2,4 @@ resources: - manager.yaml images: - name: 4pdosc/autoconfig - newTag: "0.4.2" + newTag: "0.4.3" diff --git a/config/samples/modelroute-qwen.yaml b/config/samples/modelroute-qwen.yaml index 00b6970..f17911a 100644 --- a/config/samples/modelroute-qwen.yaml +++ b/config/samples/modelroute-qwen.yaml @@ -3,8 +3,8 @@ # 前置:cart-qwen 需先用 cache_aware_router helm chart 装(一个模型一个 cart): # helm -n llm-route install cart-qwen \ # --set fullnameOverride=cart-qwen \ -# --set reload.image=4pdosc/autoconfig-reload:0.4.2 \ -# --set ha.image=4pdosc/autoconfig-hagate:0.4.2 +# --set reload.image=4pdosc/autoconfig-reload:0.4.3 \ +# --set ha.image=4pdosc/autoconfig-hagate:0.4.3 # (cart 起始 initContainer 等 cart-qwen-config 有 workers → 本 ModelRoute apply 后 autoconfig 写入即就绪) # autoconfig 据此写 openresty-conf(session_route_qwen.conf)+ cart-qwen-config(workers)。 # 所有 service / outputConfigMap 均为 ns/name 全限定 → controller 全集群 watch,本 ModelRoute 放哪个 ns 都行 diff --git a/deploy/helm/autoconfig/Chart.yaml b/deploy/helm/autoconfig/Chart.yaml index 4bea316..ab25d42 100644 --- a/deploy/helm/autoconfig/Chart.yaml +++ b/deploy/helm/autoconfig/Chart.yaml @@ -2,7 +2,7 @@ apiVersion: v2 name: autoconfig description: k8s 后端发现 → 自动同步 openresty peers / cache-aware-router workers(ModelRoute controller) type: application -version: 0.4.2 # chart 版本 -appVersion: "0.4.2" # 镜像版本(image.tag 缺省用它) +version: 0.4.3 # chart 版本 +appVersion: "0.4.3" # 镜像版本(image.tag 缺省用它) keywords: [routing, openresty, cache-aware-router, service-discovery, operator] home: https://github.com/modelsphere/autoconfig diff --git a/internal/sink/openresty_shm_test.go b/internal/sink/openresty_shm_test.go new file mode 100644 index 0000000..c2c73d1 --- /dev/null +++ b/internal/sink/openresty_shm_test.go @@ -0,0 +1,37 @@ +package sink + +import ( + "regexp" + "strconv" + "strings" + "testing" +) + +// nginx carves a shared zone into pages of the kernel page size. arm64 hosts often run 64 KiB +// pages, where a zone of 128k or less fails at startup with "ngx_slab_alloc() failed: no memory" +// (measured on Kunpeng 920: 128k fails, 192k starts). A route that renders such a dict takes the +// whole openresty down on those hosts, so none may be under 256k. +func TestRenderRoute_SharedDictsFitLargePages(t *testing.T) { + got, err := RenderRoute(llmData(map[string]string{"tps_limit_tps": "30"})) + if err != nil { + t.Fatalf("render: %v", err) + } + re := regexp.MustCompile(`(?m)^\s*lua_shared_dict\s+(\S+)\s+(\d+)([kKmM]?)\s*;`) + dicts := re.FindAllStringSubmatch(got, -1) + if len(dicts) == 0 { + t.Fatalf("no lua_shared_dict found in the rendered route -- the check would pass on nothing:\n%s", got) + } + for _, d := range dicts { + n, _ := strconv.Atoi(d[2]) + kib := n / 1024 // bytes + switch strings.ToLower(d[3]) { + case "k": + kib = n + case "m": + kib = n * 1024 + } + if kib < 256 { + t.Errorf("lua_shared_dict %s is %s%s: under 256k it fails to start on 64 KiB-page hosts", d[1], d[2], d[3]) + } + } +} diff --git a/internal/sink/route.tmpl b/internal/sink/route.tmpl index d2c62e2..fcfe490 100644 --- a/internal/sink/route.tmpl +++ b/internal/sink/route.tmpl @@ -3,8 +3,10 @@ 按 // 派生 socket 分发;不监听 per-model TCP 端口。 Route(短名,用于 dict/register/socket 名)、Extra(任意调优项)、Peers(发现结果)。 */ -}} # {{.Route}} 路由(autoconfig 模板生成,勿手改;改模板或 ModelRoute) +# Every dict is at least 1m: on arm64 hosts with 64 KiB pages a zone of 128k or less fails at +# startup with "ngx_slab_alloc() failed: no memory" (192k is the smallest that starts there). lua_shared_dict active_conns_{{.Route}} 4m; -lua_shared_dict cluster_avg_{{.Route}} 16k; +lua_shared_dict cluster_avg_{{.Route}} 1m; lua_shared_dict lc_locks_{{.Route}} 1m; lua_shared_dict bad_peers_{{.Route}} 1m; lua_shared_dict bodylog_ctl_{{.Route}} 1m; diff --git a/test/e2e/crd_e2e.sh b/test/e2e/crd_e2e.sh index 76b2afe..6e44292 100644 --- a/test/e2e/crd_e2e.sh +++ b/test/e2e/crd_e2e.sh @@ -4,13 +4,13 @@ # → 验 cart-config workers + openresty CART优先/后端兜底 peers + status → scale 跟随 → 删除清理。 # # 依赖:autoconfig helm chart(默认 $HERE/charts/autoconfig,含 CRD+RBAC+controller)。 -# 用法:NS=ac-e2e IMG=4pdosc/autoconfig:0.4.2 bash crd_e2e.sh [--keep] +# 用法:NS=ac-e2e IMG=4pdosc/autoconfig:0.4.3 bash crd_e2e.sh [--keep] set -uo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" NS=${NS:-ac-e2e} CTRL_NS=${CTRL_NS:-autoconfig} AC_CHART=${AC_CHART:-$HERE/charts/autoconfig} -IMG=${IMG:-4pdosc/autoconfig:0.4.2} +IMG=${IMG:-4pdosc/autoconfig:0.4.3} MOCK=${MOCK:-python:3.12-alpine} KEEP=0; [ "${1:-}" = "--keep" ] && KEEP=1 FAIL=0 diff --git a/test/e2e/ha_failover_check.sh b/test/e2e/ha_failover_check.sh index e53c2ce..d7dca59 100644 --- a/test/e2e/ha_failover_check.sh +++ b/test/e2e/ha_failover_check.sh @@ -7,7 +7,7 @@ NS=${NS:-kimi} CHARTS=${CHARTS:-$HERE/charts} OR_IMG=${OR_IMG:-4pdosc/llm-openresty:0.1.20} CART_IMG=${CART_IMG:-4pdosc/cache_aware_router:0.6.5} -ACR=${ACR:-4pdosc/autoconfig-reload:0.4.2} +ACR=${ACR:-4pdosc/autoconfig-reload:0.4.3} AUTH_KEY=${AUTH_KEY:?需设置:openresty 入口鉴权 key(Bearer)} FAIL=0; say(){ echo -e "\n=== $* ==="; }; ok(){ echo " PASS: $*"; }; bad(){ echo " FAIL: $*"; FAIL=1; } diff --git a/test/e2e/helm_e2e.sh b/test/e2e/helm_e2e.sh index e95394d..15bcf43 100644 --- a/test/e2e/helm_e2e.sh +++ b/test/e2e/helm_e2e.sh @@ -7,7 +7,7 @@ HERE="$(cd "$(dirname "$0")" && pwd)" CHART=${CHART:-$HERE/autoconfig} NS=${NS:-autoconfig} TNS=${TNS:-ac-helm-e2e} -IMG_TAG=${IMG_TAG:-0.4.2} +IMG_TAG=${IMG_TAG:-0.4.3} MOCK=${MOCK:-python:3.12-alpine} KEEP=0; [ "${1:-}" = "--keep" ] && KEEP=1 FAIL=0 diff --git a/test/e2e/prod_real_model_e2e.sh b/test/e2e/prod_real_model_e2e.sh index 4d2149a..160d351 100644 --- a/test/e2e/prod_real_model_e2e.sh +++ b/test/e2e/prod_real_model_e2e.sh @@ -3,7 +3,7 @@ # 后端 = 真 opt-125m vLLM(复用 e2e-test/vllm-mock-vllm-svc,跨 ns discovery)。真 /v1/completions 推理。 set -uo pipefail NS=${NS:-llm-route}; CTRL_NS=autoconfig; CHARTS=~/prod-e2e/charts -H=4pdosc; TAG=${IMG_TAG:-0.4.2} +H=4pdosc; TAG=${IMG_TAG:-0.4.3} AC=$H/autoconfig; ACR=$H/autoconfig-reload:$TAG; AH=$H/autoconfig-hagate:$TAG OR_IMG=$H/llm-openresty:0.1.20; CART_IMG=$H/cache_aware_router:0.6.5; MON_IMG=${MON_IMG:?set MON_IMG to an llm-monitor image} BACKEND_SVC=e2e-test/vllm-mock-vllm-svc; BPORT=8000; MODEL=facebook/opt-125m diff --git a/test/e2e/real_helm_e2e.sh b/test/e2e/real_helm_e2e.sh index 547bdba..db741e0 100644 --- a/test/e2e/real_helm_e2e.sh +++ b/test/e2e/real_helm_e2e.sh @@ -5,12 +5,12 @@ # Run it where kubectl and helm reach the cluster. Needs charts/{autoconfig,openresty,cache_aware_router,monitor} # next to it (the autoconfig chart carries the CRD, RBAC and controller). # openresty / monitor / cache_aware_router chart 各在其仓(llm-openresty / llm-monitor / cache_aware_router)的 k8s/helm/ —— 跑前拷进 charts/{openresty,monitor,cache_aware_router}。 -# IMG_TAG=0.4.2 bash real_helm_e2e.sh [--keep] +# IMG_TAG=0.4.3 bash real_helm_e2e.sh [--keep] set -uo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" NS=${NS:-ac-helm} CTRL_NS=${CTRL_NS:-autoconfig} -TAG=${IMG_TAG:-0.4.2} +TAG=${IMG_TAG:-0.4.3} CHARTS=${CHARTS:-$HERE/charts} AC=4pdosc/autoconfig ACR=4pdosc/autoconfig-reload:$TAG diff --git a/test/e2e/real_kimi_e2e.sh b/test/e2e/real_kimi_e2e.sh index cb99d65..fd119aa 100644 --- a/test/e2e/real_kimi_e2e.sh +++ b/test/e2e/real_kimi_e2e.sh @@ -5,12 +5,12 @@ # 真发一条 /v1/chat/completions 经 openresty→CART→kimi 拿真实回答。 # 依赖同目录:charts/{autoconfig,openresty,cache_aware_router,monitor}(autoconfig chart 含 CRD+RBAC+controller)。 # openresty / monitor / cache_aware_router chart 各在其仓(llm-openresty / llm-monitor / cache_aware_router)的 k8s/helm/ —— 跑前拷进 charts/{openresty,monitor,cache_aware_router}。 -# IMG_TAG=0.4.2 bash real_kimi_e2e.sh [--keep] +# IMG_TAG=0.4.3 bash real_kimi_e2e.sh [--keep] set -uo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" NS=${NS:-kimi} # 与 kimi LWS 同 ns(discovery 同 ns) CTRL_NS=${CTRL_NS:-autoconfig} -TAG=${IMG_TAG:-0.4.2} +TAG=${IMG_TAG:-0.4.3} CHARTS=${CHARTS:-$HERE/charts} KIMI_SVC=${KIMI_SVC:-kimi-k26-leader} MODEL=${MODEL:-kimi-k2.6} diff --git a/test/e2e/test_dynamic.sh b/test/e2e/test_dynamic.sh index 8b03e4d..496226b 100644 --- a/test/e2e/test_dynamic.sh +++ b/test/e2e/test_dynamic.sh @@ -3,7 +3,7 @@ # 后端用可扩缩 mock(autoconfig 发现行为不需真推理);真推理/GPU 数据在 resilience/opt 用真 opt-125m。 set -uo pipefail NS=${NS:-llm-route}; CTRL_NS=autoconfig; CHARTS=~/prod-e2e/charts -H=4pdosc; TAG=${IMG_TAG:-0.4.2} +H=4pdosc; TAG=${IMG_TAG:-0.4.3} AC=$H/autoconfig; ACR=$H/autoconfig-reload:$TAG; AH=$H/autoconfig-hagate:$TAG OR_IMG=$H/llm-openresty:0.1.20; CART_IMG=$H/cache_aware_router:0.6.5; MON_IMG=${MON_IMG:?set MON_IMG to an llm-monitor image}; MOCK=python:3.12-alpine KEEP=${KEEP:-0}; FAIL=0 diff --git a/test/e2e/verify_crossns_port.sh b/test/e2e/verify_crossns_port.sh index 21acff8..248774d 100644 --- a/test/e2e/verify_crossns_port.sh +++ b/test/e2e/verify_crossns_port.sh @@ -2,10 +2,10 @@ # 验证两个新特性(0.3.8 端口自动推导 + 0.3.22 service ns/name 跨 ns 发现): # 在【别的 ns(xns)】建 ModelRoute,discovery.service=kimi/kimi-k26-leader(跨 ns)、【不写 port】, # 验证仍发现 kimi leader、端口自动 = 8050。前提:kimi LWS 在跑、autoconfig controller 已升到目标 tag。 -# 依赖:autoconfig helm chart($HERE/charts/autoconfig)。用法:IMG_TAG=0.4.2 bash verify_crossns_port.sh +# 依赖:autoconfig helm chart($HERE/charts/autoconfig)。用法:IMG_TAG=0.4.3 bash verify_crossns_port.sh set -uo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" -TAG=${IMG_TAG:-0.4.2} +TAG=${IMG_TAG:-0.4.3} CTRL_NS=${CTRL_NS:-autoconfig} AC=4pdosc/autoconfig AC_CHART=${AC_CHART:-$HERE/charts/autoconfig} diff --git a/test/e2e/verify_status_error.sh b/test/e2e/verify_status_error.sh index 03fd796..f5114b5 100644 --- a/test/e2e/verify_status_error.sh +++ b/test/e2e/verify_status_error.sh @@ -1,10 +1,10 @@ #!/usr/bin/env bash # 验证:发现失败(多端口 Service 未显式配 port)时,原因写进 ModelRoute status(DiscoverError), # kubectl describe/get 看得到——而非只进 controller 日志。前提:controller 已升到目标 tag。 -# 依赖:autoconfig helm chart($HERE/charts/autoconfig)。用法:IMG_TAG=0.4.2 bash verify_status_error.sh +# 依赖:autoconfig helm chart($HERE/charts/autoconfig)。用法:IMG_TAG=0.4.3 bash verify_status_error.sh set -uo pipefail HERE="$(cd "$(dirname "$0")" && pwd)" -TAG=${IMG_TAG:-0.4.2} +TAG=${IMG_TAG:-0.4.3} CTRL_NS=${CTRL_NS:-autoconfig} AC=4pdosc/autoconfig AC_CHART=${AC_CHART:-$HERE/charts/autoconfig}