Questo documento fornisce istruzioni passo passo per il deployment di un gateway AI negli ambienti air gap di Google Distributed Cloud (GDC). Il gateway è basato su Envoy Gateway, l'implementazione dell'API Gateway di Kubernetes basata sul proxy Envoy, e Envoy Agent Router (in precedenza Envoy AI Gateway), l'estensione che trasforma Envoy Gateway in un punto di ingresso unificato e compatibile con OpenAI per il traffico dei modelli linguistici di grandi dimensioni (LLM). Vengono trattati argomenti come l'inserimento delle immagini container e dei grafici Helm nel registro Harbor locale, l'installazione di entrambi i control plane su un cluster standard, la preparazione del backenlimitazione di frequenzaza basata su token facoltativo e la convalida dell'installazione con carichi di lavoro di esempio.
I backend di erogazione del modello (Ollama, vLLM) vengono implementati con il set di guide complementari Modelli open weight su GDC con air gap; la Guida per l'utente del router dell'agente Envoy per il routing basato sul corpo mostra come instradare le richieste in base al nome del modello.
Architettura
La soluzione viene eseguita in un cluster GDC standard. Una workstation amministratore inserisce le immagini e i grafici Helm nel registro Harbor del progetto e installa i due control plane: il controller Envoy Gateway, che programma il data plane del proxy Envoy dalle risorse dell'API Gateway (GatewayClass, Gateway, HTTPRoute) e il controller Envoy Agent Router, che estende il data plane con un processore esterno (ExtProc) per il traffico AI (AIGatewayRoute, AIServiceBackend, InferencePool). I client dell'applicazione inviano richieste compatibili con OpenAI al proxy Envoy, che le indirizza ai backend di erogazione del modello o ai InferencePool. Un'istanza Redis facoltativa
memorizza i contatori del servizio di limitazione della frequenza di Envoy per la limitazione della frequenza basata su token.

