Implementasi referensi AI Gateway dengan Envoy Agent Router di GDC dengan air gap

Dokumen ini memberikan petunjuk langkah demi langkah untuk men-deploy AI Gateway di lingkungan air-gapped Google Distributed Cloud (GDC). Gateway ini dibangun dari Envoy Gateway, implementasi Kubernetes Gateway API berdasarkan proxy Envoy, dan Envoy Agent Router (sebelumnya Envoy AI Gateway), ekstensi yang mengubah Envoy Gateway menjadi titik entri terpadu yang kompatibel dengan OpenAI untuk traffic Model Bahasa Besar (LLM). Bagian ini mencakup pemberian seed pada image container dan diagram Helm ke registry Harbor lokal, penginstalan kedua bidang kontrol di cluster standar, penyiapan backend pembatasan frekuensi berbasis token opsional, dan validasi penginstalan dengan workload contoh.

Backend penyajian model (Ollama, vLLM) di-deploy dengan serangkaian panduan pendamping Model Berat Terbuka di GDC dengan air gap; Panduan pengguna perutean berbasis isi dengan Envoy Agent Router menunjukkan cara merutekan permintaan ke backend tersebut berdasarkan nama model.

Arsitektur

Solusi ini berjalan di cluster standar GDC. Workstation administrator menyebarkan image dan diagram Helm ke dalam registry Harbor project dan menginstal dua bidang kontrol: pengontrol Envoy Gateway, yang memprogram bidang data proxy Envoy dari resource Gateway API (GatewayClass, Gateway, HTTPRoute), dan pengontrol Envoy Agent Router, yang memperluas bidang data tersebut dengan pemroses eksternal (ExtProc) untuk traffic AI (AIGatewayRoute, AIServiceBackend, InferencePool). Klien aplikasi mengirim permintaan yang kompatibel dengan OpenAI ke proxy Envoy, yang merutekannya ke backend penayangan model atau InferencePool. Instance Redis opsional menyimpan penghitung layanan pembatasan kecepatan Envoy untuk pembatasan kecepatan berbasis token.

Arsitektur referensi AI Gateway dengan Envoy Agent Router di GDC dengan air gap.

Envoy Gateway

Envoy Gateway adalah project open source, yang dibangun di proxy Envoy, yang menyederhanakan adopsi, penggunaan dan pengelolaan proxy Envoy sebagai gateway API Kubernetes. API ini mengimplementasikan dan memperluas Kubernetes Gateway API, penerus Ingress API: Resource GatewayClass dan Gateway menjelaskan titik entri, resource rute seperti HTTPRoute menjelaskan cara traffic dicocokkan dan diteruskan, serta desain berorientasi peran memisahkan tanggung jawab tim infrastruktur dan aplikasi. Envoy Gateway menambahkan API ekstensi sendiri, misalnya EnvoyProxy (setelan bidang data), Backend (endpoint di luar cluster atau dirujuk oleh FQDN) dan ClientTrafficPolicy (setelan koneksi seperti batas buffer).

Router Agen Envoy

Envoy Agent Router (sebelumnya Envoy AI Gateway) adalah project open source yang menggunakan Envoy Gateway untuk menangani traffic permintaan dari klien aplikasi ke layanan AI Generatif. Layanan ini menyediakan lapisan terpadu untuk merutekan dan mengelola traffic LLM dengan perutean yang sadar model, autentikasi upstream, pembatasan frekuensi berbasis token, dan kemampuan observasi. Layanan ini juga terintegrasi dengan Ekstensi Inferensi Gateway API (InferencePool, Pemilih Endpoint) untuk pemilihan endpoint yang sadar metrik. Pengontrol memantau resource aigateway.envoyproxy.io/v1beta1 dan menyuntikkan pemroses eksternal di samping proxy Envoy; pemroses eksternal mengurai isi permintaan (misalnya, kolom model dari permintaan penyelesaian chat OpenAI), menetapkan header perutean seperti x-ai-eg-model, dan menerjemahkan antara skema API jika diperlukan.

Sebelum memulai

