Skip to content

Commit

Permalink
Add KServe destination rule for Inference Services in the ServiceMesh (
Browse files Browse the repository at this point in the history
…trustyai-explainability#315)

* Add DestinationRule creation for KServe serverless

* Add permissions for destination rules

* Add role for destination rules

* Add missing role for creating destination rules

* Fix spacing in DestinationRule template
  • Loading branch information
ruivieira authored Oct 10, 2024
1 parent c072d51 commit 97a5a5d
Show file tree
Hide file tree
Showing 6 changed files with 108 additions and 3 deletions.
4 changes: 2 additions & 2 deletions config/overlays/odh/params.env
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
trustyaiServiceImage=quay.io/trustyai/trustyai-service:v0.19.0
trustyaiOperatorImage=quay.io/trustyai/trustyai-service-operator:v1.25.0
trustyaiServiceImage=quay.io/trustyai/trustyai-service:latest
trustyaiOperatorImage=quay.io/trustyai/trustyai-service-operator:latest
oauthProxyImage=quay.io/openshift/origin-oauth-proxy:4.14.0
kServeServerless=enabled
12 changes: 12 additions & 0 deletions config/rbac/role.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -134,6 +134,18 @@ rules:
- create
- list
- watch
- apiGroups:
- networking.istio.io
resources:
- destinationrules
verbs:
- create
- delete
- get
- list
- patch
- update
- watch
- apiGroups:
- rbac.authorization.k8s.io
resources:
Expand Down
69 changes: 69 additions & 0 deletions controllers/destination_rule.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
package controllers

import (
"context"
"fmt"
"reflect"

trustyaiopendatahubiov1alpha1 "github.com/trustyai-explainability/trustyai-service-operator/api/v1alpha1"
templateParser "github.com/trustyai-explainability/trustyai-service-operator/controllers/templates"
"k8s.io/apimachinery/pkg/api/errors"
"k8s.io/apimachinery/pkg/apis/meta/v1/unstructured"
"k8s.io/apimachinery/pkg/types"
ctrl "sigs.k8s.io/controller-runtime"
"sigs.k8s.io/controller-runtime/pkg/log"
)

const (
destinationRuleTemplatePath = "service/destination-rule.tmpl.yaml"
)

// DestinationRuleConfig has the variables for the DestinationRule template
type DestinationRuleConfig struct {
Name string
Namespace string
DestinationRuleName string
}

func (r *TrustyAIServiceReconciler) ensureDestinationRule(ctx context.Context, instance *trustyaiopendatahubiov1alpha1.TrustyAIService) error {
destinationRuleName := instance.Name + "-internal"

existingDestinationRule := &unstructured.Unstructured{}
existingDestinationRule.SetKind("DestinationRule")
existingDestinationRule.SetAPIVersion("networking.istio.io/v1beta1")

// Check if the DestinationRule already exists
err := r.Get(ctx, types.NamespacedName{Name: destinationRuleName, Namespace: instance.Namespace}, existingDestinationRule)
if err == nil {
// DestinationRule exists
return nil
}

if !errors.IsNotFound(err) {
return fmt.Errorf("failed to check for existing DestinationRule: %v", err)
}

destinationRuleConfig := DestinationRuleConfig{
Name: instance.Name,
Namespace: instance.Namespace,
DestinationRuleName: destinationRuleName,
}

var destinationRule *unstructured.Unstructured
destinationRule, err = templateParser.ParseResource[unstructured.Unstructured](destinationRuleTemplatePath, destinationRuleConfig, reflect.TypeOf(&unstructured.Unstructured{}))
if err != nil {
log.FromContext(ctx).Error(err, "could not parse the DestinationRule template")
return err
}

if err := ctrl.SetControllerReference(instance, destinationRule, r.Scheme); err != nil {
return err
}

err = r.Create(ctx, destinationRule)
if err != nil {
return fmt.Errorf("failed to create DestinationRule: %v", err)
}

return nil
}
12 changes: 11 additions & 1 deletion controllers/inference_services.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,13 +3,14 @@ package controllers
import (
"context"
"fmt"
"strings"

kservev1beta1 "github.com/kserve/kserve/pkg/apis/serving/v1beta1"
trustyaiopendatahubiov1alpha1 "github.com/trustyai-explainability/trustyai-service-operator/api/v1alpha1"
appsv1 "k8s.io/api/apps/v1"
corev1 "k8s.io/api/core/v1"
"sigs.k8s.io/controller-runtime/pkg/client"
"sigs.k8s.io/controller-runtime/pkg/log"
"strings"
)

const (
Expand Down Expand Up @@ -271,6 +272,15 @@ func (r *TrustyAIServiceReconciler) patchKServe(ctx context.Context, instance *t
infService.Spec.Predictor.Logger = &logger
}

// Only if the Istio sidecar annotation is set
annotations := infService.GetAnnotations()
if inject, exists := annotations["sidecar.istio.io/inject"]; exists && inject == "true" {
err := r.ensureDestinationRule(ctx, instance)
if err != nil {
return fmt.Errorf("failed to ensure DestinationRule: %v", err)
}
}

// Update the InferenceService
err := r.Update(ctx, &infService)
if err == nil {
Expand Down
13 changes: 13 additions & 0 deletions controllers/templates/service/destination-rule.tmpl.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
apiVersion: networking.istio.io/v1beta1
kind: DestinationRule
metadata:
name: {{ .DestinationRuleName }}
namespace: {{ .Namespace }}
spec:
host: {{ .Name }}.{{ .Namespace }}.svc.cluster.local
trafficPolicy:
portLevelSettings:
- port:
number: 443
tls:
mode: SIMPLE
1 change: 1 addition & 0 deletions controllers/trustyaiservice_controller.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@ type TrustyAIServiceReconciler struct {
//+kubebuilder:rbac:groups="",resources=serviceaccounts,verbs=get;list;watch;create;update;delete
//+kubebuilder:rbac:groups=rbac.authorization.k8s.io,resources=clusterrolebindings,verbs=get;list;watch;create;update;delete
//+kubebuilder:rbac:groups=coordination.k8s.io,resources=leases,verbs=get;create;update
//+kubebuilder:rbac:groups=networking.istio.io,resources=destinationrules,verbs=create;list;watch;get;update;patch;delete

// Reconcile is part of the main kubernetes reconciliation loop which aims to
// move the current state of the cluster closer to the desired state.
Expand Down

0 comments on commit 97a5a5d

Please sign in to comment.