Deploy your first gateway
This page deploys one model, puts a single-scheduler gateway in front of it, and sends the first completion through it. Start here before adding a second model.
Overview
You will:
- Deploy
Qwen/Qwen2.5-1.5B-Instructusing the HyperPod inference operator - Create an
InferenceGatewayConfigwith one scheduler and BBR disabled - Resolve the in-cluster gateway URL and send a completion request
At this stage there is only one model pool and one replica, so no routing decision is actually being made. That is intentional — it establishes a working baseline that later pages build on.
1. Deploy the model backend
1.1 Create the InferenceEndpointConfig
The inference operator deploys models through the InferenceEndpointConfig resource. Create one for the 1.5B model:
cat <<EOF > vllm-qwen-operator.yaml
apiVersion: inference.sagemaker.aws.amazon.com/v1
kind: InferenceEndpointConfig
metadata:
name: vllm-qwen
namespace: ${MODEL_NS}
spec:
modelName: vllm-qwen
replicas: 1
modelSourceConfig:
modelSourceType: huggingface
huggingFaceModel:
modelId: Qwen/Qwen2.5-1.5B-Instruct
worker:
image: vllm/vllm-openai:v0.8.5
modelInvocationPort:
containerPort: 8000
name: http
modelVolumeMount:
name: model-volume
mountPath: /opt/ml/model
resources:
limits:
nvidia.com/gpu: "1"
requests:
nvidia.com/gpu: "1"
args:
- "--model"
- "Qwen/Qwen2.5-1.5B-Instruct"
- "--port"
- "8000"
- "--max-model-len"
- "4096"
- "--gpu-memory-utilization"
- "0.4"
EOF
Two details in this manifest matter later:
metadata.namedrives the pod label. The operator labels its podsapp=<metadata.name>, which is what the gateway'smodelSelectormatches. Naming this resourcevllm-qwenproducesapp=vllm-qwen.- The model id is passed in
args. FormodelSourceType: huggingface, the operator does not pre-populatemodelVolumeMount, so vLLM downloads the weights itself.
1.2 Deploy and wait
kubectl apply -f vllm-qwen-operator.yaml
kubectl rollout status deploy/vllm-qwen -n "${MODEL_NS}" --timeout=600s
Loading a 1.5B model takes a few minutes. Watch the pod become ready:
kubectl get pods -n "${MODEL_NS}" -w
Expected output once ready:
NAME READY STATUS RESTARTS AGE
vllm-qwen-68c5644b78-r8cnl 3/3 Running 0 2m
The pod reports 3/3 because the operator injects two sidecars — sidecar-reverse-proxy and otel-collector — alongside your model container. The operator also generates a readiness probe on /ping:8000, so READY is a trustworthy signal that vLLM is actually serving.
1.3 Confirm the pod label
The gateway finds backends by label, so verify it before wiring the gateway:
kubectl get pods -n "${MODEL_NS}" -l app=vllm-qwen \
--show-labels --no-headers
Expected output:
vllm-qwen-68c5644b78-r8cnl 3/3 Running 0 2m app=vllm-qwen,deploying-service=hyperpod-inference,pod-template-hash=68c5644b78
2. Create the gateway
2.1 Define a single-scheduler config
cat <<EOF > gateway-single.yaml
apiVersion: inference.sagemaker.aws.amazon.com/v1alpha1
kind: InferenceGatewayConfig
metadata:
name: ${GATEWAY_NAME}
namespace: ${MODEL_NS}
spec:
bbr:
enabled: false
schedulers:
- name: qwen
modelName: "Qwen/Qwen2.5-1.5B-Instruct"
modelSelector:
matchLabels:
app: vllm-qwen
targetPort: 8000
scheduler: llm-d
EOF
kubectl apply -f gateway-single.yaml
The scheduler field selects the endpoint-picker implementation, either llm-d or epp. BBR stays disabled here because there is only one scheduler.
2.2 Wait for the gateway to become ready
kubectl get inferencegatewayconfig "${GATEWAY_NAME}" -n "${MODEL_NS}" \
-o "custom-columns=NAME:.metadata.name,CONDITIONS:.status.conditions[*].status"
Expected output, once all conditions are satisfied:
NAME CONDITIONS
inference-gateway-demo True,True,True,True,False
To see which condition is which:
kubectl get inferencegatewayconfig "${GATEWAY_NAME}" -n "${MODEL_NS}" \
-o jsonpath='{range .status.conditions[*]}{.type}={.status}{"\n"}{end}'
Expected output:
Accepted=True
Ready=True
GatewayProgrammed=True
BBRReady=True
AdmissionBlocked=False
3. Send your first request
3.1 Resolve the in-cluster gateway URL
The controller creates an Envoy service whose name includes a generated suffix, so look it up by label rather than hardcoding it:
SVC=$(kubectl get svc -n "${SYSTEM_NS}" \
-l gateway.envoyproxy.io/owning-gateway-name="${GATEWAY_NAME}" \
-o jsonpath='{.items[0].metadata.name}')
export GW="http://${SVC}.${SYSTEM_NS}.svc.cluster.local"
echo "${GW}"
Expected output:
http://envoy-hyperpod-inference-system-inference-gateway-demo-de027949.hyperpod-inference-system.svc.cluster.local
3.2 Invoke the model
Send the request from a pod inside the cluster:
kubectl run curl-invoke --rm -i --restart=Never \
--image=curlimages/curl:8.10.1 -n "${MODEL_NS}" -- \
curl -sS -w '\nHTTP %{http_code}\n' --max-time 60 \
-X POST "${GW}/v1/completions" \
-H 'Content-Type: application/json' \
-d '{"model":"Qwen/Qwen2.5-1.5B-Instruct","prompt":"What is SageMaker HyperPod?","max_tokens":20,"temperature":0}'
Expected output:
{"id":"cmpl-3a1cb58a-0c94-42e7-bbf8-36562f0f40b3","object":"text_completion","created":1788380097,"model":"Qwen/Qwen2.5-1.5B-Instruct","choices":[{"index":0,"text":" It is a fully managed service that makes it easy to train","logprobs":null,"finish_reason":"length","stop_reason":null,"prompt_logprobs":null}],"usage":{"prompt_tokens":6,"total_tokens":26,"completion_tokens":20}}
HTTP 200
Run curl from a pod inside the cluster. The .svc.cluster.local name will not resolve from your laptop. The gateway also provisions internal load balancers, which are reachable only from inside the VPC.
Validation
You have completed this page when:
- The
InferenceEndpointConfigpod is3/3 Runningwith the labelapp=vllm-qwen Accepted,Ready, andGatewayProgrammedare allTrue- A POST to
/v1/completionsreturns HTTP 200 with a completion
Next steps
Continue to Inspect the gateway to see every resource the controller created on your behalf.