When a user connects to a website, the physical distance between them and the web hosting server affects the time it takes for the content to appear on the screen. In addition to reducing bandwidth consumption, the globally distributed network of data centers improves web page content delivery speed for users regardless of their location in relation to the main server.
To accomplish this, a caching system stores temporary copies of website files in the proxy server nearest to the user, speeding up the page load time.
In this tutorial we are going to deploy our own local CDN server for hosting image files.
But first we going to need some pre-requirements:
- create a directory for hosting our images ex. /home/root2/cdn-images and upload some images in it.
- create kubernetes secret with tls certificates for ingress to make it publicly available
kubectl create secret tls tls-certificate --namespace default --key certificate-key.key --cert cetificate.crt
- Create DNS A record pointing to your server , for ex. cdn.example.com
- Install ingress, you can check the guide here
- Optionally, add caching for ingress:
create manifest configmap.yaml, paste the content below and apply itapiVersion: v1 kind: ConfigMap metadata: name: ingress-nginx-controller namespace: default labels: app.kubernetes.io/name: ingress-nginx app.kubernetes.io/part-of: ingress-nginx data: proxy-connect-timeout: "10" proxy-read-timeout: "120" proxy-send-timeout: "120" http-snippet: "proxy_cache_path /tmp/nginx_cache levels=1:2 keys_zone=static-cache:10m max_size=4g inactive=120m use_temp_path=off;"
kubectl apply -f configmap.yaml
Now let’s deploy everything, just copy and paste the manifest below:
* modify externalIPs, change “YOUR public ip” with the actual adress.
apiVersion: v1 kind: ConfigMap metadata: name: cdn-config data: default.conf: | server { listen 80; server_name _; root /usr/share/nginx/html; location / { proxy_read_timeout 150; } } --- apiVersion: apps/v1 kind: Deployment metadata: name: cdn spec: selector: matchLabels: app: cdn replicas: 1 template: metadata: labels: app: cdn spec: containers: - name: nginx image: nginx:latest ports: - containerPort: 80 volumeMounts: - name: cdn-config mountPath: /etc/nginx/conf.d/default.conf subPath: default.conf - name: cdn-images mountPath: "/usr/share/nginx/html/" volumes: - name: cdn-config configMap: name: cdn-config - name: cdn-images persistentVolumeClaim: claimName: cdn-images --- apiVersion: v1 kind: Service metadata: name: cdn spec: selector: app: cdn ports: - port: 80 targetPort: 80 externalIPs: - YOUR public ip --- apiVersion: networking.k8s.io/v1 kind: Ingress metadata: name: ingress-cdn annotations: kubernetes.io/ingress.class: "nginx" nginx.ingress.kubernetes.io/rewrite-target: / nginx.ingress.kubernetes.io/proxy-body-size: 8m nginx.ingress.kubernetes.io/proxy-buffering: "on" nginx.ingress.kubernetes.io/configuration-snippet: | proxy_cache static-cache; proxy_cache_valid any 120m; add_header X-Cache-Status $upstream_cache_status; spec: tls: - hosts: - cdn.example.com secretName: tls-certificate rules: - host: cdn.example.com http: paths: - path: / pathType: Prefix backend: service: name: cdn port: number: 80 --- apiVersion: v1 kind: PersistentVolume metadata: name: cdn-images spec: storageClassName: manual capacity: storage: 4Gi accessModes: - ReadWriteOnce hostPath: path: /home/root2/cdn-images/ --- apiVersion: v1 kind: PersistentVolumeClaim metadata: name: cdn-images spec: storageClassName: manual accessModes: - ReadWriteOnce resources: requests: storage: 4Gi
kubectl apply -f cdn.yaml configmap/cdn-config created deployment.apps/cdn created service/cdn created ingress.networking.k8s.io/ingress-cdn created persistentvolume/cdn-images created persistentvolumeclaim/cdn-images created
That’s it, after couple of seconds our deployment is up.
It is accessible and caching
Now let’s take a look on the content of our manifest
Our cdn.yaml manifest consists of Configmap, Deployment, Service, PersistentVolume, PersistentVolumeClaim.
In Configmap section we create simple default.conf file for nginx
In Deployment we configure VolumeMounts with Volumes where we add our Configmap and PersistentVolumeClaim
Service section to make it accessible
Ingress to make it publicly available, here we also add annotations for proxy caching
PersistentVolume and PersistentVolumeClaim for mounting our cdn-images folder, where we gonna host our images.