How to Deploy a VPC-Only Vultr Kubernetes Engine with NAT Gateway

Updated on 25 June, 2026
Deploy a Vultr Kubernetes Engine cluster with a VPC-only node pool behind a NAT Gateway using the Vultr Console and API, giving nodes private NAT-routed egress.
How to Deploy a VPC-Only Vultr Kubernetes Engine with NAT Gateway header image

Vultr Kubernetes Engine (VKE) is a fully managed Kubernetes service that operates the control plane and worker nodes on your behalf. A VPC-only node pool attaches its worker nodes to a Virtual Private Cloud (VPC) with no public IP address, and routes their outbound traffic through a NAT Gateway attached to that VPC.

This guide explains how to deploy a VKE cluster with a VPC-only node pool backed by a NAT Gateway, using the Vultr Console to provision the network and the Vultr API to create the cluster.

Prerequisites

Before you begin, ensure you:

Create a VPC with a NAT Gateway

Create the VPC network in the Vultr Console before deploying the cluster. The Vultr Console bundles the NAT Gateway into the VPC: selecting the VPC Network with NAT Gateway option provisions a NAT Gateway with the VPC, which provides the outbound path that the VPC-only nodes use to reach the internet.

  1. Log in to the Vultr Console.
  2. Navigate to Network, then click VPC Networks.
  3. Click Create VPC Network.
  4. Select the VPC Network with NAT Gateway option.
  5. Enter a name for the VPC network in the Name field.
  6. Select the location where you intend to deploy the cluster.
  7. Click Create VPC Network.

After the VPC provisions, open it from the VPC Networks list to view its details. The detail page reports the Gateway as a NAT Gateway and lists a NAT Gateway IP Address, which is the outbound address for the VPC-only nodes. Note the VPC UUID for use as the VPC ID in the API request.

Deploy the VKE Cluster with a VPC-Only Node Pool

Create the VKE cluster with the Vultr API and attach it to the VPC you created.

  1. Export your API key as an environment variable.

    console
    $ export VULTR_API_KEY="YOUR_API_KEY"
    

    Replace YOUR_API_KEY with your Vultr API key.

  2. Send a GET request to the List Regions endpoint and note the ID of the region that matches your VPC.

    console
    $ curl "https://api.vultr.com/v2/regions" \
        -X GET \
        -H "Authorization: Bearer ${VULTR_API_KEY}" | jq '.regions[] | {id, city}'
    

    The output lists each region with its id and city.

  3. Send a GET request to the List Available Plans in Region endpoint and note a plan to use for the node pool. Replace REGION-ID with your target region.

    console
    $ curl "https://api.vultr.com/v2/regions/REGION-ID/availability" \
        -X GET \
        -H "Authorization: Bearer ${VULTR_API_KEY}" | jq '.available_plans'
    

    The output lists the plan IDs available in that region.

  4. Send a GET request to the Get Kubernetes Versions endpoint and note your target version.

    console
    $ curl "https://api.vultr.com/v2/kubernetes/versions" \
        -X GET \
        -H "Authorization: Bearer ${VULTR_API_KEY}"
    

    The output lists the supported Kubernetes versions.

  5. Send a POST request to the Create Kubernetes Cluster endpoint with vpc_only set to true and the VPC ID that has the NAT Gateway.

    console
    $ curl "https://api.vultr.com/v2/kubernetes/clusters" \
        -X POST \
        -H "Authorization: Bearer ${VULTR_API_KEY}" \
        -H "Content-Type: application/json" \
        --data '{
            "label": "CLUSTER-LABEL",
            "region": "REGION-ID",
            "version": "KUBERNETES-VERSION",
            "vpc_id": "VPC-ID",
            "node_pools": [
                {
                    "node_quantity": 3,
                    "label": "NODE-LABEL",
                    "plan": "NODE-PLAN",
                    "vpc_only": true
                }
            ]
        }'
    

    Replace:

    • CLUSTER-LABEL: A name for the cluster.
    • REGION-ID: The region that matches your VPC and NAT Gateway, such as ewr.
    • KUBERNETES-VERSION: A version from the previous step, such as v1.36.1+1.
    • VPC-ID: The ID of the VPC that has the NAT Gateway.
    • NODE-LABEL: A label for the node pool.
    • NODE-PLAN: A plan with a minimum cost of $10, such as vc2-4c-8gb.
    Note
    Omitting vpc_id while vpc_only is true instructs VKE to provision a new VPC and NAT Gateway automatically. Supplying an existing vpc_id requires that VPC to already have an active NAT Gateway, otherwise the request fails with a 422 error.

    The response returns the new cluster, including its id. Note this value to use as the cluster ID in later steps.

  6. Send a GET request to confirm the cluster reaches an active state.

    console
    $ curl "https://api.vultr.com/v2/kubernetes/clusters" \
        -X GET \
        -H "Authorization: Bearer ${VULTR_API_KEY}"
    

    The output displays the cluster with its node pool, and each node reports vpc_only as true.

