데이터 분석(Deep Dive)

Simple Kserve building

직장인B 2025. 11. 30. 00:50

Kserve는 k8s 환경 내에서 모델 서빙을 구현하도록 도와주는 플랫폼이다. 단순한 서빙 기능을 넘어 트래픽 관리, 리소스 관리, 스케일링, modeling rolling 등 실무적으로 필요한 여러 기능을 가지기에 상당히 범용적인 플랫폼이라고 할 수 있겠다.

 

오늘 블로그에서는 Kserve의 간단한 맛만 보는 차원에서 minikube로 로컬 k8s 환경을 구성하고 그 위에 kserve를 작동시켜보는 과정을 설명하고자 한다. kserve는 knative를 이용해서 serverless 방식으로 사용하는 것을 가정한다.

 

사전 작업

 

환경 구성에 필요한 도구들을 brew install 을 통해 간단히 설치해준다.

  • minikube
  • helm
  • kubectl

minikube 환경 구성

 

minikube 클러스터를 시작하고 tunnel 을 열어준다. 클러스터를 실행할 때는 자원을 충분하게 줘야하고, tunnel의 경우 80,443 포트를 점유할 수 있어야하기 때문에 관리자 권한(sudo)으로 실행한다.

minikube start --driver=docker --memory=8192 --cpus=4
sudo minikube tunnel

 

Kserve Building

 

버전 체크

 

필요한 모듈들의 버전을 미리 세팅한다. 아래는 kserve v0.16 기준으로 정해진 dependency다.

export KSERVE_VERSION=v0.16.0
export ISTIO_VERSION=1.27.1
export KNATIVE_OPERATOR_VERSION=v1.15.7
export KNATIVE_SERVING_VERSION=1.15.2
export CERT_MANAGER_VERSION=v1.16.1
export GATEWAY_API_VERSION=v1.2.1

 

Custom Resource Definition Download

 

Kserve 환경구성에 필요한 CRD들을 받아온다.

# GATEWAY_API_VERSION=v1.2.1
kubectl apply -f https://github.com/kubernetes-sigs/gateway-api/releases/download/v1.2.1/standard-install.yaml

 

아래의 네 가지 crd가 정의된다.

  • gateways.gateway.networking.k8s.io
  • grpcroutes.gateway.networking.k8s.io
  • httproutes.gateway.networking.k8s.io
  • referencegrants.gateway.networking.k8s.io

 

Istio Building

 

istio는 k8s의 서비스 매시를 지원하는 도구로, kserve를 위한 네트워킹 설정과 통제를 담당해준다.

helm repo add istio https://istio-release.storage.googleapis.com/charts --force-update

helm install istio-base istio/base -n istio-system --wait --set defaultRevision=default --create-namespace --version 1.27.1

helm install istiod istio/istiod -n istio-system --wait --version 1.27.1 \
   --set proxy.autoInject=disabled \
   --set-string pilot.podAnnotations."cluster-autoscaler\.kubernetes\.io/safe-to-evict"=true

helm install istio-ingressgateway istio/gateway -n istio-system --version 1.27.1 \
   --set-string podAnnotations."cluster-autoscaler\.kubernetes\.io/safe-to-evict"=true

kubectl wait --for=condition=Ready pod -l app=istio-ingressgateway -n istio-system --timeout=600s

 

설치가 완료되면 아래처럼 istiod와 istio-ingressgateway pods가 정상적으로 running 상태여야 한다.

~ ➤ kubectl get pods -n istio-system
NAME                                    READY   STATUS    RESTARTS   AGE
istio-ingressgateway-588f444bbb-wnq9z   1/1     Running   0          34s
istiod-5b8d544bb6-j7s8w                 1/1     Running   0          60s

 

Cert Manager Building

 

Cert Manager는 KServe에서 모델 서빙 엔드포인트에 대한 TLS(HTTPS) 인증서를 자동으로 발급하고 관리하는 역할을 한다.

