BentoML - Yatai
Prerequisites
- docker, helm, kustomize 설치 필요
- Kubernetes v1.22.7 version
- Kubeadm K8s Cluster
- 로컬환경이 아닌 LocalPC(Client)에서 Cluster Server에 요청하는 방식
- git clone https://github.com/bentoml/bentoml.git && cd ./examples/quickstart
- pip install -r ./requirements.txt
Install Kubernetes - Kubeadm
- 모두의 MLOps의 Kubeadm 설치
- kubelet kubeadm kubectl install 하는부분을 sudo apt-get install -y kubelet=1.22.7-00 kubeadm=1.22.7-00 kubectl=1.22.7-00 로 변경
- flannel 설치하는 부분을 kubectl apply -f https://raw.githubusercontent.com/flannel-io/flannel/v0.20.2/Documentation/kube-flannel.yml 로 변경
- https://mlops-for-all.github.io/docs/setup-kubernetes/kubernetes-with-kubeadm/
Install CSI Plugin : Local Path Provisioner
- https://mlops-for-all.github.io/docs/setup-kubernetes/install-kubernetes-module/ CSI Plugin : Local Path Provisioner 부분 참조
Yatai Installation
GitHub - bentoml/Yatai: Model Deployment at Scale on Kubernetes 🦄️
Model Deployment at Scale on Kubernetes 🦄️. Contribute to bentoml/Yatai development by creating an account on GitHub.
github.com
bash <(curl -s "https://raw.githubusercontent.com/bentoml/yatai/main/scripts/quick-install-yatai.sh")
위 스크립트는 yatai-system namespace에 다음의 종속성이 있는 PostgreSQL, MinIO을 같이 설치한다.
yatai-image-builder Installation
- This will install the BentoRequest CRD(Custom Resource Definition) and Bento CRD
- 이미지 빌더 컴포넌트는 도커레지스트리가 없다는 가정하에 퀵 인스톨로 설치한다.
DEVEL=true bash <(curl -s "https://raw.githubusercontent.com/bentoml/yatai-image-builder/main/scripts/quick-install-yatai-image-builder.sh")
yatai-deployment Installation
- Nginx 인그레스 컨트롤러 설치
# install the controller in the ingress-nginx namespace
helm upgrade --install ingress-nginx ingress-nginx \
--repo https://kubernetes.github.io/ingress-nginx \
--namespace ingress-nginx --create-namespace
# pod 확인
kubectl get pods --namespace=ingress-nginx
- yatai-deployment 컴포넌트 설치
# 네임스페이스 생성
# for yatai-deployment deployment
kubectl create ns yatai-deployment
# for bento deployment resources
kubectl create ns yatai
# metrics-server 설치
kubectl apply -f https://github.com/kubernetes-sigs/metrics-server/releases/latest/download/components.yaml
# Configure network
export INGRESS_CLASS=$(kubectl get ingressclass -o jsonpath='{.items[0].metadata.name}' 2> /dev/null)
echo $INGRESS_CLASS
# Install yatai-deployment
helm upgrade --install yatai-deployment-crds yatai-deployment-crds \
--repo https://bentoml.github.io/helm-charts \
-n yatai-deployment
# 다음과 같은 오류가 발생하는 경우:
# Error: rendered manifests contain a resource that already exists. Unable to continue with install: CustomResourceDefinition "bentodeployments.serving.yatai.ai" in namespace "" exists and cannot be imported into the current release: invalid ownership metadata; label validation error: missing key "app.kubernetes.io/managed-by": must be set to "Helm"; annotation validation error: missing key "meta.helm.sh/release-name": must be set to "yatai-deployment-crds"; annotation validation error: missing key "meta.helm.sh/release-namespace": must be set to "yatai-deployment"
# 이는 이미 BentoDeployment CRD가 있음을 의미하므로 다음 명령을 사용하여 수정해야 합니다.
kubectl label crd bentodeployments.serving.yatai.ai app.kubernetes.io/managed-by=Helm
kubectl annotate crd bentodeployments.serving.yatai.ai meta.helm.sh/release-name=yatai-deployment-crds meta.helm.sh/release-namespace=yatai-deployment
# yatai-deployment의 CRD가 설정되었는지 확인
kubectl wait --for condition=established --timeout=120s crd/bentodeployments.serving.yatai.ai
# 출력 확인
customresourcedefinition.apiextensions.k8s.io/bentodeployments.serving.yatai.ai condition met
# yatai-deployment helm 차트 설치
helm upgrade --install yatai-deployment yatai-deployment \
--repo https://bentoml.github.io/helm-charts \
-n yatai-deployment \
--set layers.network.ingressClass=$INGRESS_CLASS
kubectl -n yatai-deployment patch cm/network --type merge --patch '{"data":{"ingress-class":"'${INGRESS_CLASS}'"}}'
# yatai-deployment 설치 확인
kubectl -n yatai-deployment get pod -l app.kubernetes.io/name=yatai-deployment
# 출력 확인
NAME READY STATUS RESTARTS AGE
yatai-deployment-8b9fb98d7-xmtd5 1/1 Running 0 67s
yatai-deployment-default-domain-s8rh9 0/1 Completed 0 67s
웹 페이지 접속
YATAI_INITIALIZATION_TOKEN=$(kubectl get secret yatai-env --namespace yatai-system -o jsonpath="{.data.YATAI_INITIALIZATION_TOKEN}" | base64 --decode)
k get svc yatai -n yatai-system
# 만약 ClusterIP라면 edit창을 열어서 NodePort로 변경한다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
yatai NodePort 10.110.217.216 <none> 80:31215/TCP 41h
# 아래 url로 웹페이지 접속
http://{NODE IP}:31215/setup?token=$YATAI_INITIALIZATION_TOKEN