Verify the Deployment

A VPC-only node has no public IP, so every request it makes to the internet exits through the NAT Gateway and carries the NAT Gateway public IP as its source address. Run a request from inside the cluster and match the returned address to the NAT Gateway IP to confirm the routing.

  1. Note the NAT Gateway IP address from the Vultr Console. Navigate to Network, click VPC Networks, then select the VPC you created. The NAT Gateway IP Address field shows the outbound address for the VPC-only nodes.

  2. Download the cluster's kubeconfig from the Get Kubernetes Cluster Kubeconfig endpoint and save it to a file. Replace VKE-ID with your cluster ID.

    console
    $ curl "https://api.vultr.com/v2/kubernetes/clusters/VKE-ID/config" \
        -X GET \
        -H "Authorization: Bearer ${VULTR_API_KEY}" | jq -r '.kube_config' | base64 -d > vke-config.yaml
    

    The command saves the decoded kubeconfig to vke-config.yaml.

  3. Point kubectl at the downloaded configuration.

    console
    $ export KUBECONFIG=vke-config.yaml
    
  4. List the nodes and confirm they report only private VPC addresses.

    console
    $ kubectl get nodes -o wide
    

    The output lists each node with a private address in the 10.x.x.x range and no public IP address.

  5. Run a temporary pod that requests its public source address from an external service.

    console
    $ kubectl run egress-check --image=curlimages/curl --rm -i --restart=Never --command -- curl -s https://api.ipify.org
    

    The pod schedules on a VPC-only node, sends the request, prints the public source address, then kubectl removes the pod when it completes.

    The address it prints matches the NAT Gateway IP address noted in the first step, which confirms that the nodes have no direct public connectivity and that all outbound traffic routes through the NAT Gateway.

Use Cases

A VPC-only node pool removes the public IP from each worker node and routes outbound traffic through a single NAT Gateway. This network model suits workloads that need controlled connectivity rather than direct public exposure:

  • Internal backend services: Run databases, message queues, caches, and internal APIs that other services reach over private VPC addresses, without exposing them to the public internet.
  • Reduced attack surface: Remove the public network interface from every node so the cluster has no directly reachable public IP, which lowers the exposure available to external scanners and attackers.
  • Regulated and compliance-bound workloads: Keep nodes off the public network to support data-isolation requirements common to standards such as PCI DSS and HIPAA.
  • Predictable outbound IP: Route all node egress through the NAT Gateway public IP, which gives third-party services and partner firewalls a stable address to allowlist.
  • Controlled internet access: Allow nodes to pull container images and reach external services for updates while keeping inbound public access closed by default.
  • Public exposure on demand: Keep workloads private by default, and expose only the services you choose through a load balancer or a NAT Gateway port forwarding rule.

Conclusion

You have successfully deployed a VKE cluster with a VPC-only node pool backed by a NAT Gateway. The worker nodes run without public IP addresses, attach only to the VPC, and reach the internet through the NAT Gateway for outbound traffic such as image pulls. To expose workloads on these nodes to the public internet, pair the cluster with a load balancer or a NAT Gateway port forwarding rule. For more information, visit the official Vultr Kubernetes Engine documentation.

Comments