helm repo add jetstack https://charts.jetstack.io --force-update
helm install \
   cert-manager jetstack/cert-manager \
   --namespace cert-manager \
   --create-namespace \
   --version ${CERT_MANAGER_VERSION} \
   --set crds.enabled=true

 

작업이 완료되면 아래처럼 세 개의 pods가 running 되어야 한다.

~ ➤ kubectl get pods -n cert-manager
NAME                                       READY   STATUS    RESTARTS   AGE
cert-manager-c8685d75c-j7hxx               1/1     Running   0          88s
cert-manager-cainjector-6697bc4f6b-6mlzg   1/1     Running   0          88s
cert-manager-webhook-55c9496865-4srcg      1/1     Running   0          88s

 

Knative Building

 

Knative는 k8s 위에서 서버리스 워크로드를 배포, 실행, 관리하는 데 필요한 도구들을 제공해준다.

helm install knative-operator --namespace knative-serving --create-namespace --wait \
      https://github.com/knative/operator/releases/download/knative-v1.15.7/knative-operator-v1.15.7.tgz

kubectl apply -f - <<EOF
   apiVersion: operator.knative.dev/v1beta1
   kind: KnativeServing
   metadata:
     name: knative-serving
     namespace: knative-serving
   spec:
     version: "1.15.2"
     config:
       domain:
         # 추후 kserve enpoint의 도메인이 된다. 
         example.com: ""
EOF

 

작업이 완료되면 아래와 같은 pods들이 생겨났어야 한다. Completed라는 상태는 init 작업들을 정상적으로 실행한 후 down되었다는 뜻이다. KnativeServing의 READY 상태가 True가 되는 것도 잘 확인을 해야한다.

~ ➤ kubectl get pods -n knative-serving
NAME                                                     READY   STATUS      RESTARTS   AGE
activator-5445c9d667-2zgj5                               1/1     Running     0          3m19s
autoscaler-69ff8b864b-77qpk                              1/1     Running     0          3m18s
autoscaler-hpa-79c6846c4f-7b7m5                          1/1     Running     0          3m16s
cleanup-serving-serving-1.15.2-t5rqd                     0/1     Completed   0          3m16s
controller-9bf9b69d-26hlm                                1/1     Running     0          3m18s
knative-operator-6d9756dfdc-ntfdb                        1/1     Running     0          5m55s
net-istio-controller-766bc8fc7c-6lnr6                    1/1     Running     0          3m14s
net-istio-webhook-565699cbb-h5r8d                        1/1     Running     0          3m14s
operator-webhook-674d5f8489-4fszn                        1/1     Running     0          5m55s
storage-version-migration-serving-serving-1.15.2-vbjld   0/1     Completed   0          3m16s
webhook-554557dfb6-tjxqm                                 1/1     Running     0          3m17s

~ ➤ kubectl get KnativeServing -n knative-serving
NAME              VERSION   READY   REASON
knative-serving   1.15.2    False   NotReady

 

Kserve Building

 

kserve 를 설치한다. 실제 모델 서빙 작업을 관리할 컨테이너 매니저를 설치하는 것이다.

helm install kserve-crd oci://ghcr.io/kserve/charts/kserve-crd --version v0.16.0 --namespace kserve --create-namespace --wait
helm install kserve oci://ghcr.io/kserve/charts/kserve --version v0.16.0 --namespace kserve --create-namespace --wait --set-string kserve.controller.deploymentMode="Serverless"

 

설치가 완료되면 controller-manger 가 정상적으로 running 되어야 한다. 작동되는데 시간이 조금 걸린다.

~ ➤ kubectl get pods -n kserve
NAME                                         READY   STATUS    RESTARTS   AGE
kserve-controller-manager-7bcd48cd6d-7ddj2   2/2     Running   0          111s

 

Kserve Simple Inference

 

kserve에서 inference 서비스를 만드러면 두 가지의 resource를 정의해주어야 한다. 

  • Serving Runtime
  • InferenceServie

Serving Runtime 정의

 

