Train model
Ở bài blog này mình tiếp tục sử dụng tập dữ liệu Iris huyền thoại để train model Random Forest.
1 | from sklearn.datasets import load_iris |
Sau khi train xong model, chúng ta sẽ lưu model sử dụng joblib như sau
1 | import joblib |
Viết API sử dụng FastAPI
Đầu tiên chúng ta sẽ import những thư viện cần thiết
1 | from fastapi import FastAPI |
Tiếp theo chúng ta sẽ khởi tạo instance FastAPI,
1 | app = FastAPI() |
và sử dụng pydantic để validate request body [1]. Ở đây chúng ta expect request body sẽ có dạng 1 dict, với 4 attribute có type float
.
1 | from pydantic import BaseModel |
Bây giờ chúng ta sẽ định nghĩa route /predict
như sau:
1 |
|
Hàm predict
sẽ validate request nhận được, predict, và trả về kết quả. target_names
ở đây là 1 list chứa tên các class để map từ class_idx target_names = ['setosa', 'versicolor', 'virginica']
Deploy API trên k8s
Có nhiều cách config (viết YAML file) để deploy API trên k8s, mình sẽ nói chi tiết hơn trong các bài blog sau. Ở đây mình sẽ sử dụng một cách khá phổ biến đó là deployment
kết hợp với service
object.
1 | apiVersion: apps/v1 |
Một cách dễ hiểu: deployment
dùng để thông báo với k8s control plane
rằng: xin hãy khởi tạo và đảm bảo giúp tôi số lượng pod bằng số lượng replicas
. Trong khi đó, service
sẽ giống như một lớp abstract để front-end/client giao tiếp với các pod, bởi lẽ IP của các pod có thể thay đổi bất cứ lúc nào. service
sẽ sử dụng selector app: iris
để xác định các pod của mình. Khi gọi service iris
, thì các requests sẽ được phân bố tới các pod theo cơ chế mặc định là round-robin
(nôm na là request 1 tới ông pod 1 rồi thì request thứ 2 sẽ tới ông pod thứ 2).
Note: Cho các bác chưa quen với k8s, thì pod đơn giản chỉ là một nhóm các container chung storage và network.
Ơ nhưng mà tôi gọi service iris
như thế nào nhể?
Nếu các bác có một service trong cùng cluster, thì chỉ việc gọi thông qua qua DNS name
của từng service theo dạng my-svc.my-namespace.svc.cluster.local
. Ví dụ service iris
ở trên sẽ là iris.models.svc.cluster.local
.
Thế nếu service của tôi ở cluster khác thì gọi sao?
Mời các bác xem tiếp phần dưới nhé.
Quản lý traffic trong cluster
Các bác có thể sử dụng một trong những cách expose service sau để external service/client có thể gọi tới:
Nginx Ingress Controller
Đầu tiên, các bác cài đặt Nginx Ingress Controller
theo link này.
Tiếp đó chỉ cần viết Ingress
object với spec ingressClassName: nginx
hoặc annotation kubernetes.io/ingress.class: nginx
như sau:
1 | apiVersion: networking.k8s.io/v1 |
iris-ingress
định nghĩa rule cho request tới cluster như sau: khi gọi tới Nginx Ingress Controller
theo route /seldon/models/iris/api/v1.0/
, traffic sẽ được điều hướng sang service iris
.
Nguồn: https://www.nginx.com/products/nginx-ingress-controller/ |
Istio Ingress Controller
Để sử dụng cách này, trước tiên cluster phải được cài đặt Istio Service Mesh (nếu chưa có các bác có thể cài theo link này). Bộ cài đặt Kubeflow mặc định có cái này, nên khả năng cao nếu bác nào đang dùng Kubeflow thì đã có sẵn cái này luôn rồi :>. Tiếp theo chỉ cần viết bộ đôi Gateway
và VirtualService
tương tự như sau:
1 | apiVersion: networking.istio.io/v1beta1 |
Trong đó: Gateway đóng vai trò như người gác cửa giúp accept/reject external requests. Còn virtual service sẽ điều hướng các request đã được accept đi tới service iris
dựa vào route /seldon/models/iris/api/v1.0/
.
Note 1: Service mesh thông thường có các tính năng như service discovery, load balancing, encryption và failure recovery. Service mesh cũng hơn API Gateway ở chỗ mỗi lần thêm/bớt 1 microservice thì không cần config lại ở đầu API Gateway nữa.
Note 2: Nếu các bác dùng Seldon Core
, thì mỗi lần khởi tạo 1 SeldonDeployment
object, thì Deployment
, Service
, VirtualService
và Gateway
sẽ tự động được tạo ra luôn mà không cần làm gì thêm.
Note 3: Ở cách expose này, Nginx Ingress Controller
ở hình trên sẽ được thay bằng Istio Ingress Gateway
Source code
https://github.com/quan-dang/fastapi-k8s
References
[1] https://pydantic-docs.helpmanual.io/
[2] https://kubernetes.github.io/ingress-nginx/user-guide/basic-usage/
[3] https://www.journaldev.com/54888/gateway-and-virtual-service-in-istio