1. Kiến trúc và vai trò của Iceberg REST Catalog
Apache Iceberg REST Catalog đóng vai trò là lớp trừ tượng hóa (abstraction layer) trung tâm, tách biệt việc lưu trữ metadata khỏi hệ thống lưu trữ vật lý (Object Storage).
Vai trò chính của nó là cung cấp một giao diện HTTP chuẩn hóa cho các client (như Trino, Spark, Flink) để thực hiện các thao tác CRUD trên bảng (Table) và snapshot mà không cần biết backend cụ thể là gì (S3, GCS, HDFS).
Trong kiến trúc này, REST Catalog chịu trách nhiệm quản lý namespace, phân quyền (ACL), và cache metadata, giúp các engine truy vấn hoạt động độc lập và mở rộng dễ dàng hơn.
2. Chuẩn bị và cấu hình Helm Chart cho REST Catalog
Trước tiên, ta cần thêm repository Helm chính thức của Apache Iceberg vào hệ thống Kubernetes để có thể cài đặt các thành phần chuẩn.
helm repo add iceberg https://iceberg.apache.org/charts/
helm repo update
Kết quả mong đợi: Output hiển thị "repository 'iceberg' added" và danh sách các chart mới nhất được cập nhật.
Tiếp theo, tạo một file cấu hình YAML (values.yaml) để định nghĩa tham số kết nối với Object Storage. Ta sẽ sử dụng MinIO làm backend storage trong môi trường demo này, nhưng cấu hình này cũng áp dụng tương tự cho AWS S3.
Tạo file iceberg-catalog-values.yaml với nội dung hoàn chỉnh sau:
catalog-name: my-iceberg-catalog
namespace: iceberg-demo
rest:
image:
repository: tabulario/iceberg-rest
tag: latest
resources:
requests:
cpu: 500m
memory: 1Gi
limits:
cpu: 1000m
memory: 2Gi
env:
- name: iceberg.catalog.name
value: my-iceberg-catalog
- name: iceberg.catalog.warehouse
value: s3://iceberg-data/
- name: iceberg.catalog.io-impl
value: org.apache.iceberg.aws.s3.S3FileIO
- name: iceberg.catalog.storage-locations
value: s3://iceberg-data/
# Cấu hình cho MinIO (thay đổi endpoint nếu dùng S3 thật)
- name: iceberg.catalog.s3.endpoint
value: http://minio.minio.svc.cluster.local:9000
- name: iceberg.catalog.s3.path-style-access
value: "true"
- name: iceberg.catalog.s3.access-key-id
value: minioadmin
- name: iceberg.catalog.s3.secret-access-key
value: minioadmin
service:
type: ClusterIP
port: 8181
Kết quả mong đợi: File được lưu thành công, chứa đầy đủ các biến môi trường để REST Catalog có thể kết nối đến storage backend.
3. Triển khai Catalog và khởi tạo Namespace
Sử dụng lệnh Helm install để triển khai Iceberg REST Catalog dựa trên file cấu hình vừa tạo. Ta đặt tên release là "iceberg-catalog" và namespace là "iceberg-demo".
helm install iceberg-catalog iceberg/iceberg-rest \
-n iceberg-demo \
-f iceberg-catalog-values.yaml \
--create-namespace
Kết quả mong đợi: Pod và Service được tạo thành công trong namespace "iceberg-demo", trạng thái hiển thị "NAME NAMESPACE STATUS".
Chờ đợi Pod chuyển sang trạng thái "Running". Trong quá trình khởi động, container sẽ thực hiện kiểm tra kết nối đến storage backend và khởi tạo cơ sở dữ liệu metadata (thường dùng SQLite hoặc JDBC tùy config, ở đây ta dùng file-based hoặc embedded cho đơn giản nếu không config JDBC riêng).
Kiểm tra trạng thái Pod để đảm bảo không có lỗi khởi động (CrashLoopBackOff):
kubectl get pods -n iceberg-demo
Kết quả mong đợi: Pod "iceberg-catalog-rest-..." có trạng thái "Running" và "READY" là 1/1.
Để kiểm tra log khởi động và xác nhận Catalog đã sẵn sàng:
kubectl logs -n iceberg-demo -l app=iceberg-catalog --tail=50
Kết quả mong đợi: Log hiển thị dòng "Starting Iceberg REST Catalog" và "Server started on port 8181", không có lỗi "Connection refused" hoặc "AccessDenied".
4. Tạo Namespace và Table thông qua REST API
Vì REST Catalog là giao diện HTTP, ta sẽ dùng `curl` để tạo Namespace (tương đương Schema trong SQL) trước khi tạo Table. Đây là bước bắt buộc trong Iceberg.
Tạo Namespace tên là "analytics" bằng phương thức POST:
curl -X POST http://iceberg-catalog-rest.iceberg-demo.svc.cluster.local:8181/v1/namespaces/analytics \
-H "Content-Type: application/json" \
-d '{"properties": {"comment": "Namespace for analytics data"}}'
Kết quả mong đợi: Trả về mã HTTP 200 OK và JSON xác nhận namespace "analytics" đã được tạo.
Tiếp theo, tạo một Table mẫu tên là "user_events" bên trong namespace "analytics" vừa tạo. Định nghĩa schema bao gồm các cột và partitioning strategy.
curl -X POST http://iceberg-catalog-rest.iceberg-demo.svc.cluster.local:8181/v1/namespaces/analytics/tables/user_events \
-H "Content-Type: application/json" \
-d '{
"name": "user_events",
"schema": {
"type": "struct",
"fields": [
{"id": 1, "name": "user_id", "type": "string", "required": true},
{"id": 2, "name": "event_type", "type": "string", "required": false},
{"id": 3, "name": "timestamp", "type": "timestamp", "required": false}
]
},
"partition-spec": [
{"name": "event_type", "source": "event_type", "kind": "identity"}
],
"location": "s3://iceberg-data/analytics/user_events",
"properties": {
"comment": "Table for user event tracking",
"write.delete.default": "true"
}
}'
Kết quả mong đợi: Trả về mã HTTP 200 OK và JSON chứa thông tin chi tiết của table vừa tạo (table_id, schema_id, current_snapshot_id là null vì chưa có dữ liệu).
5. Xác minh kết quả và kiểm tra trạng thái
Để đảm bảo Catalog hoạt động ổn định và dữ liệu metadata đã được lưu vào Object Storage, ta thực hiện các bước kiểm tra sau.
Kiểm tra lại danh sách các Table trong namespace "analytics":
curl -X GET http://iceberg-catalog-rest.iceberg-demo.svc.cluster.local:8181/v1/namespaces/analytics/tables \
-H "Content-Type: application/json"
Kết quả mong đợi: JSON trả về chứa mảng danh sách tables, trong đó có "user_events" với các thuộc tính metadata khớp với yêu cầu tạo.
Verify trên Object Storage (MinIO) để chắc chắn metadata và data files đã được ghi vật lý. Nếu dùng MinIO console hoặc lệnh `mc`:
mc ls minio/iceberg-data/analytics/user_events/metadata/
Kết quả mong đợi: Hiển thị các file metadata có đuôi `.metadata.json` (ví dụ: v1.metadata.json) và các file snapshot. Nếu file này tồn tại, chứng tỏ Iceberg REST Catalog đã giao tiếp thành công với backend storage.
Để đảm bảo tính sẵn sàng, ta có thể expose service ra ngoài để test từ máy client (nếu cần), nhưng trong môi trường Kubernetes, việc truy cập qua Service ClusterIP là đủ để các pod khác (như Trino) trong cùng cluster sử dụng.
kubectl get svc -n iceberg-demo
Kết quả mong đợi: Service "iceberg-catalog-rest" đang lắng nghe ở port 8181 với kiểu ClusterIP.
Điều hướng series:
Mục lục: Series: Xây dựng nền tảng Data Fabric hiện đại với Apache Iceberg, Trino và Kubernetes
« Phần 1: Giới thiệu kiến trúc Data Fabric và chuẩn bị môi trường Kubernetes
Phần 2: Triển khai Apache Iceberg trên Kubernetes với Iceberg REST Catalog »