본문 바로가기
kubenetes

kserve 사용 및 설정 가이드

by kyeongseo.oh 2024. 9. 24.

kserve 사용법 및 설정 방법을 소개한다.

kubeflow를 설치할 때 함께 설치된 kserve v0.13.0을 사용한다.

 

kubeflow 설치는 다음 문서를 참고한다. (kubeflow 1.9.0 설치하기)

 

1. CSRF 오류 해결

kubeflow에서 KServe Endpoints를 클릭하면 "[403] Could not find CSRF cookie XSRF-TOKEN in the request." 에러 메시지가 출력된다. 이를 해결하기 위해서는 ConfigMap을 수정해야 한다.

 

다음 커맨드를 입력해 ConfigMap 편집 모드에 진입한다.

kubectl edit cm -n kubeflow kserve-models-web-app-config

 

ConfigMap을 아래와 같이 수정한다.

apiVersion: v1
data:
  APP_PREFIX: /kserve-endpoints
  USERID_HEADER: kubeflow-userid
  APP_SECURE_COOKIES: "false"
  APP_DISABLE_AUTH: "true"
kind: ConfigMap

 

변경사항을 적용하기 위해 deployment를 재시작한다.

kubectl rollout restart -n kubeflow deployments.apps kserve-models-web-app

 

2. sslip.io 매직 dns 설정

매직 dns 서비스를 적용하면 개발 및 테스트 환경에서 복잡한 DNS 구성 없이도 서비스에 쉽게 접근할 수 있다.

 

sslip.io는 아래와 같이 동작한다.

  • IP 주소를 도메인 이름에 포함시킨다. ex) 10.0.0.1.sslip.io
  • 이 도메인으로 DNS 쿼리를 보내면, sslip.io 서버가 자동으로 해당 IP 주소로 연결해 준다.

KServe에서 sslip.io 설정하는 방법

아래 명령어를 사용해 istio-ingressgateway service의 type을 LoadBalancer로 변경한다.

kubectl patch svc istio-ingressgateway -n istio-system -p '{"spec": {"type": "LoadBalancer"}}'

 

Knative Serving 환경에서 sslip.io를 기본 도메인을 설정하는 Job과 관련 Service를 적용한다.

kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.15.2/serving-default-domain.yaml

 

위와 같이 매직 dns를 설정하면 각 KServe InferenceService에 대해 자동으로 `<service-name>.<namespace>.<ingress-ip>.sslip.io` 형식의 URL이 생성되고, 별도 DNS 설정 없이 서비스에 접근할 수 있게 된다.

 

3. InferenceService 생성

kubeflow UI 또는 YAML 파일을 사용하여 InferenceService를 생성한다.

kserve 공식문서에서 제공하는 example을 사용해 InferenceService를 생성한다.

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

 

kubectl을 사용해 위 yaml을 적용하거나, kubeflow UI에 아래와 같이 작성 후 create 버튼을 클릭해 InferenceService를 생성할 수 있다.

 

InferenceService가 정상적으로 생성되면 아래와 같이 cluster 내/외부에서 접근할 수 있는 URL이 생성된다.

 

4. RBAC 오류 해결

kubeflow notebook server에서 아래와 같이 kserve endpoint에 요청을 보내면 RBAC : access denied 에러가 발생한다.

 

istio에서 보안을 위해 제한적인 접근 정책을 적용했기 때문에 발생하는 문제로, 아래 AuthorizationPolicy를 적용해 특정 경로에 대한 접근을 명시적으로 허용해 해결할 수 있다.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: allowlist-by-paths
  namespace: istio-system
spec:
  action: ALLOW
  rules:
  - to:
    - operation:
        paths:
        - /metrics
        - /healthz
        - /ready
        - /wait-for-drain
        - /v1/models/*
        - /v2/models/*

 

위의 AuthorizationPolicy를 적용하면 internal url에서는 return이 오나, external url에서는 여전히 RBAC 에러가 발생하는 것을 확인할 수 있다. 

이는 클러스터 외부에서 접근할 때는 api 요청 시 kubeflow에 로그인할 때 생성되는 oauth2-proxy cookies가 필요한데 해당 cookie가 요청 header에 포함되어 있지 않기 때문이다.

 

이를 해결하기 위해서는 아래 istio-ingressgateway-oauth2-proxy AuthorizationPolicy를 수정해 `/v1`, `/v2` 경로에 대해 oidc 인증 우회 정책을 적용해야 한다.

아래 yaml을 적용하면 istio-ingressgateway에 `/v1`, `/v2` 경로로 접근하는 api는 인증을 우회한다.

apiVersion: security.istio.io/v1beta1
kind: AuthorizationPolicy
metadata:
  name: istio-ingressgateway-oauth2-proxy
  namespace: istio-system
spec:
  action: CUSTOM
  provider:
    name: oauth2-proxy
  selector:
    matchLabels:
      app: istio-ingressgateway
  rules:
  - to:
    - operation:
        notPaths: ["/v1*", "/v2*"]

 

5. kserve model에 predict 요청 보내기

모든 설정이 완료되면 아래와 같이 internal url, external url에 모두 api 요청을 보낼 수 있다.

 

또한 kubernetes cluster 외부에서도 kserve에 접근할 수 있다.

import requests
import json

sklear_iris_input = dict(instances = [
        [6.8, 2.8, 4.8, 1.4],
        [6.0, 3.4, 4.5, 1.6]
    ])

response_external = requests.post("http://sklearn-iris.kubeflow-user-example-com.10.0.2.6.sslip.io/v1/models/sklearn-iris:predict", data = json.dumps(sklear_iris_input))   

print(response_external.text)

 

댓글