KFServing InferenceService 배포와 예측

InferenceService를 사용하여 모델 서버를 제공하려면, 사용할 네임스페이스가 다음과 같은지 확인해야합니다.

  • [serving.kubeflow.org/inferenceservice=enabled](<http://serving.kubeflow.org/inferenceservice=enabled>) 레이블이 네임스페이스 추가 되어 있어야 합니다.
  • 쿠버네티스 클러스터의 Istio IngressGateway에 접근할 수 있어야 합니다.

레이블 추가

Kubeflow의 대시보드나 프로필 컨트롤러(Profile Controller)를 사용하여, 사용자 네임스페이스를 만드는 경우에는 KFServing에서 모델을 배포할 수 있도록 serving.kubeflow.org/inferenceservice: enabled 레이블이 자동으로 추가됩니다. 만약 네임스페이스를 직접 생성하는 경우에는 해당 네임스페이스에 serving.kubeflow.org/inferenceservice: enabled 레이블을 추가해야만 합니다.

다음은 my-namespace 라는 네임스페이스에 레이블을 추가하는 예제입니다.

kubectl label namespace my-namespace serving.kubeflow.org/inferenceservice=enabled

Istio IngressGateway에 접근하기

InferenceService 가 정상적으로 생성되면, istio의 ingressgateway 를 모델 서버에 접속할 수 있습니다. KFServing에서 사용하는 ingressgateway의 이름을 알려면, config-istio 라는 ConfigMap을 조회하면 됩니다.

다음은 knative-serving 네임스페이스에 있는 config-istio 을 조회하는 예제입니다.

kubectl -n knative-serving get cm config-istio -o yaml

정상적으로 조회 되면 다음과 같은 결과를 얻을 수 있습니다.

apiVersion: v1
data:
  gateway.knative-serving.knative-ingress-gateway: kfserving-ingressgateway.istio-system.svc.cluster.local
  local-gateway.knative-serving.cluster-local-gateway: cluster-local-gateway.istio-system.svc.cluster.local
  local-gateway.mesh: mesh
  reconcileExternalGateway: "false"
kind: ConfigMap
metadata:
  ...
  name: config-istio
  namespace: knative-serving

data 섹션의 gateway.knative-serving.knative-ingress-gateway 필드가 현재 KFServing에서 사용하는 ingressgateway 를 설정하는 부분입니다. 위의 예제에서는 kfserving-ingressgateway를 사용하고 있습니다.

kfserving-ingressgateway를 조회해 보겠습니다.

다음은 istio-system 네임스페이스에 있는 kfserving-ingressgateway을 조회하는 예제입니다.

kubectl -n istio-system get service kfserving-ingressgateway 

KFServing이 설치된 쿠버네티스 클러스터에 따라 결과가 다르게 나옵니다. 응답 결과에 따른 크게 세가지 방법으로 접근 할 수 있습니다.

  • LoadBalancer 를 통해서 접근하기
  • NodePort를 통해서 접근하기
  • kubectl port-forward를 통해서 접근하기

LoadBalancer

쿠버네티스 클러스터가 LoadBalancer 를 지원하면 다음과 같은 결과를 얻을 수 있습니다. 서비스의 타입이 LoadBalancer 이고, EXTERNAL-IP 에 IP가 할당되어 있습니다. 이럴 경우에는 EXTERNAL-IP 를 통해서 ingressgateway에 접근할 수 있습니다.

NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                                                                                                                   AGE
kfserving-ingressgateway   LoadBalancer   10.101.141.37   10.201.121.4  15020:30543/TCP,80:32380/TCP,443:32390/TCP,31400:32400/TCP,15011:30263/TCP,8060:32119/TCP,853:32180/TCP,15029:32156/TCP,15030:30674/TCP,15031:30230/TCP,15032:32563/TCP,15443:30995/TCP   2d23h

앞으로 만들 예제에서 사용하기 위해서 ingressgateway 의 접근 주소를 다음과 같이 정의하겠습니다. EXTERNAL-IP 주소를 사용합니다.

CLUSTER_IP=10.201.121.4

NodePort

쿠버네티스 클러스터가 LoadBalancer 를 지원하지 않거나, 서비스의 타입이 NodePort 인 경우 EXTERNAL-IP 의 값이 비어 있습니다. 이럴 경우에는 클러스터의 노드 IP 와 NodePort를 통해서 접근할 수 있습니다.

NAME                       TYPE           CLUSTER-IP      EXTERNAL-IP   PORT(S)                                                                                                                                                                                   AGE
kfserving-ingressgateway   LoadBalancer   10.101.141.37   <pending>     15020:30543/TCP,80:32380/TCP,443:32390/TCP,31400:32400/TCP,15011:30263/TCP,8060:32119/TCP,853:32180/TCP,15029:32156/TCP,15030:30674/TCP,15031:30230/TCP,15032:32563/TCP,15443:30995/TCP   2d23h

노드 IP는 노드를 조회하면 알 수 있습니다.

다음은 노드를 조회 하는 예제입니다.

kubectl get node -o wide

정상적으로 조회되면 다음과 같은 응답 결과가 나옵니다.

NAME     STATUS   ROLES    AGE   VERSION    INTERNAL-IP     EXTERNAL-IP   OS-IMAGE             KERNEL-VERSION      CONTAINER-RUNTIME
mortar   Ready    master   13d   v1.15.10   192.168.21.38   <none>        Ubuntu 18.04.3 LTS   4.15.0-91-generic   docker://18.9.9

노드가 한 개가 아닌 경우에는 여러개의 노드 정보가 출력됩니다. 해당 노드들 중에서 아무 노드의 INTERNAL-IP 를 사용하면 됩니다.

앞으로 만들 예제에서 사용하기 위해서 ingressgateway 의 접근 주소를 다음과 같이 정의하겠습니다. 노드의 IP 와 80 PORT(80:32380/TCP)의 노드 포트인 32380을 포트로 사용합니다.

CLUSTER_IP=192.168.21.38:32380

port-forward

외부에서 쿠버네티스 클러스터의 서비스에 접근할 수 없는 경우, kubectl 의 port-forward를 사용할 수 있습니다. 접근 하려는 외부 시스템에서 다음 명령어 실행하면 로컬 포트를 경유 해서 쿠버네티스 서비스에 접근할 수 있습니다.

kubectl -n istio-system port-forward svc/kfserving-ingressgateway 8080:80

포트 포워딩이 정상적으로 실행되면, 로컬포트로 ingressgateay 서비스로 접근할 수 있습니다. http://localhost:8080 처럼 선언한 로컬 포트의 주소로 접근하면, 쿠버네티스 ingressgateway 의 80 포트로 포워딩 됩니다.

앞으로 만들 예제에서 사용하기 위해서 ingressgateway 의 접근 주소를 다음과 같이 정의하겠습니다.

CLUSTER_IP=localhost:8080

PVC 생성하기

InferenceService 에 사용할 모델은 PVC에 저장하겠습니다. 만약 클라우드 스토리지와 같은 다른 저장소를 사용하려면, “클라우드 저장소를 이용하여 InfeerneceService 배포와 예측”을 참조하시기 바랍니다.

kfserving-models-pvc라는 PVC 매니페스트를 작성합니다.

kfserving-models-pvc.yaml

kind: PersistentVolumeClaim
apiVersion: v1
metadata:
  name: kfserving-models-pvc
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 1Gi

다음 명령어를 실행하여, admin 네임스페이스에 kfserving-models-pvc라는 PVC를 생성하겠습니다.

kubectl -n admin apply kfserving-models-pvc.yaml

KFServing 설정

KFServing 에서 사용하는 여러 설정 정보들은 inferenceservice-config 라는 쿠버네티스 ConfigMap에 정의되어 있습니다.

이 설정 정보에는 다음과 같은 내용이 정의되어 있습니다.

  • credentials : S3나 GCS를 사용할 때 참조할 값들.
  • explainers : explainer를 실행할 때 사용할 컨테이너의 이미지 정보.
  • ingress : KFServing에서 사용할 Istio ingress 정보.
  • predictors : predictor를 실행할 때 사용할 컨테이너 이미지의 정보.

다음 명령어를 실행하면, 설정 정보를 조회할 수 있습니다.

kubectl -n kubeflow get cm inferenceservice-config -o yaml

정상적으로 실행되면 다음과 같은 응답 결과를 확인 할 수 있습니다.

apiVersion: v1
data:
  credentials: |-
    {
       "gcs": {
           "gcsCredentialFileName": "gcloud-application-credentials.json"
       },
       "s3": {
           "s3AccessKeyIDName": "awsAccessKeyID",
           "s3SecretAccessKeyName": "awsSecretAccessKey"
       }
    }
  explainers: |-
    {
        "alibi": {
            "image" : "gcr.io/kfserving/alibi-explainer",
            "defaultImageVersion": "0.2.2",
            "allowedImageVersions": [
               "0.2.2"
            ]
        }
    }
  ingress: |-
    {
        "ingressGateway" : "knative-ingress-gateway.knative-serving",
        "ingressService" : "kfserving-ingressgateway.istio-system.svc.cluster.local"
    }
  logger: |-
    {
        "image" : "gcr.io/kfserving/logger:0.2.2",
        "memoryRequest": "100Mi",
        "memoryLimit": "1Gi",
        "cpuRequest": "100m",
        "cpuLimit": "1"
    }
  predictors: |-
    {
        "tensorflow": {
            "image": "tensorflow/serving",
            "defaultImageVersion": "1.14.0",
            "defaultGpuImageVersion": "1.14.0-gpu",
            "allowedImageVersions": [
               "1.11.0",
               "1.11.0-gpu",
               "1.12.0",
               "1.12.0-gpu",
               "1.13.0",
               "1.13.0-gpu",
               "1.14.0",
               "1.14.0-gpu"
            ]
        },
        "onnx": {
            "image": "mcr.microsoft.com/onnxruntime/server",
            "defaultImageVersion": "v0.5.1",
            "allowedImageVersions": [
               "v0.5.1"
            ]
        },
        "sklearn": {
            "image": "gcr.io/kfserving/sklearnserver",
            "defaultImageVersion": "0.2.2",
            "allowedImageVersions": [
               "0.2.2"
            ]
        },
        "xgboost": {
            "image": "gcr.io/kfserving/xgbserver",
            "defaultImageVersion": "0.2.2",
            "allowedImageVersions": [
               "0.2.2"
            ]
        },
        "pytorch": {
            "image": "gcr.io/kfserving/pytorchserver",
            "defaultImageVersion": "0.2.2",
            "allowedImageVersions": [
               "0.2.2"
            ]
        },
        "tensorrt": {
            "image": "nvcr.io/nvidia/tensorrtserver",
            "defaultImageVersion": "19.05-py3",
            "allowedImageVersions": [
               "19.05-py3"
            ]
        }
    }
  storageInitializer: |-
    {
        "image" : "gcr.io/kfserving/storage-initializer:0.2.2",
        "memoryRequest": "100Mi",
        "memoryLimit": "1Gi",
        "cpuRequest": "100m",
        "cpuLimit": "1"
    }
  transformers: |-
    {
    }
kind: ConfigMap
metadata:
...
  name: inferenceservice-config
  namespace: kubeflow

“KFServing InferenceService 배포와 예측”에 대한 2개의 댓글

  1. 저처럼 쿠버네티스를 잘 모르시는 분들을 위해 추가합니다.
    네임스페이스의 라벨을 보려면
    kubectl get namespace –show-labels를 하면 될 것 같아요!

댓글 남기기

이메일은 공개되지 않습니다. 필수 입력창은 * 로 표시되어 있습니다