Cấu hình Cloudflare Workers làm Gateway Proxy cho OpenFaaS
Bước đầu tiên là thiết lập Cloudflare Workers đóng vai trò là điểm vào (Entry Point) duy nhất, chịu trách nhiệm chuyển tiếp yêu cầu từ Edge về Core (OpenFaaS Gateway).
Mục đích là giảm tải cho Kubernetes Cluster bằng cách chỉ cho phép traffic hợp lệ đi vào, đồng thời chuẩn hóa header và phương thức kết nối.
Tạo file src/index.js với nội dung sau để định nghĩa logic proxy cơ bản:
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
// Cấu hình Gateway OpenFaaS từ biến môi trường
const openfaasUrl = env.OPENFAAS_GATEWAY_URL || "http://openfaas-gateway.oasis.svc.cluster.local:8080";
// Xây dựng URL đích
const targetUrl = new URL(url.pathname + url.search, openfaasUrl);
// Chuẩn bị headers cho OpenFaaS
const headers = new Headers(request.headers);
headers.set("Host", new URL(openfaasUrl).host);
headers.set("Content-Type", request.headers.get("Content-Type") || "application/json");
// Gửi request tới OpenFaaS
try {
const response = await fetch(targetUrl, {
method: request.method,
headers: headers,
body: request.body,
});
// Trả về kết quả nguyên bản từ OpenFaaS
return new Response(response.body, {
status: response.status,
headers: response.headers,
});
} catch (error) {
return new Response("Gateway Error: Connection to OpenFaaS failed", { status: 503 });
}
}
};
Kết quả mong đợi: File src/index.js được tạo thành công, sẵn sàng để đóng gói và deploy lên Cloudflare.
Cài đặt biến môi trường trong Cloudflare Dashboard
Bạn cần cấu hình biến môi trường để Workers biết đường dẫn nội bộ của OpenFaaS Gateway.
Trên trang quản trị Cloudflare Workers, vào mục "Environment Variables" và thêm biến OPENFAAS_GATEWAY_URL với giá trị là địa chỉ public IP hoặc DNS của LoadBalancer Kubernetes (nơi OpenFaaS Gateway đang chạy).
Ví dụ giá trị: https://openfaas.example.com hoặc http://:8080.
Lưu ý: Đảm bảo OpenFaaS Gateway có thể tiếp nhận traffic từ public internet (cấu hình Service Type LoadBalancer trong K8S ở các phần trước).
Triển khai logic định tuyến động dựa trên vị trí địa lý (Geo-IP)
Tiếp theo, chúng ta sẽ tận dụng khả năng xác định vị trí của Cloudflare để định tuyến traffic. Các request từ khu vực có độ trễ thấp sẽ được xử lý tại Edge, trong khi request phức tạp hoặc từ vùng xa sẽ được chuyển về Core.
Tạo file cấu hình src/geo-router.js để chứa logic phân tách:
export const shouldRouteToEdge = (cf) => {
// Lấy mã quốc gia từ metadata Cloudflare
const countryCode = cf && cf.geo && cf.geo.country;
// Danh sách các quốc gia được phép xử lý tại Edge (ví dụ: Việt Nam, Singapore, Nhật Bản)
const edgeAllowedCountries = ["VN", "SG", "JP"];
// Nếu request đến từ các nước trong danh sách và là phương thức GET (đọc dữ liệu)
if (edgeAllowedCountries.includes(countryCode)) {
return true;
}
return false;
};
Kết quả mong đợi: Module geo-router.js được tạo, sẵn sàng để import vào file chính.
Tích hợp Geo-Router vào Index chính
Sửa lại file src/index.js để sử dụng module định tuyến vừa tạo. Logic sẽ kiểm tra vị trí và quyết định là trả cache (nếu có) hay gọi Core.
import { shouldRouteToEdge } from "./geo-router";
export default {
async fetch(request, env, ctx) {
const url = new URL(request.url);
const cf = request.cf; // Dữ liệu Cloudflare
// Logic định tuyến dựa trên Geo-IP
if (request.method === "GET" && shouldRouteToEdge(cf)) {
console.log(`Routing to Edge Cache for country: ${cf.geo.country}`);
// Gọi logic cache (sẽ được triển khai ở phần tiếp theo)
const cacheKey = "cache:" + url.pathname + url.search;
const cachedResponse = await env.MY_KV.get(cacheKey);
if (cachedResponse) {
return new Response(cachedResponse, {
headers: { "X-Cache": "HIT", "Content-Type": "application/json" }
});
}
}
// Fallback về Core (OpenFaaS) cho các trường hợp còn lại
const openfaasUrl = env.OPENFAAS_GATEWAY_URL || "http://openfaas-gateway.oasis.svc.cluster.local:8080";
const targetUrl = new URL(url.pathname + url.search, openfaasUrl);
const headers = new Headers(request.headers);
headers.set("Host", new URL(openfaasUrl).host);
headers.set("Content-Type", request.headers.get("Content-Type") || "application/json");
try {
const response = await fetch(targetUrl, {
method: request.method,
headers: headers,
body: request.body,
});
// Nếu là GET và từ vùng Edge, lưu vào cache
if (request.method === "GET" && shouldRouteToEdge(cf)) {
const cacheKey = "cache:" + url.pathname + url.search;
ctx.waitUntil(env.MY_KV.put(cacheKey, response.clone().text()));
}
return new Response(response.body, {
status: response.status,
headers: response.headers,
});
} catch (error) {
return new Response("Gateway Error: Connection to OpenFaaS failed", { status: 503 });
}
}
};
Kết quả mong đợi: Workers sẽ tự động trả về cache cho người dùng ở VN/SG/JP nếu có dữ liệu, giảm tải cho OpenFaaS.
Sử dụng Cloudflare KV để lưu cache kết quả từ OpenFaaS
Để tối ưu hóa hiệu năng, chúng ta cần tạo một namespace KV trong Cloudflare để lưu trữ kết quả trả về từ OpenFaaS.
Trên dashboard Cloudflare, vào mục "Workers & Pages" -> chọn worker của bạn -> tab "Bindings" -> "Create Binding".
Chọn loại Variable hoặc KV Namespace. Đặt tên biến là MY_KV và tạo một namespace mới có tên tương tự (ví dụ: openfaas-cache).
Cấu hình TTL (Time To Live) cho các key trong KV nếu muốn tự động xóa cache cũ (tùy chọn trong config, hoặc xử lý trong code).
Verify kết quả Cache
Thực hiện request từ địa chỉ IP thuộc vùng được phép (VN) vào endpoint API của bạn.
curl -I https://your-worker-domain.workers.dev/api/data
Kiểm tra header X-Cache trong phản hồi. Lần đầu tiên sẽ là MISS (hoặc không có), lần thứ hai phải là HIT.
Đồng thời, kiểm tra logs của Cloudflare Workers (trong tab Logs) để thấy dòng log Routing to Edge Cache.
Xử lý fallback khi Cloudflare Workers gặp lỗi hoặc quá tải
Kiến trúc Hybrid yêu cầu khả năng chịu lỗi cao. Nếu Workers gặp lỗi hoặc OpenFaaS không phản hồi, hệ thống cần có cơ chế fallback để trả về thông báo rõ ràng hoặc chuyển hướng sang một endpoint dự phòng.
Chúng ta sẽ sử dụng pattern "Circuit Breaker" đơn giản trong code để xử lý lỗi kết nối và trả về fallback.
export default {
async fetch(request, env, ctx) {
// ... (Logic Geo-IP và Cache ở trên) ...
// Thực hiện gọi OpenFaaS với cơ chế try-catch mở rộng
let response;
try {
// Giả lập delay để test fallback (xóa dòng này khi production)
// await new Promise(r => setTimeout(r, 5000));
response = await fetch(targetUrl, {
method: request.method,
headers: headers,
body: request.body,
});
} catch (err) {
// Xử lý lỗi mạng hoặc timeout
console.error("OpenFaaS connection failed, triggering fallback", err);
// Fallback: Trả về JSON thông báo lỗi hoặc dữ liệu tĩnh
const fallbackData = {
status: "degraded",
message: "Core service is currently unavailable. Please try again later.",
timestamp: new Date().toISOString()
};
return new Response(JSON.stringify(fallbackData), {
status: 503,
headers: {
"Content-Type": "application/json",
"Retry-After": "30"
}
});
}
// ... (Logic trả về response và cache) ...
}
};
Kết quả mong đợi: Khi OpenFaaS bị sập hoặc mất kết nối, người dùng vẫn nhận được phản hồi HTTP 503 có cấu trúc JSON thay vì lỗi kết nối thời gian chờ (timeout) của trình duyệt.
Tối ưu hóa đường truyền dữ liệu giữa Edge và Core
Để giảm độ trễ khi gọi từ Edge về Core, cần tối ưu hóa cấu hình mạng và header.
Sử dụng Connection: keep-alive trong header khi gọi fetch từ Workers về OpenFaaS để tái sử dụng kết nối TCP, tránh overhead handshake.
// Thêm vào phần tạo headers trong fetch
headers.set("Connection", "keep-alive");
headers.set("Accept-Encoding", "gzip"); // Nếu OpenFaaS hỗ trợ compression
Tối ưu hóa đường truyền còn bao gồm việc cấu hình Cloudflare Tunnel (Cloudflared) nếu OpenFaaS chạy trong private cluster, thay vì expose trực tiếp qua LoadBalancer public.
Triển khai Cloudflared như một DaemonSet trong Kubernetes để tạo đường hầm an toàn từ Core về Cloudflare Edge.
apiVersion: v1
kind: ConfigMap
metadata:
name: cloudflared-config
namespace: openfaas
data:
config.yml: |
ingress:
- hostname: openfaas.example.com
service: http://openfaas-gateway:8080
- hostname: "*"
service: http://localhost:8080
---
apiVersion: apps/v1
kind: DaemonSet
metadata:
name: cloudflared
namespace: openfaas
spec:
selector:
matchLabels:
name: cloudflared
template:
metadata:
labels:
name: cloudflared
spec:
containers:
- name: cloudflared
image: cloudflare/cloudflared:latest
command:
- cloudflared
- tunnel
- --config
- /etc/cloudflared/config.yml
- run
env:
- name: TUNNEL_TOKEN
valueFrom:
secretKeyRef:
name: cloudflared-secret
key: tunnel-token
volumeMounts:
- name: config
mountPath: /etc/cloudflared
volumes:
- name: config
configMap:
name: cloudflared-config
Kết quả mong đợi: Traffic từ Cloudflare vào Kubernetes được đi qua đường hầm TLS an toàn, không cần mở port public cho OpenFaaS Gateway, tăng tính bảo mật và độ ổn định đường truyền.
Verify kết quả tối ưu hóa
Sử dụng công cụ wrk hoặc ab để benchmark từ Edge về Core so với việc gọi trực tiếp.
wrk -t12 -c40 -d30 https://your-worker-domain.workers.dev/api/health
Kiểm tra latency trong response header cf-cache-status và thời gian xử lý (TTFB). Nếu cấu hình đúng, TTFB cho request cache phải < 50ms, request đi Core phải ổn định và không bị timeout do mạng.
Điều hướng series:
Mục lục: Series: Series: Xây dựng nền tảng Serverless và Edge Computing an toàn với OpenFaaS, Cloudflare Workers và Wasm trên hạ tầng Kubernetes
« Phần 5: Tích hợp WebAssembly (Wasm) vào OpenFaaS và Cloudflare
Phần 7: Bảo mật: Xác thực, mã hóa và bảo vệ API »