Akamai APIs

CDNs werden immer wichtiger. Gerade bei Applikationen, die in Cloud-Instanzen oder gar Containern in Cloud-Instanzen laufen, ist es wichtig den Content möglichst nah zur Kundin zu bringen, um einerseits eine gute "Customer Experience" zu erreichen aber andererseits nicht allzuviel Geld für Cloud-Ressourcen auszugeben.

Aber auch "legacy" Umgebungen profitieren meist stark von einem vorgeschalteten CDN (sofern dies entsprechend mitgedacht wurde). Ein paar VMs können reichen eine Corporate-Website, die auch Pressemitteilungen und Facebookstürmen widersteht, bereitzustellen, wenn ein CDN die meisten Webrequests ausliefert.

Wenn neuer Content allerdings automatisiert publiziert wird, dann will Content auch automatisiert im CDN invalidiert werden. Ein Grund, sich die Akamai APIs anzusehen. Wie in der "Products & tools A-Z" Übersicht aufgeführt, gibt es eine Horde von APIs - fast zu jedem Akamai-Produkt eine.

Für mich waren zunächst die Akamai CLI und der Akamai Terraform Provider interessant. Es gibt aber auch Library-Bindings und Beispiele für viele Programmiersprachen (solange man einen HTTP-Request damit formulieren kann).

Am Anfang aller API-Calls steht die Erstellung eines API-Clients. Dieser enthält ein Client-Secret, einen Host, ein Access-Token und ein Client-Token. Das Ganze hat eine Laufzeit, die maximal bei zwei Jahren liegt. Man muß sich also für Automatisierung ggfs. auch über eine Überwachung und Erneuerung Gedanken machen.

Hat man sich einen API-Client generiert, kann man sich schon die CLI herunterladen und installieren. Es handelt sich um ein einzelnes GO-Binary. Wer sich Download und lokale Installation sparen will, kann auch einen Docker-Container mit dem Akamai Developer Toolkit ausführen. Dieser enthält dann schon alle Module des CLI-Clients vorinstalliert (zusätzlich noch weitere Tools wie Terraform, etc.):

Akamai DevOps [bin] >> akamai
Usage:
  akamai [global flags] command [command flags] [arguments...]
 
Built-In Commands:
  config
  help
  install (alias: get)
  list
  search
  uninstall
  update
  upgrade
 
Installed Commands:
  adaptive-acceleration (aliases: a2, adaptive-acceleration/adaptive-acceleration)
  api-gateway (alias: api-gateway/api-gateway)
  api-keys (alias: api-gateway/api-keys)
  api-security (alias: api-gateway/api-security)
  appsec (alias: appsec/appsec)
  cloudlets (aliases: cloudlets, cloudlets/cloudlets)
  cps (aliases: certs, cps/cps)
  dns (alias: dns/dns)
  eaa (alias: eaa/eaa)
  edgekv (aliases: ekv, edgekv, edgeworkers/edgekv)
  edgeworkers (aliases: ew, edgeworkers, edgeworkers/edgeworkers)
  etp (alias: etp/etp)
  firewall (aliases: fw, firewall/firewall)
  gtm (alias: gtm/gtm)
  image-manager (aliases: im, image-manager/image-manager)
  jsonnet (aliases: jsonnet, jsonnet/jsonnet)
  onboard (aliases: onboard, onboard/onboard)
  pipeline (aliases: pl, pd, proddeploy, property-manager/pipeline)
  property (alias: property/property)
  property-manager (aliases: pm, snippets, property-manager/property-manager)
  purge (alias: purge/purge)
  sandbox (alias: sandbox/sandbox)
  site-shield (aliases: ss, firewall/site-shield)
  terraform (alias: terraform/terraform)
  video-manager (aliases: vm, image-manager/video-manager)
  visitor-prioritization (aliases: vp, visitor-prioritization/visitor-prioritization)

Global Flags:
   --bash                 Output bash auto-complete (default: false)
   --zsh                      Output zsh auto-complete (default: false)
   --proxy value              Set a proxy to use
   --edgerc value, -e value   edgerc config path passed to executed commands, defaults to ~/.edgerc
   --section value, -s value  edgerc section name passed to executed commands, defaults to 'default'
   --version                  Output CLI version (default: false)
 
Copyright (C) Akamai Technologies, Inc

Das aktuelle Image basiert auf Alpine-Linux 3.13.7.

Für Akamai-Debugging ist es auch sinnvoll, sich einen curl-Alias zu installieren, der die Debugging-Header von Akamai verwendet:

alias carl='curl -IXGET -H "Pragma: akamai-x-cache-on, akamai-x-cache-remote-on, akamai-x-check-cacheable, akamai-x-get-cache-key, akamai-x-get-extracted-values, akamai-x-get-nonces, akamai-x-get-ssl-client-session-id, akamai-x-get-true-cache-key, akamai-x-serial-no"'

So gerüstet, kann man dann z. B. mal die Purge-API ausprobieren.

Zunächst gucken wir mal nach, ob sich ein Bild überhaupt im Akamai Cache befindet:

