Triển khai Traefik v3 làm Kubernetes Ingress Controller: Dynamic Routing, Middleware Bảo mật và SSL Let’s Encrypt

DevOps tutorial - IT technology blog
DevOps tutorial - IT technology blog

Các tài nguyên Ingress tiêu chuẩn của Kubernetes bộc lộ rất nhiều hạn chế khi cụm (cluster) của bạn phát triển vượt quá một vài service. Bạn sẽ liên tục phải xoay xở với hàng loạt đoạn annotation rối rắm, vật lộn với các biểu thức chính quy (regex) viết lại URL dễ lỗi, và phải cài thêm nhiều bộ controller riêng lẻ chỉ để có được chứng chỉ TLS cơ bản và tính năng rate limiting.

Traefik v3 giải quyết triệt để những vấn đề đau đầu này. Được xây dựng dựa trên các Custom Resource Definition (CRD) native, Traefik xử lý dynamic routing, tự động tạo chứng chỉ Let’s Encrypt và chuỗi middleware ngay từ đầu mà không cần đến bất kỳ plugin bên thứ ba nào.

Bắt đầu nhanh: Cài đặt Traefik v3 bằng Helm

Bạn có thể đưa Traefik v3 vào hoạt động chỉ trong khoảng 5 phút. Helm giúp đơn giản hóa toàn bộ quy trình bằng cách triển khai controller vào namespace riêng và thiết lập định tuyến cổng cho HTTP, HTTPS cùng dashboard quản trị.

Thêm repository chính thức của Traefik và cập nhật chỉ mục (index) cục bộ của bạn:

helm repo add traefik https://traefik.github.io/charts
helm repo update

Tạo file values-quickstart.yaml cơ bản. Cấu hình này thiết lập 2 pod để đảm bảo tính sẵn sàng cao, mở các cổng 80 và 443, đồng thời kích hoạt web dashboard nội bộ:

# values-quickstart.yaml
deployment:
  enabled: true
  replicas: 2

ingressRoute:
  dashboard:
    enabled: true
    matchRule: Host(`traefik.local`)
    entryPoints: ["web"]

ports:
  web:
    port: 8000
    exposedPort: 80
  websecure:
    port: 8443
    exposedPort: 443

service:
  type: LoadBalancer

Triển khai chart vào namespace traefik mới:

helm install traefik traefik/traefik \
  --namespace traefik \
  --create-namespace \
  -f values-quickstart.yaml

Đợi từ 30 đến 60 giây để nhà cung cấp đám mây (như AWS NLB hoặc GCP Cloud Load Balancing) cấp phát một địa chỉ IP ngoại bộ:

kubectl get svc -n traefik traefik -w

Trước khi trỏ bản ghi DNS môi trường production về cụm, hãy kiểm tra giao diện quản trị cục bộ bằng port forward:

kubectl port-forward -n traefik $(kubectl get pods -n traefik -l app.kubernetes.io/name=traefik -o jsonpath='{.items[0].metadata.name}') 9000:9000

Truy cập http://localhost:9000/dashboard/ trên trình duyệt của bạn. Bạn sẽ thấy giao diện tổng quan trực quan về tất cả các entry point, router và backend service đang hoạt động.

Kiến trúc cốt lõi: Dynamic Routing với CRD

Các đối tượng Ingress truyền thống trong Kubernetes phụ thuộc rất nhiều vào các annotation riêng của từng nhà cung cấp. Những annotation này khiến file manifest trở nên dễ vỡ và khó xác thực trong các bước kiểm tra CI/CD. Traefik khắc phục hoàn toàn vấn đề này bằng cách sử dụng ba Custom Resource Definition chuyên dụng: IngressRoute, Middleware và TraefikService.

IngressRoute so với Kubernetes Ingress tiêu chuẩn

Traefik vẫn phân tích cú pháp các đối tượng Ingress tiêu chuẩn để đảm bảo tính tương thích ngược. Tuy nhiên, các manifest IngressRoute native mang lại cú pháp định tuyến gọn gàng và rõ ràng hơn nhiều. Thay vì các biểu thức chính quy rewrite khó đọc của NGINX, bạn có thể viết các biểu thức Boolean dễ hiểu như Host(`api.example.com`) && PathPrefix(`/v1`).