사용할 이름, 이메일, 암호를 입력 후 제출을 누르면 아래와 같이 로그인되어 메인 UI 화면으로 넘어간다.

Create API Token

오른쪽 이미지의 명령어로 실제 bentoml 라이브러리를 사용할 환경에서(client 또는 cluster server) 실행한다.
bentoml/examples/quickstart 디렉토리 위치에서
python train.py
bentoml build
bentoml push iris_classifier:latest
위 코드를 실행하면

models와 bentos web UI에 위와 같이 모델과 배포 정보를 볼 수 있다.
그다음,

배포 UI에서 필요한 정보를 입력 후 제출하면,

위와 같이 inference를 할 수 있도록 배포된 Bento에 액세스하기 위한 엔드포인트 URL로 라우팅이 되었다.

배포된 Bento 디테일 정보를 눌러서 들어가보면, 무중단 업데이트 배포를 할 수 있는 업데이트 기능과 여러 로그를 확인할 수 있는 터미널 기능들이 존재하는 것을 확인할 수 있다.
이제, 저 Bento가 배포된 네임스페이스에서 서비스 정보를 확인한다.
root@DS-DEV-005:/home/jeawoo0594# k get svc -n yatai
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
abc NodePort 10.105.233.188 <none> 3000:32185/TCP,3001:30929/TCP 4h37m
abc-runner-c1652e8c5c9d349556c6c33dbd9891bd ClusterIP 10.99.9.213 <none> 3000/TCP,3001/TCP 4h37m
나의 경우, 배포된 Bento의 서비스명은 abc이다. 만약, ClusterIP라면 NodePort로 변경해준다.
그다음, 웹에서 http://{Node IP}:32185 로 접속하면,

위와 같이, inference 관련 API 정보를 확인할 수 있다.
그럼, /classify 엔드포인트를 통해서 추론을 해보자!
curl --location --request POST 'http://{Node IP}:32185/classify' \
--header 'Content-Type: application/json' \
--data-raw '[[5.9, 3, 5.1, 1.8]]'
위 명령어로 요청을 보내면, 다음과 같이 응답이 오는 것을 확인할 수 있다.
[
2
]
추가로,
k get svc yatai -n yatai-system
# 만약 ClusterIP라면 edit창을 열어서 NodePort로 변경한다.
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
yatai NodePort 10.110.217.216 <none> 80:31215/TCP 41h
웹에서 http://{Node IP}:31215/swagger 로 접속하면, 다음과 같이 yatai api server UI에 접속할 수 있다.
