데보션앱 소개페이지 바로가기
로그인 선택

신고하기

CLOSE
신고사유 (대표 사유 1개)
상세내용 (선택)
0/200
  • 신고한 게시글은 더 이상 보이지 않습니다.
  • 이용약관과 운영정책에 따라 신고사유에 해당하는지 검토 후 조치됩니다.
  • 허위 신고인 경우, 신고자의 서비스 이용이 제한될 수 있으니 유의하시어 신중하게 신고해 주세요.
(이 회원이 작성한 모든 댓글과 커뮤니티 게시물이 보이지 않고, 알림도 오지 않습니다.)

미리보기

커뮤니티

      1,234

      badge 23.06.15

      글 등록

      카테고리를 선택해주세요.

      DEVOTEE를 활성화 시키면
      지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.

      버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.

      임시저장함에 저장되었습니다. 저장일시 : 2022.5.17 14:29:08

      임시저장함

      제목을 선택하시면 이어서 작성이 가능하며,
      최대 20건까지 저장합니다.
      컨텐츠 유형, 제목, 저장일시, 삭제로 이뤄진 임시저장 목록
      컨텐츠 유형 제목 저장일 삭제

      데보션 블로그 게재 요청

      CLOSE
      • *
      • *

      본인인증

      효율적인 데보션 서비스 이용 및
      고객님의 소중한 개인정보보호를 위해
      본인인증을 진행해주세요. 본인인증 미 진행 시 로그인이 제한됩니다.
      본인인증 실패

      본인인증 로그인에 실패하였습니다.
      회원이 아니시거나 본인인증 등록이
      완료되지 않은 사용자입니다.

      회원정보 연결

      KServe 이 보다 더 쉬운 ML Model Serving 은 없다.

      seungkyua 22.07.19
      10,843 9 0

      MLOps 라고 불리는 s/w 가 여러개 있는데 그 중에서 Kubeflow 는 Kubernetes 기반의 MLOps 를 쉽게 구축할 수 있는 오픈 소스이다.

      초창기 개발은 Google 이 주축이 되어 Arrikto 가 같이 참여하여 개발하는 형식이었는데 이제는 많은 글로벌 회사에서 같이 참여하여 점차 확대되고 있는 추세이다.

      Kubeflow 는 Kubernetes 위에서만 돌아가기 때문에 Kubernetes 를 알아야 한다는 단점이 있지만, 일단 Kubernets 를 알고 있다면 설치가 아주 쉽다.

      물론 그 안에 들어가는 컴포넌트들이 많고, MLOps 의 특성상 자동화는 workflow 를 잘 작성해서 pipeline 을 어떻게 구성하느냐가 중요하기 때문에 어려운 사용법을 익혀야 한다.

      KServe 는 Kubeflow 의 여러 기능 중에서 ML Model Serving 에 해당하는 컴포넌트이며,

      얼마전 kubeflow 내의 KFServe 컴포넌트 이었다가 독립적인 Add-Ons 으로 빠져 나오면서 KServe 로 이름을 바꾸고 자체 github repository 를 만들었다.


      KServe Architecture

      KServe 아키텍처는 다음과 같다.

      kserve_1.png

      [출처: https://www.kubeflow.org/docs/external-add-ons/kserve/kserve/]

       

       그림과 같이 런타임으로 TensorFlow, PYTORCH, SKLearn, XGBoost, ONNX 등 다양한 모델 프레임워크를 지원하며 필요하면 커스텀 런타임을 만들어서 지원할 수 도 있다.

      KServe 하단에는 Knative 와 Istio (Serverless Layer) 를 갖을 수 있는데 하단에는 다음과 같이 구성할 수 있다.

      1. KServe + Knative + Istio

      2. KServe + Istio

      Knative 는 옵션이기는 하나 Knative 를 설치하면서 로깅 (fluentbit + ElasticSearch + Kibana), 모니터링 (Prometheus, Exporter), 트레이싱(Jaeger + ElasticSearch) 을 쉽게 연결할 수 있다는 장점이 있다.

      또한 Istio 가 제공하는 Network 핸들링 기능을 쉽게 사용할 수 있다.

      KServe 설치는 Istio 설치 → Knative 설치 → KServe 설치 순으로 진행하며, 이에 맞는 버전은 다음과 같다.

      Recommended Version Matrix

      Kubernetes Version

      Istio Version

      Knative Version

      1.20

      1.9, 1.10, 1.11

      0.25, 0.26, 1.0

      1.21

      1.10, 1.11

      0.25, 0.26, 1.0

      1.22

      1.11, 1.12

      0.25, 0.26, 1.0

      여기서는 Kubernetes 1.22 에 맞춰서 설치한다.


      Istio 설치

      Istio 는 Service Mesh 를 쉽게 구성가능하도록 지원하는 플랫폼으로 proxy 가 sidecar 형태로 추가되어 네트워크를 조절할 수 있다.

      네트워크를 조절기능의 대표적인 것은 네트워크 쉬프팅이 있다. Canary Release 나 A/B Test 에서는 서로 다른 버전의 서비스로 호출되는 네트워크의 흐름 비중을 조절가능해야 한다.

      이런 이유로 요즘 Service Mesh 는 Sidecar 활용 패턴을 사용하는데 Istio 에서는 서비스 배포 시에 Sidecar 를 자동으로 Injection 해주는 기능을 지원하고 있으며, 많은 곳에서 대부분 auto injeciton 을 사용하고 있다.

      하지만 Knative 에서는 auto injection 을 사용하지 않는다.

      auto injection 은 kubernetes namespace 에 label 을 추가하여 (istio-injeciton=enabled) 자동으로 해당 namespace 에 배포되는 pod 에는 sidecar proxy 가 자동으로 설치되는 기능이라,

      Service Mesh 를 사용하고 싶지 않은 서비스들에게도 영향을 줄 수 있기 때문에 auto injection 을 disable 할 것을 권장하고 있다.

      Istio 설치는 helm chart 로 쉽게 설치할 수 있다.

      helm repo 를 추가하고 value 값을 오버라이드할 파일을 만든다.

      $ helm repo add istio https://istio-release.storage.googleapis.com/charts
      $ helm repo update
      
      $ vi istiod_1.12.8_default_values.yaml
      global:
        proxy:
      		autoInject: disabled   # 원래 값은 enabled 임

      Istio-system 네임스페이스를 생성한 후 helm chart 를 설치한다.

      base 는 crd 를 설치하며, istiod 가 실제 데몬 서비스다.

      $ kubectl create namespace istio-system
      $ helm upgrade -i istio-base istio/base --version 1.12.8 -n istio-system -f istiod_1.12.8_default_values.yaml
      $ helm upgrade -i istiod istio/istiod --version 1.12.8 -n istio-system -f istiod_1.12.8_default_values.yaml --wait

      외부에서 서비스로 접근하기 위한 North - South 통신은 Istio Ingress Gateway 를 통해서 가능하다. 그러므로 Istio Gateway 를 추가로 설치해 준다.

      먼저, value 값을 오버라이드할 파일을 만든다.

      $ vi gateway_1.12.8_default_values.yaml
      podAnnotations:
        prometheus.io/port: "15020"
        prometheus.io/scrape: "true"
        prometheus.io/path: "/stats/prometheus"
        inject.istio.io/templates: "gateway"
        sidecar.istio.io/inject: "true" 

      istio-ingress 네임스페이스를 생성하고 istio ingress gateway 를 helm chart로 설치한다.

      $ kubectl create ns istio-ingress
      $ helm upgrade -i istio-ingress istio/gateway --version 1.12.8 -n istio-ingress -f gateway_1.12.8_default_values.yaml

      아래와 같이 잘 설치되어 있음을 확인할 수 있다.

      $ kubectl get pods -n istio-system
      NAME                      READY   STATUS    RESTARTS   AGE
      istiod-68d7bfb6d8-nt82m   1/1     Running   0          20d
      
      $ kubectl get pods -n istio-ingress
      NAME                             READY   STATUS    RESTARTS   AGE
      istio-ingress-69495c6667-7njv8   1/1     Running   0          20d


      Knative 설치

      Knative 는 Serverless 플랫폼이라 생각하면 된다. 서비스를 Istio 를 활용하여 배포하면 Gateway, VirtualServie 를 만들어서 연결해야 하는데 Knative 를 이를 자동으로 생성해주기 때문에 편리하다.

      또한 앞에서도 설명한 모니터링, 로깅, 트레이싱이 잘 연결되기 때문에 일단 설치를 한다면 사용하기 편리하다.

      Knative 는 설치 모듈이 Serving 과 Eventing 2개로 나눠져 있다. 일단 API 서비스가 가능한 Serving 모듈만 설치하고 테스트를 한다.

      또한 모니터링, 로깅, 트레이싱도 다음에 설명하고 지금은 Knative Serving 기능에 집중한다.

      Knative 는 Yaml 과 Operator 로 설치할 수 있는데 공식 문서에서 Operator 는 개발/테스트 환경에서만 사용하라고 권고하기 때문에 yaml 로 설치한다.

      먼저, crd 를 설치하고, Serving 모듈을 설치한다.

      $ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.5.0/serving-crds.yaml
      --- output ---
      customresourcedefinition.apiextensions.k8s.io/certificates.networking.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/configurations.serving.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/clusterdomainclaims.networking.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/domainmappings.serving.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/ingresses.networking.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/metrics.autoscaling.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/podautoscalers.autoscaling.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/revisions.serving.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/routes.serving.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/serverlessservices.networking.internal.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/services.serving.knative.dev created
      customresourcedefinition.apiextensions.k8s.io/images.caching.internal.knative.dev created
      
      $ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.5.0/serving-core.yaml
      --- output ---
      namespace/knative-serving created
      clusterrole.rbac.authorization.k8s.io/knative-serving-aggregated-addressable-resolver created
      clusterrole.rbac.authorization.k8s.io/knative-serving-addressable-resolver created
      clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-admin created
      clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-edit created
      clusterrole.rbac.authorization.k8s.io/knative-serving-namespaced-view created
      clusterrole.rbac.authorization.k8s.io/knative-serving-core created
      clusterrole.rbac.authorization.k8s.io/knative-serving-podspecable-binding created
      serviceaccount/controller created
      clusterrole.rbac.authorization.k8s.io/knative-serving-admin created
      clusterrolebinding.rbac.authorization.k8s.io/knative-serving-controller-admin created
      clusterrolebinding.rbac.authorization.k8s.io/knative-serving-controller-addressable-resolver created
      customresourcedefinition.apiextensions.k8s.io/images.caching.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/certificates.networking.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/configurations.serving.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/clusterdomainclaims.networking.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/domainmappings.serving.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/ingresses.networking.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/metrics.autoscaling.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/podautoscalers.autoscaling.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/revisions.serving.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/routes.serving.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/serverlessservices.networking.internal.knative.dev unchanged
      customresourcedefinition.apiextensions.k8s.io/services.serving.knative.dev unchanged
      image.caching.internal.knative.dev/queue-proxy created
      configmap/config-autoscaler created
      configmap/config-defaults created
      configmap/config-deployment created
      configmap/config-domain created
      configmap/config-features created
      configmap/config-gc created
      configmap/config-leader-election created
      configmap/config-logging created
      configmap/config-network created
      configmap/config-observability created
      configmap/config-tracing created
      horizontalpodautoscaler.autoscaling/activator created
      poddisruptionbudget.policy/activator-pdb created
      deployment.apps/activator created
      service/activator-service created
      deployment.apps/autoscaler created
      service/autoscaler created
      deployment.apps/controller created
      service/controller created
      deployment.apps/domain-mapping created
      deployment.apps/domainmapping-webhook created
      service/domainmapping-webhook created
      horizontalpodautoscaler.autoscaling/webhook created
      poddisruptionbudget.policy/webhook-pdb created
      deployment.apps/webhook created
      service/webhook created
      validatingwebhookconfiguration.admissionregistration.k8s.io/config.webhook.serving.knative.dev created
      mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook.serving.knative.dev created
      mutatingwebhookconfiguration.admissionregistration.k8s.io/webhook.domainmapping.serving.knative.dev created
      secret/domainmapping-webhook-certs created
      validatingwebhookconfiguration.admissionregistration.k8s.io/validation.webhook.domainmapping.serving.knative.dev created
      validatingwebhookconfiguration.admissionregistration.k8s.io/validation.webhook.serving.knative.dev created
      secret/webhook-certs created

      다음은 Isito 와 연동하기 위한 network 들을 설치한다.

      $ kubectl apply -f https://github.com/knative/net-istio/releases/download/knative-v1.5.0/net-istio.yaml

      그대로 설치하면 Isito gateway 와 연동되지 않는다. 그렇기 때문에 아래와 같이 selector 를 수정해 줘야 한다.

      $ kubectl edit gateway -n knative-serving knative-ingress-gateway
      ...
      spec:
        selector:
          istio: ingressgateway
          istio: ingress          # 추가
      
      $ kubectl edit gateway -n knative-serving knative-local-gateway
      ...
      spec:
        selector:
          istio: ingressgateway
          istio: ingress          # 추가

      Istio 의 Ingress gateway 앞단에는 LoadBalancer 가 연결되어 있다.

      LoadBalancer 가 External IP 로 연결되어 있으면 IP 를 dns 로 연결해 주는 magic dns (sslip.io) 를 사용할 수 있고,

      LoadBalancer 가 domain name 으로 연결되어 있으면 실제 DNS 에 CNAME 을 등록하여 연결하면 된다.

      $ kubectl get svc -n istio-ingress
      NAME            TYPE           CLUSTER-IP       EXTERNAL-IP 
      istio-ingress   LoadBalancer   10.107.111.229   xxxxx.ap-northeast-2.elb.amazonaws.com

      여기서는 aws 를 사용하고 있기 때문에 Route53 에 CNAME 을 등록하였다.

      서비스 도메인: helloworld-go-default.taco-cat.xyz
      target: xxxxx.ap-northeast-2.elb.amazonaws.com
      type: CNAME

      Knative ConfigMap 설정

      마지막으로 Knative ConfigMap 에 기본 도메인과 full 도메인 설정을 세팅한다.

      이 설정은 앞서 Route53 에 등록한 서비스 도메인과 같은 형식으로 설정되게 구성해야 한다.

      ## Domain: taco-cat.xyz
      $ kubectl edit cm config-domain -n knative-serving
      apiVersion: v1
      data:
        taco-cat.xyz: ""
      kind: ConfigMap
      [...]
      
      ## Name: helloworld-go
      ## Namesapce: default
      ## Domain: taco-cat.xyz
      $ kubectl edit cm config-network -n knative-serving
      apiVersion: v1
      data:
        domain-template: "{{.Name}}-{{.Namespace}}.{{.Domain}}"

      Knative sample 배포 테스트

      Knative 에서 제공하는 helloworld-go 샘플 프로그램을 배포해 보자.

      서비스 이름이 helloworld-go, Namespace 가 default 로 앞서 Route53 및 ConfigMap 에 설정한 도메인 형식과 동일함을 할 수 있다.

      $ git clone https://github.com/knative/docs knative-docs
      $ cd knative-docs/code-samples/serving/hello-world/helloworld-go
      
      $ vi service.yaml
      apiVersion: serving.knative.dev/v1
      kind: Service
      metadata:
        name: helloworld-go
        namespace: default
      spec:
        template:
          spec:
            containers:
            - image: gcr.io/knative-samples/helloworld-go
              env:
              - name: TARGET
                value: "Go Sample v1"
      
      $ kubectl apply -f service.yaml

      배포가 제대로 되었는지 확인해 보자.

      $ kubectl get route
      NAME            URL                                         READY   REASON
      helloworld-go   http://helloworld-go-default.taco-cat.xyz   True

      Knative 는 zero replicas 를 사용한다

      Serverless 를 어떻게 구현했을까? 사실 Knative 는 Kubernetes 의 zero replicas 를 사용했다.

      배포 후에 deployment 를 조회하면 아래과 같이 Ready 와 Available 이 0 상태임을 알 수 있다.

      $ kubectl get deploy
      NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
      helloworld-go-00001-deployment             0/0     0            0           10d

      배포도 잘되고 Route53 에 dns 도 어느 정도 시간이 지났다면 브라우저 혹은 curl 로 확인할 수 있다.

      $ curl http://helloworld-go-default.taco-cat.xyz
      --- output ---
      Hello Go Sample v1!

      이렇게 요청이 들어오면 실제로 pod 가 실행되고 있음을 알 수 있다. 1분 동안 아무런 요청이 없으면 pod 는 다시 사라지고 대기 상태가 된다. (요청이 없더라도 중간에 다시 pod 가 생겨서 실제로는 일정 시간 동안 새로운 pod 로 교체된다)

      $ kubectl get deploy
      NAME                                       READY   UP-TO-DATE   AVAILABLE   AGE
      helloworld-go-00001-deployment             1/1     1            1           10d

      TLS 인증서 적용

      인증서를 가지고 있다면 gateway 에 tls 를 적용하여 tls termination 을 할 수 있다.

      아래는 istio-ingress 네임스페이스에 secret 으로 taco-cat-tls 인증서를 설치한 후 gateway 에서 해당 인증서를 읽을 수 있도록 tls 를 추가한 부분이다.

      $ kubectl edit gateway knative-ingress-gateway -n knative-serving
      ...
      spec:
        selector:
          istio: ingress
        servers:
        - hosts:
          - '*'
          port:
            name: http
            number: 80
            protocol: HTTP
        - hosts:
          - '*.taco-cat.xyz'
          port:
            name: https
            number: 443
            protocol: HTTPS
          ## tls 추가
          tls:
            mode: SIMPLE
            credentialName: taco-cat-tls

      HPA 설치

      서비스에 요청이 신규로 들어오거나, 많아지면 replicas 수를 조절하여 pod 를 실행해주는 activator 가 있다. 이 activator 를 auto scaling 하는 hpa 를 설치한다.

      $ kubectl apply -f https://github.com/knative/serving/releases/download/knative-v1.5.0/serving-hpa.yaml

      hpa 를 조회해서 확인할 수 있다.

      $ kubectl get hpa -n knative-serving
      NAME        REFERENCE              TARGETS   MINPODS   MAXPODS   REPLICAS   AGE
      activator   Deployment/activator   0%/100%   1         20        1          13d
      webhook     Deployment/webhook     3%/100%   1         5         1          13d


      KServe 설치

      KServe 는 이제 막 Helm chart 가 만들어지고 있다. 그렇기 때문에 일단은 yaml 로 설치를 진행한다.

      먼저 KServe 컴포넌트를 설치하고 이어서 각종 ML Framework 를 나타내는 Runtime을 설치한다.

      $ kubectl apply -f https://github.com/kserve/kserve/releases/download/v0.8.0/kserve.yaml
      --- output ---
      namespace/kserve created
      customresourcedefinition.apiextensions.k8s.io/clusterservingruntimes.serving.kserve.io created
      customresourcedefinition.apiextensions.k8s.io/inferenceservices.serving.kserve.io created
      customresourcedefinition.apiextensions.k8s.io/servingruntimes.serving.kserve.io created
      customresourcedefinition.apiextensions.k8s.io/trainedmodels.serving.kserve.io created
      serviceaccount/kserve-controller-manager created
      role.rbac.authorization.k8s.io/leader-election-role created
      clusterrole.rbac.authorization.k8s.io/kserve-manager-role created
      clusterrole.rbac.authorization.k8s.io/kserve-proxy-role created
      rolebinding.rbac.authorization.k8s.io/leader-election-rolebinding created
      clusterrolebinding.rbac.authorization.k8s.io/kserve-manager-rolebinding created
      clusterrolebinding.rbac.authorization.k8s.io/kserve-proxy-rolebinding created
      configmap/inferenceservice-config created
      configmap/kserve-config created
      secret/kserve-webhook-server-secret created
      service/kserve-controller-manager-metrics-service created
      service/kserve-controller-manager-service created
      service/kserve-webhook-server-service created
      statefulset.apps/kserve-controller-manager created
      certificate.cert-manager.io/serving-cert created
      issuer.cert-manager.io/selfsigned-issuer created
      mutatingwebhookconfiguration.admissionregistration.k8s.io/inferenceservice.serving.kserve.io created
      validatingwebhookconfiguration.admissionregistration.k8s.io/inferenceservice.serving.kserve.io created
      validatingwebhookconfiguration.admissionregistration.k8s.io/trainedmodel.serving.kserve.io created
      
      $ kubectl apply -f https://github.com/kserve/kserve/releases/download/v0.8.0/kserve-runtimes.yaml
      --- output---
      clusterservingruntime.serving.kserve.io/kserve-lgbserver created
      clusterservingruntime.serving.kserve.io/kserve-mlserver created
      clusterservingruntime.serving.kserve.io/kserve-paddleserver created
      clusterservingruntime.serving.kserve.io/kserve-pmmlserver created
      clusterservingruntime.serving.kserve.io/kserve-sklearnserver created
      clusterservingruntime.serving.kserve.io/kserve-tensorflow-serving created
      clusterservingruntime.serving.kserve.io/kserve-torchserve created
      clusterservingruntime.serving.kserve.io/kserve-tritonserver created
      clusterservingruntime.serving.kserve.io/kserve-xgbserver created

      KServe 설치를 확인한다.

      $ kubectl get pod -n kserve
      NAME                          READY   STATUS    RESTARTS   AGE
      kserve-controller-manager-0   2/2     Running   0          7d10h

      Rumtime 도 설치되었는지 확인한다.

      $ kubectl get clusterservingruntimes
      NAME                        DISABLED   MODELTYPE    CONTAINERS         AGE
      kserve-lgbserver                       lightgbm     kserve-container   7d10h
      kserve-mlserver                        sklearn      kserve-container   7d10h
      kserve-paddleserver                    paddle       kserve-container   7d10h
      kserve-pmmlserver                      pmml         kserve-container   7d10h
      kserve-sklearnserver                   sklearn      kserve-container   7d10h
      kserve-tensorflow-serving              tensorflow   kserve-container   7d10h
      kserve-torchserve                      pytorch      kserve-container   7d10h
      kserve-tritonserver                    tensorrt     kserve-container   7d10h
      kserve-xgbserver                       xgboost      kserve-container   7d10h

      Sample model 을 KServe 를 활용하여 배포

      tensorflow 로 개발된 mnist 샘플 모델을 KServe 로 배포해 보자.

      KServe 는 model in load 패턴을 적용하여 인퍼런스 서비스를 수행한다. 아래에서는 모델이 gs 에 저장되어 있으면 이를 가져와서 서빙하는 구조이다.

      runtime 은 앞서 설치한 clusterservingruntime 중에 하나인 kserve-tensorflow-serving 이고 버전이 2 임을 알 수 있다.

      $ vi mnist_tensorflow.yaml
      ---
      apiVersion: "serving.kserve.io/v1beta1"
      kind: "InferenceService"
      metadata:
        name: "mnist"
      spec:
        predictor:
          model:
            modelFormat:
              name: tensorflow
              version: "2"
            storageUri: "gs://kserve/models/mnist"
            runtime: kserve-tensorflow-serving
          logger:
            mode: all
      
      $ kubectl apply -f mnist_tensorflow.yaml

      서빙 배포 확인은 다음과 같다.

      KServe 에서 도메인을 만들 때 namespace 를 추가로 붙히기 때문에 도메인이 아래와

      $ kubectl get isvc
      NAME    URL     READY   PREV   LATEST   PREVROLLEDOUTREVISION  LATESTREADYREVISION
      mnist   http://mnist-default.taco-cat.xyz   True           100 mnist-predictor-default-00001
      
      $ kubectl get route
      NAME                      URL                                                   READY   REASON
      mnist-predictor-default   http://mnist-predictor-default-default.taco-cat.xyz   True

      Route53 에 도메인을 추가한다.

      서비스 도메인: mnist-predictor-default-default.taco-cat.xyz
      target: xxxxx.ap-northeast-2.elb.amazonaws.com
      type: CNAME

      아래와 같이 요청하여 결과값이 제대로 나오는지 확인한다.

      $ curl https://mnist-predictor-default-default.taco-cat.xyz/v1/models/mnist:predict \
         -H 'Content-Type: application/json' \
         -d @mnist.json
      --- output ---
      {
          "predictions": [[3.2338352e-09, 1.66207215e-09, 1.17224181e-06, 0.000114716699, 4.34008705e-13, 4.64885304e-08, 3.96761454e-13, 0.999883413, 1.21785089e-08, 6.44099089e-07]
          ]
      }

      댓글 0

      DEVOTEE를 활성화 시키면
      지금 작성한 댓글에 AI가 댓글을 달아줍니다.

      seungkyua 님의 최신 블로그

      더보기
      동영상 기고하기