모델 inference 작업이 돌아가는 base image/runtime을 정의해놓는 것이다. 적절한 args를 입력해놓아야한다.

apiVersion: serving.kserve.io/v1alpha1
kind: ServingRuntime
metadata:
  name: sklearn-runtime
  namespace: kserve-test
spec:
  supportedModelFormats:
    - name: sklearn
      version: "1"
      autoSelect: true
  containers:
    - name: kserve-container
      image: kserve/sklearnserver:v0.16.0
      args:
        - --model_dir=/mnt/models
        - --model_name=sklearn-iris
        - --http_port=8080

 

 

Inference Service 정의

 

서빙 서비스를 정의한다. Runtime에 부합되도록 작업을 구성해야하고, 여기서 트래픽 관리 등 서빙에 관련된 복잡한 기능들을 정의할 수 있다. storageUri 는 실제로 작동할 모델을 넣어놓는 것이다. 서비스가 작동할 때 해당 모델이 runtime 내에 다운로드되어 사용된다. 

apiVersion: serving.kserve.io/v1beta1
kind: InferenceService
metadata:
  name: sklearn-iris
  namespace: kserve-test
spec:
  predictor:
    model:
      modelFormat:
        name: sklearn
      storageUri: "gs://kfserving-examples/models/sklearn/1.0/model"
      resources:
        requests:
          cpu: "100m"
          memory: "512Mi"
        limits:
          cpu: "1"
          memory: "1Gi"

 

inferenceservice 가 정상적으로 등록이 되었다면 아래처럼 URL 등록이 잘 되어야 하고, 예측 작업을 위한 pods가 정상적으로 running하고 있어야 한다. 

~ ➤ 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-00001   75s

~ ➤ kubectl get pods -n kserve-test
NAME                                                       READY   STATUS    RESTARTS   AGE
sklearn-iris-predictor-00001-deployment-6c7fcb5477-b2vck   2/2     Running   0          2m2s

 

 

Inference Test !

서빙 테스트는 배포된 endpoint에 간단히 http 호출을 보내는 것으로 실행할 수 있다. 

curl -v  \ 
    -H "Host: sklearn-iris.kserve-test.example.com" \ 
    -H "Content-Type: application/json" \ 
    http://127.0.0.1:80/v1/models/sklearn-iris:predict \ 
    -d @./iris-input.json

 

호출 결과 로그는 아래와 같다. 

 

*   Trying 127.0.0.1:80...
* Connected to 127.0.0.1 (127.0.0.1) port 80 (#0)
> POST /v1/models/sklearn-iris:predict HTTP/1.1
> Host: sklearn-iris.kserve-test.example.com
> User-Agent: curl/7.87.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 76
> 
* Mark bundle as not supporting multiuse
< HTTP/1.1 200 OK
< content-length: 21
< content-type: application/json
< date: Sat, 29 Nov 2025 15:43:58 GMT
< server: istio-envoy
< x-envoy-upstream-service-time: 19
< 
* Connection #0 to host 127.0.0.1 left intact
{"predictions":[1,1]}% <- 예측 결과

 

 

참고

 

- https://kserve.github.io/website/docs/getting-started/quickstart-guide

 

Quickstart Guide | KServe

Welcome to the KServe Quickstart Guide! This guide will help you set up a KServe Quickstart environment for testing and experimentation. KServe provides two deployment paths based on your use case:

kserve.github.io

 

- https://kserve.github.io/website/docs/concepts/resources/servingruntime

 

Serving Runtime | KServe

Learn how to use ServingRuntimes in KServe to define reusable model serving environments for various model formats.

kserve.github.io

- https://kserve.github.io/website/docs/getting-started/predictive-first-isvc

 

Deploy Your First Predictive AI Service | KServe

Learn how to deploy your first Predictive InferenceService with a scikit-learn model using KServe.

kserve.github.io

 

'데이터 분석(Deep Dive)' 카테고리의 다른 글

Simple Deep Learning Regression  (0) 2025.10.18