
Eco² vocabulary
- edge
- auth offload
- domain api
- task queue
- scan pipeline
- chat agent
- event bus
- cluster
- gitops
- autoscaling
- observability
- load test
- evaluation
Edge: ROUTE 53 · ALB · HTTPS 443 · internet-facing · external-dns · istio-ingressgateway · NodePort · eco2-gateway · VirtualService · x-canary · AuthorizationPolicy · ENVOY SIDECAR · kiali-serverAuth Offload: AuthorizationPolicy · action: CUSTOM · notPaths · envoyExtAuthzGrpc · failOpen: false · CheckRequest · x-user-id · BlacklistCache · BootstrapFromRedis · outbox:blacklist · blacklist.events · UsersServiceDomain API: VirtualService · x-user-id · /api/v1/scan · X-Idempotency-Key · job_id · stream_url · 202 ACCEPTED · Retry-After · ScanTask · UsersService · ImageService · ENVOY SIDECARTask Queue: outbox:blacklist · blacklist.events · RabbitmqCluster · scan.direct · reward.events · dlx · x-dead-letter-exchange · chat.process · AioPikaBroker · task_acks_late · apply_async · gevent · scan.vision · scan.rule · scan.answer · scan.reward · CELERY CHAIN · QueueLength · inspect ping · QUEUE SATURATIONScan Pipeline: ScanTask · scan.direct · reward.events · apply_async · gevent · scan.vision · scan.rule · scan.answer · scan.reward · CELERY CHAIN · RewardStep · item_class_list.yaml · situation_tags.yaml · LITE RAG · JsonRegulationRetriever · PipelineStage · waste_rag · XADD · domain: worker-ai · pipeline_duration · vision_stage_durationChat Agent: ImageService · chat.process · AioPikaBroker · create_chat_graph · route_by_intent · MULTI-INTENT FANOUT · waste_rag · recyclable_price · collection_point · image_generation · aggregator · thread_id · SyncableRedisSaver · AsyncPostgresSaver · LANGSMITH_TRACING · regenerateEvent Bus: job_id · stream_url · PipelineStage · XADD · scan:events:{shard} · XREADGROUP · XACK · XAUTOCLAIM · PendingReclaimer · STATE KV · scan:state:{job_id} · sse:events:{shard} · SSEBroadcastManager · Last-Event-ID · scan_sse_connections_active · ServiceMonitor · traceparentCluster: NodePort · kubeadm init · kubeadm join · vxlanMode · BGPConfiguration · module "vpc" · worker_ai · nodeSelector · domain: worker-ai · NoSchedule · 24-NODE CLUSTERGitOps: external-dns · x-canary · dev-root · ApplicationSet · sync-wave · selfHeal · ignoreDifferences · argocd-image-updater · update-strategy: digest · write-back-method · targetRevision · ci-services.ymlAutoscaling: ignoreDifferences · ScaledObject · QueueLength · cooldownPeriod · pollingInterval · fallback · maxReplicaCount · stabilizationWindowSeconds · HorizontalPodAutoscaler · scan_sse_connections_active · prometheus-adapterObservability: 24-NODE CLUSTER · prometheus-adapter · FLUENT BIT · Elasticsearch · Kibana · kube-prometheus-stack · AlertmanagerConfig · ServiceMonitor · JAEGER · OPENTELEMETRY · traceparent · kiali-server · LANGSMITH_TRACINGLoad Test: k6 · ramping-vus · thresholds · pipeline_duration · vision_stage_duration · poll_timeout · inspect ping · WORKER RESTART · POLLING TIMEOUT · QUEUE SATURATIONEvaluation: EvalConfig · eval_mode · eval_sample_rate · eval_cost_budget_daily_usd · EvalResult · EvalGrade · code_grader · llm_grader · CUSUM · regenerate · OpenAIBARSEvaluator
24 個節點實際上如何連接,一次看一條流程。
以 kubeadm 建置的自行管理 Kubernetes。架構圖將 24 個實體節點及其上的工作負載,放進 README 的五個層級中,並以實際連線相接。選擇一條流程,即只標示該路徑並附上步驟編號。
它從照片辨識廢棄物並說明丟棄方式,在對話中呼叫地點、天氣、回收價格與網路搜尋等工具,並生成圖片。在這個團隊專案中,我從叢集與部署基礎開始,逐步將負責範圍擴展到領域後端、非同步處理、對話代理與驗證。
從競賽開發到後端與維運強化
服務已結束營運;錄製的示範影片與技術報告呈現其運作情形。
Scan 請求 → 即時傳遞
照片分析請求成為排入佇列的工作,其進度事件回到同一個瀏覽器。
瀏覽器DNS 查詢: DNS 查詢Route 53
只從 Route 53 的記錄解析名稱。請求不會經過 DNS。
瀏覽器資料流: HTTPS 443AWS ALB
TLS 在 ALB 終止。
AWS ALB資料流: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gateway經由 EC2 執行個體目標的 NodePort,交給 Istio ingress Envoy。
Istio ingress Envoy
k8s-ingress-gateway資料流: VirtualServiceScan APIk8s-api-scan路由至 Scan API,由它將工作排入佇列並立即傳回 job_id;查詢結果時,在作業完成前都回應 202。
Scan API
k8s-api-scan資料流: Celery 任務RabbitMQk8s-rabbitmqScan 任務放入 RabbitMQ。
RabbitMQ
k8s-rabbitmq資料流: consumescan-workerk8s-worker-ai · k8s-worker-ai-2AI 池中的 scan-worker(Celery · gevent)取得任務,執行 Vision → Rule → Answer → Reward。這四個階段是以 chain 串接的 Celery 任務,不是節點。
AI 池
k8s-worker-ai · k8s-worker-ai-2資料流: HTTPSLLM APIscan 與 chat worker 呼叫 OpenAI 與 Google API。
scan-worker
k8s-worker-ai · k8s-worker-ai-2資料流: XADD scan:eventsStreamsk8s-redis-streams進度事件寫入四個 Streams 分片之一。
Streams
k8s-redis-streams資料流: XREADGROUPEvent Routerk8s-event-routerEvent Router 以 consumer group 讀取,處理後執行 XACK;pending 與 reclaim 確保 at-least-once 傳遞。
Event Router
k8s-event-router資料流: SETEX stateState KVk8s-redis-streams它將最新狀態與重複處理標記,寫入同一 Redis 節點上的 State KV。
Event Router
k8s-event-router資料流: PUBLISHPub/Subk8s-redis-pubsub透過分片 Pub/Sub 中該作業的頻道即時傳送。
Pub/Sub
k8s-redis-pubsub資料流: SUBSCRIBESSE Gatewayk8s-sse-gatewaySSE Gateway 在每個行程中以一個共用的 listener 訂閱,再分送給每個已連線的瀏覽器。
SSE Gateway
k8s-sse-gateway資料流: SSE 串流瀏覽器經由相同 ALB 與 ingress 路徑開啟的連線。傳遞為 at-least-once;重複以冪等方式處理。
State KV
k8s-redis-streams資料流: 重新連線復原SSE Gatewayk8s-sse-gateway帶著 Last-Event-ID 重新連線時,由 State KV 與保留的 Streams 補上遺漏的事件。
Chat · token 與儲存
Chat 的 token 與 Scan 走相同的事件路徑;檢查點與訊息由兩個不同的工作負載儲存。
瀏覽器資料流: HTTPS 443AWS ALB
TLS 在 ALB 終止。
AWS ALB資料流: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gateway經由 EC2 執行個體目標的 NodePort,交給 Istio ingress Envoy。
Istio ingress Envoy
k8s-ingress-gateway資料流: VirtualServiceChat APIk8s-api-chat路由至 Chat API。
Chat API
k8s-api-chat資料流: Taskiq 任務RabbitMQk8s-rabbitmqChat 任務放入 RabbitMQ。
RabbitMQ
k8s-rabbitmq資料流: consumechat-workerk8s-worker-ai · k8s-worker-ai-2chat-worker(Taskiq · asyncio)以 LangGraph 分類意圖,接著視需要執行 vision、選定的工具、aggregator,必要時再產生摘要,然後回答。每個請求只執行所需的分支。
AI 池
k8s-worker-ai · k8s-worker-ai-2資料流: HTTPSLLM APIscan 與 chat worker 呼叫 OpenAI 與 Google API。
chat-worker
k8s-worker-ai · k8s-worker-ai-2資料流: XADD chat:eventsStreamsk8s-redis-streamstoken 與階段事件寫入四個 Streams 分片;之後的傳遞路徑與 Scan 相同。
Streams
k8s-redis-streams資料流: XREADGROUPEvent Routerk8s-event-routerEvent Router 以 consumer group 讀取,處理後執行 XACK;pending 與 reclaim 確保 at-least-once 傳遞。
Event Router
k8s-event-router資料流: PUBLISHPub/Subk8s-redis-pubsub透過分片 Pub/Sub 中該作業的頻道即時傳送。
Pub/Sub
k8s-redis-pubsub資料流: SUBSCRIBESSE Gatewayk8s-sse-gatewaySSE Gateway 在每個行程中以一個共用的 listener 訂閱,再分送給每個已連線的瀏覽器。
SSE Gateway
k8s-sse-gateway資料流: SSE 串流瀏覽器經由相同 ALB 與 ingress 路徑開啟的連線。傳遞為 at-least-once;重複以冪等方式處理。
chat-worker
k8s-worker-ai · k8s-worker-ai-2資料流: checkpointCachek8s-redis-cacheLangGraph 的檢查點保存在 Redis Cache 中。
Cache
k8s-redis-cache資料流: 讀取檢查點checkpoint-syncerk8s-worker-ai · k8s-worker-ai-2checkpoint-syncer 從 Redis 讀取檢查點。
checkpoint-syncer
k8s-worker-ai · k8s-worker-ai-2資料流: 同步至 PostgreSQLPostgreSQLk8s-postgresqlAsyncPostgresSaver 以非同步方式將其存入 PostgreSQL。
Streams
k8s-redis-streams資料流: chat-persistence grouppersistence consumerk8s-api-chatChat 節點上的 persistence consumer 以 consumer group 讀取 done 事件。
persistence consumer
k8s-api-chat資料流: 儲存訊息PostgreSQLk8s-postgresqlChat 訊息存入 PostgreSQL。這與 checkpoint-syncer 是不同的工作負載。
入口 · 身分驗證
從叢集入口到達領域 API 的同步路徑。只有受策略保護的路徑會先檢查身分驗證;節點之間的 Pod 通訊使用 Calico VXLAN。
瀏覽器DNS 查詢: DNS 查詢Route 53
只從 Route 53 的記錄解析名稱。請求不會經過 DNS。
瀏覽器資料流: HTTPS 443AWS ALB
TLS 在 ALB 終止。
AWS ALB資料流: HTTP · NodePortIstio ingress Envoy
k8s-ingress-gateway經由 EC2 執行個體目標的 NodePort,交給 Istio ingress Envoy。
Istio ingress Envoy
k8s-ingress-gateway資料流: ext-authz · gRPC 50051ext-authzk8s-api-auth只有套用 CUSTOM 策略的路徑,才會先詢問 Go ext-authz(逾時 2 秒,failOpen false)。登入、health 與 docs 等路徑不在此列。
ext-authz
k8s-api-auth資料流: 黑名單查詢blacklistk8s-redis-auth以 Redis 黑名單檢查權杖。
Istio ingress Envoy
k8s-ingress-gateway資料流: VirtualServiceChat APIk8s-api-chat路由至 Chat API。
Chat API
k8s-api-chat資料流: gRPCimages APIk8s-api-imageREADME 中載明的 chat → images 同步呼叫。
auth API
k8s-api-auth資料流: gRPCusers APIk8s-api-usersREADME 中載明的 auth → users 同步呼叫。
儲存池 · 非同步儲存
身分驗證黑名單與角色擁有權,由儲存池的 worker 儲存,這些 worker 從 RabbitMQ 取得工作。
blacklist
k8s-redis-auth資料流: outbox:blacklistauth-relayk8s-worker-storage · k8s-worker-storage-2auth-relay(README 中的 auth-Bus)讀取 Redis outbox。
auth-relay
k8s-worker-storage · k8s-worker-storage-2資料流: blacklist.eventsRabbitMQk8s-rabbitmq它重新發布到 RabbitMQ,並具備重試與 DLQ。
RabbitMQ
k8s-rabbitmq資料流: blacklist.eventsauth-workerk8s-worker-storage · k8s-worker-storage-2auth-worker 接收黑名單事件。
auth-worker
k8s-worker-storage · k8s-worker-storage-2資料流: 儲存黑名單blacklistk8s-redis-auth事件存入 Redis 黑名單。
RabbitMQ
k8s-rabbitmq資料流: Celery batchusers-workerk8s-worker-storage · k8s-worker-storage-2users-worker 以批次接收角色擁有權的工作。
users-worker
k8s-worker-storage · k8s-worker-storage-2資料流: UPSERTPostgreSQLk8s-postgresql套用至 PostgreSQL。
設定 · 擴展 · 觀測
Platform Layer 不是請求經過的步驟;它部署、設定、擴展並觀測其他層級。節點是以 Terraform 建立的 EC2,並以 Ansible 安裝 kubeadm 與 Calico;CI 只驗證 Terraform,從不自動 apply。
GitHub Actions · Docker Hub設定 · 擴縮: 映像檔 · manifest 修訂版本Argo CD image updater
k8s-masterArgo CD 透過 App-of-Apps 與 Sync Waves 使叢集設定保持一致。只確認了 image updater 位於 control-plane。
ALB Controller · ExternalDNS
k8s-master設定 · 擴縮: Ingress → ALB · DNS 記錄AWS 託管ALB Controller 與 ExternalDNS 設定 AWS 端的資源。這不是請求經過的路徑。
Istiod
k8s-master設定 · 擴縮: xDS 設定Istio ingress Envoyk8s-ingress-gatewayIstiod 透過 xDS,將 Gateway、VirtualService 與 EnvoyFilter 設定推送到 ingress Envoy 與各 API 的 Envoy sidecar。
KEDA
k8s-monitoring設定 · 擴縮: Pod 數量AI 池k8s-worker-ai · k8s-worker-ai-2KEDA 調整 worker Pod 的數量。節點數量不變。
KEDA
k8s-monitoring設定 · 擴縮: Pod 數量儲存池k8s-worker-storage · k8s-worker-storage-2儲存池的 worker Pod 也以相同方式調整規模。
Fluent Bit觀測: 日誌Elasticsearch
k8s-loggingFluent Bit 是每個節點上的 DaemonSet,將日誌送往 Elasticsearch。
AI 池
k8s-worker-ai · k8s-worker-ai-2觀測: LLM 執行追蹤LangSmithLLM 呼叫的追蹤送往外部 SaaS LangSmith。
所有連線以相同粗細顯示。選擇一個流程,即只突顯其路徑,並標出步驟編號。
- 實線 · 請求、工作、事件與寫入的流向
- 點線 · DNS 查詢;請求不經過此處
- 虛線 · 設定或擴縮;不是資料路徑
- 長點劃線 · 日誌與執行追蹤
- 粗黑線 · 所選流程;數字表示順序
- 方框 · 實體節點,標題為主機名稱
- 內層小框 · 在該節點上執行的工作負載
- 虛線框 · 由兩個節點組成的排程池
- 虛線框 · 位於叢集之外,不計入節點數
- 橘色外框 · 模型做出判斷之處
- Control plane1 個節點
- Domain API8 個節點
- AI 池2 個節點
- 儲存池2 個節點
- Data5 個節點
- Platform6 個節點
README 的五個層級(帶狀區)與實體群組(各節點標頭的色調),以不同方式歸組同樣的 24 個節點。State KV 與 Streams 共用節點,不另行計算;Route 53、ALB 與叢集外的服務不是節點。池是排程範圍,並不表示每個 Pod 都在兩個節點上執行。
24節點
24 = 1 control plane + 8 API + 4 worker + 5 data + 6 platform
1Control plane
role: control-planekube-apiserver · scheduler · controller-manager · etcd,以及平台控制器。
- k8s-master
8Domain API
domain: <服務>每個領域一個節點。內部呼叫使用 gRPC。
- k8s-api-auth
- k8s-api-users
- k8s-api-scan
- k8s-api-character
- k8s-api-location
- k8s-api-image
- k8s-api-chat
- k8s-api-info
4Execution worker
兩個排程池,各有兩個節點。KEDA 調整 Pod 數量;節點數量維持不變。
儲存池
domain: worker-storage- k8s-worker-storage
- k8s-worker-storage-2
AI 池
domain: worker-ai- k8s-worker-ai
- k8s-worker-ai-2
5Data
Redis 依用途分為四個節點。PostgreSQL 的儲存使用 EBS CSI · gp3。
- k8s-postgresql
- k8s-redis-auth
- k8s-redis-streams
- k8s-redis-cache
- k8s-redis-pubsub
6Platform
訊息傳遞、可觀測性、入口與即時傳遞,各自擁有節點。
- k8s-rabbitmq
- k8s-monitoring
- k8s-logging
- k8s-ingress-gateway
- k8s-sse-gateway
- k8s-event-router
- 每個節點
- Fluent Bit · DaemonSet
- Calico
設定的模型 · 依供應商
服務已終止,因此這些是儲存庫中設定的模型,而非現今可選的模型。每個角色分別列出;這不是經驗證執行的清單。
OpenAI
Chat 預設供應商
Chat
openai/gpt-5.2預設
預設模型為 gpt-5.2;請求中指定模型時,改用該模型。
Scan
gpt-5.2預設gpt-5.2-progpt-5.1gpt-5gpt-5-progpt-5-mini
不在 13 個模型對應表中的模型會被拒絕。
圖片對應
gpt-image-1.5
與 Responses 協調模型 gpt-5.2 分開。影像生成預設為關閉。
評測
gpt-4o-mini預設
對話評測的 LLM grader,與 Chat 模型分開。
Google
Chat 選擇 Google 時
Chat
google/gemini-3-pro-previewgoogle/gemini-3-flash-preview
選擇 Google 時,預設為 gemini-3-flash-preview。
Scan
gemini-3-pro-previewgemini-3-flash-previewgemini-2.5-progemini-2.5-flashgemini-2.5-flash-litegemini-2.0-flashgemini-2.0-flash-lite
圖片對應
gemini-3-pro-image-preview