+5

Hướng dẫn cách tự xây dựng CDN server đơn giản trên Kubernetes

Việc phân phối nội dung website hiệu quả là yếu tố then chốt, ảnh hưởng trực tiếp đến tốc độ tải trang và trải nghiệm của người dùng. Bài viết này sẽ hướng dẫn các bạn cách triển khai một CDN server đơn giản trên Kubernetes để tối ưu hóa việc phân phối hình ảnh, nội dung cho website.

Khoảng cách địa lý giữa người dùng và máy chủ lưu trữ web ảnh hưởng đến thời gian hiển thị nội dung trên màn hình. Việc rút ngắn khoảng cách này sẽ giúp giảm mức tiêu thụ băng thông và cải thiện tốc độ phân phối nội dung trang web cho người dùng. Hệ thống CDN (Content Delivery Network) với mạng lưới máy chủ phân tán toàn cầu ra đời nhằm giải quyết bài toán này.

Hệ thống CDN hoạt động dựa trên cơ chế lưu trữ bản sao tạm thời của các tệp tin website trên máy chủ proxy gần người dùng nhất. Điều này giúp tăng tốc độ tải trang đáng kể. Trong bài viết này, chúng ta sẽ cùng tìm hiểu cách triển khai một CDN server cục bộ để lưu trữ các tệp tin hình ảnh.

Để thực hiện việc này, trước tiên bạn cần chuẩn bị một số yêu cầu sau:

  1. Đầu tiên, bạn hãy tạo một thư mục để lưu trữ hình ảnh, ví dụ: /home/root2/cdn-images và tải một số hình ảnh vào đó. image.png

  2. Tiếp theo, bạn cần tạo Kubernetes secret với chứng chỉ TLS cho ingress để cung cấp dịch vụ ra công cộng. Bạn có thể sử dụng lệnh sau:

kubectl create secret tls tls-certificate --namespace default --key certificate-key.key --cert cetificate.crt
  1. Sau đó, bạn tạo bản ghi DNS A trỏ đến máy chủ của bạn, ví dụ: cdn.example.com.

  2. Tiếp theo, bạn cài đặt ingress và có thể tham khảo hướng dẫn chi tiết tại đây.

  3. Để tối ưu hóa hiệu suất, bạn nên bổ sung bộ nhớ đệm cho ingress. Bạn tạo tệp manifest configmap.yaml, dán nội dung bên dưới và áp dụng nó:

apiVersion: 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;"

Sử dụng lệnh sau để áp dụng thay đổi:

kubectl apply -f configmap.yaml

Bây giờ chúng ta sẽ triển khai mọi thứ. Sao chép và dán tệp manifest bên dưới, sau đó sửa đổi externalIPs, thay thế “YOUR public ip” bằng địa chỉ IP thực tế của bạn.

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

Sử dụng lệnh sau để áp dụng thay đổi:

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

Sau một vài giây, quá trình triển khai sẽ hoàn tất. image.png

Kiểm tra khả năng truy cập và bộ nhớ đệm: image.png

Tệp manifest cdn.yaml bao gồm Configmap, Deployment, Service, PersistentVolume và PersistentVolumeClaim. Phần Configmap chứa tệp default.conf đơn giản cho nginx. Trong phần Deployment, chúng ta cấu hình VolumeMounts với Volumes, nơi thêm Configmap và PersistentVolumeClaim.

Phần Service giúp dịch vụ có thể truy cập được. Ingress được sử dụng để cung cấp dịch vụ ra công cộng. Bên cạnh đó, chúng ta cũng thêm các annotations cho bộ nhớ đệm proxy. PersistentVolume và PersistentVolumeClaim được sử dụng để mount thư mục cdn-images, nơi lưu trữ hình ảnh.

Vậy đó là toàn bộ hướng dẫn cách tự xây dựng CDN server đơn giản trên Kubernetes, cảm ơn các bạn đã theo dõi bài viết.


All Rights Reserved

Viblo
Let's register a Viblo Account to get more interesting posts.