Skip to content

Commit

Permalink
Add new labels to Services (#1555)
Browse files Browse the repository at this point in the history
* Add new labels in pod creation

Signed-off-by: glindsell <[email protected]>

* Remove test pod labels and add service labels

Signed-off-by: glindsell <[email protected]>

* Replace default bool with canary bool

Signed-off-by: glindsell <[email protected]>

* Remove canary field in CRD and update Canary logic

Signed-off-by: glindsell <[email protected]>

* Move labels logic and add tests

Signed-off-by: glindsell <[email protected]>
  • Loading branch information
George authored Mar 24, 2020
1 parent a7a83d9 commit a70fdbf
Show file tree
Hide file tree
Showing 4 changed files with 200 additions and 14 deletions.
22 changes: 17 additions & 5 deletions operator/apis/machinelearning/v1/seldondeployment_types.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,17 +19,29 @@ package v1
import (
"crypto/md5"
"encoding/hex"
"strconv"

autoscalingv2beta2 "k8s.io/api/autoscaling/v2beta1"
v1 "k8s.io/api/core/v1"
metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
"strconv"
)

const (
Label_seldon_id = "seldon-deployment-id"
Label_seldon_app = "seldon-app"
Label_seldon_app_svc = "seldon-app-svc"
Label_svc_orch = "seldon-deployment-contains-svcorch"
Label_seldon_id = "seldon-deployment-id"
Label_seldon_app = "seldon-app"
Label_seldon_app_svc = "seldon-app-svc"
Label_svc_orch = "seldon-deployment-contains-svcorch"
Label_app = "app"
Label_fluentd = "fluentd"
Label_router = "router"
Label_combiner = "combiner"
Label_model = "model"
Label_transformer = "transformer"
Label_output_transformer = "output-transformer"
Label_default = "default"
Label_shadow = "shadow"
Label_canary = "canary"
Label_explainer = "explainer"

PODINFO_VOLUME_NAME = "podinfo"
PODINFO_VOLUME_PATH = "/etc/podinfo"
Expand Down
40 changes: 40 additions & 0 deletions operator/controllers/labels.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
package controllers

import (
machinelearningv1 "github.com/seldonio/seldon-core/operator/apis/machinelearning/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
)

func addLabelsToService(svc *corev1.Service, pu *machinelearningv1.PredictiveUnit, p machinelearningv1.PredictorSpec) {
switch *pu.Type {
case machinelearningv1.ROUTER:
svc.Labels[machinelearningv1.Label_router] = "true"
case machinelearningv1.COMBINER:
svc.Labels[machinelearningv1.Label_combiner] = "true"
case machinelearningv1.MODEL:
svc.Labels[machinelearningv1.Label_model] = "true"
case machinelearningv1.TRANSFORMER:
svc.Labels[machinelearningv1.Label_transformer] = "true"
case machinelearningv1.OUTPUT_TRANSFORMER:
svc.Labels[machinelearningv1.Label_output_transformer] = "true"
}
if p.Shadow != true && (p.Traffic >= 50 || p.Traffic == 0) {
svc.Labels[machinelearningv1.Label_default] = "true"
}
if p.Shadow == true {
svc.Labels[machinelearningv1.Label_shadow] = "true"
}
if p.Traffic < 50 && p.Traffic > 0 {
svc.Labels[machinelearningv1.Label_canary] = "true"
}
if p.Explainer != nil {
svc.Labels[machinelearningv1.Label_explainer] = "true"
}
}

func addLabelsToDeployment(deploy *appsv1.Deployment, containerServiceKey, containerServiceValue string) {
deploy.ObjectMeta.Labels[containerServiceKey] = containerServiceValue
deploy.Spec.Selector.MatchLabels[containerServiceKey] = containerServiceValue
deploy.Spec.Template.ObjectMeta.Labels[containerServiceKey] = containerServiceValue
}
132 changes: 132 additions & 0 deletions operator/controllers/labels_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
package controllers

import (
"testing"

. "github.com/onsi/gomega"
machinelearningv1 "github.com/seldonio/seldon-core/operator/apis/machinelearning/v1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"

metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
)

func TestAddLabelsToDeployment(t *testing.T) {
g := NewGomegaWithT(t)
d := &appsv1.Deployment{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{},
},
Spec: appsv1.DeploymentSpec{
Selector: &metav1.LabelSelector{
MatchLabels: map[string]string{},
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{},
},
},
},
}
t.Run("adds correct label to Deployment", func(t *testing.T) {
addLabelsToDeployment(d, "TestKey", "TestValue")
g.Expect(d.ObjectMeta.Labels["TestKey"]).To(Equal("TestValue"))
g.Expect(d.Spec.Selector.MatchLabels["TestKey"]).To(Equal("TestValue"))
g.Expect(d.Spec.Template.ObjectMeta.Labels["TestKey"]).To(Equal("TestValue"))
})
}

