HTTP/3 with Amazon Elastic Kubernetes Service (EKS)
Amazon Elastic Kubernetes Service HTTP/3 configuration
This guide shows how to setup HTTP/3 support for Amazon Elastic Kubernetes Service (EKS) The instructions provided in this page are a continuation of the HTTP/3 in Emissary documentation.
Create a network load balancer (NLB)
The virtual private cloud (VPC) for your load balancer needs one public subnet in each availability zone where you have targets.
SUBNET_IDS=(<your-subnet1-id> <your-subnet2-id> <your-subnet3-id>)
aws elbv2 create-load-balancer \
--name ${CLUSTER_NAME}-nlb \
--type network \
--subnets ${SUBNET_IDS}
Create a NodePort service
Now create a NodePort
service for Emissary installation with two entries. Use port: 443
to include support for both TCP and UDP traffic.
# Selectors and labels removed for clarity.
apiVersion: v1
kind: Service
metadata:
name: $productDeploymentName$-http3
namespace: $productNamespace$
spec:
type: NodePort
ports:
- name: http
port: 80
targetPort: 8080
protocol: TCP
nodePort: 30080
- name: https
port: 443
targetPort: 8443
protocol: TCP
nodePort: 30443
- name: http3
port: 443
targetPort: 8443
protocol: UDP
nodePort: 30443
Create target groups
Run the following command with the variables for your VPC ID and cluster name:
VPC_ID=<your-vpc-id>
CLUSTER_NAME=<your-cluster-name>
aws elbv2 create-target-group --name ${CLUSTER_NAME}-tcp-tg \
--protocol TCP --port 30080 --vpc-id ${VPC_ID} \
--health-check-protocol TCP \
--health-check-port 30080 \
--target-type instance
aws elbv2 create-target-group --name ${CLUSTER_NAME}-tcp-udp-tg \
--protocol TCP_UDP --port 30443 --vpc-id ${VPC_ID} \
--health-check-protocol TCP \
--health-check-port 30443 \
--target-type instance
Register your instances
Next, register your cluster’s instance with the the instance IDs and Amazon Resource Names (ARN).
To get your cluster’s instance IDs, enter the following command:
aws ec2 describe-instances \
--filters Name=tag:eks:cluster-name,Values=${CLUSTER_NAME} \
--output text
--query 'Reservations[*].Instances[*].InstanceId' \
To get your ARNs, enter the following command:
TCP_TG_NAME=${CLUSTER_NAME}-tcp-tg-name
TCP_UDP_TG_NAME=${CLUSTER_NAME}-tcp-udp-tg-name
aws elbv2 describe-target-groups \
--query 'TargetGroups[?TargetGroupName==`'${TCP_TG_NAME}'`].TargetGroupArn' \
--output text
aws elbv2 describe-target-groups \
--query 'TargetGroups[?TargetGroupName==`'${TCP_UDP_TG_NAME}'`]. TargetGroupArn' \
--output text
Register the instances with the target groups and load balancer using the instance IDs and ARNs you retrieved.
INSTANCE_IDS=(<Id=i-07826...> <Id=i-082fd...>)
REGION=<your-region>
TG_NAME=<your-tg-name>
TCP_TG_ARN=arn:aws:elasticloadbalancing:${REGION}:079.....:targetgroup/${TG_NAME}/...
TCP_UDP_TG_ARN=arn:aws:elasticloadbalancing:${REGION}:079.....:targetgroup/${TG_NAME}/...
aws elbv2 register-targets --target-group-arn ${TCP_TG_ARN} --targets ${INSTANCE_IDS}
aws elbv2 register-targets --target-group-arn ${TCP_UDP_TG_ARN} --targets ${INSTANCE_IDS}
Create listeners in AWS.
Register your cluster’s instance with the instance IDs and ARNs.
To get the load balancer’s ARN, enter the following command:
aws elbv2 describe-load-balancers --name ${CLUSTER_NAME}-nlb \
--query 'LoadBalancers[0].LoadBalancerArn' \
--output text
Create a TCP listener on port 80 that that forwards to the TargetGroup {TCP_TG_ARN}.
aws elbv2 create-listener --load-balancer-arn ${LB_ARN} \
--protocol TCP --port 80 \
--default-actions Type=forward,TargetGroupArn=${TCP_TG_ARN}
Create a TCP_UDP listener on port 443 that forwards to the TargetGroup {TCP_UDP_TG_ARN}.
aws elbv2 create-listener --load-balancer-arn ${LB_ARN} \
--protocol TCP_UDP --port 443 \
--default-actions Type=forward,TargetGroupArn=${TCP_UDP_TG_ARN}
Update the security groups
Now you need to update your security groups to receive traffic. This security group covers all node groups attached to the EKS cluster:
aws eks describe-cluster --name ${CLUSTER_NAME} | grep clusterSecurityGroupId
Now authorize the cluster security group to allow internet traffic:
for x in ${CLUSTER_SG}; do \
aws ec2 authorize-security-group-ingress --group-id $$x --protocol tcp --port 30080 --cidr 0.0.0.0/0; \
aws ec2 authorize-security-group-ingress --group-id $$x --protocol tcp --port 30443 --cidr 0.0.0.0/0; \
aws ec2 authorize-security-group-ingress --group-id $$x --protocol udp --port 30443 --cidr 0.0.0.0/0; \
done
Get the DNS name for the load balancers
Enter the following command to get the DNS name for your load balancers and create a CNAME record at your domain provider:
aws elbv2 describe-load-balancers --name ${CLUSTER_NAME}-nlb \
--query 'LoadBalancers[0].DNSName' \
--output text
Create Listener resources
Now you need to create the Listener
resources for Emissary. The first Listener
in the example below handles traffic for HTTP/1.1 and HTTP/2, while the second Listener
handles all HTTP/3 traffic.
kubectl apply -f - <<EOF
# This is a standard Listener that leverages TCP to serve HTTP/2 and HTTP/1.1 traffic.
# It is bound to the same address and port (0.0.0.0:8443) as the UDP listener.
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
name: $productDeploymentName$-https-listener
namespace: $productNamespace$
spec:
port: 8443
protocol: HTTPS
securityModel: XFP
hostBinding:
namespace:
from: ALL
---
# This is a Listener that leverages UDP and HTTP to serve HTTP/3 traffic.
# NOTE: Raw UDP traffic is not supported. UDP and HTTP must be used together.
apiVersion: getambassador.io/v3alpha1
kind: Listener
metadata:
name: $productDeploymentName$-https-listener-udp
namespace: $productNamespace$
spec:
port: 8443
# Order is important here. UDP must be last item. HTTP is required.
protocolStack:
- TLS
- HTTP
- UDP
securityModel: XFP
hostBinding:
namespace:
from: ALL
EOF
Create a Host resource
Create a Host
resource for your domain name.
kubectl apply -f - <<EOF
apiVersion: getambassador.io/v3alpha1
kind: Host
metadata:
name: $productDeploymentName$-aws-host
namespace: $productNamespace$
spec:
hostname: <your-hostname>
acmeProvider:
authority: none
tlsSecret:
name: tls-cert # The QUIC network protocol requires TLS with a valid certificate
tls:
min_tls_version: v1.3
max_tls_version: v1.3
alpn_protocols: h2,http/1.1
EOF
Apply the quote service and a Mapping to test the HTTP/3 configuration.
Finally, apply the quote service to a Emissary Mapping
.
kubectl apply -f https://app.getambassador.io/yaml/v2-docs/$version$/quickstart/qotm.yaml
kubectl apply -f - <<EOF
---
apiVersion: getambassador.io/v3alpha1
kind: Mapping
metadata:
name: quote-backend
spec:
hostname: "*"
prefix: /backend/
service: quote
docs:
path: "/.ambassador-internal/openapi-docs"
EOF
Now verify the connection:
$ curl -i http://<your-hostname>/backend/
Your domain now shows that it is being served with HTTP/3.
Feedback
Was this page helpful?
Glad to hear it! Please tell us how we can improve.
Sorry to hear that. Please tell us how we can improve.