Triển khai ứng dụng mẫu với Dynamic Routing

Khởi chạy một HTTP echo service gọn nhẹ với 2 replica trong namespace default của bạn:

apiVersion: apps/v1
kind: Deployment
metadata:
  name: demo-app
  namespace: default
spec:
  replicas: 2
  selector:
    matchLabels:
      app: demo-app
  template:
    metadata:
      labels:
        app: demo-app
    spec:
      containers:
      - name: web
        image: hashicorp/http-echo
        args: ["-text=Xin chào từ Traefik v3 Ingress!"]
        ports:
        - containerPort: 5678
---
apiVersion: v1
kind: Service
metadata:
  name: demo-service
  namespace: default
spec:
  ports:
  - port: 80
    targetPort: 5678
  selector:
    app: demo-app

Public deployment này ra ngoài bằng custom resource IngressRoute:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: demo-ingress-route
  namespace: default
spec:
  entryPoints:
    - web
  routes:
    - match: Host(`demo.example.com`) && PathPrefix(`/api`)
      kind: Rule
      services:
        - name: demo-service
          port: 80

Áp dụng các manifest này bằng lệnh kubectl apply -f app.yaml. Traefik theo dõi Kubernetes API server để đón nhận các sự kiện tài nguyên. Nó cập nhật bảng định tuyến nội bộ trong chưa đầy 50 mili giây mà không làm gián đoạn các kết nối TCP đang truyền tải hay phải khởi động lại binary cốt lõi.

Cấu hình nâng cao: Middleware bảo mật & SSL tự động

Các môi trường production đòi hỏi HTTP header phải được tăng cường bảo mật, kiểm soát lưu lượng (rate throttling) linh hoạt và quản lý vòng đời TLS hoàn toàn tự động.

1. Cấu hình tự động cấp phát SSL qua ACME (Let’s Encrypt)

Traefik tích hợp sẵn một ACME client. Nó tự động xử lý toàn bộ vòng đời cấp phát và gia hạn chứng chỉ, đồng thời lưu các khóa (key) tương ứng vào ổ đĩa, nhờ đó bạn không cần phải cài đặt hay duy trì các CRD của cert-manager cho các mô hình ingress độc lập.

Lưu cấu hình này thành values-production.yaml để bật xác thực HTTP-01 challenge tự động và bắt buộc chuyển hướng HTTPS. Lưu ý rằng chúng ta đặt replicas là 1 vì một volume ReadWriteOnce không thể chia sẻ đồng thời giữa nhiều node:

# values-production.yaml
deployment:
  replicas: 1

persistence:
  enabled: true
  name: data
  accessMode: ReadWriteOnce
  size: 1Gi
  path: /data

additionalArguments:
  - "[email protected]"
  - "--certificatesresolvers.letsencrypt.acme.storage=/data/acme.json"
  - "--certificatesresolvers.letsencrypt.acme.httpchallenge=true"
  - "--certificatesresolvers.letsencrypt.acme.httpchallenge.entrypoint=web"
  - "--entrypoints.web.http.redirections.entrypoint.to=websecure"
  - "--entrypoints.web.http.redirections.entrypoint.scheme=https"

Các tham số này chuyển hướng toàn bộ lưu lượng cổng 80 đến sang HTTPS, đồng thời thiết lập resolver letsencrypt để xử lý các challenge qua cổng 80 một cách liền mạch.

Cập nhật những thay đổi cấu hình này vào bản release đang chạy của bạn:

helm upgrade traefik traefik/traefik -n traefik -f values-production.yaml

2. Áp dụng các Middleware bảo mật

Middleware nằm trực tiếp trên đường dẫn request giữa Traefik và các pod downstream. Chúng cho phép bạn viết lại header, chèn token xác thực và chặn lưu lượng độc hại trước khi request chạm tới mã nguồn ứng dụng.

Dưới đây là manifest middleware chuẩn production. Nó áp dụng các security header thiết yếu theo khuyến nghị của OWASP và giới hạn lưu lượng đến ở mức 100 request/giây với ngưỡng bùng nổ (burst) cho phép là 50:

apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: app-security-headers
  namespace: default
