本文提供逐步說明,協助您在 Google Distributed Cloud (GDC) 實體隔離環境中部署 AI Gateway。這個閘道是以 Envoy Gateway、以 Envoy Proxy 為基礎的 Kubernetes Gateway API 實作項目,以及 Envoy Agent Router (前身為 Envoy AI Gateway) 為基礎建構而成,後者是將 Envoy Gateway 轉換為大型語言模型 (LLM) 流量的統一入口點,並與 OpenAI 相容的擴充功能。內容涵蓋將容器映像檔和 Helm 資訊套件植入本機 Harbor 登錄檔、在標準叢集上安裝兩個控制層、準備選用的權杖式速率限制後端,以及使用範例工作負載驗證安裝作業。
模型服務後端 (Ollama、vLLM) 會隨附一組指南部署,請參閱 GDC 氣隙環境中的開放權重模型;Envoy 代理程式路由器使用者指南中的主體式路由說明如何依模型名稱將要求轉送至這些後端。
架構
這項解決方案會在 GDC 標準叢集中執行。管理員工作站會將映像檔和 Helm 圖表植入專案的 Harbor 登錄檔,並安裝兩個控制平面:Envoy Gateway 控制器 (可從 Gateway API 資源 (GatewayClass、Gateway、HTTPRoute) 程式化 Envoy 代理程式資料平面),以及 Envoy 代理程式路由器控制器 (可透過 AI 流量的外部處理器 (ExtProc) 擴充該資料平面 (AIGatewayRoute、AIServiceBackend、InferencePool))。應用程式用戶端會將與 OpenAI 相容的要求傳送至 Envoy 代理程式,後者會將要求路由至模型服務後端或 InferencePool。選用的 Redis 執行個體會儲存 Envoy 速率限制服務的計數器,用於以權杖為基礎的速率限制。

