BackendTLSPolicy Example
This example will use the echo-server sample application to demonstrate how to use BackendTLSPolicy.
You will need mkcert tool to generate certificates. See the tool’s upstream site for details.
This task uses a self-signed CA, and is only for demonstration purposes.
Deploy echo-server
Apply the following to deploy the echo-server.
apiVersion: v1
kind: ServiceAccount
metadata:
name: backend
---
apiVersion: v1
kind: Service
metadata:
name: backend
labels:
app: backend
service: backend
spec:
ports:
- name: http
port: 3000
targetPort: 3000
selector:
app: backend
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: backend
spec:
replicas: 1
selector:
matchLabels:
app: backend
version: v1
template:
metadata:
labels:
app: backend
version: v1
spec:
serviceAccountName: backend
containers:
- image: gcr.io/k8s-staging-gateway-api/echo-basic:v20231214-v1.0.0-140-gf544a46e
imagePullPolicy: IfNotPresent
name: backend
ports:
- containerPort: 3000
env:
- name: POD_NAME
valueFrom:
fieldRef:
fieldPath: metadata.name
- name: NAMESPACE
valueFrom:
fieldRef:
fieldPath: metadata.namespace
Apply the following to create a Gateway and HTTPRoute for the echo-server:
apiVersion: gateway.networking.k8s.io/v1
kind: Gateway
metadata:
name: my-gateway
spec:
gatewayClassName: cilium
listeners:
- name: http
protocol: HTTP
port: 80
---
apiVersion: gateway.networking.k8s.io/v1
kind: HTTPRoute
metadata:
name: backend
spec:
parentRefs:
- name: my-gateway
hostnames:
- "www.example.com"
rules:
- backendRefs:
- group: ""
kind: Service
name: backend
port: 3000
weight: 1
matches:
- path:
type: PathPrefix
value: /
Test the sample application:
$ curl -v --resolve www.example.com:80:<GATEWAY_IP_ADDRESS> http://www.example.com/get
The curl command will return the information about the request. It should look like the following:
{
"path": "/get",
"host": "www.example.com",
"method": "GET",
"proto": "HTTP/1.1",
"headers": {
"Accept": [
"*/*"
],
"User-Agent": [
"curl/8.20.0"
],
"X-Envoy-Internal": [
"true"
],
"X-Forwarded-For": [
"172.19.0.1"
],
"X-Forwarded-Proto": [
"http"
],
"X-Request-Id": [
"bb913f3e-7538-4873-88e4-25499fe5b3ff"
]
},
"namespace": "default",
"ingress": "",
"service": "",
"pod": "backend-86c6c76f-ptczl"
}
Generate demo TLS Certificates
Generate the certificates and keys for example.com.
First, create the root certificate.
mkcert www.example.com
This will output the certificate and key in the current directory.
Create the secret and configmap in your cluster
Store the cert and key into a Kubernetes Secret.
kubectl create secret tls example-cert --key=www.example.com-key.pem --cert=www.example.com.pem
Create a configmap in your cluster.
kubectl create configmap example-ca --from-file=ca.crt=www.example.com.pem
Setup TLS between gateway and backend
Patch the backend deployment to enable TLS. The following command mounts the TLS certificate secret into the backend container as a volume.
kubectl patch deployment backend --type=json --patch '
- op: add
path: /spec/template/spec/containers/0/volumeMounts
value:
- name: secret-volume
mountPath: /etc/secret-volume
- op: add
path: /spec/template/spec/volumes
value:
- name: secret-volume
secret:
secretName: example-cert
items:
- key: tls.crt
path: crt
- key: tls.key
path: key
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: TLS_SERVER_CERT
value: /etc/secret-volume/crt
- op: add
path: /spec/template/spec/containers/0/env/-
value:
name: TLS_SERVER_PRIVKEY
value: /etc/secret-volume/key
'
Configure the backend service to expose port 443. Apply the following to update backend service the ports to listen on 443:
apiVersion: v1
kind: Service
metadata:
labels:
app: backend
service: backend
name: backend
spec:
selector:
app: backend
ports:
- name: https
port: 443
protocol: TCP
targetPort: 8443
Create the BackendTLSPolicy to tell the Cilium Gateway to use a TLS connection with the backend.
apiVersion: gateway.networking.k8s.io/v1
kind: BackendTLSPolicy
metadata:
name: enable-backend-tls
namespace: default
spec:
targetRefs:
- group: ''
kind: Service
name: backend
sectionName: https
validation:
caCertificateRefs:
- name: example-ca
group: ''
kind: ConfigMap
hostname: www.example.com
Patch the HTTPRoute backend reference, so that it uses the correct port edited in the backend service.
kubectl patch HTTPRoute backend --type=json --patch '
- op: replace
path: /spec/rules/0/backendRefs/0/port
value: 443
'
Testing the backend TLS connection
Try to curl the service through the Gateway.
$ curl -vI --resolve "www.example.com:80:<YOUR_GATEWAY_EXTERNAL_IP>" http://www.example.com:80/get
You should receive back a 200 OK response. The curl response will look similar to the earlier curl response, but note that the response also demonstrates the TLS encryption details:
{
"tls": {
"version": "TLSv1.3",
"serverName": "www.example.com",
"negotiatedProtocol": "http/1.1",
"cipherSuite": "TLS_AES_128_GCM_SHA256"
}
}