MLOPS/SERVING

Kserve

개발허재 2023. 1. 6. 13:59

Environment

Kubernetes version:  v1.21.7

Kserve version:  0.8

kubeadm single cluster

cni: flannel

k8s cluster reference: https://mlops-for-all.github.io/docs/setup-kubernetes/kubernetes-with-kubeadm/

Install the KServe "Quickstart"

curl -s "https://raw.githubusercontent.com/kserve/kserve/release-0.8/hack/quick_install.sh" | bash

 

istio-ingressgateway의 External-IP 가 pending 이라면 istio-ingressgateway 서비스의 통신규칙 변경

kubectl edit svc istio-ingressgateway -n istio-system

# 위명령어로 edit 창을 연다음

spec:
  clusterIP: 10.105.254.55
  clusterIPs:
  - 10.105.254.55
  ...
  selector:
    app: istio-ingressgateway
    istio: ingressgateway
  sessionAffinity: None
  type: NodePort ##LoadBalancer를 NodePort로 변경한다.
status:
  loadBalancer: {}

 

변경 후 적용하면 위와 같이 NodePort로 변경되었음을 확인할 수 있다.

 

InferenceService 생성

kubectl create namespace kserve-test
# create namespace kserve-test

kubectl apply -n kserve-test -f - <<EOF
apiVersion: "serving.kserve.io/v1beta1"
kind: "InferenceService"
metadata:
  name: "sklearn-iris"
spec:
  predictor:
    sklearn:
      storageUri: "gs://kfserving-examples/models/sklearn/1.0/model"
EOF

 

Knative

기본적으로 사용자는 pod만 생성해서는 app에 접근할 수 없다. 그래서 별도로 service를 생성해주던지 loadbalancer를 설정해주거나 ingress를 만들었었고, 네트워크 설정이 필수 불가결 했다.

반면에 Knative위에서의 배포는 서비스 컨테이너 이름과 컨테이너만 정의해주면 바로 배포가 된다. 서비스를 하는데 필요한 복잡한 설정을 추상화 시켜서 개발자가 필요한 최소한의 설정만으로 서비스를 제공할 수 있게 된다.

지금 Knative는 Istio를 기반으로 올라가있으며 그를 통해 배포한 pod은 자동으로 Istio의 gateway를 통해 서비스되고 있다.

또한 Istio의 Service Mesh Architecture상, Istio의 gateway가 모든 knative서비스를 라우팅하기 때문에(단일 ip) 원하는 서비스를 구분할 수 있어야 한다. 방법은 두가지이다.

  • Hostname
  • URI

위 그림과 같이 Knative서비스들은 Istio-gateway에 연결되어 서비스됩니다.

각 서비스에 접근하기 위해서는 각 서비스들의 식별자(Hostname또는 URI)와 Istio-gateway의 ip정보만 있으면 됩니다.

 

sklearn-iris 인퍼런스 서비스에 접근

kubectl get ksvc -A

URL은 http://{RouteName}.{k8s-namespace}.{Domain}구성으로 되어있고, Domain같은 경우는 default가 example.com이다.

sklearn-iris-predictor-default의 RouteName은 sklearn-iris이고, 쿠버네티스 namespace는 kserve-test를 사용하였기 때문에, sklearn-iris-predictor-default.kserve-test.example.com 이 전체 서비스 호스트명이 됩니다.

 

그 다음, istio-ingressgateway 서비스의 80:30464/TCP 포트포워딩 정보를 통해

curl --location --request POST 'http://{cluster ip}:30464/v1/models/sklearn-iris:predict' \
--header 'Host: sklearn-iris-predictor-default.kserve-test.example.com' \
--header 'Content-Type: application/json' \
--data-raw '{
  "instances": [
    [6.8,  2.8,  4.8,  1.4],
    [6.0,  3.4,  4.5,  1.6]
  ]
}'

외부에서 위와 같이 호출하면 

{
    "predictions": [
        1,
        1
    ]
}

위와 같이 predict 결과를 받아 볼 수 있다.

* NodePort로 Istio-gateway를 설정해줬을 경우는 노드의 ip가 필요하며 LoadBalancer로 설정해줬을 경우엔 External-IP 사용

* 포트가 30464인 이유는 내부 80포트의 포트포워딩이 30464으로 되었기 때문

 

Serverless Inference

Knative는 트래픽이 발생하지 않는 pod은 없애버렸다가 트래픽이 발생하는 순간 pod을 새로 띄운다.

 * 1분정도 아무 트래픽이 없으면 pod을 끄는 것으로 확인

이렇게 자주 사용하는 pod은 scale up하여 신속한 처리를 가능하게 하고 자주 사용하지 않는 pod은 scale down (to Zero) 하여 클러스터의 Serverless 운용을 가능하게 한다.