DEV Community

Leon Nunes
Leon Nunes

Posted on

Let's deploy kgateway using vCluster

Hey folks

Been a while I've decided to once again start writing up some of the things I do, last year was a lot of travelling.

Today I'm going to try installing Vcluster and then deploy Kgateway to it

What exactly is Vcluster?

Taken straight from their docs

vCluster is an open source solution that enables teams to run virtual Kubernetes clusters inside existing infrastructure. It helps platform engineers create secure, isolated environments for development, testing, CI/CD, and even production workloads, without the cost or overhead of managing separate physical clusters.

This sounds fun, what challenges am I trying to solve for myself? Well I work with multiple customers in my day job and while I like creating multiple kind clusters for this it's not really that much fun when I need to switch contexts etc, let's see if I can achieve this with Vcluster.

Their docs are pretty straightforward, so I'm gonna use Helm

helm upgrade --install vcluster-test  cluster \
   --repo https://charts.loft.sh  \
   --namespace products \
   --repository-config='' \
   --create-namespace
Enter fullscreen mode Exit fullscreen mode

Once you run this you should see

Release "vcluster-test" does not exist. Installing it now.
NAME: vcluster-test
LAST DEPLOYED: Thu Jan 29 18:52:02 2026
NAMESPACE: products
STATUS: deployed
REVISION: 1
TEST SUITE: None
Enter fullscreen mode Exit fullscreen mode

Next we will see how to setup something in this namespace, to begin with let's follow the sample guide here

vcluster connect vcluster-test -n products
Enter fullscreen mode Exit fullscreen mode

This shows me

19:57:18 done vCluster is up and running
Forwarding from 127.0.0.1:10078 -> 8443
Forwarding from [::1]:10078 -> 8443
Handling connection for 10078
19:57:19 done Switched active kube context to vcluster_vcluster-test_products_gke
19:57:19 warn Since you are using port-forwarding to connect, you will need to leave this terminal open
- Use CTRL+C to return to your previous kube context
- Use `kubectl get namespaces` in another terminal to access the vcluster
Handling connection for 10078
Enter fullscreen mode Exit fullscreen mode

On another terminal I can now see I have new context with the following namespaces available

kubectl get namespaces
NAME              STATUS   AGE
default           Active   63m
kube-node-lease   Active   63m
kube-public       Active   63m
kube-system       Active   63m
Enter fullscreen mode Exit fullscreen mode

As a user after this the docs doesn't seem to tell me where to go so I was kinda lost for a bit, there's something like deploy a sample app, seems like the notion is that I would use vCluster Platform(Not at the moment), let's go ahead with a sample deployment using helm and see what happens

I'm going to install Kgateway

What is Kgateway?

Kgateway is a control plane that implements the Kubernetes Gateway API for both microservices and AI workloads. The control plane translates your Kubernetes Gateway API resources into the configuration that the underlying data plane proxy can understand. The proxy layer is handled by kgateway’s implementation of Envoy for microservices workloads.

Let's begin with CRD's for Gateway API

$ kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.0/standard-install.yaml
Warning: unrecognized format "int64"
Warning: unrecognized format "int32"
customresourcedefinition.apiextensions.k8s.io/backendtlspolicies.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gatewayclasses.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/gateways.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/grpcroutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/httproutes.gateway.networking.k8s.io created
customresourcedefinition.apiextensions.k8s.io/referencegrants.gateway.networking.k8s.io created
Enter fullscreen mode Exit fullscreen mode

Then our CRD's for Kgateway

$ helm upgrade -i --create-namespace \
--namespace kgateway-system \
--version 2.1.0 enterprise-kgateway-crds oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/enterprise-kgateway-crds

NAME: enterprise-kgateway-crds
LAST DEPLOYED: Thu Jan 29 20:11:51 2026
NAMESPACE: kgateway-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing the enterprise-kgateway-crds chart.
Enter fullscreen mode Exit fullscreen mode

Then the Kgateway Installation

$ helm upgrade -i enterprise-kgateway oci://us-docker.pkg.dev/solo-public/enterprise-kgateway/charts/enterprise-kgateway    -n kgateway-system    --version 2.1.0    --set licensing.licenseKey=$GQ --create-namespace
Release "enterprise-kgateway" does not exist. Installing it now.
NAME: enterprise-kgateway
LAST DEPLOYED: Thu Jan 29 20:06:10 2026
NAMESPACE: kgateway-system
STATUS: deployed
REVISION: 1
TEST SUITE: None
NOTES:
Thank you for installing the enterprise-kgateway chart.
Enter fullscreen mode Exit fullscreen mode

Alright we have kgateway up and running now

Lets deploy the sample app

Then we can go ahead and create the Gateway

kubectl apply -f- <<EOF
kind: Gateway
apiVersion: gateway.networking.k8s.io/v1
metadata:
  name: http
  namespace: kgateway-system
spec:
  gatewayClassName: enterprise-kgateway
  listeners:
  - protocol: HTTP
    port: 8080
    name: http
    allowedRoutes:
      namespaces:
        from: All
EOF
Enter fullscreen mode Exit fullscreen mode

And that works

kubectl get gateway http -n kgateway-system
NAME   CLASS                 ADDRESS   PROGRAMMED   AGE
http   enterprise-kgateway             True         11s
Enter fullscreen mode Exit fullscreen mode

Let's expose this app on the Cluster

kubectl apply -f- <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
  name: httpbin
  namespace: httpbin
spec:
  parentRefs:
    - name: http
      namespace: kgateway-system
  hostnames:
    - "www.example.com"
  rules:
    - backendRefs:
        - name: httpbin
          port: 8000
EOF
Enter fullscreen mode Exit fullscreen mode

And now the final part sending a request

curl -i localhost:8080/headers -H "host: www.example.com"
HTTP/1.1 200 OK
access-control-allow-credentials: true
access-control-allow-origin: *
content-type: application/json; encoding=utf-8
date: Thu, 29 Jan 2026 14:49:30 GMT
content-length: 442
x-envoy-upstream-service-time: 3
server: envoy

{
  "headers": {
    "Accept": [
      "*/*"
    ],
    "Host": [
      "www.example.com"
    ],
    "User-Agent": [
      "curl/8.18.0"
    ],
    "X-Envoy-Expected-Rq-Timeout-Ms": [
      "15000"
    ],
    "X-Envoy-External-Address": [
      "127.0.0.1"
    ],
    "X-Forwarded-For": [
      "10.124.3.10"
    ],
    "X-Forwarded-Proto": [
      "http"
    ],
    "X-Request-Id": [
      "c6575a96-59ba-4c7b-a433-beca541d6501"
    ]
  }
}
Enter fullscreen mode Exit fullscreen mode

Note: I had to setup port-forwarding, ideally I think there's some settings to let the platform manage the LB IP handling but I need to check that

That's it for this post, gotta try some more fun stuff with this now, maybe ArgoCD deployments and deploying Kgateway there

Top comments (0)