Skip to content

Commit

Permalink
configurable metrics port name
Browse files Browse the repository at this point in the history
  • Loading branch information
xaniasd authored and seldondev committed May 13, 2020
1 parent 3949a00 commit bad3e08
Show file tree
Hide file tree
Showing 6 changed files with 76 additions and 40 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,12 @@ package v1
import (
"crypto/md5"
"encoding/hex"
"strconv"

"github.com/seldonio/seldon-core/operator/constants"
autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strconv"
)

const (
Expand All @@ -49,6 +50,7 @@ const (
ENV_PREDICTIVE_UNIT_SERVICE_PORT = "PREDICTIVE_UNIT_SERVICE_PORT"
ENV_PREDICTIVE_UNIT_SERVICE_PORT_METRICS = "PREDICTIVE_UNIT_METRICS_SERVICE_PORT"
ENV_PREDICTIVE_UNIT_METRICS_ENDPOINT = "PREDICTIVE_UNIT_METRICS_ENDPOINT"
ENV_PREDICTIVE_UNIT_METRICS_PORT_NAME = "PREDICTIVE_UNIT_METRICS_PORT_NAME"
ENV_PREDICTIVE_UNIT_PARAMETERS = "PREDICTIVE_UNIT_PARAMETERS"
ENV_PREDICTIVE_UNIT_IMAGE = "PREDICTIVE_UNIT_IMAGE"
ENV_PREDICTIVE_UNIT_ID = "PREDICTIVE_UNIT_ID"
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"context"
"encoding/json"
"fmt"
"os"
"strconv"

"github.com/seldonio/seldon-core/operator/constants"
corev1 "k8s.io/api/core/v1"
apierrors "k8s.io/apimachinery/pkg/api/errors"
Expand All @@ -28,12 +31,10 @@ import (
"k8s.io/apimachinery/pkg/runtime/schema"
k8types "k8s.io/apimachinery/pkg/types"
"k8s.io/apimachinery/pkg/util/validation/field"
"os"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/client"
logf "sigs.k8s.io/controller-runtime/pkg/runtime/log"
"sigs.k8s.io/controller-runtime/pkg/webhook"
"strconv"
)

var (
Expand All @@ -44,6 +45,7 @@ var (
C client.Client
envPredictiveUnitServicePort = os.Getenv(ENV_PREDICTIVE_UNIT_SERVICE_PORT)
envPredictiveUnitServicePortMetrics = os.Getenv(ENV_PREDICTIVE_UNIT_SERVICE_PORT_METRICS)
predictiveUnitMetricsPortName = GetEnv(ENV_PREDICTIVE_UNIT_METRICS_ENDPOINT, constants.DefaultMetricsPortName)
)

const PredictorServerConfigMapKeyName = "predictor_servers"
Expand Down Expand Up @@ -186,10 +188,10 @@ func getUpdatePortNumMap(name string, nextPortNum *int32, portMap map[string]int
}

func addMetricsPortAndIncrement(nextMetricsPortNum *int32, con *corev1.Container) {
existingMetricPort := GetPort(constants.MetricsPortName, con.Ports)
existingMetricPort := GetPort(predictiveUnitMetricsPortName, con.Ports)
if existingMetricPort == nil {
con.Ports = append(con.Ports, corev1.ContainerPort{
Name: constants.MetricsPortName,
Name: predictiveUnitMetricsPortName,
ContainerPort: *nextMetricsPortNum,
Protocol: corev1.ProtocolTCP,
})
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package v1

import (
"os"
"testing"

. "github.com/onsi/gomega"
"github.com/seldonio/seldon-core/operator/constants"
v1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/errors"
v12 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/runtime"
"sigs.k8s.io/controller-runtime/pkg/client/fake"
"testing"
)

func TestValidateBadProtocol(t *testing.T) {
Expand Down Expand Up @@ -208,10 +210,9 @@ func TestDefaultSingleContainer(t *testing.T) {
spec.DefaultSeldonDeployment("mydep", "default")

// Test Metric Ports
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

// Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -266,15 +267,13 @@ func TestMetricsPortAddedTwoContainers(t *testing.T) {

//Metrics
spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

metricPort = GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[1].Ports)
metricPort = GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[1].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber + 1))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -352,14 +351,12 @@ func TestMetricsPortAddedTwoComponentSpecsTwoContainers(t *testing.T) {
spec.DefaultSeldonDeployment(name, namespace)

// Metrics
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))
metricPort = GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[1].Spec.Containers[0].Ports)
metricPort = GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[1].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber + 1))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -394,6 +391,41 @@ func TestMetricsPortAddedTwoComponentSpecsTwoContainers(t *testing.T) {
g.Expect(volFound).To(BeTrue())
}