Envoy Gateway
Envoy Gateway 是以 Envoy Proxy 為基礎建構的開放原始碼專案,可簡化 Envoy Proxy 的採用、使用和管理作業,做為 Kubernetes API 閘道。這項功能實作並擴充了 Kubernetes Gateway API (Ingress API 的後繼產品):GatewayClass 和 Gateway 資源會說明進入點,而 HTTPRoute 等路徑資源則會說明流量的比對和轉送方式。此外,這項功能採用角色導向設計,可區分基礎架構和應用程式團隊的責任。Envoy Gateway 會新增自己的擴充 API,例如 EnvoyProxy (資料平面設定)、Backend (叢集外部或由 FQDN 參照的端點) 和 ClientTrafficPolicy (緩衝區限制等連線設定)。
Envoy 代理程式路由器
Envoy Agent Router (舊稱 Envoy AI Gateway) 是開放原始碼專案,可使用 Envoy Gateway 處理從應用程式用戶端到生成式 AI 服務的要求流量。這項服務提供統一的層,可透過模型感知型路由、上游驗證、以權杖為準的頻率限制和觀測能力,管理及傳送 LLM 流量,並與 Gateway API Inference Extension (InferencePool、Endpoint Picker) 整合,根據指標選取端點。控制器會監控 aigateway.envoyproxy.io/v1beta1 資源,並在 Envoy 代理伺服器旁插入外部處理器;外部處理器會剖析要求主體 (例如 OpenAI 聊天完成要求中的 model 欄位)、設定 x-ai-eg-model 等路由標頭,並視需要轉換 API 結構定義。
事前準備
繼續部署前,請確認您的環境符合所有必要條件,且已正確設定必要的命令列公用程式。在工作站上設定這些工具,是管理容器登錄檔、與叢集互動,以及自動化部署程序的重要步驟。
- GDC air-gapped 1.16.2-hf1 以上環境適用於執行 Kubernetes v1.32.13-gke.400 以上版本的標準叢集。
- 使用足夠資源建立的標準叢集。閘道元件只能在 CPU 上執行;提供模型後端有自己的加速晶片需求 (請參閱 GDC 實體隔離方案中的開放權重模型指南)。
- 可存取且可用的 Harbor 執行個體。
- 已套用必要的 IAM。
- 工作站必須具備連線至環境和網際網路的必要連線能力
環境設定
環境設定涵蓋身分和權限、工作站,以及 GDC 環境和叢集的存取權。
Identity and Access Management
請確認已正確設定必要的 IAM 帳戶、角色和權限。
專案的 GDC 使用者角色 (由專案 IAM 管理員在專案命名空間中授予,RoleBinding):
- Harbor 執行個體檢視者 (
harbor-instance-viewer) - Harbor 專案建立者 (
harbor-project-creator,僅限 Harbor 專案尚不存在時) - 標準叢集管理員 (
standard-cluster-admin,gdcloud clusters get-credentials的必要角色)
標準叢集的 GDC 使用者角色:上述專案角色不會授予叢集內的任何權限。專案 IAM 管理員必須在管理 API 伺服器的專案命名空間中,將使用者繫結至 StandardClusterRole cluster-admin (使用 StandardClusterRoleBinding,繫結會在一秒內傳播至專案的標準叢集 (status.clusters[].conditions 顯示 Propagated=True)。由於本指南會安裝自訂資源定義、ClusterRole 和 GatewayClass,因此需要叢集層級的權限。
cat <<EOF | kubectl --kubeconfig MANAGEMENT_API_SERVER apply -f -
apiVersion: iam.gdc.goog/v1
kind: StandardClusterRoleBinding
metadata:
name: user-USER-cluster-admin
namespace: PROJECT
spec:
roleRef:
apiGroup: iam.gdc.goog
kind: StandardClusterRole
name: cluster-admin
subjects:
- apiGroup: rbac.authorization.k8s.io
kind: User
name: USER
EOF
更改下列內容:
MANAGEMENT_API_SERVER:管理 API 伺服器 kubeconfig 檔案的路徑。USER:使用者。PROJECT:專案。
Harbor crane (crane) 機器人帳戶權限:
- 列出存放區
- 提取存放區
- 推送存放區
- 讀取構件
- 列出構件
- 建立標記
- 清單標記
Harbor Kubernetes 映像檔提取 (kubernetes-image-puller) 機器人帳戶 權限:
- 列出存放區
- 提取存放區
- 讀取構件
- 列出構件
- 清單標記
工作站
本指南需要工作站具備連線至環境和網際網路的必要連線能力。
需求條件
工作站必須安裝下列工具:
crane:在登錄檔之間管理及複製容器映像檔和 OCI 構件 (說明文件)。gdcloud:用於管理 GDC 資源的指令列介面 (CLI) (說明文件)。kubectl:用於與 Kubernetes 叢集通訊及管理叢集的指令列介面 (CLI)。helm:Kubernetes 的套件管理工具,版本須為 3.8 以上 (支援 OCI 登錄檔) (說明文件)。curl:透過網址傳輸資料的指令列工具。jq:輕巧靈活的指令列 JSON 處理器。yq:可攜式指令列 YAML 處理器。
除非步驟另有說明,否則請在工作站執行本指南中的所有指令。
工作站設定
工作站設定需要下列環境資訊:
GDC_STANDARD_CLUSTER_NAME:GDC 標準叢集的名稱。GDC_DOMAIN_SUFFIX:GDC 環境的網域尾碼 (例如gdc.example.com)。GDC_ORG:GDC 機構的名稱。GDC_PROJECT:GDC 專案的名稱。GDC_ZONE:GDC 部署區域的名稱。GDC_HARBOR_INSTANCE_NAME:專案中的 Harbor 執行個體名稱。GDCS_HARBOR_PROJECT_NAME:用於映像檔的 Harbor 專案名稱 (預設值:solutions)GDCS_HARBOR_CRANE_ROBOT_NAME:Harborcrane機器人帳戶的名稱。GDCS_HARBOR_CRANE_ROBOT_TOKEN:Harborcrane機器人帳戶的驗證權杖。GDCS_HARBOR_K8S_ROBOT_NAME:Harbor Kubernetes 映像檔提取機器人帳戶的名稱。GDCS_HARBOR_K8S_ROBOT_TOKEN:Harbor Kubernetes 映像檔提取機器人帳戶的驗證權杖。
收集所有必要變數的值後,請繼續產生環境變數檔案。建立後,您隨時可以手動編輯檔案。
建立根解決方案目錄和祕密資料夾:
mkdir -p ${HOME}/gdcag-solutions/env.d mkdir -p ${HOME}/gdcag-solutions/secrets touch ${HOME}/gdcag-solutions/secrets/harbor_crane_robot_token touch ${HOME}/gdcag-solutions/secrets/harbor_k8s_robot_token chmod u=rwx,go= ${HOME}/gdcag-solutions/secrets chmod -R u=rw,go= ${HOME}/gdcag-solutions/secrets/*建立平台環境設定檔:
cat << 'EOF' > ${HOME}/gdcag-solutions/env.d/platform.sh && echo "Successfully created." || echo "Failed to create!" # Infrastructure (Platform Native) export GDC_STANDARD_CLUSTER_NAME="STANDARD_CLUSTER_NAME" export GDC_DOMAIN_SUFFIX="DOMAIN_SUFFIX" export GDC_ORG="ORG" export GDC_PROJECT="PROJECT" export GDC_ZONE="ZONE" export GDC_HARBOR_INSTANCE_NAME="HARBOR_INSTANCE_NAME" # Derived platform values export GDC_ZONAL_HOSTNAME="${GDC_ORG}.${GDC_ZONE}.${GDC_DOMAIN_SUFFIX}" export GDC_ZONAL_CONSOLE_URL="https://console.${GDC_ZONAL_HOSTNAME}" export GDC_HARBOR_HOST="${GDC_HARBOR_INSTANCE_NAME}-${GDC_PROJECT}.${GDC_ORG}.${GDC_ZONE}.${GDC_DOMAIN_SUFFIX}" EOF更改下列內容:
STANDARD_CLUSTER_NAME: GDC 標準叢集名稱。DOMAIN_SUFFIX:GDC 網域尾碼。ORG:GDC 組織。PROJECT:GDC 專案。ZONE:GDC 區域。HARBOR_INSTANCE_NAME: GDC Harbor 執行個體名稱。
建立登錄環境設定檔:
cat << 'EOF' > ${HOME}/gdcag-solutions/env.d/registry.sh && echo "Successfully created." || echo "Failed to create!" # GDC Solutions Registry & Secrets export GDCS_HARBOR_PROJECT_NAME="solutions" export GDCS_HARBOR_CRANE_ROBOT_NAME="HARBOR_CRANE_ROBOT_NAME" export GDCS_HARBOR_CRANE_ROBOT_TOKEN="$(cat ${GDCS_ROOT_HOME}/secrets/harbor_crane_robot_token)" export GDCS_HARBOR_K8S_ROBOT_NAME="HARBOR_K8S_ROBOT_NAME" export GDCS_HARBOR_K8S_ROBOT_TOKEN="$(cat ${GDCS_ROOT_HOME}/secrets/harbor_k8s_robot_token)" export GDCS_HARBOR_K8S_PULL_SECRET="gdcs-image-pull-secret" # Derived registry values export GDCS_HARBOR_PROJECT_URI="${GDC_HARBOR_HOST}/${GDCS_HARBOR_PROJECT_NAME}" export GDCS_HARBOR_CHART_OCI_URI="oci://${GDCS_HARBOR_PROJECT_URI}" EOF更改下列內容:
HARBOR_CRANE_ROBOT_NAME: GDC Harbor 機器人帳戶名稱。HARBOR_K8S_ROBOT_NAME: GDC Harbor 機器人帳戶名稱。
將權杖新增至密鑰檔案:
set +o history echo "CRANE_ROBOT_TOKEN" > ${HOME}/gdcag-solutions/secrets/harbor_crane_robot_token echo "KUBERNETES_ROBOT_TOKEN" > ${HOME}/gdcag-solutions/secrets/harbor_k8s_robot_token set -o history更改下列內容:
CRANE_ROBOT_TOKEN:起重機機器人權杖。KUBERNETES_ROBOT_TOKEN:Kubernetes 機器人權杖。
建立根環境載入器檔案:
cat << 'EOF' > ${HOME}/gdcag-solutions/env.sh && echo "Successfully created." || echo "Failed to create!" export GDCS_ROOT_HOME="${HOME}/gdcag-solutions" echo "GDCS_ROOT_HOME=${GDCS_ROOT_HOME}" # Sourced in dependency order source "${GDCS_ROOT_HOME}/env.d/platform.sh" source "${GDCS_ROOT_HOME}/env.d/registry.sh" EOF
設定解決方案變數
建立解決方案實作目錄:
mkdir -p ${HOME}/gdcag-solutions/ai-gateway/envoy/env.d建立解決方案環境設定檔:
cat << 'EOF' > ${HOME}/gdcag-solutions/ai-gateway/envoy/env.d/envoy.sh && echo "Successfully created." || echo "Failed to create!" # Envoy Gateway export GDCS_ENVOY_GATEWAY_NAMESPACE="envoy-gateway-system" export GDCS_ENVOY_GATEWAY_VERSION="v1.8.5" export GDCS_ENVOY_PROXY_IMAGE_TAG="distroless-v1.38.4" export GDCS_ENVOY_RATELIMIT_IMAGE_TAG="8fe6ea42" export GDCS_GATEWAY_API_ECHO_IMAGE_TAG="v1.5.1" # Envoy Agent Router (formerly Envoy AI Gateway; the images and charts keep the ai-gateway names) export GDCS_ENVOY_AGENT_ROUTER_NAMESPACE="envoy-ai-gateway-system" export GDCS_ENVOY_AGENT_ROUTER_VERSION="v1.1.0" # Gateway API Inference Extension (InferencePool, Endpoint Picker) export GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION="v1.5.0" # Redis (token-based rate limiting backend) export GDCS_REDIS_IMAGE_TAG="8.10.2-alpine3.23" export GDCS_REDIS_NAMESPACE="${GDCS_ENVOY_GATEWAY_NAMESPACE}" # Gateway class shared by the user guides export GDCS_GATEWAY_CLASS_NAME="envoy-ai-gateway" # Docker configuration directories for crane and Kubernetes export GDCS_HARBOR_CRANE_DOCKER_CONFIG="${GDCS_IMPLEMENTATION_HOME}/docker/crane" export GDCS_HARBOR_K8S_DOCKER_CONFIG="${GDCS_IMPLEMENTATION_HOME}/docker/k8s" EOF建立實作環境載入器檔案:
cat << 'EOF' > ${HOME}/gdcag-solutions/ai-gateway/envoy/env.sh && echo "Successfully created." || echo "Failed to create!" source "${HOME}/gdcag-solutions/env.sh" export GDCS_IMPLEMENTATION_HOME="${HOME}/gdcag-solutions/ai-gateway/envoy" echo "GDCS_IMPLEMENTATION_HOME=${GDCS_IMPLEMENTATION_HOME}" # Sourced in dependency order source "${GDCS_IMPLEMENTATION_HOME}/env.d/envoy.sh" EOF使用偏好的編輯器編輯及檢查環境檔案:
${EDITOR:-vi} ${HOME}/gdcag-solutions/env.d/platform.sh ${EDITOR:-vi} ${HOME}/gdcag-solutions/env.d/registry.sh ${EDITOR:-vi} ${HOME}/gdcag-solutions/ai-gateway/envoy/env.d/envoy.sh取得環境檔案的來源:
source ${HOME}/gdcag-solutions/ai-gateway/envoy/env.sh輸出結果會與下列內容相似:
GDCS_ROOT_HOME=HOME_DIRECTORY_PATH/gdcag-solutions GDCS_IMPLEMENTATION_HOME=HOME_DIRECTORY_PATH/gdcag-solutions/ai-gateway/envoy
GDC
本指南假設您的工作站已設定為信任 GDC 環境和 Harbor 執行個體的 TLS 憑證。
設定
gdcloud:gdcloud config set core/account "default-user" gdcloud config set core/organization_console_url "${GDC_ZONAL_CONSOLE_URL}" gdcloud config set core/project "${GDC_PROJECT}" gdcloud config set core/zone "${GDC_ZONE}"向 GDC 環境進行驗證:
gdcloud auth login
叢集
擷取叢集憑證:
gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \ --project="${GDC_PROJECT}" \ --standard \ --zone="${GDC_ZONE}"驗證叢集的連線:
kubectl get nodes -L node.cluster.private.gdc.goog/machine-class確認每個節點執行的 Kubernetes 版本符合本指南「開始前」一節的要求:
kubectl get nodes -o custom-columns='NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion'
準備遷移構件
- 確認構件登錄服務的連線和設定。
為 crane 建立 Docker 設定檔。使用機器人帳戶推送大型映像檔層,避免使用受管理 Harbor 服務 (MHS) 憑證輔助程式 (docker-credential-mhs) 和使用者帳戶時,發生授權權杖逾時問題:
set +o history export DOCKER_CONFIG="${GDCS_HARBOR_CRANE_DOCKER_CONFIG}" crane auth login "${GDC_HARBOR_HOST}" \ --password="${GDCS_HARBOR_CRANE_ROBOT_TOKEN}" \ --username="${GDCS_HARBOR_CRANE_ROBOT_NAME}" set -o history為 Kubernetes 建立 Docker 設定檔:
set +o history export DOCKER_CONFIG="${GDCS_HARBOR_K8S_DOCKER_CONFIG}" crane auth login "${GDC_HARBOR_HOST}" \ --password="${GDCS_HARBOR_K8S_ROBOT_TOKEN}" \ --username="${GDCS_HARBOR_K8S_ROBOT_NAME}" set -o history使用 Kubernetes 映像檔提取機器人帳戶,透過
helm登入 Harbor OCI 登錄檔。helm會保留自己的登錄憑證,並需要這些憑證才能從 Harbor 擷取圖表:set +o history helm registry login "${GDC_HARBOR_HOST}" \ --password="${GDCS_HARBOR_K8S_ROBOT_TOKEN}" \ --username="${GDCS_HARBOR_K8S_ROBOT_NAME}" set -o history輸出結果會與下列內容相似:
Login Succeeded建立
seed_registry.sh指令碼:cat << 'EOF' > ${GDCS_IMPLEMENTATION_HOME}/seed_registry.sh && echo "Successfully created." || echo "Failed to create!" #!/bin/bash # seed_registry.sh: Modular artifact migration for GDC Solutions # Requires the env.sh file to be sourced first. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" set -o nounset source "${SCRIPT_DIR}/env.sh" # Set the Docker config export DOCKER_CONFIG="${GDCS_HARBOR_CRANE_DOCKER_CONFIG}" eval "${SERIALIZED_IMAGES}" # Ensure GDCS_REGISTRY_IMAGES is set if [[ ${#GDCS_REGISTRY_IMAGES[@]} -eq 0 ]]; then echo "GDCS_REGISTRY_IMAGES must be set, exiting..." exit 1 fi # Migrate the images for source_image in "${GDCS_REGISTRY_IMAGES[@]}"; do # Strip the registry host only when the first path segment is a host (contains a dot or a port) first_segment="${source_image%%/*}" if [[ "${first_segment}" == *.* || "${first_segment}" == *:* ]]; then image_path="${source_image#*/}" else image_path="${source_image}" fi destination_image="${GDCS_HARBOR_PROJECT_URI}/${image_path}" # Ensure the folder structure is created crane append \ --new_layer=<(tar czf - -T /dev/null) \ --new_tag="${destination_image%:*}:create" \ --oci-empty-base 2> /dev/null || true # Copy the linux/amd64 platform only to avoid transferring multi-arch layers over air-gapped links crane copy --platform linux/amd64 "${source_image}" "${destination_image}" 2> /dev/null done echo "Migration complete: Images are available at ${GDCS_HARBOR_PROJECT_URI}" EOF chmod u+x "${GDCS_IMPLEMENTATION_HOME}/seed_registry.sh"建立
seed_charts.sh指令碼。以 OCI 構件形式發布的 Helm 資訊套件也會使用crane複製,且不需選取平台,也不會使用容器映像檔存放區的create標記:cat << 'EOF' > ${GDCS_IMPLEMENTATION_HOME}/seed_charts.sh && echo "Successfully created." || echo "Failed to create!" #!/bin/bash # seed_charts.sh: OCI Helm chart migration for GDC Solutions # Requires the env.sh file to be sourced first. SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" set -o nounset source "${SCRIPT_DIR}/env.sh" # Set the Docker config export DOCKER_CONFIG="${GDCS_HARBOR_CRANE_DOCKER_CONFIG}" eval "${SERIALIZED_CHARTS}" # Ensure GDCS_REGISTRY_CHARTS is set if [[ ${#GDCS_REGISTRY_CHARTS[@]} -eq 0 ]]; then echo "GDCS_REGISTRY_CHARTS must be set, exiting..." exit 1 fi # Migrate the charts (source format: REGISTRY_HOST/REPOSITORY:CHART_VERSION) for source_chart in "${GDCS_REGISTRY_CHARTS[@]}"; do chart_path="${source_chart#*/}" destination_chart="${GDCS_HARBOR_PROJECT_URI}/${chart_path}" crane copy "${source_chart}" "${destination_chart}" || { echo "Failed to copy ${source_chart} to ${destination_chart}"; exit 1; } done echo "Migration complete: Charts are available at ${GDCS_HARBOR_CHART_OCI_URI}" EOF chmod u+x "${GDCS_IMPLEMENTATION_HOME}/seed_charts.sh"更改下列內容:
REGISTRY_HOST:登錄主機。REPOSITORY:存放區。CHART_VERSION:圖表版本。
定義解決方案所需的容器映像檔清單:
declare -a GDCS_REGISTRY_IMAGES=( "docker.io/envoyproxy/gateway:${GDCS_ENVOY_GATEWAY_VERSION}" "docker.io/envoyproxy/envoy:${GDCS_ENVOY_PROXY_IMAGE_TAG}" "docker.io/envoyproxy/ratelimit:${GDCS_ENVOY_RATELIMIT_IMAGE_TAG}" "docker.io/envoyproxy/ai-gateway-controller:${GDCS_ENVOY_AGENT_ROUTER_VERSION}" "docker.io/envoyproxy/ai-gateway-extproc:${GDCS_ENVOY_AGENT_ROUTER_VERSION}" "docker.io/envoyproxy/ai-gateway-testupstream:${GDCS_ENVOY_AGENT_ROUTER_VERSION}" "docker.io/library/redis:${GDCS_REDIS_IMAGE_TAG}" "registry.k8s.io/gateway-api/echo-basic:${GDCS_GATEWAY_API_ECHO_IMAGE_TAG}" ) export SERIALIZED_IMAGES=$(declare -p GDCS_REGISTRY_IMAGES)將必要的容器映像檔植入 Artifact Registry:
${GDCS_IMPLEMENTATION_HOME}/seed_registry.sh
定義解決方案所需的 Helm 資訊套件清單:
declare -a GDCS_REGISTRY_CHARTS=( "docker.io/envoyproxy/gateway-crds-helm:${GDCS_ENVOY_GATEWAY_VERSION}" "docker.io/envoyproxy/gateway-helm:${GDCS_ENVOY_GATEWAY_VERSION}" "docker.io/envoyproxy/ai-gateway-crds-helm:${GDCS_ENVOY_AGENT_ROUTER_VERSION}" "docker.io/envoyproxy/ai-gateway-helm:${GDCS_ENVOY_AGENT_ROUTER_VERSION}" ) export SERIALIZED_CHARTS=$(declare -p GDCS_REGISTRY_CHARTS)將必要的 Helm 資訊套件植入 Artifact Registry:
${GDCS_IMPLEMENTATION_HOME}/seed_charts.sh確認可以從 Harbor 讀回圖表:
helm show chart "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/gateway-helm" --version "${GDCS_ENVOY_GATEWAY_VERSION}" | grep -E '^(name|version):' helm show chart "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/ai-gateway-helm" --version "${GDCS_ENVOY_AGENT_ROUTER_VERSION}" | grep -E '^(name|version):'輸出結果會與下列內容相似:
name: gateway-helm version: v1.8.5 name: ai-gateway-helm version: v1.1.0下載 Gateway API 推論擴充功能資訊清單。發布為發行資產,而非排行榜:
mkdir -p "${GDCS_IMPLEMENTATION_HOME}/manifests" curl --fail --location --show-error --silent \ --output "${GDCS_IMPLEMENTATION_HOME}/manifests/gateway-api-inference-extension-${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}.yaml" \ "https://github.com/kubernetes-sigs/gateway-api-inference-extension/releases/download/${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}/manifests.yaml" grep --count '^kind: CustomResourceDefinition' "${GDCS_IMPLEMENTATION_HOME}/manifests/gateway-api-inference-extension-${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}.yaml"輸出結果會與下列內容相似:
4
Envoy Gateway
首先,請安裝 Envoy Gateway,並使用上游快速入門指南驗證其本身;Envoy Agent Router 整合項目則會在下一節中說明。
命名空間
為 Envoy Gateway 建立命名空間。這個命名空間也會建立每個
Gateway的 Envoy 代理程式Deployment:kubectl create namespace "${GDCS_ENVOY_GATEWAY_NAMESPACE}"加入
imagePullSecret:kubectl create secret docker-registry "${GDCS_HARBOR_K8S_PULL_SECRET}" \ --dry-run=client \ --from-file=.dockerconfigjson=${GDCS_HARBOR_K8S_DOCKER_CONFIG}/config.json \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --output=yaml | kubectl apply -f -
自訂資源定義
從已植入的圖表安裝 Gateway API (標準管道) 和 Envoy Gateway 自訂資源定義 (CRD):
helm template eg-crds "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/gateway-crds-helm" \ --set crds.gatewayAPI.channel=standard \ --set crds.gatewayAPI.enabled=true \ --set crds.envoyGateway.enabled=true \ --version "${GDCS_ENVOY_GATEWAY_VERSION}" | kubectl apply --server-side --filename=-確認已註冊 CRD:
kubectl get crd | grep -E 'gateway.networking.k8s.io|gateway.envoyproxy.io'
控制器
為 Envoy Gateway 建立 Helm 值檔案。映像檔會透過映像檔提取密鑰從 Harbor 提取;
crds.enabled=false因為 CRD 是分開安裝:cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-values.yaml" && echo "Successfully created." || echo "Failed to create!" config: envoyGateway: extensionApis: enableBackend: true enableEnvoyPatchPolicy: true gateway: controllerName: gateway.envoyproxy.io/gatewayclass-controller logging: level: default: info provider: type: Kubernetes crds: enabled: false global: imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} imageRegistry: ${GDCS_HARBOR_PROJECT_URI} images: envoyProxy: image: ${GDCS_HARBOR_PROJECT_URI}/envoyproxy/envoy:${GDCS_ENVOY_PROXY_IMAGE_TAG} pullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} EOF安裝 Envoy Gateway:
helm upgrade --install eg "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/gateway-helm" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --values="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-values.yaml" \ --version="${GDCS_ENVOY_GATEWAY_VERSION}"等待 Envoy Gateway 控制器進入「Available」狀態:
watch --color --interval 5 --no-title \ "kubectl get deployment/envoy-gateway \ --namespace=${GDCS_ENVOY_GATEWAY_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"確認控制器映像檔及其憑證產生作業來自 Harbor:
kubectl get pods --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --output=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
Envoy Proxy 和 Gateway 類別
為
EnvoyProxy資料平面範本和GatewayClass建立資訊清單。EnvoyProxy會設定 Proxy 映像檔、映像檔提取密鑰和 ProxyPod的資源要求;GatewayClass由使用者指南共用:cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/gateway-class.yaml" && echo "Successfully created." || echo "Failed to create!" apiVersion: gateway.envoyproxy.io/v1alpha1 kind: EnvoyProxy metadata: name: ${GDCS_GATEWAY_CLASS_NAME} namespace: ${GDCS_ENVOY_GATEWAY_NAMESPACE} spec: provider: type: Kubernetes kubernetes: envoyDeployment: container: image: ${GDCS_HARBOR_PROJECT_URI}/envoyproxy/envoy:${GDCS_ENVOY_PROXY_IMAGE_TAG} resources: limits: memory: 2Gi requests: cpu: 250m memory: 512Mi pod: imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: ${GDCS_GATEWAY_CLASS_NAME} spec: controllerName: gateway.envoyproxy.io/gatewayclass-controller parametersRef: group: gateway.envoyproxy.io kind: EnvoyProxy name: ${GDCS_GATEWAY_CLASS_NAME} namespace: ${GDCS_ENVOY_GATEWAY_NAMESPACE} EOF為
EnvoyProxy和GatewayClass套用資訊清單:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/gateway-class.yaml"確認「
GatewayClass」為「已接受」:kubectl get gatewayclass "${GDCS_GATEWAY_CLASS_NAME}"輸出結果會與下列內容相似:
NAME CONTROLLER ACCEPTED AGE envoy-ai-gateway gateway.envoyproxy.io/gatewayclass-controller True 5s
驗證
驗證作業會將 Envoy Gateway 快速入門 (位於 HTTPRoute 後方的 Echo 後端) 部署至 Envoy Gateway 命名空間,然後移除。
為快速入門工作負載建立資訊清單:
cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" && echo "Successfully created." || echo "Failed to create!" apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: eg-quickstart spec: gatewayClassName: ${GDCS_GATEWAY_CLASS_NAME} listeners: - name: http protocol: HTTP port: 80 --- apiVersion: v1 kind: ServiceAccount metadata: name: eg-quickstart-backend --- apiVersion: v1 kind: Service metadata: name: eg-quickstart-backend labels: app: eg-quickstart-backend spec: ports: - name: http port: 3000 targetPort: 3000 selector: app: eg-quickstart-backend --- apiVersion: apps/v1 kind: Deployment metadata: name: eg-quickstart-backend spec: replicas: 1 selector: matchLabels: app: eg-quickstart-backend template: metadata: labels: app: eg-quickstart-backend spec: serviceAccountName: eg-quickstart-backend containers: - image: ${GDCS_HARBOR_PROJECT_URI}/gateway-api/echo-basic:${GDCS_GATEWAY_API_ECHO_IMAGE_TAG} imagePullPolicy: IfNotPresent name: backend ports: - containerPort: 3000 env: - name: POD_NAME valueFrom: fieldRef: fieldPath: metadata.name - name: NAMESPACE valueFrom: fieldRef: fieldPath: metadata.namespace imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} --- apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: eg-quickstart-backend spec: parentRefs: - name: eg-quickstart hostnames: - "www.example.com" rules: - backendRefs: - group: "" kind: Service name: eg-quickstart-backend port: 3000 weight: 1 matches: - path: type: PathPrefix value: / EOF套用快速入門工作負載的資訊清單:
kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"等待
Gateway完成程式設計:watch --color --interval 5 --no-title \ "kubectl get gateway/eg-quickstart \ --namespace=${GDCS_ENVOY_GATEWAY_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e 'True'"等待後端
Deployment變成「Available」:watch --color --interval 5 --no-title \ "kubectl get deployment/eg-quickstart-backend \ --namespace=${GDCS_ENVOY_GATEWAY_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"使用通訊埠轉送功能,透過閘道傳送測試要求。系統會根據
Gateway的擁有閘道標籤,找出 EnvoyService:export ENVOY_SERVICE=$(kubectl get service --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" --selector="gateway.envoyproxy.io/owning-gateway-namespace=${GDCS_ENVOY_GATEWAY_NAMESPACE},gateway.envoyproxy.io/owning-gateway-name=eg-quickstart" --output=jsonpath='{.items[0].metadata.name}') echo "ENVOY_SERVICE=${ENVOY_SERVICE}" kubectl port-forward "service/${ENVOY_SERVICE}" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" 8888:80 & PF_PID=$! sleep 2 curl --header "Host: www.example.com" \ --no-progress-meter \ --show-error \ http://127.0.0.1:8888/get | jq kill -9 ${PF_PID}輸出結果會與下列內容相似:
{ "path": "/get", "host": "www.example.com", "method": "GET", ... "namespace": "envoy-gateway-system", "pod": "eg-quickstart-backend-...", ... }移除快速入門工作負載:
kubectl delete \ --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"
Envoy 代理程式路由器
Envoy 代理程式路由器會安裝在自己的命名空間中,然後重新設定 Envoy Gateway,將其做為擴充伺服器呼叫。
命名空間
為 Envoy 代理程式路由器控制器建立命名空間:
kubectl create namespace "${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"加入
imagePullSecret:kubectl create secret docker-registry "${GDCS_HARBOR_K8S_PULL_SECRET}" \ --dry-run=client \ --from-file=.dockerconfigjson=${GDCS_HARBOR_K8S_DOCKER_CONFIG}/config.json \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}" \ --output=yaml | kubectl apply -f -
自訂資源定義
從已播種的圖表安裝 Envoy 代理程式路由器 CRD:
helm template aieg-crds "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/ai-gateway-crds-helm" \ --version "${GDCS_ENVOY_AGENT_ROUTER_VERSION}" | kubectl apply --server-side --filename=-從下載的資訊清單安裝 Gateway API 推論擴充功能 CRD (
InferencePool、InferenceObjective):kubectl apply --server-side \ --filename="${GDCS_IMPLEMENTATION_HOME}/manifests/gateway-api-inference-extension-${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}.yaml"確認已註冊 CRD:
kubectl get crd | grep -E 'aigateway.envoyproxy.io|inference.networking'輸出結果會與下列內容相似:
aigatewayroutes.aigateway.envoyproxy.io ... aiservicebackends.aigateway.envoyproxy.io ... backendsecuritypolicies.aigateway.envoyproxy.io ... gatewayconfigs.aigateway.envoyproxy.io ... inferencemodelrewrites.inference.networking.x-k8s.io ... inferenceobjectives.inference.networking.x-k8s.io ... inferencepoolimports.inference.networking.x-k8s.io ... inferencepools.inference.networking.k8s.io ... mcproutes.aigateway.envoyproxy.io ... quotapolicies.aigateway.envoyproxy.io ...
Redis
系統會透過 Envoy 速率限制服務強制執行以權杖為準的速率限制,並將計數器儲存在 Redis 中。本指南會部署沒有持續性的單一副本 Redis;您也可以變更下一節中的 rateLimit.backend.redis.url 值,改用現有的 Redis 服務。
建立 Redis
Deployment的資訊清單:cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/redis.yaml" && echo "Successfully created." || echo "Failed to create!" apiVersion: v1 kind: Service metadata: name: redis labels: app: redis spec: ports: - name: redis port: 6379 selector: app: redis --- apiVersion: apps/v1 kind: Deployment metadata: name: redis spec: replicas: 1 selector: matchLabels: app: redis template: metadata: labels: app: redis spec: containers: - image: ${GDCS_HARBOR_PROJECT_URI}/library/redis:${GDCS_REDIS_IMAGE_TAG} imagePullPolicy: IfNotPresent name: redis ports: - name: redis containerPort: 6379 resources: limits: memory: 512Mi requests: cpu: 100m memory: 128Mi imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} restartPolicy: Always EOF為 Redis
Deployment套用資訊清單:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/redis.yaml" \ --namespace="${GDCS_REDIS_NAMESPACE}"等待 Redis
Deployment變成「Available」:watch --color --interval 5 --no-title \ "kubectl get deployment/redis \ --namespace=${GDCS_REDIS_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"
控制器
為 Envoy 代理程式路由器建立 Helm 值檔案:
cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/envoy-agent-router-values.yaml" && echo "Successfully created." || echo "Failed to create!" controller: image: repository: ${GDCS_HARBOR_PROJECT_URI}/envoyproxy/ai-gateway-controller imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} envoyGateway: namespace: ${GDCS_ENVOY_GATEWAY_NAMESPACE} extProc: image: repository: ${GDCS_HARBOR_PROJECT_URI}/envoyproxy/ai-gateway-extproc imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} global: imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} EOF安裝 Envoy 代理程式路由器:
helm upgrade --install aieg "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/ai-gateway-helm" \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}" \ --values="${GDCS_IMPLEMENTATION_HOME}/envoy-agent-router-values.yaml" \ --version="${GDCS_ENVOY_AGENT_ROUTER_VERSION}"等待 Envoy 代理程式路由器控制器變成「Available」:
watch --color --interval 5 --no-title \ "kubectl get deployment/ai-gateway-controller \ --namespace=${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"
整合 Envoy Gateway
必須重新設定 Envoy Gateway,將 Envoy Agent Router 控制器做為擴充伺服器呼叫,接受 InferencePool 資源做為後端,並使用 Redis 支援的速率限制服務。
為整合建立 Helm 值檔案:
cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-agent-router-values.yaml" && echo "Successfully created." || echo "Failed to create!" config: envoyGateway: extensionManager: backendResources: - group: inference.networking.k8s.io kind: InferencePool version: v1 hooks: xdsTranslator: post: - Translation - Cluster - Route translation: cluster: includeAll: true listener: includeAll: true route: includeAll: true secret: includeAll: true service: fqdn: hostname: ai-gateway-controller.${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}.svc.cluster.local port: 1063 rateLimit: backend: redis: url: redis.${GDCS_REDIS_NAMESPACE}.svc.cluster.local:6379 type: Redis EOF使用這兩個值檔案升級 Envoy Gateway:
helm upgrade --install eg "${GDCS_HARBOR_CHART_OCI_URI}/envoyproxy/gateway-helm" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --values="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-values.yaml" \ --values="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-agent-router-values.yaml" \ --version="${GDCS_ENVOY_GATEWAY_VERSION}"建立
ClusterRole的資訊清單,讓 Envoy Gateway 控制器監控InferencePool資源。圖表不會授予這項權限;與圖表管理ClusterRole的修補程式不同,獨立的ClusterRoleBinding會在圖表升級後繼續存在:cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-inferencepool-rbac.yaml" && echo "Successfully created." || echo "Failed to create!" apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: name: envoy-gateway-inferencepool-reader rules: - apiGroups: - inference.networking.k8s.io resources: - inferencepools verbs: - get - list - watch --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRoleBinding metadata: name: envoy-gateway-inferencepool-reader roleRef: apiGroup: rbac.authorization.k8s.io kind: ClusterRole name: envoy-gateway-inferencepool-reader subjects: - kind: ServiceAccount name: envoy-gateway namespace: ${GDCS_ENVOY_GATEWAY_NAMESPACE} EOF為
ClusterRole套用資訊清單:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-inferencepool-rbac.yaml"重新啟動 Envoy Gateway 控制器,讓新的設定和權限生效,並等待控制器顯示「Available」:
kubectl rollout restart deployment/envoy-gateway \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" kubectl rollout status deployment/envoy-gateway \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --timeout=5m確認已部署速率限制服務,且該服務處於「Available」(可用) 狀態:
watch --color --interval 5 --no-title \ "kubectl get deployment/envoy-ratelimit \ --namespace=${GDCS_ENVOY_GATEWAY_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"
驗證
驗證作業會將 Envoy 代理程式路由器基本範例 (AIGatewayRoute 後方與 OpenAI 相容的模擬上游) 部署到 Envoy 代理程式路由器命名空間,然後移除該範例。
建立驗證工作負載的資訊清單:
cat <<EOF > "${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" && echo "Successfully created." || echo "Failed to create!" apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: aieg-basic spec: gatewayClassName: ${GDCS_GATEWAY_CLASS_NAME} listeners: - name: http protocol: HTTP port: 80 --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: ClientTrafficPolicy metadata: name: aieg-basic-buffer-limit spec: targetRefs: - group: gateway.networking.k8s.io kind: Gateway name: aieg-basic connection: bufferLimit: 50Mi --- apiVersion: aigateway.envoyproxy.io/v1beta1 kind: AIGatewayRoute metadata: name: aieg-basic spec: parentRefs: - name: aieg-basic kind: Gateway group: gateway.networking.k8s.io rules: - matches: - headers: - type: Exact name: x-ai-eg-model value: some-cool-self-hosted-model backendRefs: - name: aieg-basic-testupstream --- apiVersion: aigateway.envoyproxy.io/v1beta1 kind: AIServiceBackend metadata: name: aieg-basic-testupstream spec: schema: name: OpenAI backendRef: name: aieg-basic-testupstream kind: Backend group: gateway.envoyproxy.io --- apiVersion: gateway.envoyproxy.io/v1alpha1 kind: Backend metadata: name: aieg-basic-testupstream spec: endpoints: - fqdn: hostname: aieg-basic-testupstream.${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}.svc.cluster.local port: 80 --- apiVersion: apps/v1 kind: Deployment metadata: name: aieg-basic-testupstream spec: replicas: 1 selector: matchLabels: app: aieg-basic-testupstream template: metadata: labels: app: aieg-basic-testupstream spec: containers: - name: testupstream image: ${GDCS_HARBOR_PROJECT_URI}/envoyproxy/ai-gateway-testupstream:${GDCS_ENVOY_AGENT_ROUTER_VERSION} imagePullPolicy: IfNotPresent ports: - containerPort: 8080 env: - name: TESTUPSTREAM_ID value: test readinessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 5 periodSeconds: 10 livenessProbe: httpGet: path: /health port: 8080 initialDelaySeconds: 10 periodSeconds: 20 imagePullSecrets: - name: ${GDCS_HARBOR_K8S_PULL_SECRET} --- apiVersion: v1 kind: Service metadata: name: aieg-basic-testupstream spec: selector: app: aieg-basic-testupstream ports: - protocol: TCP port: 80 targetPort: 8080 type: ClusterIP EOF為驗證工作負載套用資訊清單:
kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"等待
Gateway完成程式設計:watch --color --interval 5 --no-title \ "kubectl get gateway/aieg-basic \ --namespace=${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e 'True'"等待模擬上游
Deployment變成「Available」(可用):watch --color --interval 5 --no-title \ "kubectl get deployment/aieg-basic-testupstream \ --namespace=${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} | GREP_COLORS='mt=01;92' egrep --color=always -e '^' -e '1/1 1 1'"確認 Envoy Proxy
Pod的Gateway執行 Envoy Agent Router 插入的外部處理器 Sidecar:kubectl get pods --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --selector="gateway.envoyproxy.io/owning-gateway-name=aieg-basic" \ --output=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].name}{"\n"}{end}'輸出結果會與下列內容相似:
envoy-envoy-ai-gateway-system-aieg-basic-... envoy shutdown-manager ai-gateway-extproc透過閘道使用連接埠轉送功能傳送對話完成要求。 外部處理器會讀取要求主體的
model欄位,並將要求傳送至模擬上游:export ENVOY_SERVICE=$(kubectl get service --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" --selector="gateway.envoyproxy.io/owning-gateway-namespace=${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE},gateway.envoyproxy.io/owning-gateway-name=aieg-basic" --output=jsonpath='{.items[0].metadata.name}') echo "ENVOY_SERVICE=${ENVOY_SERVICE}" kubectl port-forward "service/${ENVOY_SERVICE}" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" 8888:80 & PF_PID=$! sleep 2 curl http://127.0.0.1:8888/v1/chat/completions \ --data '{"model": "some-cool-self-hosted-model", "messages": [{"role": "user", "content": "Say this is a test."}]}' \ --header "Content-Type: application/json" \ --no-progress-meter \ --show-error | jq kill -9 ${PF_PID}輸出結果會與下列內容相似:
{ "choices": [ { "index": 0, "message": { "role": "assistant", "content": "..." }, "finish_reason": "stop" } ], "usage": { ... } }移除驗證工作負載:
kubectl delete \ --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"
作業
閘道控制層的第 2 天工作。
升級
- 為新版本提供圖片和圖表 (更新
env.sh中的版本變數,重新執行seed_registry.sh和seed_charts.sh),使用kubectl apply --server-side套用新的 CRD 圖表,然後使用新的--version執行相同的helm upgrade --install指令。請參閱 Envoy 代理程式路由器相容性矩陣,瞭解目標版本支援的 Envoy Gateway 和 Gateway API 版本;Envoy 代理程式路由器 1.1.0 是以 Envoy Gateway 1.8 為基礎建構。
解除安裝
- 請先刪除使用者指南的
Gateway、AIGatewayRoute和InferencePool資源,然後依序刪除helm uninstall aieg --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"、helm uninstall eg --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"、ClusterRoleenvoy-gateway-inferencepool-reader、GatewayClass、RedisDeployment和 CRD。
疑難排解
| 問題 | 可能原因 | 動作 |
|---|---|---|
helm show chart 或 helm upgrade 失敗,並顯示 unauthorized 或 FetchReference |
helm 沒有 Harbor 的憑證 (不會使用 crane Docker 設定) |
使用 Kubernetes 映像檔提取機器人帳戶再次執行 helm registry login 步驟。 |
Envoy Gateway 或 Envoy Agent Router Pods 停留在 ImagePullBackOff |
未植入映像檔,或命名空間中缺少映像檔提取密鑰 | 檢查 kubectl describe pod、比較圖片路徑與 crane ls "${GDCS_HARBOR_PROJECT_URI}/envoyproxy/gateway",並確認密鑰存在於 ${GDCS_ENVOY_GATEWAY_NAMESPACE} 和 ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} 中。 |
整合後,Gateway 仍為 Programmed=False |
Envoy Gateway 控制器無法連線至擴充功能伺服器,或是在升級後未重新啟動 | 確認 service/ai-gateway-controller 是否存在於 ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} 中,且列出 1063 連接埠;重複推出作業重新啟動。kubectl logs deployment/envoy-gateway --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" |
AIGatewayRoute參照InferencePool不接受 |
Envoy Gateway 缺少讀取 inferencepools 的權限,或缺少 InferencePool CRD |
驗證 ClusterRoleBinding envoy-gateway-inferencepool-reader 和 inferencepools.inference.networking.k8s.io CRD;檢查控制器的 forbidden 記錄。 |
聊天完成要求會傳回 413,或系統會重設大型提示的連線 |
預設 Envoy 緩衝區大小 (32 KiB) 不足以容納 AI 酬載 | 將 ClientTrafficPolicy 附加至 connection.bufferLimit (驗證使用 50Mi) 的 Gateway。 |
服務 Pod 的速率限制為 CrashLoopBackOff |
無法透過設定的網址連上 Redis | kubectl get service redis --namespace="${GDCS_REDIS_NAMESPACE}",修正整合值檔案中的 rateLimit.backend.redis.url,然後再次升級。 |
其他資料
- Envoy Agent Router 說明文件
- Envoy Agent Router 版本資訊和相容性矩陣
- Envoy Gateway 說明文件
- Kubernetes Gateway API
- Gateway API 推論擴充功能
- 建立標準叢集 | Google Distributed Cloud 實體隔離方案