MLOPS/SERVING

BentoML - Yatai

개발허재 2023. 1. 12. 15:29

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

Install 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에 접속할 수 있다.