mirror of
https://github.com/hanzo-ml/kserve.git
synced 2026-10-30 20:53:49 +00:00
2392 lines
70 KiB
Go
2392 lines
70 KiB
Go
/*
|
|
Copyright 2021 The KServe Authors.
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
you may not use this file except in compliance with the License.
|
|
You may obtain a copy of the License at
|
|
|
|
http://www.apache.org/licenses/LICENSE-2.0
|
|
|
|
Unless required by applicable law or agreed to in writing, software
|
|
distributed under the License is distributed on an "AS IS" BASIS,
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
See the License for the specific language governing permissions and
|
|
limitations under the License.
|
|
*/
|
|
|
|
package pod
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strconv"
|
|
"testing"
|
|
|
|
"github.com/onsi/gomega"
|
|
"github.com/onsi/gomega/types"
|
|
"k8s.io/apimachinery/pkg/api/resource"
|
|
"k8s.io/apimachinery/pkg/util/intstr"
|
|
fakeclientset "k8s.io/client-go/kubernetes/fake"
|
|
"k8s.io/utils/ptr"
|
|
"knative.dev/pkg/kmp"
|
|
|
|
"github.com/kserve/kserve/pkg/apis/serving/v1beta1"
|
|
"github.com/kserve/kserve/pkg/credentials"
|
|
|
|
corev1 "k8s.io/api/core/v1"
|
|
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
|
|
|
|
"github.com/kserve/kserve/pkg/constants"
|
|
)
|
|
|
|
const (
|
|
AgentDefaultCPURequest = "100m"
|
|
AgentDefaultCPULimit = "1"
|
|
AgentDefaultMemoryRequest = "200Mi"
|
|
AgentDefaultMemoryLimit = "1Gi"
|
|
)
|
|
|
|
var (
|
|
storagePath = "/logger"
|
|
storageParameters = map[string]string{
|
|
"type": "s3",
|
|
"region": "us-west-2",
|
|
"format": "json",
|
|
}
|
|
storageKey = "logger-credentials"
|
|
agentConfig = &AgentConfig{
|
|
Image: "gcr.io/kserve/agent:latest",
|
|
CpuRequest: AgentDefaultCPURequest,
|
|
CpuLimit: AgentDefaultCPULimit,
|
|
MemoryRequest: AgentDefaultMemoryRequest,
|
|
MemoryLimit: AgentDefaultMemoryLimit,
|
|
}
|
|
|
|
loggerConfig = &LoggerConfig{
|
|
Image: "gcr.io/kserve/agent:latest",
|
|
DefaultUrl: "http://httpbin.org/",
|
|
}
|
|
loggerTLSConfig = &LoggerConfig{
|
|
Image: "gcr.io/kserve/agent:latest",
|
|
DefaultUrl: "https://httpbin.org/",
|
|
CaBundle: "kserve-tls-bundle",
|
|
CaCertFile: "ca.crt",
|
|
TlsSkipVerify: true,
|
|
}
|
|
saName = constants.LoggerDefaultServiceAccountName
|
|
loggerConfigWithStorage = &LoggerConfig{
|
|
Image: "gcr.io/kserve/agent:latest",
|
|
DefaultUrl: "http://httpbin.org/",
|
|
Store: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &storagePath,
|
|
Parameters: &storageParameters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &saName,
|
|
},
|
|
}
|
|
batcherTestConfig = &BatcherConfig{
|
|
Image: "gcr.io/kserve/batcher:latest",
|
|
}
|
|
agentResourceRequirement = corev1.ResourceRequirements{
|
|
Limits: map[corev1.ResourceName]resource.Quantity{
|
|
corev1.ResourceCPU: resource.MustParse(AgentDefaultCPULimit),
|
|
corev1.ResourceMemory: resource.MustParse(AgentDefaultMemoryLimit),
|
|
},
|
|
Requests: map[corev1.ResourceName]resource.Quantity{
|
|
corev1.ResourceCPU: resource.MustParse(AgentDefaultCPURequest),
|
|
corev1.ResourceMemory: resource.MustParse(AgentDefaultMemoryRequest),
|
|
},
|
|
}
|
|
)
|
|
|
|
func TestAgentInjector(t *testing.T) {
|
|
scenarios := map[string]struct {
|
|
original *corev1.Pod
|
|
expected *corev1.Pod
|
|
}{
|
|
"AddAgent": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
constants.AgentModelConfigVolumeNameAnnotationKey: "modelconfig-deployment-0",
|
|
constants.AgentModelDirAnnotationKey: "/mnt/models",
|
|
constants.AgentModelConfigMountPathAnnotationKey: "/mnt/configs",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: agentConfig.Image,
|
|
Resources: agentResourceRequirement,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.ModelDirVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelDir,
|
|
},
|
|
{
|
|
Name: constants.ModelConfigVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelConfigDir,
|
|
},
|
|
},
|
|
Args: []string{
|
|
"--enable-puller", "--config-dir", "/mnt/configs", "--model-dir", "/mnt/models", constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "model-dir",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
{
|
|
Name: "model-config",
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "modelconfig-deployment-0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"DoNotAddAgent": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
"AddLogger": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"AddLoggerWithMetadata": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
constants.LoggerMetadataHeadersInternalAnnotationKey: "Foo,Bar",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentMetadataHeaders,
|
|
"Foo,Bar",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"AddLoggerWithAnnotation": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
constants.LoggerMetadataAnnotationsInternalAnnotationKey: "Foo,Fizz",
|
|
"Foo": "Bar",
|
|
"Fizz": "Buzz",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentMetadataAnnotations,
|
|
"Foo=Bar,Fizz=Buzz",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"DoNotAddLogger": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
"AddBatcher": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.BatcherInternalAnnotationKey: "true",
|
|
constants.BatcherMaxLatencyInternalAnnotationKey: "100",
|
|
constants.BatcherMaxBatchSizeInternalAnnotationKey: "30",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.BatcherInternalAnnotationKey: "true",
|
|
constants.BatcherMaxLatencyInternalAnnotationKey: "100",
|
|
constants.BatcherMaxBatchSizeInternalAnnotationKey: "30",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
BatcherEnableFlag,
|
|
BatcherArgumentMaxBatchSize,
|
|
"30",
|
|
BatcherArgumentMaxLatency,
|
|
"100",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"DoNotAddBatcher": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{{
|
|
Name: "sklearn",
|
|
}},
|
|
},
|
|
},
|
|
},
|
|
"AgentAlreadyInjected": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
constants.AgentModelConfigVolumeNameAnnotationKey: "modelconfig-deployment-0",
|
|
constants.AgentModelDirAnnotationKey: "/mnt/models",
|
|
constants.AgentModelConfigMountPathAnnotationKey: "/mnt/configs",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: agentConfig.Image,
|
|
Resources: agentResourceRequirement,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.ModelDirVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelDir,
|
|
},
|
|
{
|
|
Name: constants.ModelConfigVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelConfigDir,
|
|
},
|
|
},
|
|
Args: []string{"--enable-puller", "--config-dir", "/mnt/configs", "--model-dir", "/mnt/models"},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "model-dir",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
{
|
|
Name: "model-config",
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "modelconfig-deployment-0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: agentConfig.Image,
|
|
Resources: agentResourceRequirement,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.ModelDirVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelDir,
|
|
},
|
|
{
|
|
Name: constants.ModelConfigVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelConfigDir,
|
|
},
|
|
},
|
|
Args: []string{"--enable-puller", "--config-dir", "/mnt/configs", "--model-dir", "/mnt/models"},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{
|
|
{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"},
|
|
},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "model-dir",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
{
|
|
Name: "model-config",
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "modelconfig-deployment-0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"DefaultLoggerConfig": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"QueueProxyUserPortProvided": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{
|
|
{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"},
|
|
{Name: "USER_PORT", Value: "8080"},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{
|
|
{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"},
|
|
{Name: "USER_PORT", Value: constants.InferenceServiceDefaultAgentPortStr},
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{
|
|
{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"},
|
|
{Name: "USER_PORT", Value: "8080"},
|
|
},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"KserveContainer has port": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
constants.AgentModelConfigVolumeNameAnnotationKey: "modelconfig-deployment-0",
|
|
constants.AgentModelDirAnnotationKey: "/mnt/models",
|
|
constants.AgentModelConfigMountPathAnnotationKey: "/mnt/configs",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "serving-port",
|
|
ContainerPort: 80,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "kserve-container",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "serving-port",
|
|
ContainerPort: 80,
|
|
},
|
|
},
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{Name: "model-dir", MountPath: "/mnt/models"},
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: agentConfig.Image,
|
|
Resources: agentResourceRequirement,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.ModelDirVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelDir,
|
|
},
|
|
{
|
|
Name: constants.ModelConfigVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelConfigDir,
|
|
},
|
|
},
|
|
Args: []string{
|
|
"--enable-puller", "--config-dir", "/mnt/configs", "--model-dir", "/mnt/models",
|
|
constants.AgentComponentPortArgName, "80",
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "model-dir",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
{
|
|
Name: "model-config",
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "modelconfig-deployment-0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
scenariosTls := map[string]struct {
|
|
original *corev1.Pod
|
|
expected *corev1.Pod
|
|
}{
|
|
"AddLogger": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "https://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "https://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"https://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentCaCertFile,
|
|
loggerTLSConfig.CaCertFile,
|
|
LoggerArgumentTlsSkipVerify,
|
|
strconv.FormatBool(loggerTLSConfig.TlsSkipVerify),
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.LoggerCaBundleVolume,
|
|
ReadOnly: true,
|
|
MountPath: constants.LoggerCaCertMountPath,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: constants.LoggerCaBundleVolume,
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: loggerTLSConfig.CaBundle,
|
|
},
|
|
Optional: ptr.To(true),
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
scenariosLoggerStorage := map[string]struct {
|
|
original *corev1.Pod
|
|
expected *corev1.Pod
|
|
}{
|
|
"AddLoggerWithStorage": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.LoggerInternalAnnotationKey: "true",
|
|
constants.LoggerSinkUrlInternalAnnotationKey: "http://httpbin.org/",
|
|
constants.LoggerModeInternalAnnotationKey: string(v1beta1.LogAll),
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.IntOrString{
|
|
IntVal: 8080,
|
|
},
|
|
},
|
|
},
|
|
InitialDelaySeconds: 0,
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: "queue-proxy",
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: loggerConfig.Image,
|
|
Args: []string{
|
|
LoggerArgumentLogUrl,
|
|
"http://httpbin.org/",
|
|
LoggerArgumentSourceUri,
|
|
"deployment",
|
|
LoggerArgumentMode,
|
|
"all",
|
|
LoggerArgumentInferenceService,
|
|
"sklearn",
|
|
LoggerArgumentNamespace,
|
|
"default",
|
|
LoggerArgumentEndpoint,
|
|
"default",
|
|
LoggerArgumentComponent,
|
|
"predictor",
|
|
LoggerArgumentStorePath,
|
|
storagePath,
|
|
LoggerArgumentStoreFormat,
|
|
"json",
|
|
LoggerArgumentTlsSkipVerify,
|
|
"false",
|
|
constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"tcpSocket\":{\"port\":8080},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
Resources: agentResourceRequirement,
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
"AddAgentWithHTTPGetReadinessProbe": {
|
|
original: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Namespace: "default",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
constants.AgentModelConfigVolumeNameAnnotationKey: "modelconfig-deployment-0",
|
|
constants.AgentModelDirAnnotationKey: "/mnt/models",
|
|
constants.AgentModelConfigMountPathAnnotationKey: "/mnt/configs",
|
|
},
|
|
Labels: map[string]string{
|
|
"serving.kserve.io/inferenceservice": "sklearn",
|
|
constants.KServiceModelLabel: "sklearn",
|
|
constants.KServiceEndpointLabel: "default",
|
|
constants.KServiceComponentLabel: "predictor",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
Path: "/v1/health/ready",
|
|
Port: intstr.FromInt(8080),
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
expected: &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "deployment",
|
|
Annotations: map[string]string{
|
|
constants.AgentShouldInjectAnnotationKey: "true",
|
|
},
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
ServiceAccountName: "sa",
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "sklearn",
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
Path: "/v1/health/ready",
|
|
Port: intstr.FromInt(8080),
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
TimeoutSeconds: 1,
|
|
PeriodSeconds: 10,
|
|
SuccessThreshold: 1,
|
|
FailureThreshold: 3,
|
|
},
|
|
},
|
|
{
|
|
Name: constants.AgentContainerName,
|
|
Image: agentConfig.Image,
|
|
Resources: agentResourceRequirement,
|
|
VolumeMounts: []corev1.VolumeMount{
|
|
{
|
|
Name: constants.ModelDirVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelDir,
|
|
},
|
|
{
|
|
Name: constants.ModelConfigVolumeName,
|
|
ReadOnly: false,
|
|
MountPath: constants.ModelConfigDir,
|
|
},
|
|
},
|
|
Args: []string{
|
|
"--enable-puller", "--config-dir", "/mnt/configs", "--model-dir", "/mnt/models", constants.AgentComponentPortArgName,
|
|
constants.InferenceServiceDefaultHttpPort,
|
|
},
|
|
Ports: []corev1.ContainerPort{
|
|
{
|
|
Name: "agent-port",
|
|
ContainerPort: constants.InferenceServiceDefaultAgentPort,
|
|
Protocol: "TCP",
|
|
},
|
|
},
|
|
Env: []corev1.EnvVar{{Name: "SERVING_READINESS_PROBE", Value: "{\"httpGet\":{\"path\":\"/v1/health/ready\",\"port\":8080,\"scheme\":\"HTTP\"},\"timeoutSeconds\":1,\"periodSeconds\":10,\"successThreshold\":1,\"failureThreshold\":3}"}},
|
|
ReadinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
HTTPHeaders: []corev1.HTTPHeader{
|
|
{
|
|
Name: "K-Network-Probe",
|
|
Value: "queue",
|
|
},
|
|
},
|
|
Port: intstr.FromInt(9081),
|
|
Path: "/v1/health/ready",
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
Volumes: []corev1.Volume{
|
|
{
|
|
Name: "model-dir",
|
|
VolumeSource: corev1.VolumeSource{
|
|
EmptyDir: &corev1.EmptyDirVolumeSource{},
|
|
},
|
|
},
|
|
{
|
|
Name: "model-config",
|
|
VolumeSource: corev1.VolumeSource{
|
|
ConfigMap: &corev1.ConfigMapVolumeSource{
|
|
LocalObjectReference: corev1.LocalObjectReference{
|
|
Name: "modelconfig-deployment-0",
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
}
|
|
clientset := fakeclientset.NewSimpleClientset()
|
|
credentialBuilder := credentials.NewCredentialBuilder(c, clientset, &corev1.ConfigMap{
|
|
Data: map[string]string{},
|
|
})
|
|
|
|
for name, scenario := range scenarios {
|
|
injector := &AgentInjector{
|
|
credentialBuilder,
|
|
agentConfig,
|
|
loggerConfig,
|
|
batcherTestConfig,
|
|
}
|
|
_ = injector.InjectAgent(scenario.original)
|
|
if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" {
|
|
t.Errorf("Test %q unexpected result (-want +got): %v", name, diff)
|
|
}
|
|
}
|
|
// Run TLS logger config with non-TLS scenarios
|
|
for name, scenario := range scenarios {
|
|
injector := &AgentInjector{
|
|
credentialBuilder,
|
|
agentConfig,
|
|
loggerTLSConfig,
|
|
batcherTestConfig,
|
|
}
|
|
_ = injector.InjectAgent(scenario.original)
|
|
if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" {
|
|
t.Errorf("Test %q unexpected result (-want +got): %v", name, diff)
|
|
}
|
|
}
|
|
// Run TLS logger config with TLS scenarios
|
|
for name, scenario := range scenariosTls {
|
|
injector := &AgentInjector{
|
|
credentialBuilder,
|
|
agentConfig,
|
|
loggerTLSConfig,
|
|
batcherTestConfig,
|
|
}
|
|
_ = injector.InjectAgent(scenario.original)
|
|
if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" {
|
|
t.Errorf("Test %q unexpected result (-want +got): %v", name, diff)
|
|
}
|
|
}
|
|
// Run logger storage scenarios
|
|
for name, scenario := range scenariosLoggerStorage {
|
|
injector := &AgentInjector{
|
|
credentialBuilder,
|
|
agentConfig,
|
|
loggerConfigWithStorage,
|
|
batcherTestConfig,
|
|
}
|
|
_ = injector.InjectAgent(scenario.original)
|
|
if diff, _ := kmp.SafeDiff(scenario.expected.Spec, scenario.original.Spec); diff != "" {
|
|
t.Errorf("Test %q unexpected result (-want +got): %v", name, diff)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestGetLoggerConfigs(t *testing.T) {
|
|
g := gomega.NewGomegaWithT(t)
|
|
url := "s3://bucket/logger"
|
|
mode := v1beta1.LogAll
|
|
serviceAccountName := "logger-service-account-name"
|
|
defaultServiceAccountName := constants.LoggerDefaultServiceAccountName
|
|
path := "/logger"
|
|
parameters := map[string]string{
|
|
"type": "s3",
|
|
"region": "us-west-2",
|
|
"format": "json",
|
|
}
|
|
pod := &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "podname",
|
|
},
|
|
}
|
|
|
|
cases := []struct {
|
|
name string
|
|
configMap *corev1.ConfigMap
|
|
isvc *v1beta1.InferenceService
|
|
matchers []types.GomegaMatcher
|
|
pod *corev1.Pod
|
|
}{
|
|
{
|
|
name: "Logger storage nil",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
LoggerConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/logger:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200Mi",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
isvc: &v1beta1.InferenceService{
|
|
Spec: v1beta1.InferenceServiceSpec{
|
|
Predictor: v1beta1.PredictorSpec{
|
|
ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{
|
|
Logger: &v1beta1.LoggerSpec{
|
|
URL: &url,
|
|
Mode: mode,
|
|
MetadataHeaders: nil,
|
|
MetadataAnnotations: nil,
|
|
Storage: nil,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
pod: pod,
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&LoggerConfig{
|
|
Image: "gcr.io/kfserving/logger:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200Mi",
|
|
MemoryLimit: "1Gi",
|
|
Store: nil,
|
|
}),
|
|
gomega.BeNil(),
|
|
},
|
|
},
|
|
{
|
|
name: "Logger storage service account nil",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
LoggerConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/logger:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200Mi",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
isvc: &v1beta1.InferenceService{
|
|
Spec: v1beta1.InferenceServiceSpec{
|
|
Predictor: v1beta1.PredictorSpec{
|
|
ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{
|
|
Logger: &v1beta1.LoggerSpec{
|
|
URL: &url,
|
|
Mode: mode,
|
|
MetadataHeaders: nil,
|
|
MetadataAnnotations: nil,
|
|
Storage: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &path,
|
|
Parameters: ¶meters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
pod: pod,
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&LoggerConfig{
|
|
Image: "gcr.io/kfserving/logger:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200Mi",
|
|
MemoryLimit: "1Gi",
|
|
Store: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &storagePath,
|
|
Parameters: &storageParameters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &defaultServiceAccountName,
|
|
},
|
|
}),
|
|
gomega.BeNil(),
|
|
},
|
|
},
|
|
{
|
|
name: "Logger storage service account nil",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
LoggerConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/logger:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200Mi",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
isvc: &v1beta1.InferenceService{
|
|
Spec: v1beta1.InferenceServiceSpec{
|
|
Predictor: v1beta1.PredictorSpec{
|
|
ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{
|
|
Logger: &v1beta1.LoggerSpec{
|
|
URL: &url,
|
|
Mode: mode,
|
|
MetadataHeaders: nil,
|
|
MetadataAnnotations: nil,
|
|
Storage: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &path,
|
|
Parameters: ¶meters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &serviceAccountName,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
pod: pod,
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&LoggerConfig{
|
|
Image: "gcr.io/kfserving/logger:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200Mi",
|
|
MemoryLimit: "1Gi",
|
|
Store: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &storagePath,
|
|
Parameters: &storageParameters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &serviceAccountName,
|
|
},
|
|
}),
|
|
gomega.BeNil(),
|
|
},
|
|
},
|
|
{
|
|
name: "Valid Logger Config",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
LoggerConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/logger:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200Mi",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
isvc: &v1beta1.InferenceService{
|
|
Spec: v1beta1.InferenceServiceSpec{
|
|
Predictor: v1beta1.PredictorSpec{
|
|
ComponentExtensionSpec: v1beta1.ComponentExtensionSpec{
|
|
Logger: &v1beta1.LoggerSpec{
|
|
URL: &url,
|
|
Mode: mode,
|
|
MetadataHeaders: nil,
|
|
MetadataAnnotations: nil,
|
|
Storage: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &path,
|
|
Parameters: ¶meters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &serviceAccountName,
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
},
|
|
pod: pod,
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&LoggerConfig{
|
|
Image: "gcr.io/kfserving/logger:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200Mi",
|
|
MemoryLimit: "1Gi",
|
|
Store: &v1beta1.LoggerStorageSpec{
|
|
StorageSpec: v1beta1.StorageSpec{
|
|
Path: &storagePath,
|
|
Parameters: &storageParameters,
|
|
StorageKey: &storageKey,
|
|
},
|
|
ServiceAccountName: &serviceAccountName,
|
|
},
|
|
}),
|
|
gomega.BeNil(),
|
|
},
|
|
},
|
|
{
|
|
name: "Invalid Resource Value",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
LoggerConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/logger:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200mc",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
pod: pod,
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&LoggerConfig{
|
|
Image: "gcr.io/kfserving/logger:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200mc",
|
|
MemoryLimit: "1Gi",
|
|
}),
|
|
gomega.HaveOccurred(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
loggerConfigs, err := getLoggerConfigs(tc.pod, tc.configMap, tc.isvc)
|
|
g.Expect(err).Should(tc.matchers[1], tc.name)
|
|
g.Expect(loggerConfigs).Should(tc.matchers[0], tc.name)
|
|
}
|
|
}
|
|
|
|
func TestGetAgentConfigs(t *testing.T) {
|
|
g := gomega.NewGomegaWithT(t)
|
|
cases := []struct {
|
|
name string
|
|
configMap *corev1.ConfigMap
|
|
matchers []types.GomegaMatcher
|
|
}{
|
|
{
|
|
name: "Valid Agent Config",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
constants.AgentConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/agent:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200Mi",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&AgentConfig{
|
|
Image: "gcr.io/kfserving/agent:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200Mi",
|
|
MemoryLimit: "1Gi",
|
|
}),
|
|
gomega.BeNil(),
|
|
},
|
|
},
|
|
{
|
|
name: "Invalid Resource Value",
|
|
configMap: &corev1.ConfigMap{
|
|
TypeMeta: metav1.TypeMeta{},
|
|
ObjectMeta: metav1.ObjectMeta{},
|
|
Data: map[string]string{
|
|
constants.AgentConfigMapKeyName: `{
|
|
"Image": "gcr.io/kfserving/agent:latest",
|
|
"CpuRequest": "100m",
|
|
"CpuLimit": "1",
|
|
"MemoryRequest": "200mc",
|
|
"MemoryLimit": "1Gi"
|
|
}`,
|
|
},
|
|
BinaryData: map[string][]byte{},
|
|
},
|
|
matchers: []types.GomegaMatcher{
|
|
gomega.Equal(&AgentConfig{
|
|
Image: "gcr.io/kfserving/agent:latest",
|
|
CpuRequest: "100m",
|
|
CpuLimit: "1",
|
|
MemoryRequest: "200mc",
|
|
MemoryLimit: "1Gi",
|
|
}),
|
|
gomega.HaveOccurred(),
|
|
},
|
|
},
|
|
}
|
|
|
|
for _, tc := range cases {
|
|
loggerConfigs, err := getAgentConfigs(tc.configMap)
|
|
g.Expect(err).Should(tc.matchers[1], tc.name)
|
|
g.Expect(loggerConfigs).Should(tc.matchers[0], tc.name)
|
|
}
|
|
}
|
|
|
|
func TestReadinessProbeInheritance(t *testing.T) {
|
|
tests := []struct {
|
|
name string
|
|
readinessProbe *corev1.Probe
|
|
queueProxyAvailable bool
|
|
expectEnvVar bool
|
|
expectedProbeJson string
|
|
}{
|
|
{
|
|
name: "HTTPGet Readiness Probe",
|
|
readinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
HTTPGet: &corev1.HTTPGetAction{
|
|
Path: "/ready",
|
|
Port: intstr.FromInt(8080),
|
|
Scheme: "HTTP",
|
|
},
|
|
},
|
|
TimeoutSeconds: 0,
|
|
PeriodSeconds: 0,
|
|
SuccessThreshold: 0,
|
|
FailureThreshold: 0,
|
|
},
|
|
queueProxyAvailable: false,
|
|
expectEnvVar: true,
|
|
expectedProbeJson: `{"httpGet":{"path":"/ready","port":8080,"scheme":"HTTP"},"timeoutSeconds":0,"periodSeconds":0,"successThreshold":0,"failureThreshold":0}`,
|
|
},
|
|
{
|
|
name: "TCPSocket Readiness Probe",
|
|
readinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
TCPSocket: &corev1.TCPSocketAction{
|
|
Port: intstr.FromInt(8080),
|
|
},
|
|
},
|
|
TimeoutSeconds: 0,
|
|
PeriodSeconds: 0,
|
|
SuccessThreshold: 0,
|
|
FailureThreshold: 0,
|
|
},
|
|
queueProxyAvailable: false,
|
|
expectEnvVar: true,
|
|
expectedProbeJson: `{"tcpSocket":{"port":8080},"timeoutSeconds":0,"periodSeconds":0,"successThreshold":0,"failureThreshold":0}`,
|
|
},
|
|
{
|
|
name: "Exec Readiness Probe",
|
|
readinessProbe: &corev1.Probe{
|
|
ProbeHandler: corev1.ProbeHandler{
|
|
Exec: &corev1.ExecAction{
|
|
Command: []string{"echo", "hello"},
|
|
},
|
|
},
|
|
},
|
|
queueProxyAvailable: false,
|
|
expectEnvVar: false, // Exec probes should not be inherited
|
|
},
|
|
}
|
|
|
|
for _, tt := range tests {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
// Prepare the pod with the given readiness probe
|
|
pod := &corev1.Pod{
|
|
ObjectMeta: metav1.ObjectMeta{
|
|
Name: "test-pod",
|
|
Namespace: "default",
|
|
},
|
|
Spec: corev1.PodSpec{
|
|
Containers: []corev1.Container{
|
|
{
|
|
Name: "test-container",
|
|
ReadinessProbe: tt.readinessProbe,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
var agentEnvs []corev1.EnvVar
|
|
if !tt.queueProxyAvailable {
|
|
readinessProbe := pod.Spec.Containers[0].ReadinessProbe
|
|
|
|
// Handle HTTPGet and TCPSocket probes
|
|
if readinessProbe != nil {
|
|
if readinessProbe.HTTPGet != nil || readinessProbe.TCPSocket != nil {
|
|
readinessProbeJson, err := marshalReadinessProbe(readinessProbe)
|
|
if err != nil {
|
|
t.Errorf("failed to marshal readiness probe: %v", err)
|
|
} else {
|
|
agentEnvs = append(agentEnvs, corev1.EnvVar{Name: "SERVING_READINESS_PROBE", Value: readinessProbeJson})
|
|
}
|
|
} else if readinessProbe.Exec != nil {
|
|
// Exec probes are skipped; log the information
|
|
t.Logf("INFO: Exec readiness probe skipped for pod %s/%s", pod.Namespace, pod.Name)
|
|
}
|
|
}
|
|
}
|
|
|
|
// Validate the presence of the SERVING_READINESS_PROBE environment variable
|
|
foundEnvVar := false
|
|
actualProbeJson := ""
|
|
for _, envVar := range agentEnvs {
|
|
if envVar.Name == "SERVING_READINESS_PROBE" {
|
|
foundEnvVar = true
|
|
actualProbeJson = envVar.Value
|
|
break
|
|
}
|
|
}
|
|
|
|
if foundEnvVar != tt.expectEnvVar {
|
|
t.Errorf("%s: expected SERVING_READINESS_PROBE to be %v, got %v", tt.name, tt.expectEnvVar, foundEnvVar)
|
|
}
|
|
|
|
if tt.expectEnvVar && actualProbeJson != tt.expectedProbeJson {
|
|
t.Errorf("%s: expected probe JSON %q, got %q", tt.name, tt.expectedProbeJson, actualProbeJson)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func marshalReadinessProbe(probe *corev1.Probe) (string, error) {
|
|
if probe == nil {
|
|
return "", nil
|
|
}
|
|
|
|
// Create a custom struct to ensure all fields are included
|
|
type ReadinessProbe struct {
|
|
HTTPGet *corev1.HTTPGetAction `json:"httpGet,omitempty"`
|
|
TCPSocket *corev1.TCPSocketAction `json:"tcpSocket,omitempty"`
|
|
TimeoutSeconds int32 `json:"timeoutSeconds"`
|
|
PeriodSeconds int32 `json:"periodSeconds"`
|
|
SuccessThreshold int32 `json:"successThreshold"`
|
|
FailureThreshold int32 `json:"failureThreshold"`
|
|
}
|
|
|
|
readinessProbe := ReadinessProbe{
|
|
HTTPGet: probe.HTTPGet,
|
|
TCPSocket: probe.TCPSocket,
|
|
TimeoutSeconds: probe.TimeoutSeconds,
|
|
PeriodSeconds: probe.PeriodSeconds,
|
|
SuccessThreshold: probe.SuccessThreshold,
|
|
FailureThreshold: probe.FailureThreshold,
|
|
}
|
|
|
|
probeJson, err := json.Marshal(readinessProbe)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
return string(probeJson), nil
|
|
}
|