Envoy Gateway
Envoy Gateway è un progetto open source, basato
sul proxy Envoy, che semplifica l'adozione, l'utilizzo
e la gestione del proxy Envoy come gateway API Kubernetes. Implementa ed estende l'API Gateway di Kubernetes, il successore dell'API Ingress: le risorse GatewayClass e Gateway descrivono i punti di ingresso, le risorse di route come HTTPRoute descrivono come il traffico viene abbinato e inoltrato e la progettazione orientata ai ruoli separa le responsabilità dei team dell'infrastruttura e delle applicazioni. Envoy Gateway aggiunge le proprie API di estensione, ad esempio EnvoyProxy (impostazioni del data plane), Backend (endpoint esterni al cluster o a cui viene fatto riferimento tramite FQDN) e ClientTrafficPolicy (impostazioni di connessione come i limiti del buffer).
Router agente Envoy
Envoy Agent Router (in precedenza Envoy AI
Gateway) è un progetto open source che utilizza Envoy Gateway per gestire il traffico
delle richieste dai client delle applicazioni ai servizi di AI generativa. Fornisce un
livello unificato per il routing e la gestione del traffico LLM con routing basato sul modello,
autenticazione upstream,limitazione di frequenzaza basata su token e osservabilità e si
integra con l'estensione Gateway API Inference(InferencePool, Endpoint Picker) per la selezione degli endpoint basata sulle metriche. Il
controller monitora le risorse aigateway.envoyproxy.io/v1beta1 e inserisce
un processore esterno accanto al proxy Envoy; il processore esterno analizza il
corpo della richiesta (ad esempio il campo model di una richiesta di completamento della chat OpenAI), imposta le intestazioni di routing come x-ai-eg-model e traduce tra
gli schemi API, se necessario.
Prima di iniziare
Prima di procedere con il deployment, assicurati che il tuo ambiente soddisfi tutti i prerequisiti necessari e che le utilità della riga di comando richieste siano configurate correttamente. La configurazione di questi strumenti sulla workstation è essenziale per gestire i registri dei container, interagire con i cluster e automatizzare il processo di deployment.
- L'ambiente GDC con air gap 1.16.2-hf1 o versioni successive è disponibile con un cluster standard che esegue Kubernetes v1.32.13-gke.400 o versioni successive.
- Cluster standard creato con risorse sufficienti. I componenti del gateway vengono eseguiti solo sulla CPU; i backend di erogazione del modello hanno requisiti propri per gli acceleratori (consulta le guide Open Weight Models on GDC air-gapped).
- L'istanza Harbor è disponibile e accessibile.
- IAM necessario applicato.
- Workstation con la connettività necessaria all'ambiente e a internet
Configurazione dell'ambiente
La configurazione dell'ambiente copre le identità e le autorizzazioni, la workstation e l'accesso all'ambiente GDC e al cluster.
Identity and Access Management
Assicurati che gli account, i ruoli e le autorizzazioni IAM necessari siano configurati correttamente.
Ruoli Utente GDC nel progetto (RoleBinding nello spazio dei nomi del progetto, concessi da un amministratore IAM progetto):
- Visualizzatore istanze Harbor (
harbor-instance-viewer) - Autore progetto Harbor (
harbor-project-creator, solo se il progetto Harbor non esiste ancora) - Amministratore cluster standard (
standard-cluster-admin, obbligatorio pergdcloud clusters get-credentials)
Ruolo Utente GDC sul cluster standard: i
ruoli di progetto precedenti non concedono autorizzazioni all'interno del cluster. Un amministratore IAM del progetto deve inoltre associare l'utente a StandardClusterRole cluster-admin con un StandardClusterRoleBinding nello spazio dei nomi del progetto sul server API di gestione; l'associazione viene propagata ai cluster standard del progetto in pochi secondi (status.clusters[].conditions mostra Propagated=True). Sono necessarie autorizzazioni a livello di cluster perché questa guida installa definizioni di risorse personalizzate, ClusterRole e un 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
Sostituisci quanto segue:
MANAGEMENT_API_SERVER: il percorso del file kubeconfig del server API di gestione.USER: utente.PROJECT: progetto.
Autorizzazioni dell'account robot Harbor crane (crane):
- Elenca repository
- Pull Repository
- Repository push
- Leggi artefatto
- Elenca artefatto
- Crea tag
- Tag elenco
Account robot Harbor Kubernetes image pull (kubernetes-image-puller) permessi:
- Elenca repository
- Pull Repository
- Leggi artefatto
- Elenca artefatto
- Tag elenco
Workstation
Questa guida richiede una workstation con la connettività necessaria all'ambiente e a internet.
Requisiti
Sulla workstation devono essere installati i seguenti strumenti:
crane: gestisci e copia immagini container e artefatti OCI tra i registri (documentazione).gdcloud: interfaccia a riga di comando (CLI) per la gestione delle risorse GDC (documentazione).kubectl: interfaccia a riga di comando (CLI) utilizzata per comunicare con un cluster Kubernetes e gestirlo.helm: package manager per Kubernetes, versione 3.8 o successive (supporto del registro OCI) (documentazione).curl: strumento a riga di comando per il trasferimento di dati con URL.jq: processore JSON da riga di comando leggero e flessibile.yq: processore YAML portatile da riga di comando.
Esegui tutti i comandi di questa guida dalla workstation, a meno che un passaggio non indichi diversamente.
Configurazione workstation
Per la configurazione della workstation sono necessarie le seguenti informazioni sull'ambiente:
GDC_STANDARD_CLUSTER_NAME: il nome del cluster standard GDC.GDC_DOMAIN_SUFFIX: il suffisso di dominio per l'ambiente GDC (ad esempiogdc.example.com).GDC_ORG: il nome dell'organizzazione GDC.GDC_PROJECT: il nome del progetto GDC.GDC_ZONE: il nome della zona di deployment di GDC.GDC_HARBOR_INSTANCE_NAME: il nome dell'istanza Harbor nel progetto.GDCS_HARBOR_PROJECT_NAME: il nome del progetto Harbor da utilizzare per l'immagine (impostazione predefinita:solutions)GDCS_HARBOR_CRANE_ROBOT_NAME: il nome dell'account di servizio robotcranedi Harbor.GDCS_HARBOR_CRANE_ROBOT_TOKEN: il token di autenticazione per l'account robot Harborcrane.GDCS_HARBOR_K8S_ROBOT_NAME: il nome del service account robot di pull dell'immagine Kubernetes di Harbor.GDCS_HARBOR_K8S_ROBOT_TOKEN: il token di autenticazione per l'account di servizio di pull delle immagini Kubernetes di Harbor.
Una volta raccolti i valori di tutte le variabili richieste, procedi con la generazione del file delle variabili di ambiente. Una volta creato, puoi modificare manualmente il file in qualsiasi momento.
Crea le directory della soluzione radice e la cartella dei segreti:
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/*Crea il file di configurazione dell'ambiente della piattaforma:
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}" EOFSostituisci quanto segue:
STANDARD_CLUSTER_NAME: Nome del cluster standard GDC.DOMAIN_SUFFIX: suffisso del dominio GDC.ORG: Organizzazione GDC.PROJECT: Progetto GDC.ZONE: zona GDC.HARBOR_INSTANCE_NAME: Il nome dell'istanza GDC Harbor.
Crea il file di configurazione dell'ambiente del registro:
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}" EOFSostituisci quanto segue:
HARBOR_CRANE_ROBOT_NAME: Nome dell'account robot GDC Harbor.HARBOR_K8S_ROBOT_NAME: Nome dell'account robot GDC Harbor.
Aggiungi i token ai file dei secret:
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 historySostituisci quanto segue:
CRANE_ROBOT_TOKEN: token del robot gru.KUBERNETES_ROBOT_TOKEN: token robot Kubernetes.
Crea il file di caricamento dell'ambiente principale:
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
Configura le variabili della soluzione
Crea la directory di implementazione della soluzione:
mkdir -p ${HOME}/gdcag-solutions/ai-gateway/envoy/env.dCrea il file di configurazione dell'ambiente della soluzione:
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" EOFCrea il file di caricamento dell'ambiente di implementazione:
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" EOFModifica e rivedi i file di ambiente con il tuo editor preferito:
${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.shRecupera il file di ambiente:
source ${HOME}/gdcag-solutions/ai-gateway/envoy/env.shL'output è simile al seguente:
GDCS_ROOT_HOME=HOME_DIRECTORY_PATH/gdcag-solutions GDCS_IMPLEMENTATION_HOME=HOME_DIRECTORY_PATH/gdcag-solutions/ai-gateway/envoy
GDC
Questa guida presuppone che la workstation sia configurata per considerare attendibili i certificati TLS per l'ambiente GDC e l'istanza Harbor.
Configura
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}"Esegui l'autenticazione nell'ambiente GDC:
gdcloud auth login
Cluster
Recupera le credenziali del cluster:
gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \ --project="${GDC_PROJECT}" \ --standard \ --zone="${GDC_ZONE}"Verifica la connettività al cluster:
kubectl get nodes -L node.cluster.private.gdc.goog/machine-classVerifica che ogni nodo esegua la versione di Kubernetes richiesta dalla sezione Prima di iniziare di questa guida:
kubectl get nodes -o custom-columns='NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion'
Preparazione della migrazione degli artefatti
- Verifica la connettività e la configurazione per il registro degli artefatti.
Crea un file di configurazione Docker per crane. Un account robot viene utilizzato per trasferire livelli di immagini di grandi dimensioni per evitare timeout dei token di autenticazione quando si utilizza l'helper delle credenziali Managed Harbor Service (MHS) (docker-credential-mhs) con un account utente:
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 historyCrea un file di configurazione Docker per Kubernetes:
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 historyAccedi al registro Harbor OCI con
helmutilizzando l'account robot pull di immagini Kubernetes.helmconserva le proprie credenziali del registro e le utilizza per recuperare i grafici da Harbor:set +o history helm registry login "${GDC_HARBOR_HOST}" \ --password="${GDCS_HARBOR_K8S_ROBOT_TOKEN}" \ --username="${GDCS_HARBOR_K8S_ROBOT_NAME}" set -o historyL'output è simile al seguente:
Login SucceededCrea lo script
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"Crea lo script
seed_charts.sh. Anche i grafici Helm pubblicati come artefatti OCI vengono copiati concrane, senza selezione della piattaforma e senza il tagcreateutilizzato per i repository di immagini container: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"Sostituisci quanto segue:
REGISTRY_HOST: host del registro.REPOSITORY: repository.CHART_VERSION: versione del grafico.
Definisci l'elenco delle immagini container richieste per la soluzione:
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)Inserisci le immagini container richieste in Artifact Registry:
${GDCS_IMPLEMENTATION_HOME}/seed_registry.sh
Definisci l'elenco dei grafici Helm richiesti per la soluzione:
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)Inserisci i grafici Helm richiesti nel registro degli artefatti:
${GDCS_IMPLEMENTATION_HOME}/seed_charts.shVerifica che i grafici possano essere letti da 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):'L'output è simile al seguente:
name: gateway-helm version: v1.8.5 name: ai-gateway-helm version: v1.1.0Scarica i manifest dell'estensione di inferenza dell'API Gateway. Vengono pubblicati come asset di rilascio, non come grafico:
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"L'output è simile al seguente:
4
Envoy Gateway
Envoy Gateway viene installato per primo e convalidato separatamente con la guida rapida upstream. L'integrazione di Envoy Agent Router viene descritta nella sezione successiva.
Spazio dei nomi
Crea lo spazio dei nomi per Envoy Gateway. Anche i proxy Envoy
Deploymentdi ogniGatewayvengono creati in questo spazio dei nomi:kubectl create namespace "${GDCS_ENVOY_GATEWAY_NAMESPACE}"Aggiungi
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 -
Definizioni di risorse personalizzate
Installa l'API Gateway (canale standard) e le definizioni di risorse personalizzate (CRD) di Envoy Gateway dal grafico seed:
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=-Verifica che le CRD siano registrate:
kubectl get crd | grep -E 'gateway.networking.k8s.io|gateway.envoyproxy.io'
Controller
Crea il file dei valori Helm per Envoy Gateway. Le immagini vengono estratte da Harbor con il segreto di pull delle immagini;
crds.enabled=falseperché le CRD sono state installate separatamente: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} EOFInstalla 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}"Attendi che il controller Envoy Gateway sia disponibile:
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'"Verifica che le immagini del controller e il relativo job di generazione dei certificati provengano da Harbor:
kubectl get pods --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --output=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
Proxy Envoy e classe gateway
Crea il manifest per il modello del data plane
EnvoyProxye perGatewayClass.EnvoyProxyimposta l'immagine proxy, il segreto di pull dell'immagine e le richieste di risorse dei proxyPod;GatewayClassè condiviso dalle guide utente: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} EOFApplica il manifest per
EnvoyProxyeGatewayClass:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/gateway-class.yaml"Verifica che
GatewayClasssia accettato:kubectl get gatewayclass "${GDCS_GATEWAY_CLASS_NAME}"L'output è simile al seguente:
NAME CONTROLLER ACCEPTED AGE envoy-ai-gateway gateway.envoyproxy.io/gatewayclass-controller True 5s
Convalida
La convalida esegue il deployment della guida rapida di Envoy Gateway (un backend echo dietro un
HTTPRoute) nello spazio dei nomi di Envoy Gateway e lo rimuove in seguito.
Crea il manifest per il carico di lavoro di avvio rapido:
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: / EOFApplica il manifest per il carico di lavoro di avvio rapido:
kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"Attendi che
Gatewayvenga programmato: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'"Attendi che il backend
Deploymentsia disponibile: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'"Invia una richiesta di test tramite il gateway utilizzando il port forwarding. L'Envoy
Servicedi unGatewayviene trovato dalle etichette del gateway proprietario: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}L'output è simile al seguente:
{ "path": "/get", "host": "www.example.com", "method": "GET", ... "namespace": "envoy-gateway-system", "pod": "eg-quickstart-backend-...", ... }Rimuovi il workload di avvio rapido:
kubectl delete \ --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"
Router agente Envoy
Envoy Agent Router viene installato nel proprio spazio dei nomi; Envoy Gateway viene quindi riconfigurato per chiamarlo come server di estensione.
Spazio dei nomi
Crea lo spazio dei nomi per il controller del router dell'agente Envoy:
kubectl create namespace "${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"Aggiungi
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 -
Definizioni di risorse personalizzate
Installa le CRD del router agente Envoy dal grafico iniziale:
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=-Installa i CRD dell'estensione di inferenza dell'API Gateway (
InferencePool,InferenceObjective) dai manifest scaricati:kubectl apply --server-side \ --filename="${GDCS_IMPLEMENTATION_HOME}/manifests/gateway-api-inference-extension-${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}.yaml"Verifica che le CRD siano registrate:
kubectl get crd | grep -E 'aigateway.envoyproxy.io|inference.networking'L'output è simile al seguente:
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
La limitazione di frequenza basata sui token viene applicata dal servizio di limitazione di frequenza Envoy, che archivia i contatori in Redis. Questa guida esegue il deployment di una singola replica Redis senza
persistenza. In alternativa, è possibile utilizzare un servizio Redis esistente modificando il
valore di rateLimit.backend.redis.url nella sezione successiva.
Crea il manifest per 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 EOFApplica il manifest per Redis
Deployment:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/redis.yaml" \ --namespace="${GDCS_REDIS_NAMESPACE}"Attendi che Redis
Deploymentsia disponibile: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'"
Controller
Crea il file dei valori Helm per Envoy Agent Router:
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} EOFInstalla Envoy Agent Router:
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}"Attendi che il controller Envoy Agent Router sia disponibile:
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'"
Integrazione di Envoy Gateway
Envoy Gateway deve essere riconfigurato per chiamare il controller Envoy Agent Router come
server di estensione, per accettare le risorse InferencePool come backend e per utilizzare
il servizio di limitazione della frequenza basato su Redis.
Crea il file dei valori di Helm per l'integrazione:
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 EOFEsegui l'upgrade di Envoy Gateway con entrambi i file di valori:
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}"Crea il manifest per
ClusterRoleche consente al controller Envoy Gateway di monitorare le risorseInferencePool. Il grafico non concede questa autorizzazione; unClusterRoleBindingseparato sopravvive agli upgrade del grafico, a differenza di una patch delClusterRolegestito dal grafico: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} EOFApplica il manifest per
ClusterRole:kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-inferencepool-rbac.yaml"Riavvia il controller Envoy Gateway in modo che applichi la nuova configurazione e le nuove autorizzazioni e attendi che lo stato sia Disponibile:
kubectl rollout restart deployment/envoy-gateway \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" kubectl rollout status deployment/envoy-gateway \ --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \ --timeout=5mVerifica che il servizio di limite di frequenza sia stato implementato e sia disponibile:
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'"
Convalida
La convalida esegue il deployment dell'esempio di base di Envoy Agent Router (un upstream compatibile con OpenAI simulato dietro un AIGatewayRoute) nello spazio dei nomi di Envoy Agent Router e lo rimuove in seguito.
Crea il manifest per il workload di convalida:
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 EOFApplica il manifest per il workload di convalida:
kubectl apply \ --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"Attendi che
Gatewayvenga programmato: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'"Attendi che il mock upstream
Deploymentsia disponibile: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'"Verifica che il proxy Envoy
PoddiGatewayesegua il sidecar del processore esterno inserito da Envoy Agent Router: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}'L'output è simile al seguente:
envoy-envoy-ai-gateway-system-aieg-basic-... envoy shutdown-manager ai-gateway-extprocInvia una richiesta di completamento della chat tramite il gateway utilizzando il port forwarding. Il processore esterno legge il campo
modeldel corpo della richiesta e lo indirizza al mock upstream: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}L'output è simile al seguente:
{ "choices": [ { "index": 0, "message": { "role": "assistant", "content": "..." }, "finish_reason": "stop" } ], "usage": { ... } }Rimuovi il workload di convalida:
kubectl delete \ --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \ --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"
Operazioni
Attività del secondo giorno per i control plane del gateway.
Esegui l'upgrade
- Inserisci le immagini e i grafici delle nuove versioni (aggiorna le variabili di versione
in
env.sh, esegui di nuovoseed_registry.sheseed_charts.sh), applica i nuovi grafici CRD conkubectl apply --server-side, quindi esegui gli stessi comandihelm upgrade --installcon il nuovo--version. Consulta la matrice di compatibilità di Envoy Agent Router per le versioni di Envoy Gateway e Gateway API supportate dalla release di destinazione. Envoy Agent Router 1.1.0 è basato su Envoy Gateway 1.8.
Disinstalla
- Elimina prima le risorse
Gateway,AIGatewayRouteeInferencePooldelle guide utente, poihelm uninstall aieg --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}",helm uninstall eg --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}",ClusterRoleenvoy-gateway-inferencepool-reader,GatewayClass, RedisDeploymente infine i CRD.
Risoluzione dei problemi
| Sintomo | Probabile causa | Azione |
|---|---|---|
helm show chart o helm upgrade non riesce con unauthorized o FetchReference |
helm non dispone di credenziali per Harbor (non utilizza la configurazione Docker crane) |
Esegui di nuovo il passaggio helm registry login con l'account di servizio robot pull dell'immagine Kubernetes. |
Envoy Gateway o Envoy Agent Router Pods rimangono in ImagePullBackOff |
L'immagine non è stata inizializzata o il secret di pull dell'immagine non è presente nello spazio dei nomi | Controlla kubectl describe pod, confronta il percorso dell'immagine con crane ls "${GDCS_HARBOR_PROJECT_URI}/envoyproxy/gateway" e verifica che il secret esista in ${GDCS_ENVOY_GATEWAY_NAMESPACE} e ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}. |
Gateway rimane Programmed=False dopo l'integrazione |
Il controller Envoy Gateway non riesce a raggiungere il server delle estensioni o non è stato riavviato dopo l'upgrade | kubectl logs deployment/envoy-gateway --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"; verifica che service/ai-gateway-controller esista in ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} e che la porta 1063 sia elencata; ripeti il riavvio del lancio. |
AIGatewayRoute che fa riferimento a un InferencePool non è accettato |
Envoy Gateway non dispone dell'autorizzazione per leggere inferencepools o mancano le CRD InferencePool |
Verifica ClusterRoleBinding envoy-gateway-inferencepool-reader e inferencepools.inference.networking.k8s.io CRD; controlla i log del controller per forbidden. |
La richiesta di completamento della chat restituisce 413 o la connessione viene reimpostata per i prompt di grandi dimensioni |
Il limite predefinito del buffer Envoy (32 KiB) è troppo piccolo per i payload AI | Allega un ClientTrafficPolicy con connection.bufferLimit (la convalida utilizza 50 Mi) a Gateway. |
Il servizio di limitazione di frequenza Pod è CrashLoopBackOff |
Redis non è raggiungibile all'URL configurato | kubectl get service redis --namespace="${GDCS_REDIS_NAMESPACE}"; correggi rateLimit.backend.redis.url nel file dei valori di integrazione ed esegui di nuovo l'upgrade. |
Materiali aggiuntivi
- Documentazione di Envoy Agent Router
- Note di rilascio e matrice di compatibilità di Envoy Agent Router
- Documentazione di Envoy Gateway
- API Kubernetes Gateway
- Estensione Gateway API Inference
- Crea un cluster standard | Google Distributed Cloud con air gap
Routing basato sul corpo con la guida per l'utente di Envoy Agent Router