The article describes how to configure SAP BTP, Kyma runtime to work with Content Delivery Network (CDN) such as Akamai CDN.
A Content Delivery Network consists of multiple servers placed around the world. These servers, called edge servers, are responsible for caching website content and serving it to end users from the nearest location. The original content lives in the ‘origin server’, which is Kyma in our case.
The configuration that defines how Akamai edge servers handle traffic for a given domain is called a ‘Property’. It maps hostnames (for example, www.example.com) to specific edge behaviors, such as caching rules, security settings, and origin server communication.
Akamai edge servers also support TLS termination, so they act as endpoints for HTTPs connections and serve TLS certificates for external domains.
A single Kyma instance can serve content for multiple domains (multiple Akamai Properties), which may then be redirected to any workloads. It is visualized in the following diagram:
As we can see, there are two Akamai Properties, each with two host names. We want to redirect requests for all external host names to the same Kyma instance, ab1234.kyma.ondemand.com, with the IP address 203.0.113.50. At this point, we need a host name on the Kyma side that would accept the traffic. To keep things simple, we may use a subdomain of the Kyma cluster domain, like cdn.ab1234.kyma.ondemand.com, for which we can easily register a DNS entry and generate a TLS certificate.
In the Akamai Property, you need to configure a rule in the following way:
Let’s now imagine that an end user makes a request to the domain www.foo.example.com, configured as in the above screenshot. In such a case, the Akamai edge server acts as a reverse proxy and contacts the Kyma origin server in the following way:
Connection is technically made to the origin server defined in the ‘Origin Server Hostname’, so the edge server resolves the DNS name cdn.ab1234.kyma.ondemand.com and connects to the IP address 203.0.113.50.In Layer 4, the SNI host name points to the external domain www.foo.example.com.In Layer 7, the Host header also points to the external domain www.foo.example.com.It is expected that the origin server provides a valid TLS certificate with a Common Name or Subject Alternative Name equal to the origin hostname, which is cdn.ab1234.kyma.ondemand.com.
To accept such traffic on the Kyma side, we need a custom Istio Gateway:
With internal domain:cdn.ab1234.kyma.ondemand.comWith external domains:Either www.foo.example.com, api.foo.example.com, www.bar.example.com, www.bar.example.com, m.bar.example.comOr *.foo.example.com, *.bar.example.comOr *.example.comPointing to secret with a key and a certificate for internal domain cdn.ab1234.kyma.ondemand.com.
Note that the Gateway above doesn’t need a TLS certificate for external domains, which is hosted by the CDN. The Akamai edge server expects the certificate to be valid for the origin hostname.
To create such a configuration, follow this example:
1. Create three resources: DNSEntry, Certificate, and Istio Gateway.
kubectl create ns gateway-nsapiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: cdn-internal-domain-dnsentry
namespace: gateway-ns
annotations:
dns.gardener.cloud/class: garden
spec:
dnsName: “cdn.ab1234.kyma.ondemand.com”
ttl: 600
targets:
– 203.0.113.50 # Load Balancer IP addressapiVersion: cert.gardener.cloud/v1alpha1
kind: Certificate
metadata:
name: cdn-internal-domain-certificate
namespace: istio-system
spec:
secretName: cdn-internal-domain-certificate
commonName: “cdn.ab1234.kyma.ondemand.com”
issuerRef:
name: gardenapiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cdn-gateway
namespace: gateway-ns
spec:
selector:
app: istio-ingressgateway
istio: ingressgateway
servers:
– port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: cdn-internal-domain-certificate
hosts:
– “cdn.ab1234.kyma.ondemand.com”
– “*.example.com”
2. Deploy an application.
kubectl create ns application
kubectl label namespace application istio-injection=enabled –overwriteapiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
namespace: application
—
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: application
labels:
app: httpbin
service: httpbin
spec:
ports:
– name: http
port: 8000
targetPort: 80
selector:
app: httpbin
—
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: application
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
– image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
– containerPort: 80
3. Create an APIRule resource, which exposes the above application via the previously created Gateway and on a particular external domain:
apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: application-foo-external-domain
namespace: application
spec:
gateway: gateway-ns/cdn-gateway
hosts:
– “www.foo.example.com”
rules:
– methods:
– GET
noAuth: true
path: /*
service:
name: httpbin
port: 8000
4. For each external domain, create a separate APIRule resource:
apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: application-bar-external-domain
namespace: application
spec:
gateway: gateway-ns/cdn-gateway
hosts:
– “www.bar.example.com”
rules:
– methods:
– GET
noAuth: true
path: /*
service:
name: httpbin
port: 8000
5. To test this configuration, we need to simulate what the Akamai edge server does:
Make a TLS connection to the internal domain cdn.ab1234.kyma.ondemand.comUse SNI host name pointing to external domain www.foo.example.comProvide an HTTP Host header pointing to the external domain www.foo.example.com
You can use the following bash command:
(
echo -ne “GET /headers HTTP/1.1rn”
echo -ne “Host: www.foo.example.comrn”
echo -ne “Connection: closernrn”
) | openssl s_client -connect “cdn.ab1234.kyma.ondemand.com:443” -servername “www.foo.example.com” -quiet
6. If this works, your Kyma instance is prepared. Once the Akamai Property configuration is applied, try to make a request via the external domain:
curl “https://www.foo.example.com/headers”
The article describes how to configure SAP BTP, Kyma runtime to work with Content Delivery Network (CDN) such as Akamai CDN.A Content Delivery Network consists of multiple servers placed around the world. These servers, called edge servers, are responsible for caching website content and serving it to end users from the nearest location. The original content lives in the ‘origin server’, which is Kyma in our case.The configuration that defines how Akamai edge servers handle traffic for a given domain is called a ‘Property’. It maps hostnames (for example, www.example.com) to specific edge behaviors, such as caching rules, security settings, and origin server communication.Akamai edge servers also support TLS termination, so they act as endpoints for HTTPs connections and serve TLS certificates for external domains.A single Kyma instance can serve content for multiple domains (multiple Akamai Properties), which may then be redirected to any workloads. It is visualized in the following diagram: As we can see, there are two Akamai Properties, each with two host names. We want to redirect requests for all external host names to the same Kyma instance, ab1234.kyma.ondemand.com, with the IP address 203.0.113.50. At this point, we need a host name on the Kyma side that would accept the traffic. To keep things simple, we may use a subdomain of the Kyma cluster domain, like cdn.ab1234.kyma.ondemand.com, for which we can easily register a DNS entry and generate a TLS certificate.In the Akamai Property, you need to configure a rule in the following way:Let’s now imagine that an end user makes a request to the domain www.foo.example.com, configured as in the above screenshot. In such a case, the Akamai edge server acts as a reverse proxy and contacts the Kyma origin server in the following way:Connection is technically made to the origin server defined in the ‘Origin Server Hostname’, so the edge server resolves the DNS name cdn.ab1234.kyma.ondemand.com and connects to the IP address 203.0.113.50.In Layer 4, the SNI host name points to the external domain www.foo.example.com.In Layer 7, the Host header also points to the external domain www.foo.example.com.It is expected that the origin server provides a valid TLS certificate with a Common Name or Subject Alternative Name equal to the origin hostname, which is cdn.ab1234.kyma.ondemand.com.To accept such traffic on the Kyma side, we need a custom Istio Gateway:With internal domain:cdn.ab1234.kyma.ondemand.comWith external domains:Either www.foo.example.com, api.foo.example.com, www.bar.example.com, www.bar.example.com, m.bar.example.comOr *.foo.example.com, *.bar.example.comOr *.example.comPointing to secret with a key and a certificate for internal domain cdn.ab1234.kyma.ondemand.com.Note that the Gateway above doesn’t need a TLS certificate for external domains, which is hosted by the CDN. The Akamai edge server expects the certificate to be valid for the origin hostname.To create such a configuration, follow this example:1. Create three resources: DNSEntry, Certificate, and Istio Gateway.kubectl create ns gateway-nsapiVersion: dns.gardener.cloud/v1alpha1
kind: DNSEntry
metadata:
name: cdn-internal-domain-dnsentry
namespace: gateway-ns
annotations:
dns.gardener.cloud/class: garden
spec:
dnsName: “cdn.ab1234.kyma.ondemand.com”
ttl: 600
targets:
– 203.0.113.50 # Load Balancer IP addressapiVersion: cert.gardener.cloud/v1alpha1
kind: Certificate
metadata:
name: cdn-internal-domain-certificate
namespace: istio-system
spec:
secretName: cdn-internal-domain-certificate
commonName: “cdn.ab1234.kyma.ondemand.com”
issuerRef:
name: gardenapiVersion: networking.istio.io/v1alpha3
kind: Gateway
metadata:
name: cdn-gateway
namespace: gateway-ns
spec:
selector:
app: istio-ingressgateway
istio: ingressgateway
servers:
– port:
number: 443
name: https
protocol: HTTPS
tls:
mode: SIMPLE
credentialName: cdn-internal-domain-certificate
hosts:
– “cdn.ab1234.kyma.ondemand.com”
– “*.example.com”2. Deploy an application.kubectl create ns application
kubectl label namespace application istio-injection=enabled –overwriteapiVersion: v1
kind: ServiceAccount
metadata:
name: httpbin
namespace: application
—
apiVersion: v1
kind: Service
metadata:
name: httpbin
namespace: application
labels:
app: httpbin
service: httpbin
spec:
ports:
– name: http
port: 8000
targetPort: 80
selector:
app: httpbin
—
apiVersion: apps/v1
kind: Deployment
metadata:
name: httpbin
namespace: application
spec:
replicas: 1
selector:
matchLabels:
app: httpbin
version: v1
template:
metadata:
labels:
app: httpbin
version: v1
spec:
serviceAccountName: httpbin
containers:
– image: docker.io/kennethreitz/httpbin
imagePullPolicy: IfNotPresent
name: httpbin
ports:
– containerPort: 803. Create an APIRule resource, which exposes the above application via the previously created Gateway and on a particular external domain:apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: application-foo-external-domain
namespace: application
spec:
gateway: gateway-ns/cdn-gateway
hosts:
– “www.foo.example.com”
rules:
– methods:
– GET
noAuth: true
path: /*
service:
name: httpbin
port: 8000 4. For each external domain, create a separate APIRule resource: apiVersion: gateway.kyma-project.io/v2
kind: APIRule
metadata:
name: application-bar-external-domain
namespace: application
spec:
gateway: gateway-ns/cdn-gateway
hosts:
– “www.bar.example.com”
rules:
– methods:
– GET
noAuth: true
path: /*
service:
name: httpbin
port: 80005. To test this configuration, we need to simulate what the Akamai edge server does:Make a TLS connection to the internal domain cdn.ab1234.kyma.ondemand.comUse SNI host name pointing to external domain www.foo.example.comProvide an HTTP Host header pointing to the external domain www.foo.example.comYou can use the following bash command:(
echo -ne “GET /headers HTTP/1.1rn”
echo -ne “Host: www.foo.example.comrn”
echo -ne “Connection: closernrn”
) | openssl s_client -connect “cdn.ab1234.kyma.ondemand.com:443” -servername “www.foo.example.com” -quiet6. If this works, your Kyma instance is prepared. Once the Akamai Property configuration is applied, try to make a request via the external domain:curl “https://www.foo.example.com/headers” Read More Technology Blog Posts by SAP articles
#SAP
#SAPTechnologyblog