개발/MLOps

019. [Kubeflow][KServe] InferenceService 처음 배포하기!

봉자씨 2022. 9. 19. 16:31
반응형

이번 튜토리얼에서는 ScikitLearn InferenceService를 배포할 것입니다.

 

이 InferenceService는 간단한 [iris] ML model을 서빙합니다. 속성 리스트를 InferenceService에 전송하면, 붓꽃(iris)의 종(species)을 예측해서 보여줍니다.

 

모델은 원시(raw) 쿠버네티스 서비스가 아닌 InferenceService로 배포되고 있기 때문에, 훈련된 모델을 제공하기만 하면 바로 사용이 가능합니다 마치 초능력을 가진것처럼 말이죠!

1. 테스트 InferenceService 생성하기

apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
  name: "sklearn-iris"
spec:
  predictor:
    sklearn:
      storageUri: "gs://kfserving-samples/models/sklearn/iris"

"sklearn.yaml" 이름으로 YAML 파일을 생성했다면 다음 명령어로 InferenceService를 생성합니다.

kubectl create namespace kserve-test
kubectl apply -f sklearn.yaml -n kserve-test

2. InferenceService 상태 확인하기

다음 명령으로 위에서 생성한 InferenceService의 상태를 확인합니다.

kubectl get inferenceservices sklearn-iris -n kserve-test
NAME           URL                                                 READY   PREV   LATEST   PREVROLLEDOUTREVISION   LATESTREADYREVISION                    AGE
sklearn-iris   http://sklearn-iris.kserve-test.example.com         True           100                              sklearn-iris-predictor-default-47q2g   7d23h

DNS에 example.com이 포함되어 있는 경우 DNS 구성 또는 사용자 지정 도메인 사용에 대해 관리자에게 문의해야합니다. 혹은 로컬서버에서 테스트하고 있다면 아래 Ingress 요청하기 챕터를 살펴주세요.

3. Ingress IP, Port 확인하기

다음 명령을 사용하여 외부 로드 밸런서를 지원하는 환경에서 kubernetes 클러스터가 실행 중인지 확인합니다.

kubectl get svc istio-ingressgateway -n istio-system
NAME                   TYPE           CLUSTER-IP       EXTERNAL-IP      PORT(S)   AGE
istio-ingressgateway   LoadBalancer   172.21.109.129   130.211.10.121   ...       17h

Load Balancer

EXTERNAL-IP 가 설정 되어 있다면 로드 밸런서 타입을 사용하고 있는것입니다. 다음 명령으로 Ingress IP, Port를 가져오세요.

export INGRESS_HOST=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.status.loadBalancer.ingress[0].ip}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].port}')

NodePort

EXTERNAL-IP 값이 없음(또는 계속 Pending)인 경우 사용자 환경은 입력 게이트웨이에 외부 로드 밸런서를 제공하지 않는 것입니다. 이 경우 서비스의 노드 포트를 사용하여 게이트웨이에 액세스할 수 있습니다.

# GKE
export INGRESS_HOST=worker-node-address
# Minikube
export INGRESS_HOST=$(minikube ip)
# Other environment(On Prem)
export INGRESS_HOST=$(kubectl get po -l istio=ingressgateway -n istio-system -o jsonpath='{.items[0].status.hostIP}')
export INGRESS_PORT=$(kubectl -n istio-system get service istio-ingressgateway -o jsonpath='{.spec.ports[?(@.name=="http2")].nodePort}')

Port Forward

다른 대안으로 테스트 용도로 port-forward를 사용합니다.

INGRESS_GATEWAY_SERVICE=$(kubectl get svc --namespace istio-system --selector="app=istio-ingressgateway" --output jsonpath='{.items[0].metadata.name}')
kubectl port-forward --namespace istio-system svc/${INGRESS_GATEWAY_SERVICE} 8080:80
# start another terminal
export INGRESS_HOST=localhost
export INGRESS_PORT=8080

4. Curl 로InferenceService에 추론 요청하기

먼저 추론을 요청하기 위한 데이터를 준비합니다.

{
  "instances": [
    [6.8,  2.8,  4.8,  1.4],
    [6.0,  3.4,  4.5,  1.6]
  ]
}

"iris-input.json"으로 저장합니다.

다음 네가지 타입으로 추론 요청을 보낼 수 있습니다.

[!Note]
kubeflow의 Component로 KServe를 설치한 경우 Dex 인증정보가 반드시 필요합니다. (Multi-user, auth-enabled 모드 설정된 경우)
[[Kubeflow KServe 인증문제 해결하기]]에서 Dex 인증 정보와 함께 추론요청을 보내는 방법을 알아보세요!

Real DNS

DNS가 설정되어 있다면 바로 InferenceService에 요청을 보낼 수 있습니다!

curl -v http://sklearn-iris.kserve-test.${CUSTOM_DOMAIN}/v1/models/sklearn-iris:predict -d @./iris-input.json

Magic DNS

실제 도메인을 얻기위한 복잡한 과정을 겪고싶지 않다면 Magic DNS xip.io는 훌륭한 대안이 될 수 있습니다. 단, EXTERNAL-IP가 설정된 경우에만 사용할 수 있습니다.

kubectl get svc istio-ingressgateway --namespace istio-system

EXTERNEL-IP 컬럼의 값을 잘 기억하세요! (이 예제의 경우 35.237.217.209)

NAME                   TYPE           CLUSTER-IP     EXTERNAL-IP      PORT(S)    AGE
istio-ingressgateway   LoadBalancer   10.51.253.94   35.237.217.209

다음은 커스텀 도메인을 설정합니다.

kubectl edit cm config-domain --namespace knative-serving

이제 요청을 보낼때 example.com{{externel-ip}}.xip.ip로 바꿔서 보내세요! {{externel-ip}} 부분을 위에서 기억한 IP로 바꾸는 것을 잊지마세요!

curl -v http://sklearn-iris.kserve-test.35.237.217.209.xip.io/v1/models/sklearn-iris:predict -d @./iris-input.json

HOST Header와 함께 Ingress gateway 사용하기

DNS가 설정되지 않았다면, Ingress-gateway의 Externel-IP와 HOST Header를 사용하여 요청을 보낼 수 있습니다.

SERVICE_HOSTNAME=$(kubectl get inferenceservice sklearn-iris -n kserve-test -o jsonpath='{.status.url}' | cut -d "/" -f 3)
curl -v -H "Host: ${SERVICE_HOSTNAME}" http://${INGRESS_HOST}:${INGRESS_PORT}/v1/models/sklearn-iris:predict -d @./iris-input.json

cluster 내부에서 요청하기

클러스터 내부에서 요청을 한다면 local-cluster-gateway에 요청을 보내면 됩니다.

curl -v http://sklearn-iris.kserve-test/v1/models/sklearn-iris:predict -d @./iris-input.json

(optional) 5. Performance Test

베지터(vegeta)를 사용하여 성능 테스트를 해볼 수 있습니다.

# kubectl apply 대신 create를 사용하세요. job template에서 generateName을 사용하기 때문에 kubectl apply로는 동작하지 않습니다.
kubectl create -f https://raw.githubusercontent.com/kserve/kserve/release-0.7/docs/samples/v1beta1/sklearn/v1/perf.yaml -n kserve-test

Reference

[0] KServe First InferenceService https://kserve.github.io/website/0.7/get_started/first_isvc/

반응형