Sebelum melanjutkan deployment, pastikan lingkungan Anda memenuhi semua prasyarat yang diperlukan dan utilitas command line yang diperlukan dikonfigurasi dengan benar. Menyiapkan alat ini di workstation Anda sangat penting untuk mengelola registry container, berinteraksi dengan cluster, dan mengotomatiskan proses deployment.

  • Lingkungan GDC dengan air gap 1.16.2-hf1 atau yang lebih baru tersedia dengan cluster standar yang menjalankan Kubernetes v1.32.13-gke.400 atau yang lebih baru.
  • Cluster Standard dibuat dengan resource yang memadai. Komponen gateway hanya berjalan di CPU; backend penayangan model memiliki persyaratan akseleratornya sendiri (lihat panduan Model Berat Terbuka di GDC yang terisolasi dari internet).
  • Instance Harbor tersedia dan dapat diakses.
  • IAM yang diperlukan diterapkan.
  • Workstation dengan konektivitas yang diperlukan ke lingkungan dan internet

Konfigurasi lingkungan

Konfigurasi lingkungan mencakup identitas dan izin, workstation, serta akses ke lingkungan GDC dan cluster.

Identity and Access Management

Pastikan akun, peran, dan izin IAM yang diperlukan telah dikonfigurasi dengan benar.

Peran Pengguna GDC di project (RoleBinding di namespace project, diberikan oleh Admin IAM Project):

  • Harbor Instance Viewer (harbor-instance-viewer)
  • Harbor Project Creator (harbor-project-creator, hanya jika project Harbor belum ada)
  • Admin Cluster Standar (standard-cluster-admin, diperlukan untuk gdcloud clusters get-credentials)

Peran Pengguna GDC di cluster standar: peran project sebelumnya tidak memberikan izin di dalam cluster. Admin IAM Project juga harus mengikat pengguna ke StandardClusterRole cluster-admin dengan StandardClusterRoleBinding di namespace project di server API pengelolaan; pengikatan disebarkan ke cluster standar project dalam hitungan detik (status.clusters[].conditions menampilkan Propagated=True). Izin di seluruh cluster diperlukan karena panduan ini menginstal Definisi Resource Kustom, ClusterRole, dan 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

Ganti kode berikut:

  • MANAGEMENT_API_SERVER: jalur ke file kubeconfig server API pengelolaan.
  • USER: pengguna.
  • PROJECT: project.

Izin akun robot Harbor crane (crane):

  • Daftar Repositori
  • Tarik Repositori
  • Repositori Push
  • Membaca Artefak
  • Mencantumkan Artefak
  • Buat Tag
  • Tag Daftar

Izin akun robot penarikan image Kubernetes Harbor (kubernetes-image-puller):

  • Daftar Repositori
  • Tarik Repositori
  • Membaca Artefak
  • Mencantumkan Artefak
  • Tag Daftar

Workstation

Panduan ini memerlukan workstation dengan konektivitas yang diperlukan ke lingkungan dan internet.

Persyaratan

Alat berikut harus diinstal di workstation:

  • crane: mengelola dan menyalin image container dan artefak OCI antar-registry (dokumentasi).
  • gdcloud: antarmuka command line (CLI) untuk mengelola resource GDC (dokumentasi).
  • kubectl: antarmuka command line (CLI) yang digunakan untuk berkomunikasi dengan dan mengelola cluster Kubernetes.
  • helm: pengelola paket untuk Kubernetes, versi 3.8 atau yang lebih baru (dukungan registry OCI) (dokumentasi).
  • curl: alat command line untuk mentransfer data dengan URL.
  • jq: pemroses JSON command-line yang ringan dan fleksibel.
  • yq: pemroses YAML command line portabel.

Jalankan semua perintah dalam panduan ini dari workstation, kecuali jika langkah menyatakan sebaliknya.

Konfigurasi workstation

Informasi berikut tentang lingkungan diperlukan untuk Konfigurasi Workstation:

  • GDC_STANDARD_CLUSTER_NAME: Nama cluster standar GDC.
  • GDC_DOMAIN_SUFFIX: Akhiran domain untuk lingkungan GDC (misalnya, gdc.example.com).
  • GDC_ORG: Nama organisasi GDC.
  • GDC_PROJECT: Nama project GDC.
  • GDC_ZONE: Nama zona deployment GDC.
  • GDC_HARBOR_INSTANCE_NAME: Nama instance Harbor dalam project.

  • GDCS_HARBOR_PROJECT_NAME: Nama project Harbor yang akan digunakan untuk image (default: solutions)

  • GDCS_HARBOR_CRANE_ROBOT_NAME: Nama akun robot crane Harbor.

  • GDCS_HARBOR_CRANE_ROBOT_TOKEN: Token autentikasi untuk akun robot crane Harbor.

  • GDCS_HARBOR_K8S_ROBOT_NAME: Nama akun robot penarikan image Kubernetes Harbor.

  • GDCS_HARBOR_K8S_ROBOT_TOKEN: Token autentikasi untuk akun robot penarikan image Kubernetes Harbor.