func TestAddLabelsToService(t *testing.T) {
g := NewGomegaWithT(t)
cases1 := []struct {
puType machinelearningv1.PredictiveUnitType
result string
}{
{
puType: machinelearningv1.ROUTER,
result: machinelearningv1.Label_router,
},
{
puType: machinelearningv1.COMBINER,
result: machinelearningv1.Label_combiner,
},
{
puType: machinelearningv1.MODEL,
result: machinelearningv1.Label_model,
},
{
puType: machinelearningv1.TRANSFORMER,
result: machinelearningv1.Label_transformer,
},
{
puType: machinelearningv1.OUTPUT_TRANSFORMER,
result: machinelearningv1.Label_output_transformer,
},
}
cases2 := []struct {
shadow bool
explainer *machinelearningv1.Explainer
traffic int32
result string
}{
{
shadow: false,
explainer: nil,
traffic: 0,
result: machinelearningv1.Label_default,
},
{
shadow: false,
explainer: nil,
traffic: 50,
result: machinelearningv1.Label_default,
},
{
shadow: false,
explainer: nil,
traffic: 75,
result: machinelearningv1.Label_default,
},
{
shadow: true,
explainer: nil,
traffic: 0,
result: machinelearningv1.Label_shadow,
},
{
shadow: false,
explainer: nil,
traffic: 49,
result: machinelearningv1.Label_canary,
},
{
shadow: false,
explainer: &machinelearningv1.Explainer{},
traffic: 0,
result: machinelearningv1.Label_explainer,
},
}
svc := &corev1.Service{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{},
},
}
p := machinelearningv1.PredictorSpec{}
pu := &machinelearningv1.PredictiveUnit{}
t.Run("adds correct label to Service from Predictive Unit Type", func(t *testing.T) {
for _, c := range cases1 {
pu.Type = &c.puType
addLabelsToService(svc, pu, p)
g.Expect(svc.Labels[c.result]).To(Equal("true"))
}
})
t.Run("adds correct label to Service for Default, Shadow, Canary & Explainer from Predictor Spec", func(t *testing.T) {
for _, c := range cases2 {
p.Shadow = c.shadow
p.Explainer = c.explainer
p.Traffic = c.traffic
addLabelsToService(svc, pu, p)
g.Expect(svc.Labels[c.result]).To(Equal("true"))
}
})
}
20 changes: 11 additions & 9 deletions operator/controllers/seldondeployment_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ import (
"bytes"
"context"
"fmt"
"strconv"
"strings"

types2 "github.com/gogo/protobuf/types"
"github.com/seldonio/seldon-core/operator/constants"
"github.com/seldonio/seldon-core/operator/utils"
Expand All @@ -31,8 +34,6 @@ import (
"k8s.io/client-go/tools/record"
"knative.dev/pkg/kmp"
"sigs.k8s.io/controller-runtime/pkg/controller/controllerutil"
"strconv"
"strings"

"github.com/go-logr/logr"
ctrl "sigs.k8s.io/controller-runtime"
Expand Down Expand Up @@ -681,11 +682,8 @@ func createContainerService(deploy *appsv1.Deployment, p machinelearningv1.Predi
SessionAffinity: corev1.ServiceAffinityNone,
},
}

//Add labels for this service to deployment
deploy.ObjectMeta.Labels[containerServiceKey] = containerServiceValue
deploy.Spec.Selector.MatchLabels[containerServiceKey] = containerServiceValue
deploy.Spec.Template.ObjectMeta.Labels[containerServiceKey] = containerServiceValue
addLabelsToService(svc, pu, p)
addLabelsToDeployment(deploy, containerServiceKey, containerServiceValue)

if existingPort == nil || con.Ports == nil {
con.Ports = append(con.Ports, corev1.ContainerPort{Name: portType, ContainerPort: portNum, Protocol: corev1.ProtocolTCP})
Expand Down Expand Up @@ -754,7 +752,11 @@ func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpe
},
Template: corev1.PodTemplateSpec{
ObjectMeta: metav1.ObjectMeta{
Labels: map[string]string{machinelearningv1.Label_seldon_id: seldonId, "app": depName, "fluentd": "true"},
Labels: map[string]string{
machinelearningv1.Label_seldon_id: seldonId,
machinelearningv1.Label_app: depName,
machinelearningv1.Label_fluentd: "true",
},
Annotations: mlDep.Spec.Annotations,
},
},
Expand All @@ -770,7 +772,7 @@ func createDeploymentWithoutEngine(depName string, seldonId string, seldonPodSpe
deploy.Spec.Template.Annotations["prometheus.io/scrape"] = "true"

if p.Shadow == true {
deploy.Spec.Template.ObjectMeta.Labels["shadow"] = "true"
deploy.Spec.Template.ObjectMeta.Labels[machinelearningv1.Label_shadow] = "true"
}

if seldonPodSpec != nil {
Expand Down

0 comments on commit a70fdbf

Please sign in to comment.