func TestOverrideMetricsPortName(t *testing.T) {
os.Setenv(ENV_PREDICTIVE_UNIT_METRICS_PORT_NAME, "myMetricsPort")
defer os.Unsetenv(ENV_PREDICTIVE_UNIT_METRICS_PORT_NAME)
g := NewGomegaWithT(t)
scheme := runtime.NewScheme()
C = fake.NewFakeClientWithScheme(scheme)
impl := PredictiveUnitImplementation(constants.PrePackedServerTensorflow)
spec := &SeldonDeploymentSpec{
Predictors: []PredictorSpec{
{
Name: "p1",
Graph: &PredictiveUnit{
Name: "classifier",
Implementation: &impl,
},
},
},
}

spec.DefaultSeldonDeployment("mydep", "default")
// Metrics
metricPort := GetPort("myMetricsPort", spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))

defaultMetricsPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(defaultMetricsPort).To(BeNil())

// Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
g.Expect(pu).ToNot(BeNil())
g.Expect(pu.Endpoint.Type).To(Equal(REST))
g.Expect(*pu.Type).To(Equal(MODEL))
}

func TestPortUseExisting(t *testing.T) {
g := NewGomegaWithT(t)
containerPortMetrics := int32(1234)
Expand All @@ -409,7 +441,7 @@ func TestPortUseExisting(t *testing.T) {
{
Image: "seldonio/mock_classifier:1.0",
Name: "classifier",
Ports: []v1.ContainerPort{{Name: constants.MetricsPortName, ContainerPort: containerPortMetrics},
Ports: []v1.ContainerPort{{Name: constants.DefaultMetricsPortName, ContainerPort: containerPortMetrics},
{Name: constants.HttpPortName, ContainerPort: containerPortAPI}},
},
},
Expand All @@ -424,10 +456,9 @@ func TestPortUseExisting(t *testing.T) {
}

spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(containerPortMetrics))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -458,10 +489,9 @@ func TestMetricsPortAddedToPrepacked(t *testing.T) {
}

spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -490,10 +520,9 @@ func TestPredictorProtocolGrpc(t *testing.T) {
}

spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down Expand Up @@ -533,10 +562,9 @@ func TestPrepackedWithExistingContainer(t *testing.T) {
}

spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

// empty image name as no configmap - but is set
g.Expect(spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Image).To(Equal(":"))
Expand Down Expand Up @@ -573,15 +601,13 @@ func TestMetricsPortAddedToTwoPrepacked(t *testing.T) {
}

spec.DefaultSeldonDeployment("mydep", "default")
metricPort := GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
metricPort := GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[0].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

metricPort = GetPort(constants.MetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[1].Ports)
metricPort = GetPort(constants.DefaultMetricsPortName, spec.Predictors[0].ComponentSpecs[0].Spec.Containers[1].Ports)
g.Expect(metricPort).NotTo(BeNil())
g.Expect(metricPort.ContainerPort).To(Equal(constants.FirstMetricsPortNumber + 1))
g.Expect(metricPort.Name).To(Equal(constants.MetricsPortName))

//Graph
pu := GetPredictiveUnit(spec.Predictors[0].Graph, "classifier")
Expand Down
3 changes: 2 additions & 1 deletion operator/constants/constants.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,10 @@ const (
HttpPortName = "http"
)

// Metrics-related constants
const (
MetricsPortName = "metrics"
FirstMetricsPortNumber = int32(6000)
DefaultMetricsPortName = "metrics"
)

const (
Expand Down
3 changes: 2 additions & 1 deletion operator/controllers/seldondeployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -762,7 +762,8 @@ func createContainerService(deploy *appsv1.Deployment,
}...)

//Add Metric Env Var
metricPort := getPort(constants.MetricsPortName, con.Ports)
predictiveUnitMetricsPortName := GetEnv(machinelearningv1.ENV_PREDICTIVE_UNIT_METRICS_ENDPOINT, constants.DefaultMetricsPortName)
metricPort := getPort(predictiveUnitMetricsPortName, con.Ports)
if metricPort != nil {
con.Env = append(con.Env, []corev1.EnvVar{
corev1.EnvVar{Name: machinelearningv1.ENV_PREDICTIVE_UNIT_SERVICE_PORT_METRICS, Value: strconv.Itoa(int(metricPort.ContainerPort))},
Expand Down
22 changes: 13 additions & 9 deletions operator/controllers/seldondeployment_engine.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,21 +18,23 @@ package controllers

import (
"fmt"
"os"
"strconv"
"strings"

machinelearningv1 "github.com/seldonio/seldon-core/operator/apis/machinelearning.seldon.io/v1"
"github.com/seldonio/seldon-core/operator/constants"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"k8s.io/apimachinery/pkg/api/resource"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"k8s.io/apimachinery/pkg/util/intstr"
"os"
"strconv"
"strings"
)

const (
ENV_DEFAULT_EXECUTOR_SERVER_PORT = "EXECUTOR_SERVER_PORT"
ENV_DEFAULT_EXECUTOR_SERVER_GRPC_PORT = "EXECUTOR_SERVER_GRPC_PORT"
ENV_EXECUTOR_METRICS_PORT_NAME = "EXECUTOR_SERVER_METRICS_PORT_NAME"
ENV_EXECUTOR_PROMETHEUS_PATH = "EXECUTOR_PROMETHEUS_PATH"
ENV_ENGINE_PROMETHEUS_PATH = "ENGINE_PROMETHEUS_PATH"
ENV_EXECUTOR_USER = "EXECUTOR_CONTAINER_USER"
Expand All @@ -57,6 +59,8 @@ var (
envEngineUser = os.Getenv(ENV_ENGINE_USER)
envExecutorUser = os.Getenv(ENV_EXECUTOR_USER)
envUseExecutor = os.Getenv(ENV_USE_EXECUTOR)

executorMetricsPortName = GetEnv(ENV_EXECUTOR_METRICS_PORT_NAME, constants.DefaultMetricsPortName)
)

func addEngineToDeployment(mlDep *machinelearningv1.SeldonDeployment, p *machinelearningv1.PredictorSpec, engine_http_port int, engine_grpc_port int, pSvcName string, deploy *appsv1.Deployment) error {
Expand Down Expand Up @@ -251,9 +255,9 @@ func createExecutorContainer(mlDep *machinelearningv1.SeldonDeployment, p *machi
{Name: "REQUEST_LOGGER_DEFAULT_ENDPOINT_PREFIX", Value: GetEnv("EXECUTOR_REQUEST_LOGGER_DEFAULT_ENDPOINT_PREFIX", "")},
},
Ports: []corev1.ContainerPort{
{ContainerPort: int32(http_port), Protocol: corev1.ProtocolTCP},
{ContainerPort: int32(http_port), Protocol: corev1.ProtocolTCP, Name: constants.MetricsPortName},
{ContainerPort: int32(grpc_port), Protocol: corev1.ProtocolTCP},
{ContainerPort: int32(http_port), Protocol: corev1.ProtocolTCP, Name: constants.HttpPortName},
{ContainerPort: int32(http_port), Protocol: corev1.ProtocolTCP, Name: executorMetricsPortName},
{ContainerPort: int32(grpc_port), Protocol: corev1.ProtocolTCP, Name: constants.GrpcPortName},
},
ReadinessProbe: &corev1.Probe{Handler: corev1.Handler{HTTPGet: &corev1.HTTPGetAction{Port: intstr.FromInt(http_port), Path: "/ready", Scheme: corev1.URISchemeHTTP}},
InitialDelaySeconds: 20,
Expand Down Expand Up @@ -302,9 +306,9 @@ func createEngineContainerSpec(mlDep *machinelearningv1.SeldonDeployment, p *mac
{Name: "JAVA_OPTS", Value: getAnnotation(mlDep, machinelearningv1.ANNOTATION_JAVA_OPTS, "-server")},
},
Ports: []corev1.ContainerPort{
{ContainerPort: int32(engine_http_port), Protocol: corev1.ProtocolTCP},
{ContainerPort: int32(engine_http_port), Protocol: corev1.ProtocolTCP, Name: constants.MetricsPortName},
{ContainerPort: int32(engine_grpc_port), Protocol: corev1.ProtocolTCP},
{ContainerPort: int32(engine_http_port), Protocol: corev1.ProtocolTCP, Name: constants.HttpPortName},
{ContainerPort: int32(engine_http_port), Protocol: corev1.ProtocolTCP, Name: executorMetricsPortName},
{ContainerPort: int32(engine_grpc_port), Protocol: corev1.ProtocolTCP, Name: constants.GrpcPortName},
{ContainerPort: 8082, Name: "admin", Protocol: corev1.ProtocolTCP},
{ContainerPort: 9090, Name: "jmx", Protocol: corev1.ProtocolTCP},
},
Expand Down

0 comments on commit bad3e08

Please sign in to comment.