Setelah Anda mengumpulkan nilai untuk semua variabel yang diperlukan, lanjutkan dengan membuat file variabel lingkungan. Setelah dibuat, Anda dapat mengedit file secara manual kapan saja.

  1. Buat direktori solusi root dan folder rahasia:

    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/*
    
  2. Buat file konfigurasi lingkungan platform:

    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
    

    Ganti kode berikut:

    • STANDARD_CLUSTER_NAME: Nama cluster standar GDC.
    • DOMAIN_SUFFIX: Suffix domain GDC.
    • ORG: Organisasi GDC.
    • PROJECT: Project GDC.
    • ZONE: Zona GDC.
    • HARBOR_INSTANCE_NAME: Nama instance GDC Harbor.
  3. Buat file konfigurasi lingkungan registri:

    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
    

    Ganti kode berikut:

    • HARBOR_CRANE_ROBOT_NAME: Nama akun robot GDC Harbor.
    • HARBOR_K8S_ROBOT_NAME: Nama akun robot GDC Harbor.
  4. Tambahkan token Anda ke file 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 history
    

    Ganti kode berikut:

    • CRANE_ROBOT_TOKEN: token robot derek.
    • KUBERNETES_ROBOT_TOKEN: Token robot Kubernetes.
  5. Buat file pemuat lingkungan root:

    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
    

Mengonfigurasi variabel solusi

  1. Buat direktori penerapan solusi:

    mkdir -p ${HOME}/gdcag-solutions/ai-gateway/envoy/env.d
    
  2. Buat file konfigurasi lingkungan solusi:

    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
    
  3. Buat file loader lingkungan penerapan:

    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
    
  4. Edit dan tinjau file lingkungan dengan editor pilihan Anda:

    ${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
    
  5. Mendapatkan file lingkungan:

    source ${HOME}/gdcag-solutions/ai-gateway/envoy/env.sh
    

    Outputnya mirip dengan hal berikut ini:

    GDCS_ROOT_HOME=HOME_DIRECTORY_PATH/gdcag-solutions
    GDCS_IMPLEMENTATION_HOME=HOME_DIRECTORY_PATH/gdcag-solutions/ai-gateway/envoy
    

GDC

Panduan ini mengasumsikan bahwa workstation Anda dikonfigurasi untuk memercayai sertifikat TLS untuk lingkungan GDC dan instance Harbor Anda.

  1. Konfigurasi 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}"
    
  2. Lakukan autentikasi ke lingkungan GDC:

    gdcloud auth login
    

Cluster

  1. Ambil kredensial cluster:

    gdcloud clusters get-credentials "${GDC_STANDARD_CLUSTER_NAME}" \
    --project="${GDC_PROJECT}" \
    --standard \
    --zone="${GDC_ZONE}"
    
  2. Verifikasi konektivitas ke cluster:

    kubectl get nodes -L node.cluster.private.gdc.goog/machine-class
    
  3. Pastikan setiap node menjalankan versi Kubernetes yang diperlukan di bagian Sebelum memulai dalam panduan ini:

    kubectl get nodes -o custom-columns='NAME:.metadata.name,VERSION:.status.nodeInfo.kubeletVersion'
    

Persiapan migrasi artefak

  1. Buat file konfigurasi Docker untuk crane. Akun robot digunakan untuk mengirimkan lapisan gambar berukuran besar untuk menghindari waktu tunggu habis token autentikasi saat menggunakan Managed Harbor Service (MHS) credential helper (docker-credential-mhs) dengan akun pengguna:

    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
    
  2. Buat file konfigurasi Docker untuk 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 history
    
  3. Login ke registry OCI Harbor dengan helm menggunakan akun robot pull image Kubernetes. helm menyimpan kredensial registrinya sendiri dan memerlukannya untuk mengambil diagram dari 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
    

    Outputnya mirip dengan hal berikut ini:

    Login Succeeded
    
  4. Buat skrip 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"
    
  5. Buat skrip seed_charts.sh. Diagram Helm yang dipublikasikan sebagai artefak OCI juga disalin dengan crane, tanpa pemilihan platform dan tanpa tag create yang digunakan untuk repositori image 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"
    

    Ganti kode berikut:

    • REGISTRY_HOST: host registry.
    • REPOSITORY: repositori.
    • CHART_VERSION: versi diagram.
  6. Tentukan daftar image container yang diperlukan untuk solusi:

    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)
    
  7. Lakukan seeding image container yang diperlukan ke artifact registry:

    ${GDCS_IMPLEMENTATION_HOME}/seed_registry.sh
    
  1. Tentukan daftar diagram Helm yang diperlukan untuk solusi:

    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)
    
  2. Lakukan seeding pada diagram Helm yang diperlukan ke Artifact Registry:

    ${GDCS_IMPLEMENTATION_HOME}/seed_charts.sh
    
  3. Pastikan diagram dapat dibaca kembali dari 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):'
    

    Outputnya mirip dengan hal berikut ini:

    name: gateway-helm
    version: v1.8.5
    name: ai-gateway-helm
    version: v1.1.0
    
  4. Download manifes Ekstensi Inferensi API Gateway. Aset ini dipublikasikan sebagai aset rilis, bukan sebagai diagram:

    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"
    

    Outputnya mirip dengan hal berikut ini:

    4
    

Envoy Gateway

Envoy Gateway diinstal terlebih dahulu dan divalidasi sendiri dengan panduan memulai cepat upstream; integrasi Envoy Agent Router akan dibahas di bagian berikutnya.

Namespace

  1. Buat namespace untuk Envoy Gateway. Proxy Envoy Deployment dari setiap Gateway juga dibuat di namespace ini:

    kubectl create namespace "${GDCS_ENVOY_GATEWAY_NAMESPACE}"
    
  2. Tambahkan 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 -
    

Definisi Resource Kustom

  1. Instal Gateway API (saluran standar) dan Definisi Resource Kustom (CRD) Envoy Gateway dari diagram yang di-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=-
    
  2. Verifikasi bahwa CRD sudah terdaftar:

    kubectl get crd | grep -E 'gateway.networking.k8s.io|gateway.envoyproxy.io'
    

Pengontrol

  1. Buat file nilai Helm untuk Envoy Gateway. Image ditarik dari Harbor dengan secret penarikan image; crds.enabled=false karena CRD diinstal secara terpisah:

    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
    
  2. Instal 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}"
    
  3. Tunggu hingga pengontrol Envoy Gateway menjadi Tersedia:

    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'"
    
  4. Pastikan image pengontrol dan tugas pembuatan sertifikatnya berasal dari Harbor:

    kubectl get pods --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \
    --output=jsonpath='{range .items[*]}{.metadata.name}{"\t"}{.spec.containers[*].image}{"\n"}{end}'
    

Proxy Envoy dan class Gateway

  1. Buat manifes untuk template bidang data EnvoyProxy dan GatewayClass. EnvoyProxy menetapkan gambar proxy, secret penarikan gambar dan permintaan resource proxy Pod; GatewayClass dibagikan oleh panduan pengguna:

    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
    
  2. Terapkan manifes untuk EnvoyProxy dan GatewayClass:

    kubectl apply \
    --filename="${GDCS_IMPLEMENTATION_HOME}/gateway-class.yaml"
    
  3. Verifikasi bahwa GatewayClass diterima:

    kubectl get gatewayclass "${GDCS_GATEWAY_CLASS_NAME}"
    

    Outputnya mirip dengan hal berikut ini:

    NAME               CONTROLLER                                      ACCEPTED   AGE
    envoy-ai-gateway   gateway.envoyproxy.io/gatewayclass-controller   True       5s
    

Validasi

Validasi men-deploy mulai cepat Envoy Gateway (backend echo di balik HTTPRoute) ke namespace Envoy Gateway, lalu menghapusnya.

  1. Buat manifes untuk beban kerja panduan memulai:

    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
    
  2. Terapkan manifes untuk workload mulai cepat:

    kubectl apply \
    --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \
    --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"
    
  3. Tunggu hingga Gateway Diprogram:

    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'"
    
  4. Tunggu hingga backend Deployment Tersedia:

    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'"
    
  5. Kirim permintaan pengujian melalui gateway menggunakan penerusan port. Envoy Service dari Gateway ditemukan berdasarkan label gateway pemiliknya:

    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}
    

    Outputnya mirip dengan hal berikut ini:

    {
      "path": "/get",
      "host": "www.example.com",
      "method": "GET",
      ...
      "namespace": "envoy-gateway-system",
      "pod": "eg-quickstart-backend-...",
      ...
    }
    
  6. Hapus workload panduan memulai:

    kubectl delete \
    --filename="${GDCS_IMPLEMENTATION_HOME}/eg-quickstart.yaml" \
    --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"
    

Router Agen Envoy

Envoy Agent Router diinstal ke namespace-nya sendiri; Envoy Gateway kemudian dikonfigurasi ulang untuk memanggilnya sebagai server ekstensi.

Namespace

  1. Buat namespace untuk pengontrol Envoy Agent Router:

    kubectl create namespace "${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"
    
  2. Tambahkan 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 -
    

Definisi Resource Kustom

  1. Instal CRD Envoy Agent Router dari diagram yang di-seed:

    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=-
    
  2. Instal CRD Ekstensi Inferensi Gateway API (InferencePool, InferenceObjective) dari manifes yang didownload:

    kubectl apply --server-side \
    --filename="${GDCS_IMPLEMENTATION_HOME}/manifests/gateway-api-inference-extension-${GDCS_GATEWAY_API_INFERENCE_EXTENSION_VERSION}.yaml"
    
  3. Verifikasi bahwa CRD sudah terdaftar:

    kubectl get crd | grep -E 'aigateway.envoyproxy.io|inference.networking'
    

    Outputnya mirip dengan hal berikut ini:

    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

Pembatasan kapasitas berbasis token diterapkan oleh layanan pembatasan kapasitas Envoy, yang menyimpan penghitungnya di Redis. Panduan ini men-deploy Redis replika tunggal tanpa persistensi; layanan Redis yang ada dapat digunakan sebagai gantinya dengan mengubah nilai rateLimit.backend.redis.url di bagian berikutnya.

  1. Buat manifes untuk Deployment Redis:

    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
    
  2. Terapkan manifes untuk Redis Deployment:

    kubectl apply \
    --filename="${GDCS_IMPLEMENTATION_HOME}/redis.yaml" \
    --namespace="${GDCS_REDIS_NAMESPACE}"
    
  3. Tunggu hingga Redis Deployment Tersedia:

    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'"
    

Pengontrol

  1. Buat file nilai Helm untuk 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}
    EOF
    
  2. Instal Perute Agen 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}"
    
  3. Tunggu hingga pengontrol Envoy Agent Router tersedia:

    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'"
    

Integrasi Envoy Gateway

Envoy Gateway harus dikonfigurasi ulang untuk memanggil pengontrol Envoy Agent Router sebagai server ekstensi, untuk menerima resource InferencePool sebagai backend, dan untuk menggunakan layanan pembatasan frekuensi yang didukung Redis.

  1. Buat file nilai Helm untuk integrasi:

    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
    
  2. Upgrade Envoy Gateway dengan kedua file nilai:

    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}"
    
  3. Buat manifes untuk ClusterRole yang memungkinkan pengontrol Envoy Gateway memantau resource InferencePool. Diagram tidak memberikan izin ini; ClusterRoleBinding terpisah tetap ada setelah upgrade diagram, tidak seperti patch ClusterRole yang dikelola diagram:

    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
    
  4. Terapkan manifes untuk ClusterRole:

    kubectl apply \
    --filename="${GDCS_IMPLEMENTATION_HOME}/envoy-gateway-inferencepool-rbac.yaml"
    
  5. Mulai ulang pengontrol Envoy Gateway agar dapat mengambil konfigurasi dan izin baru, lalu tunggu hingga statusnya menjadi Tersedia:

    kubectl rollout restart deployment/envoy-gateway \
    --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"
    
    kubectl rollout status deployment/envoy-gateway \
    --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}" \
    --timeout=5m
    
  6. Pastikan layanan batas frekuensi di-deploy dan Tersedia:

    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'"
    

Validasi

Validasi men-deploy contoh dasar Envoy Agent Router (upstream yang kompatibel dengan OpenAI tiruan di belakang AIGatewayRoute) ke namespace Envoy Agent Router dan menghapusnya setelahnya.

  1. Buat manifes untuk beban kerja validasi:

    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
    
  2. Terapkan manifes untuk workload validasi:

    kubectl apply \
    --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \
    --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"
    
  3. Tunggu hingga Gateway Diprogram:

    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'"
    
  4. Tunggu hingga upstream tiruan Deployment menjadi Tersedia:

    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'"
    
  5. Verifikasi bahwa proxy Envoy Pod dari Gateway menjalankan sidecar prosesor eksternal yang disuntikkan oleh 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}'
    

    Outputnya mirip dengan hal berikut ini:

    envoy-envoy-ai-gateway-system-aieg-basic-...   envoy shutdown-manager ai-gateway-extproc
    
  6. Mengirim permintaan penyelesaian chat melalui gateway menggunakan penerusan port. Prosesor eksternal membaca kolom model isi permintaan dan merutekannya ke upstream tiruan:

    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}
    

    Outputnya mirip dengan hal berikut ini:

    {
      "choices": [
        {
          "index": 0,
          "message": {
            "role": "assistant",
            "content": "..."
          },
          "finish_reason": "stop"
        }
      ],
      "usage": {
        ...
      }
    }
    
  7. Hapus workload validasi:

    kubectl delete \
    --filename="${GDCS_IMPLEMENTATION_HOME}/aieg-basic.yaml" \
    --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}"
    

Operasi

Tugas hari kedua untuk bidang kontrol gateway.

Upgrade

  • Isi gambar dan diagram versi baru (perbarui variabel versi di env.sh, jalankan kembali seed_registry.sh dan seed_charts.sh), terapkan diagram CRD baru dengan kubectl apply --server-side, lalu jalankan perintah helm upgrade --install yang sama dengan --version baru. Periksa matriks kompatibilitas Router Agen Envoy untuk versi Envoy Gateway dan Gateway API yang didukung oleh rilis target; Router Agen Envoy 1.1.0 dibangun berdasarkan Envoy Gateway 1.8.

Uninstal

  • Hapus resource Gateway, AIGatewayRoute, dan InferencePool dari panduan pengguna terlebih dahulu, lalu helm uninstall aieg --namespace="${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}", helm uninstall eg --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}", ClusterRole envoy-gateway-inferencepool-reader, GatewayClass, Redis Deployment, dan terakhir CRD.

Pemecahan masalah

Gejala Kemungkinan penyebab Tindakan
helm show chart atau helm upgrade gagal dengan unauthorized atau FetchReference helm tidak memiliki kredensial untuk Harbor (tidak menggunakan konfigurasi Docker crane) Jalankan langkah helm registry login lagi dengan akun robot pengambilan image Kubernetes.
Envoy Gateway atau Envoy Agent Router Pods tetap berada di ImagePullBackOff Gambar tidak di-seed, atau secret penarikan gambar tidak ada di namespace Periksa kubectl describe pod, bandingkan jalur image dengan crane ls "${GDCS_HARBOR_PROJECT_URI}/envoyproxy/gateway", dan verifikasi bahwa secret ada di ${GDCS_ENVOY_GATEWAY_NAMESPACE} dan ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE}.
Gateway tetap Programmed=False setelah integrasi Pengontrol Envoy Gateway tidak dapat menjangkau server ekstensi, atau tidak dimulai ulang setelah upgrade kubectl logs deployment/envoy-gateway --namespace="${GDCS_ENVOY_GATEWAY_NAMESPACE}"; konfirmasi bahwa service/ai-gateway-controller ada di ${GDCS_ENVOY_AGENT_ROUTER_NAMESPACE} dan port 1063 tercantum; ulangi mulai ulang peluncuran.
AIGatewayRoute yang mereferensikan InferencePool tidak Diterima Envoy Gateway tidak memiliki izin untuk membaca inferencepools, atau CRD InferencePool tidak ada Verifikasi ClusterRoleBinding envoy-gateway-inferencepool-reader dan CRD inferencepools.inference.networking.k8s.io; periksa log pengontrol untuk forbidden.
Permintaan penyelesaian chat menampilkan 413 atau koneksi direset untuk perintah yang besar Batas buffer Envoy default (32 KiB) terlalu kecil untuk payload AI Lampirkan ClientTrafficPolicy dengan connection.bufferLimit (validasi menggunakan 50 Mi) ke Gateway.
Layanan pembatasan kapasitas Pod adalah CrashLoopBackOff Redis tidak dapat dijangkau di URL yang dikonfigurasi kubectl get service redis --namespace="${GDCS_REDIS_NAMESPACE}"; perbaiki rateLimit.backend.redis.url di file nilai integrasi dan upgrade lagi.

Materi tambahan