spec:
  headers:
    frameDeny: true
    sslRedirect: true
    browserXssFilter: true
    contentTypeNosniff: true
    stsIncludeSubdomains: true
    stsPreload: true
    stsSeconds: 31536000
    customResponseHeaders:
      X-Robots-Tag: "none,noindex,nofollow"
---
apiVersion: traefik.io/v1alpha1
kind: Middleware
metadata:
  name: app-ratelimit
  namespace: default
spec:
  rateLimit:
    average: 100
    burst: 50

3. Kết hợp TLS và Middleware trong IngressRoute

Liên kết các chính sách bảo mật và TLS resolver tự động vào một IngressRoute HTTPS:

apiVersion: traefik.io/v1alpha1
kind: IngressRoute
metadata:
  name: demo-secure-route
  namespace: default
spec:
  entryPoints:
    - websecure
  routes:
    - match: Host(`app.example.com`)
      kind: Rule
      services:
        - name: demo-service
          port: 80
      middlewares:
        - name: app-security-headers
        - name: app-ratelimit
  tls:
    certResolver: letsencrypt

Trong các môi trường có thông lượng cao—xử lý hơn 12.000 request/giây trên 45 microservice—mô hình này vẫn vận hành cực kỳ ổn định. Chi phí định tuyến (overhead) dưới mức mili giây giúp độ trễ p99 duy trì dưới 5ms, đồng thời ngăn chặn các đợt lưu lượng tăng đột biến làm quá tải cơ sở dữ liệu backend.

Vận hành Day-2: Sẵn sàng cho môi trường Production

Để vận hành Traefik ổn định dưới tải lớn kéo dài trong môi trường production, bạn cần lên kế hoạch cẩn thận về quản lý trạng thái, áp dụng quy tắc toàn cục (global rules) và khả năng quan sát (observability).

Xử lý xung đột khóa lưu trữ ACME trong cụm High Availability

Traefik ghi dữ liệu chứng chỉ ACME vào một file cục bộ duy nhất (acme.json). Các persistent volume tiêu chuẩn trong Kubernetes (EBS, GPD hoặc Ceph RBD) sử dụng chế độ ReadWriteOnce, ngăn không cho nhiều pod ghi đồng thời. Nếu bạn mở rộng Traefik lên nhiều replica với resolver dùng chung file, xung đột khóa file (file lock collision) sẽ làm hỏng dữ liệu chứng chỉ của bạn.

Hãy chọn một trong hai giải pháp đã được kiểm chứng thực tế cho cụm ingress nhiều replica:

  • Ủy quyền cấp phát cho cert-manager: Chạy cert-manager độc lập. Nó sẽ ghi chứng chỉ TLS vào các đối tượng Secret native của Kubernetes, giúp nhiều pod Traefik có thể mount đồng thời qua tls.secretName.
  • Nâng cấp lên Traefik Enterprise: Nếu bạn ưu tiên khả năng clustering native mà không cần operator bên thứ ba, phiên bản Enterprise sẽ điều phối chứng chỉ giữa các node phân tán thông qua cơ chế đồng thuận Raft.

Áp dụng Middleware toàn cục cho các EntryPoint

Khai báo lặp lại cùng một bộ security header trên 50 manifest microservice riêng biệt rất dễ dẫn đến sai sót của con người. Thay vào đó, hãy gắn trực tiếp các middleware chung vào định nghĩa entry point trong Helm:

ports:
  websecure:
    middlewares:
      - default-app-security-headers@kubernetescrd

Traefik sẽ thực thi HSTS và rate limit trên phạm vi toàn cục, ngay cả khi các lập trình viên quên định nghĩa middleware trong manifest service của họ.

Giám sát các tín hiệu vàng (Golden Signals) với Prometheus

Traefik cung cấp sẵn telemetry native cho Prometheus trên cổng 9100. Hãy bật tính năng thu thập metrics trong values của Helm:

metrics:
  prometheus:
    entryPoint: metrics
    addEntryPointsLabels: true
    addServicesLabels: true

Kết hợp endpoint này với ServiceMonitor của Prometheus Operator. Theo dõi traefik_entrypoint_request_duration_seconds_bucket để kịp thời phát hiện độ trễ tăng cao trước khi ảnh hưởng đến người dùng, và thiết lập cảnh báo cho traefik_service_requests_total{code=~"5.."} để phát hiện lỗi theo thời gian thực.

Share: