Skip to content

Instantly share code, notes, and snippets.

@Kamukage3e
Forked from mikesparr/gke-cdn-backend-config.sh
Created September 16, 2024 11:51
Show Gist options
  • Select an option

  • Save Kamukage3e/544f6209da692a2a5fd3c3554b18e3a1 to your computer and use it in GitHub Desktop.

Select an option

Save Kamukage3e/544f6209da692a2a5fd3c3554b18e3a1 to your computer and use it in GitHub Desktop.
Example BackendConfig for Google Kubernetes Engine (GKE) to enable Cloud CDN and cache content
#!/usr/bin/env bash
#####################################################################
# REFERENCES
# - https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#cloud_cdn
# - https://cloud.google.com/kubernetes-engine/docs/how-to/ingress-features#expandable-1
#####################################################################
export PROJECT_ID=$(gcloud config get-value project)
export PROJECT_USER=$(gcloud config get-value core/account) # set current user
export PROJECT_NUMBER=$(gcloud projects describe $PROJECT_ID --format="value(projectNumber)")
export IDNS=${PROJECT_ID}.svc.id.goog # workload identity domain
export GCP_REGION="us-central1" # CHANGEME (OPT)
export GCP_ZONE="us-central1-a" # CHANGEME (OPT)
export NETWORK_NAME="default"
# enable apis
gcloud services enable compute.googleapis.com \
container.googleapis.com
# configure gcloud sdk
gcloud config set compute/region $GCP_REGION
gcloud config set compute/zone $GCP_ZONE
# create cluster
export CLUSTER_NAME="central"
gcloud beta container --project $PROJECT_ID clusters create $CLUSTER_NAME \
--zone $GCP_ZONE \
--no-enable-basic-auth \
--cluster-version "1.22.6-gke.300" \
--release-channel "regular" \
--machine-type "e2-medium" \
--image-type "COS_CONTAINERD" \
--disk-type "pd-standard" --disk-size "100" \
--metadata disable-legacy-endpoints=true \
--scopes "https://www.googleapis.com/auth/cloud-platform" \
--max-pods-per-node "110" \
--num-nodes "1" \
--logging=SYSTEM,WORKLOAD \
--monitoring=SYSTEM \
--enable-ip-alias \
--network "projects/$PROJECT_ID/global/networks/default" \
--subnetwork "projects/$PROJECT_ID/regions/us-central1/subnetworks/default" \
--no-enable-intra-node-visibility \
--default-max-pods-per-node "110" \
--enable-autoscaling --min-nodes "0" --max-nodes "3" \
--no-enable-master-authorized-networks \
--addons HorizontalPodAutoscaling,HttpLoadBalancing,NodeLocalDNS,GcePersistentDiskCsiDriver \
--enable-autoupgrade \
--enable-autorepair \
--max-surge-upgrade 1 \
--max-unavailable-upgrade 0 \
--workload-pool "$PROJECT_ID.svc.id.goog" \
--enable-shielded-nodes \
--node-locations $GCP_ZONE
# create deployment (fake app)
cat > deployment.yaml << EOF
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment
labels:
app: hello
spec:
replicas: 1
selector:
matchLabels:
app: hello
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello
# image: nicholasjackson/fake-service:vm-v1.10.7-v0.22.7
image: us-docker.pkg.dev/google-samples/containers/gke/hello-app-cdn:1.0
# env:
# - name: NAME
# value: "Hello Dave Service"
# - name: MESSAGE
# value: "Hello, Dave!"
ports:
- containerPort: 8080
EOF
# create backend config with CDN
cat > backend.yaml << EOF
apiVersion: cloud.google.com/v1
kind: BackendConfig
metadata:
namespace: default
name: hello-backendconfig
spec:
cdn:
enabled: true
cachePolicy:
includeHost: true
includeProtocol: true
includeQueryString: false
EOF
# expose hello app with NodePort service
cat > service.yaml << EOF
apiVersion: v1
kind: Service
metadata:
name: hello-service
annotations:
cloud.google.com/backend-config: '{"ports": {"80":"hello-backendconfig"}}'
spec:
type: NodePort
selector:
app: hello
ports:
- port: 80
targetPort: 8080
EOF
# expose hello service with Ingress and public IP
cat > ingress.yaml << EOF
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
name: hello-ingress
# annotations:
spec:
rules:
- http:
paths:
- path: /*
pathType: ImplementationSpecific
backend:
service:
name: hello-service
port:
number: 80
EOF
###################### TESTING ####################
# get the public IP (after 10 min) of the Ingress
export PUBLIC_IP=$(kubectl get ingress/hello-ingress -o jsonpath="{.status.loadBalancer.ingress[0].ip}")
# test app with curl
curl -v "$PUBLIC_IP/?cache=true"
# wait 1 minute for CDN to warm up and retry (confirm Age: is in header)
# < HTTP/1.1 200 OK
# < Content-Length: 73
# < Via: 1.1 google
# < Date: Thu, 31 Mar 2022 15:25:34 GMT
# < Content-Type: text/plain; charset=utf-8
# < Age: 20 <------------------- AGE CONFIRMS CACHED *******
# < Cache-Control: max-age=3600,public
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment