CONTROL_PLANE_DETAILS=$(curl -X POST "https://us.api.konghq.com/v2/control-planes" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"name": "My KIC CP",
"cluster_type": "CLUSTER_TYPE_K8S_INGRESS_CONTROLLER"
}'
)Redirect HTTP to HTTPS
Configure an ExternalName service, then create an HTTPRoute to route traffic to the service.
Prerequisites
Kong Konnect
If you don’t have a Konnect account, you can get started quickly with our onboarding wizard.
- The following Konnect items are required to complete this tutorial:
- Personal access token (PAT): Create a new personal access token by opening the Konnect PAT page and selecting Generate Token.
-
Set the personal access token as an environment variable:
export KONNECT_TOKEN='YOUR KONNECT TOKEN'Copied!
Enable the Gateway API
-
Install the Gateway API CRDs before installing Kong Ingress Controller.
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.4.1/standard-install.yamlCopied! -
Create a
GatewayandGatewayClassinstance to use.echo " apiVersion: v1 kind: Namespace metadata: name: kong --- apiVersion: gateway.networking.k8s.io/v1 kind: GatewayClass metadata: name: kong annotations: konghq.com/gatewayclass-unmanaged: 'true' spec: controllerName: konghq.com/kic-gateway-controller --- apiVersion: gateway.networking.k8s.io/v1 kind: Gateway metadata: name: kong spec: gatewayClassName: kong listeners: - name: proxy port: 80 protocol: HTTP allowedRoutes: namespaces: from: All " | kubectl apply -n kong -f -Copied!
Create a KIC Control Plane
Use the Konnect API to create a new CLUSTER_TYPE_K8S_INGRESS_CONTROLLER Control Plane:
We’ll need the id and telemetry_endpoint for the values.yaml file later. Save them as environment variables:
CONTROL_PLANE_ID=$(echo $CONTROL_PLANE_DETAILS | jq -r .id)
CONTROL_PLANE_TELEMETRY=$(echo $CONTROL_PLANE_DETAILS | jq -r '.config.telemetry_endpoint | sub("https://";"")')Create mTLS certificates
Kong Ingress Controller talks to Konnect over a connected secured with TLS certificates.
Generate a new certificate using openssl:
openssl req -new -x509 -nodes -newkey rsa:2048 -subj "/CN=kongdp/C=US" -keyout ./tls.key -out ./tls.crtThe certificate needs to be a single line string to send it to the Konnect API with curl. Use awk to format the certificate:
export CERT=$(awk 'NF {sub(/\r/, ""); printf "%s\\n",$0;}' tls.crt);Next, upload the certificate to Konnect:
curl -X POST "https://us.api.konghq.com/v2/control-planes/$CONTROL_PLANE_ID/dp-client-certificates" \
--no-progress-meter --fail-with-body \
-H "Authorization: Bearer $KONNECT_TOKEN" \
--json '{
"cert": "'$CERT'"
}'Finally, store the certificate in a Kubernetes secret so that Kong Ingress Controller can read it:
kubectl create namespace kong -o yaml --dry-run=client | kubectl apply -f -
kubectl create secret tls konnect-client-tls -n kong --cert=./tls.crt --key=./tls.keyKong Ingress Controller running (attached to Konnect)
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo updateCopied! -
Create a
values.yamlfile:cat <<EOF > values.yaml controller: ingressController: image: tag: "3.5" env: feature_gates: "FillIDs=true" konnect: license: enabled: true enabled: true controlPlaneID: "$CONTROL_PLANE_ID" tlsClientCertSecretName: konnect-client-tls apiHostname: "us.kic.api.konghq.com" gateway: image: repository: kong tag: "3.9.1" env: konnect_mode: 'on' vitals: "off" cluster_mtls: pki cluster_telemetry_endpoint: "$CONTROL_PLANE_TELEMETRY:443" cluster_telemetry_server_name: "$CONTROL_PLANE_TELEMETRY" cluster_cert: /etc/secrets/konnect-client-tls/tls.crt cluster_cert_key: /etc/secrets/konnect-client-tls/tls.key lua_ssl_trusted_certificate: system proxy_access_log: "off" dns_stale_ttl: "3600" secretVolumes: - konnect-client-tls EOFCopied! -
Install Kong Ingress Controller using Helm:
helm install kong kong/ingress -n kong --create-namespace --values ./values.yaml --waitCopied! -
Set
$PROXY_IPas an environment variable for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{range .status.loadBalancer.ingress[0]}{@.ip}{@.hostname}{end}') echo $PROXY_IPCopied!
Kong Ingress Controller running
-
Add the Kong Helm charts:
helm repo add kong https://charts.konghq.com helm repo updateCopied! -
Install Kong Ingress Controller using Helm:
helm install kong kong/ingress -n kong --create-namespace --waitCopied! -
Set
$PROXY_IPas an environment variable for future commands:export PROXY_IP=$(kubectl get svc --namespace kong kong-gateway-proxy -o jsonpath='{range .status.loadBalancer.ingress[0]}{@.ip}{@.hostname}{end}') echo $PROXY_IPCopied!
Required Kubernetes resources
This how-to requires some Kubernetes services to be available in your cluster. These services will be used by the resources created in this how-to.
kubectl apply -f https://developer.konghq.com/manifests/kic/echo-service.yaml -n kongWait until the pods for the services are ready:
kubectl wait --for=condition=Ready pod --all -n kong --timeout=300sCreate an HTTPRoute
To route HTTP traffic, you need to create an HTTPRoute or an Ingress resource pointing at your Kubernetes Service.
Add TLS configuration
The routing configuration can include a certificate to present when clients connect over HTTPS. This is not required, as Kong Gateway will serve a default certificate if it cannot find another, but including TLS configuration along with routing configuration is typical.
-
Create a test certificate for the
example.comhostname. This will be used to secure TLS traffic.Older OpenSSL versions, including the version provided with macOS Monterey, require using the alternative version of this command.
- Create a Secret containing the certificate:
kubectl create secret -n kong tls example.com --cert=./server.crt --key=./server.keyCopied! -
Update your routing configuration to use this certificate:
-
Send requests to verify if the configured certificate is served:
curl -ksv https://example.com/echo --resolve example.com:443:$PROXY_IP 2>&1 | grep -A1 "certificate:"Copied!The results should look like this:
* Server certificate: * subject: CN=example.com
Configure an HTTPS redirect
Kong Gateway handles HTTPS redirects by automatically issuing redirects to requests whose characteristics match an HTTPS-only route except for the protocol. For example, with a Kong Gateway Route like the following:
{ "protocols": ["https"], "hosts": ["example.com"],
"https_redirect_status_code": 301, "paths": ["/echo/"], "name": "example" }A request for http://example.com/echo/green receives a 301 response with a Location: https://example.com/echo/green header. Kubernetes resource annotations instruct the controller to create a route with protocols=[https] and https_redirect_status_code set to the code of your choice (the default if unset is 426).
-
Configure the protocols that are allowed in the
konghq.com/protocolsannotation: -
Configure the status code used to redirect in the
konghq.com/https-redirect-status-codeannotation:
Note: Kong Ingress Controller does not use a HTTPRequestRedirectFilter to configure the redirect. Using the filter to redirect HTTP to HTTPS requires a separate
HTTPRouteto handle redirected HTTPS traffic, which doesn’t align well with Kong Gateway’s single Route redirect model.Work to support the standard filter-based configuration is ongoing. Until then, the annotations allow you to configure HTTPS-only
HTTPRoutes.
Validate your configuration
With the redirect configuration in place, HTTP requests now receive a redirect rather than being proxied upstream:
- Send an HTTP request:
curl -ksvo /dev/null http://example.com/echo --resolve example.com:80:$PROXY_IP 2>&1 | grep -i httpCopied!The results should look like this:
> GET /echo HTTP/1.1 < HTTP/1.1 301 Moved Permanently < Location: https://example.com/echo -
Send a curl request to follow redirects using the
-Lflag. This navigates to the HTTPS URL and receives a proxied response from the upstream.curl -Lksv http://example.com/echo --resolve example.com:80:$PROXY_IP --resolve example.com:443:$PROXY_IP 2>&1Copied!The results should look like this (some output removed for brevity):
> GET /echo HTTP/1.1 > Host: example.com > < HTTP/1.1 301 Moved Permanently < Location: https://example.com/echo < Server: kong/3.4.2 * Issue another request to this URL: 'https://example.com/echo' * Server certificate: * subject: CN=example.com > GET /echo HTTP/2 > Host: example.com > < HTTP/2 200 < via: kong/3.4.2 < Welcome, you are connected to node kind-control-plane. Running on Pod echo-74d47cc5d9-pq2mw. In namespace default. With IP address 10.244.0.7.
Kong Gateway correctly serves the request only on the HTTPS protocol and redirects the user
if the HTTP protocol is used. The -k flag in cURL skips certificate
validation as the certificate is served by Kong Gateway is a self-signed one. If you are
serving this traffic through a domain that you control and have configured TLS
properties for it, then the flag won’t be necessary.
Cleanup
Delete created Kubernetes resources
kubectl delete -n kong -f https://developer.konghq.com/manifests/kic/echo-service.yamlUninstall KIC from your cluster
helm uninstall kong -n kong