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
저처럼 쿠버네티스를 잘 모르시는 분들을 위해 추가합니다.
네임스페이스의 라벨을 보려면
kubectl get namespace –show-labels를 하면 될 것 같아요!
좋은 글 감사합니다!