For the complete documentation index, see llms.txt. Markdown versions of all docs pages are available by appending .md to any docs URL.
AWS EC2
Route traffic directly to AWS EC2 instances that the gateway proxy discovers dynamically by using tag-based filters. Endpoints are refreshed periodically and served to Envoy through EDS (Endpoint Discovery Service), so your routing stays up to date as instances start and stop.
Before you begin
-
Follow the Get started guide to install kgateway.
-
Follow the Sample app guide to create a gateway proxy with an HTTP listener and deploy the httpbin sample app.
-
Get the external address of the gateway and save it in an environment variable.
export INGRESS_GW_ADDRESS=$(kubectl get svc -n kgateway-system http -o jsonpath="{.status.loadBalancer.ingress[0]['hostname','ip']}") echo $INGRESS_GW_ADDRESS
Step 1: Enable EC2 discovery
Enable EC2 discovery by setting the controller.enableAwsEc2Discovery Helm value to true in your kgateway Helm chart.
-
Optional: Get the values of your current installation.
helm get values kgateway -n kgateway-system -o yaml > values.yaml open values.yaml -
Enable EC2 discovery by setting the
controller.enableAwsEc2DiscoveryHelm value totrue. The--reuse-valuessetting re-applies any Helm values that you previously set.helm upgrade -i kgateway oci://cr.kgateway.dev/kgateway-dev/charts/kgateway \ --namespace kgateway-system \ --reuse-values \ --version v2.4.0-main \ --set controller.enableAwsEc2Discovery=true -
Verify that the control plane pods are up and running.
kubectl get pods -n kgateway-system
Step 2: Create an AWS EC2 instance
-
Follow the AWS documentation to launch an EC2 instance with the following settings:
- Use an Amazon Linux image.
- Allow inbound HTTP traffic on port 80 in the instance’s security group.
- Add at least one tag that you later use to discover the instance, for example
app: payments. - Create a key file so that you can later connect to your instance by using SSH.
-
Save the AWS region that your EC2 instance is created in as an environment variable. Make sure to use the region name (for example,
us-east-1), not an availability zone (for example,us-east-1b).export AWS_REGION=<aws-region> -
Start an HTTP server on the EC2 instance. You can use the HTTP server that is built into Python by default.
sudo python3 -m http.server 80 & -
Verify that you can send requests to the local HTTP server.
curl http://localhost/Example output:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".bash_logout">.bash_logout</a></li> <li><a href=".bash_profile">.bash_profile</a></li> <li><a href=".bashrc">.bashrc</a></li> <li><a href=".ssh/">.ssh/</a></li> </ul> <hr> </body> </html>
Step 3: Configure AWS credentials
For the gateway proxy to discover and route traffic to the EC2 instance, you must configure the proxy with the required AWS credentials. You can choose between the following authentication methods:
- Static AWS credentials: Store your AWS access key ID and secret access key in a Kubernetes secret.
- Role assumption: Configure an IAM role that the gateway proxy assumes to get temporary credentials.
For static credentials, the IAM user must have at least ec2:DescribeInstances permissions. For role assumption, the IAM user must have sts:AssumeRole permissions and the role must have at least ec2:DescribeInstances permissions.
Use this method when your IAM user and EC2 instances are in the same AWS account and you want a simple setup. The ec2:DescribeInstances permission is attached directly to your IAM user, and the gateway proxy uses those credentials as-is to discover EC2 instances.
-
Create the policy document and save the ARN in an environment variable. At a minimum, you must assign the
ec2:DescribeInstancespermission.export POLICY_ARN=$(aws iam create-policy \ --policy-name kgateway-ec2-discovery \ --policy-document '{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ec2:DescribeInstances", "Resource": "*" } ] }' \ --query 'Policy.Arn' \ --output text) echo $POLICY_ARN -
Get your IAM username and attach the policy directly to your IAM user.
export AWS_ACCOUNT_ID=$(aws sts get-caller-identity --query Account --output text) export IAM_USERNAME=$(aws sts get-caller-identity --query 'Arn' --output text | cut -d'/' -f2) aws iam attach-user-policy \ --user-name ${IAM_USERNAME} \ --policy-arn $POLICY_ARN -
Create permanent AWS credentials for your user.
eval $(aws iam create-access-key --user-name ${IAM_USERNAME} \ --query 'AccessKey.[AccessKeyId,SecretAccessKey]' \ --output text | \ awk '{print "export AWS_ACCESS_KEY_ID="$1"\nexport AWS_SECRET_ACCESS_KEY="$2}') echo "AWS_ACCESS_KEY_ID $AWS_ACCESS_KEY_ID" echo "AWS_SECRET_ACCESS_KEY $AWS_SECRET_ACCESS_KEY" -
Create a Kubernetes secret that holds the credentials.
kubectl apply -n kgateway-system -f - <<EOF apiVersion: v1 kind: Secret metadata: name: aws-creds type: Opaque stringData: accessKey: "${AWS_ACCESS_KEY_ID}" secretKey: "${AWS_SECRET_ACCESS_KEY}" EOF
Step 4: Set up EC2 routing
Create a Backend resource that represents your EC2 instance and an HTTPRoute to route requests to it.
-
Create a Backend resource that represents the EC2 instance. Set the tag that you added to your EC2 instance earlier in the
ec2.filtersfield so that the gateway proxy can discover the instance. You can also choose to route traffic to the instance’s public or private IP address by using theaddressTypefield. Note that if you choose a private address, your cluster must be in the same private network as the EC2 instance, such as in the same VPC.kubectl apply -n kgateway-system -f - <<EOF apiVersion: gateway.kgateway.dev/v1alpha1 kind: Backend metadata: name: ec2-backend spec: type: AWS aws: region: ${AWS_REGION} auth: type: Secret secretRef: name: aws-creds ec2: port: 80 addressType: PublicIP filters: - keyValue: key: app value: payments EOFField Description ec2.portThe port on the EC2 instance to route to. ec2.addressTypePublicIPto route to the public IP address;PrivateIPto route to the private IP address.ec2.roleArnThe ARN of the IAM role to assume before listing instances. Required only when using role assumption. ec2.filtersTag-based filters to select EC2 instances. Only running instances that match all filters are included as endpoints. -
Create an HTTPRoute resource that references the
ec2-backendBackend.kubectl apply -n kgateway-system -f - <<EOF apiVersion: gateway.networking.k8s.io/v1 kind: HTTPRoute metadata: name: ec2-route spec: parentRefs: - name: http namespace: kgateway-system hostnames: - ec2.example rules: - matches: - path: type: PathPrefix value: / backendRefs: - name: ec2-backend group: gateway.kgateway.dev kind: Backend EOF -
Verify that the Backend endpoint is discovered. The gateway proxy periodically calls
ec2:DescribeInstancesto refresh the list of running instances that match your filters.kubectl get backend ec2-backend -n kgateway-system -o yaml -
Send a request to the EC2 instance through the gateway proxy. Verify that the output equals the output that you saw earlier when you sent a request to the EC2 directly.
curl http://$INGRESS_GW_ADDRESS:8080/ -H "host: ec2.example"Example output:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8"> <title>Directory listing for /</title> </head> <body> <h1>Directory listing for /</h1> <hr> <ul> <li><a href=".bash_logout">.bash_logout</a></li> <li><a href=".bash_profile">.bash_profile</a></li> <li><a href=".bashrc">.bashrc</a></li> <li><a href=".ssh/">.ssh/</a></li> </ul> <hr> </body> </html>
Cleanup
You can remove the resources that you created in this guide.
-
Delete the HTTPRoute and Backend.
kubectl delete httproute ec2-route -n kgateway-system kubectl delete backend ec2-backend -n kgateway-system -
Delete the AWS credentials secret.
kubectl delete secret aws-creds -n kgateway-system -
Clean up the AWS IAM resources.
aws iam detach-user-policy --user-name ${IAM_USERNAME} --policy-arn ${POLICY_ARN} aws iam delete-policy --policy-arn ${POLICY_ARN} -
Terminate the EC2 instance from the AWS console.