Gateway TLS for Cluster Operators¶
This user guide walks you through an example of how to configure TLS for all routes attached to an ingress gateway.
Requisites¶
Setup¶
This step uses tooling from the Kuadrant Operator component to create a containerized Kubernetes server locally using Kind, where it installs Istio, Kubernetes Gateway API, CertManager and Kuadrant itself.
Clone the project:
Setup the environment:
Create a namespace:
Create an ingress gateway¶
Create a gateway:
kubectl -n my-gateways apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: prod-web
spec:
gatewayClassName: istio
listeners:
- allowedRoutes:
namespaces:
from: All
name: api
hostname: "*.toystore.local"
port: 443
protocol: HTTPS
tls:
mode: Terminate
certificateRefs:
- name: toystore-local-tls
kind: Secret
EOF
Enable TLS on the gateway¶
The TLSPolicy requires a reference to an existing CertManager Issuer.
Create a CertManager Issuer:
kubectl apply -n my-gateways -f - <<EOF
apiVersion: cert-manager.io/v1
kind: Issuer
metadata:
name: selfsigned-issuer
spec:
selfSigned: {}
EOF
Note: We are using a self-signed issuer here but any supported CerManager issuer or cluster issuer can be used.
Response:
Create a Kuadrant TLSPolicy
to configure TLS:
kubectl apply -n my-gateways -f - <<EOF
apiVersion: kuadrant.io/v1
kind: TLSPolicy
metadata:
name: prod-web
spec:
targetRef:
name: prod-web
group: gateway.networking.k8s.io
kind: Gateway
issuerRef:
group: cert-manager.io
kind: Issuer
name: selfsigned-issuer
EOF
Check policy status:
Response:
Check a Certificate resource was created:
Response
Check a TLS Secret resource was created:
Response:
Deploy a sample API to test TLS¶
Deploy the sample API:
kubectl -n my-gateways apply -f examples/toystore/toystore.yaml
kubectl -n my-gateways wait --for=condition=Available deployments toystore --timeout=60s
Route traffic to the API from our gateway:
kubectl -n my-gateways apply -f - <<EOF
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: toystore
spec:
parentRefs:
- name: prod-web
namespace: my-gateways
hostnames:
- "*.toystore.local"
rules:
- backendRefs:
- name: toystore
port: 80
EOF
Verify TLS works by sending requests¶
Get the gateway address@
GWADDRESS=`kubectl get gateway/prod-web -n my-gateways -o=jsonpath='{.status.addresses[?(@.type=="IPAddress")].value}'`
echo $GWADDRESS
Response:
Verify we can access the service via TLS:
Response:
* Added api.toystore.local:443:172.18.200.1 to DNS cache
* Hostname api.toystore.local was found in DNS cache
* Trying 172.18.200.1:443...
* Connected to api.toystore.local (172.18.200.1) port 443 (#0)
* ALPN: offers h2
* ALPN: offers http/1.1
* TLSv1.0 (OUT), TLS header, Certificate Status (22):
* TLSv1.3 (OUT), TLS handshake, Client hello (1):
* TLSv1.2 (IN), TLS header, Certificate Status (22):
* TLSv1.3 (IN), TLS handshake, Server hello (2):
* TLSv1.2 (IN), TLS header, Finished (20):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Encrypted Extensions (8):
* TLSv1.3 (IN), TLS handshake, Certificate (11):
* TLSv1.3 (IN), TLS handshake, CERT verify (15):
* TLSv1.3 (IN), TLS handshake, Finished (20):
* TLSv1.2 (OUT), TLS header, Finished (20):
* TLSv1.3 (OUT), TLS change cipher, Change cipher spec (1):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.3 (OUT), TLS handshake, Finished (20):
* SSL connection using TLSv1.3 / TLS_AES_256_GCM_SHA384
* ALPN: server accepted h2
* Server certificate:
* subject: [NONE]
* start date: Feb 15 11:46:50 2024 GMT
* expire date: May 15 11:46:50 2024 GMT
* Using HTTP2, server supports multiplexing
* Copying HTTP/2 data in stream buffer to connection buffer after upgrade: len=0
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* h2h3 [:method: HEAD]
* h2h3 [:path: /]
* h2h3 [:scheme: https]
* h2h3 [:authority: api.toystore.local]
* h2h3 [user-agent: curl/7.85.0]
* h2h3 [accept: */*]
* Using Stream ID: 1 (easy handle 0x5623e4fe5bf0)
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
> HEAD / HTTP/2
> Host: api.toystore.local
> user-agent: curl/7.85.0
> accept: */*
>
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* TLSv1.3 (IN), TLS handshake, Newsession Ticket (4):
* old SSL session ID is stale, removing
* TLSv1.2 (IN), TLS header, Supplemental data (23):
* Connection state changed (MAX_CONCURRENT_STREAMS == 2147483647)!
* TLSv1.2 (OUT), TLS header, Supplemental data (23):
* TLSv1.2 (IN), TLS header, Supplemental data (23):
< HTTP/2 200
HTTP/2 200
< content-type: application/json
content-type: application/json
< server: istio-envoy
server: istio-envoy
< date: Thu, 15 Feb 2024 12:13:27 GMT
date: Thu, 15 Feb 2024 12:13:27 GMT
< content-length: 1658
content-length: 1658
< x-envoy-upstream-service-time: 1
x-envoy-upstream-service-time: 1
<
* Connection #0 to host api.toystore.local left intact