03:08:32 toens@NB-46261 ~ → carl https://www.krones.com/media/images/Gruppenfoto_1240x826px.jpg
HTTP/2 200
server: Apache
last-modified: Wed, 09 Mar 2022 06:02:37 GMT
etag: "1a371f-592e9-5d9c2d828f940"
accept-ranges: bytes
content-length: 365289
x-frame-options: SAMEORIGIN
strict-transport-security: max-age=63072000;includeSubDomains
x-xss-protection: 1; mode=block
x-cnection: close
content-type: image/jpeg
date: Fri, 11 Mar 2022 14:10:38 GMT
x-cache: TCP_HIT from a2-16-187-12.deploy.akamaitechnologies.com (AkamaiGHost/10.7.3-39449967) (-)
x-cache-key: S/L/2797/541975/14d/www.krones.com/media/images/Gruppenfoto_1240x826px.jpg
x-cache-key-extended-internal-use-only: S/L/2797/541975/14d/www.krones.com/media/images/Gruppenfoto_1240x826px.jpg vcd=3406
x-true-cache-key: /L/www.krones.com/media/images/Gruppenfoto_1240x826px.jpg vcd=3406
x-akamai-session-info: name=AKA_PM_BASEDIR; value=
x-akamai-session-info: name=AKA_PM_CACHEABLE_OBJECT; value=true
x-akamai-session-info: name=AKA_PM_FWD_URL; value=/media/images/Gruppenfoto_1240x826px.jpg
x-akamai-session-info: name=AKA_PM_PREFETCHABLE; value=on
x-akamai-session-info: name=AKA_PM_PREFETCH_ON; value=false
x-akamai-session-info: name=AKA_PM_PROPERTY_NAME; value=www.krones.com
x-akamai-session-info: name=AKA_PM_PROPERTY_VERSION; value=48
x-akamai-session-info: name=AKA_PM_RUM_ENABLED; value=on
x-akamai-session-info: name=AKA_PM_RUM_RATE; value=5
x-akamai-session-info: name=AKA_PM_SR_ENABLED; value=true
x-akamai-session-info: name=AKA_PM_SR_NODE_ID; value=0
x-akamai-session-info: name=AKA_PM_TD_ENABLED; value=false
x-akamai-session-info: name=AKA_PM_TD_MAP_PREFIX; value=ch2
x-akamai-session-info: name=ANS_PEARL_VERSION; value=0.13.0
x-akamai-session-info: name=FASTTCP_RENO_FALLBACK_DISABLE_OPTOUT; value=on
x-akamai-session-info: name=FOFR_PERF_CIP_BUCKET; value=2152
x-akamai-session-info: name=FOFR_PERF_HASH; value=215281
x-akamai-session-info: name=FOFR_PERF_TIME_BUCKET; value=83
x-akamai-session-info: name=HEADER_NAMES; value=Host%3aUser-Agent%3aAccept%3aPragma; full_location_id=
x-akamai-session-info: name=NL_68665_20191125CLOUDMINELTD_NAME; value=2019_11_25_CLOUD_MINE_LTD
x-akamai-session-info: name=NL_69582_HTTPPROXYKRONESCOM_NAME; value=http-proxy.krones.com
x-akamai-session-info: name=OVERRIDE_HTTPS_IE_CACHE_BUST; value=all
x-akamai-session-info: name=PCH_SERIAL_HASH; value=864
x-akamai-session-info: name=PCH_SERIAL_PREFIX; value=a
x-akamai-session-info: name=PCH_SITE_SHIELD_MAP; value=chws.akamaiedge.net
x-akamai-session-info: name=PCH_SS_SERIAL_PREFIX; value=e
x-akamai-session-info: name=RANDOM_SAMPLE; value=false
x-akamai-session-info: name=SEC_CLIENT_IP_ASNUM_MASK_SIZE; value=64
x-akamai-session-info: name=SEC_XFF_ASNUM_MASK_SIZE; value=64
x-akamai-session-info: name=TCP_OPT_APPLIED; value=low
x-akamai-session-info: name=UA_IDENTIFIER; value=curl%2f7.68.0; full_location_id=User-Agent
x-akamai-session-info: name=WAF_EXCEPTION_DLR_STATE; value=false
x-akamai-session-info: name=WAF_XSS_FILTER_STATE; value=false
x-akamai-session-info: name=Y_HATS_CIP_BUCKET; value=7937
x-akamai-session-info: name=Y_HATS_CIP_HASH; value=793774
x-akamai-session-info: name=Y_HATS_TIME_BUCKET; value=76
x-serial: 2797
x-check-cacheable: YES

Interessant ist für uns i. W. die Zeile

x-cache: TCP_HIT from a2-16-187-12.deploy.akamaitechnologies.com (AkamaiGHost/10.7.3-39449967) (-)

die zeigt, dass der Content aus dem Cache ausgeliefert wird.

Per Purge-API kann man den jetzt invalidieren:

03:13:25 toens@NB-46261 ~ → akamai purge invalidate  https://www.krones.com/media/images/Gruppenfoto_1240x826px.jpg
Purging...... [OK]
Purged 1 objects (ETA: 5 seconds)
Purge ID: eiup-FkMHPnYeYrBLhRdJzWvqHW

Und dann nochmal per Debugging-Header verifizieren, dass der Content auch wirklich invalidiert wurde:

x-cache: TCP_REFRESH_HIT from a2-16-187-12.deploy.akamaitechnologies.com (AkamaiGHost/10.7.3-39449967) (S)
x-cache-remote: TCP_MISS from a2-16-110-182.deploy.akamaitechnologies.com (AkamaiGHost/10.7.3-39449967) (-)

Der Content war also nicht mehr im Cache enthalten und wir haben ihn durch unseren Request wieder 'reingeladen.

Für uns dürften sicher auch die APIs für Edge DNS und Global Traffic Management (aka Loadbalancing) interessant sein, denn in dynamischen Infrastrukturen, die größer und kleiner skalieren, müssen natürlich auch DNS und Loadbalancing dynamisch angepasst werden. Das läßt sich per API-Call erreichen.