Geauthenticeerde gRPC-service op Kubernetes
Gebouwd voor snelheid: ~10ms latentie, zelfs onder belasting
De razendsnelle manier om je modellen te bouwen, volgen en implementeren!
- Verwerkt 350+ RPS op slechts 1 vCPU — geen tuning nodig
- Productieklaar met volledige enterprise-ondersteuning
In onze blogreeks over Kubernetes hebben we het gehad over het bouwen van schaalbare MLOps op Kubernetes, architectuur voor MLOps en het oplossen van applicatieontwikkeling. In deze blog bespreken we het hosten van een gRPC-service op een AWS EKS-cluster. Het proces is in grote lijnen hetzelfde voor elk Kubernetes-cluster — we moesten echter enkele specifieke instellingen op de AWS Load Balancer toepassen om dit te laten werken.
Wat is gRPC & onze usecase
gRPC is een open-source RPC-framework dat in elke omgeving kan draaien. Het is in staat om services binnen en tussen datacenters efficiënt met elkaar te verbinden, met ondersteuning voor load balancing, tracing, health checking en authenticatie.
Onze usecase: Het hosten van TensorFlow-modellen als API's die een payload van ongeveer 100MB verwerkten. gRPC presteert veel beter bij grotere payloads — dus hebben we de gRPC-poort exposed op poort 5000.
De service hosten
We hebben de service op Kubernetes gehost met behulp van de onderstaande Deployment YAML:
apiVersion: apps/v1
kind: Deployment
metadata:
name: ml-api
namespace: ml-services
spec:
replicas: 1
selector:
matchLabels:
truefoundry.com/component: ml-api
template:
metadata:
labels:
truefoundry.com/application: ml-api
spec:
containers:
- name: ml-api
image: >-
XXXX.dkr.ecr.us-east-1.amazonaws.com/ml-services-ml-api:latest
ports:
- name: port-8500
containerPort: 8500
protocol: TCP
resources:
limits:
cpu: '4'
ephemeral-storage: 2G
memory: 4G
requests:
cpu: '1'
ephemeral-storage: 1G
memory: 500M
imagePullPolicy: IfNotPresent
restartPolicy: Always
terminationGracePeriodSeconds: 30
dnsPolicy: ClusterFirst
securityContext: {}
imagePullSecrets:
- name: ml-api-image-pull-secret
schedulerName: default-scheduler
strategy:
type: RollingUpdate
rollingUpdate:
maxUnavailable: 25%
maxSurge: 0
Dit brengt de pod in de lucht. Vervolgens moeten we het Service-object aanmaken met de onderstaande YAML:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
labels:
argocd.argoproj.io/instance: tfy-istio-ingress
name: tfy-wildcard
namespace: istio-system
spec:
selector:
istio: tfy-istio-ingress
servers:
- hosts:
- 'ml.example.com'
port:
name: http-tfy-wildcard
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- 'ml.example.com'
port:
name: https-tfy-wildcard
number: 443
protocol: HTTP
De service exposen
We gebruiken Istio als de ingress-laag in Kubernetes. Istio provisiont een Load Balancer wanneer de istio-ingress wordt geïnstalleerd. De configuratie van de load balancer kan worden aangepast met behulp van annotaties op de Istio Gateway. De spec voor het aanmaken van de Istio Gateway is als volgt:
apiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
labels:
argocd.argoproj.io/instance: tfy-istio-ingress
name: tfy-wildcard
namespace: istio-system
spec:
selector:
istio: tfy-istio-ingress
servers:
- hosts:
- 'ml.example.com'
port:
name: http-tfy-wildcard
number: 80
protocol: HTTP
tls:
httpsRedirect: true
- hosts:
- 'ml.example.com'
port:
name: https-tfy-wildcard
number: 443
protocol: HTTP
We voeren de SSL-terminatie uit op de AWS Load Balancer. Hiervoor moeten we het certificaat aan de Load Balancer koppelen. Dit kan worden bereikt door de onderstaande annotaties toe te voegen aan de istio gateway chart (https://istio-release.storage.googleapis.com/charts).
"service.beta.kubernetes.io/aws-load-balancer-type": "nlb"
"service.beta.kubernetes.io/aws-load-balancer-backend-protocol": "tcp"
"service.beta.kubernetes.io/aws-load-balancer-ssl-cert": "<certificate-arn>"
"service.beta.kubernetes.io/aws-load-balancer-ssl-ports": "https"
"service.beta.kubernetes.io/aws-load-balancer-alpn-policy": "HTTP2Preferred"
Het alpn-policy is belangrijk om op te geven om gRPC-verkeer toe te staan. Onze service ml-api kan worden exposed door een VirtualService aan te maken die verwijst naar de Kubernetes-service. De YAML voor de VirtualService is als volgt:
apiVersion: networking.istio.io/v1alpha3
kind: VirtualService
metadata:
labels:
argocd.argoproj.io/instance: ml-services_ml-api
name: ml-apiport-8500-vs
namespace: ml-services
spec:
gateways:
- istio-system/tfy-wildcard
hosts:
- ml.example.com
http:
- route:
- destination:
host: ml-api
port:
number: 8500
Zodra de VirtualService is exposed, kunnen we requests doen naar onze service op ml.example.com. Vervolgens wilden we authenticatie toevoegen aan de API, zodat niet iedereen de API kan aanroepen. We hadden de authenticatie in de code kunnen toevoegen, maar we hebben ervoor gekozen om deze op de Istio-laag toe te voegen, zodat het een uniforme laag vormt voor alle services.
Om authenticatie toe te voegen op de istio-ingress-laag, hebben we gekozen voor een IstioWasm Plugin. De YAML voor de plugin ziet er ongeveer zo uit:
apiVersion: extensions.istio.io/v1alpha1
kind: WasmPlugin
metadata:
name: ml-services-ml-api-0
namespace: istio-system
spec:
phase: AUTHN
pluginConfig:
basic_auth_rules:
- credentials:
- username:password
hosts:
- ml.example.com
prefix: /
request_methods:
- GET
- PUT
- POST
- PATCH
- DELETE
selector:
matchLabels:
istio: tfy-istio-ingress
url: oci://ghcr.io/istio-ecosystem/wasm-extensions/basic_auth:1.12.0
Zodra je de bovenstaande spec op het cluster hebt toegepast, vraagt de app om de gebruikersnaam en het wachtwoord zodra je deze in de browser opent.
We hebben het supersimpel gemaakt op TrueFoundry
Om het bovenstaande proces veel eenvoudiger te maken, hebben we besloten het heel gemakkelijk te maken op het TrueFoundry-platform.

TrueFoundry AI Gateway levert een latentie van ~3–4 ms, verwerkt 350+ RPS op 1 vCPU, schaalt moeiteloos horizontaal en is klaar voor productie, terwijl LiteLLM last heeft van hoge latentie, moeite heeft boven een gemiddeld aantal RPS, geen ingebouwde schaling heeft en het meest geschikt is voor lichte workloads of prototypes.



















.png)

.webp)



.webp)








.webp)





