From 0c95c2ab41d7c875a059c62274e815a0a2ee86ad Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Thu, 10 Apr 2025 14:50:39 +0300 Subject: [PATCH 01/73] Add initial support for scorers, used as part of decision which pod will be the target for a request. Session affinity scorer added --- pkg/epp/datastore/datastore.go | 22 +++++++++- pkg/epp/handlers/request.go | 13 +++++- pkg/epp/handlers/server.go | 11 +++++ pkg/epp/scheduling/scheduler.go | 58 ++++++++++++++++++++++++-- pkg/epp/scheduling/scorer.go | 69 +++++++++++++++++++++++++++++++ pkg/epp/scheduling/types/types.go | 1 + 6 files changed, 168 insertions(+), 6 deletions(-) create mode 100644 pkg/epp/scheduling/scorer.go diff --git a/pkg/epp/datastore/datastore.go b/pkg/epp/datastore/datastore.go index 5435e3af..51a2ed31 100644 --- a/pkg/epp/datastore/datastore.go +++ b/pkg/epp/datastore/datastore.go @@ -65,6 +65,9 @@ type Datastore interface { PodDelete(namespacedName types.NamespacedName) PodResyncAll(ctx context.Context, ctrlClient client.Client, pool *v1alpha2.InferencePool) + SetPodForSession(sessionId string, pod *backendmetrics.Pod) + GetPodForSession(sessionId string) *backendmetrics.Pod + // Clears the store state, happens when the pool gets deleted. Clear() } @@ -75,6 +78,7 @@ func NewDatastore(parentCtx context.Context, pmf *backendmetrics.PodMetricsFacto poolAndModelsMu: sync.RWMutex{}, models: make(map[string]*v1alpha2.InferenceModel), pods: &sync.Map{}, + sessions: &sync.Map{}, pmf: pmf, } return store @@ -90,7 +94,9 @@ type datastore struct { models map[string]*v1alpha2.InferenceModel // key: types.NamespacedName, value: backendmetrics.PodMetrics pods *sync.Map - pmf *backendmetrics.PodMetricsFactory + // key: session id, value: *backendmetrics.Pod + sessions *sync.Map + pmf *backendmetrics.PodMetricsFactory } func (ds *datastore) Clear() { @@ -291,6 +297,20 @@ func (ds *datastore) PodDelete(namespacedName types.NamespacedName) { } } +func (ds *datastore) SetPodForSession(sessionId string, pod *backendmetrics.Pod) { + ds.sessions.Store(sessionId, pod) +} + +func (ds *datastore) GetPodForSession(sessionId string) *backendmetrics.Pod { + if value, ok := ds.sessions.Load(sessionId); ok { + if pod, ok := value.(*backendmetrics.Pod); ok { + return pod + } + } + + return nil +} + func selectorFromInferencePoolSelector(selector map[v1alpha2.LabelKey]v1alpha2.LabelValue) labels.Selector { return labels.SelectorFromSet(stripLabelKeyAliasFromLabelMap(selector)) } diff --git a/pkg/epp/handlers/request.go b/pkg/epp/handlers/request.go index 44537923..78c170ee 100644 --- a/pkg/epp/handlers/request.go +++ b/pkg/epp/handlers/request.go @@ -62,12 +62,23 @@ func (s *StreamingServer) HandleRequestBody( return reqCtx, errutil.Error{Code: errutil.BadConfiguration, Msg: fmt.Sprintf("error getting target model name for model %v", modelObj.Name)} } } + + // missing session id is OK, currently session id is not generated + sessionId := "" + if rawSession, ok := requestBodyMap[SessionIdHeader]; ok { + sessionId, ok = rawSession.(string) + if !ok { + return reqCtx, errutil.Error{Code: errutil.BadRequest, Msg: "session id is invalid"} + } + } + llmReq := &schedulingtypes.LLMRequest{ Model: model, ResolvedTargetModel: modelName, Critical: modelObj.Spec.Criticality != nil && *modelObj.Spec.Criticality == v1alpha2.Critical, + SessionId: sessionId, } - logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical) + logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical, "sessionId", sessionId) var err error // Update target models in the body. diff --git a/pkg/epp/handlers/server.go b/pkg/epp/handlers/server.go index 7bb0fcb1..41366eee 100644 --- a/pkg/epp/handlers/server.go +++ b/pkg/epp/handlers/server.go @@ -108,6 +108,8 @@ const ( TrailerResponseResponsesComplete StreamRequestState = 7 ) +const SessionIdHeader = "session-id" + func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) error { ctx := srv.Context() logger := log.FromContext(ctx) @@ -195,7 +197,16 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) } else if header.Key == "content-type" && strings.Contains(value, "text/event-stream") { reqCtx.modelServerStreaming = true loggerTrace.Info("model server is streaming response") + } else if header.Key == SessionIdHeader && value != "" { + allPods := s.datastore.PodGetAll() + + for _, pod := range allPods { + if pod.GetPod().NamespacedName.String() == reqCtx.TargetPod { + s.datastore.SetPodForSession(value, pod.GetPod()) + } + } } + } reqCtx.RequestState = ResponseRecieved reqCtx.respHeaderResp = &extProcPb.ProcessingResponse{ diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index 8679ffba..e889482b 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -20,7 +20,7 @@ package scheduling import ( "context" "fmt" - "math/rand" + "math/rand/v2" "sigs.k8s.io/controller-runtime/pkg/log" backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics" @@ -120,6 +120,7 @@ func NewScheduler(datastore Datastore) *Scheduler { datastore: datastore, criticalRequestFilter: lowLatencyFilter, sheddableRequestFilter: sheddableRequestFilter, + scorers: []Scorer{NewSessionAffinityScorer(1)}, } } @@ -127,10 +128,12 @@ type Scheduler struct { datastore Datastore criticalRequestFilter Filter sheddableRequestFilter Filter + scorers []Scorer } type Datastore interface { PodGetAll() []backendmetrics.PodMetrics + GetPodForSession(sessionId string) *backendmetrics.Pod } // Schedule finds the target pod based on metrics and the requested lora adapter. @@ -154,7 +157,54 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target if err != nil || len(pods) == 0 { return nil, fmt.Errorf("failed to apply filter, resulted %v pods, this should never happen: %w", len(pods), err) } - logger.V(logutil.DEBUG).Info(fmt.Sprintf("Selecting a random pod from %d candidates: %+v", len(pods), pods)) - i := rand.Intn(len(pods)) - return pods[i], nil + + // order filtered pods based on available scorers + selectedPod, err := s.scoreTargets(sCtx, pods) + if err != nil { + return nil, fmt.Errorf("failed to apply scorers: %w", err) + } + + return selectedPod, nil +} + +func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) (*types.PodMetrics, error) { + podsTotalScore := make(map[*types.PodMetrics]float64) + + // initialize zero score for all pods + for _, pod := range pods { + podsTotalScore[pod] = 0.0 + } + + // add scores from all scorers + for _, scorer := range s.scorers { + scoredPods, err := scorer.ScoreTargets(ctx, pods, s.datastore) + if err != nil { + return nil, err + } + + for _, scoredPod := range scoredPods { + podsTotalScore[scoredPod.pod] += scoredPod.score + } + } + + // select pod with maximum score, if more than one with the max score - use random pods from the list + var highestScoreTargets []*types.PodMetrics + maxScore := -1.0 + + for pod, score := range podsTotalScore { + if score > maxScore { + maxScore = score + highestScoreTargets = []*types.PodMetrics{pod} + } else if score == maxScore { + highestScoreTargets = append(highestScoreTargets, pod) + } + } + + // single pod with max score + if len(highestScoreTargets) == 1 { + return highestScoreTargets[0], nil + } + + // select random pod from list of pods with max score + return highestScoreTargets[rand.IntN(len(highestScoreTargets))], nil } diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go new file mode 100644 index 00000000..f86954d7 --- /dev/null +++ b/pkg/epp/scheduling/scorer.go @@ -0,0 +1,69 @@ +/* +Copyright 2025 The Kubernetes 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 scheduling + +import ( + "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" +) + +type ScoredPod struct { + score float64 + pod *types.PodMetrics +} + +// Scorer is the interface that scorers must implement +type Scorer interface { + ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore) ([]ScoredPod, error) +} + +// sessionAffinity is a routing scorer that routes subsequent +// requests in a session to the same pod as the first request in the +// session was sent to, by giving that pod the specified weight and assigning +// zero score to the rest of the targets +type SessionAffinityScorer struct { + weight float64 +} + +func NewSessionAffinityScorer(weight float64) Scorer { + return SessionAffinityScorer{} +} + +// ScoreTargets does the actual scoring of the target pods by the session affinity. +func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore) ([]ScoredPod, error) { + sessionID := ctx.Req.SessionId + scoredPods := make([]ScoredPod, len(pods)) + selectedPodFullName := "" + + if sessionID != "" { + selectedPod := datastore.GetPodForSession(sessionID) + if selectedPod != nil { + selectedPodFullName = selectedPod.NamespacedName.String() + } + } + + // session is not defined - no score for all pods + for i, pod := range pods { + if selectedPodFullName != "" && selectedPodFullName == pod.NamespacedName.String() { + scoredPods[i].score = s.weight + } else { + scoredPods[i].score = 0.0 + } + scoredPods[i].pod = pod + } + + return scoredPods, nil +} diff --git a/pkg/epp/scheduling/types/types.go b/pkg/epp/scheduling/types/types.go index 9450652e..7fc3b731 100644 --- a/pkg/epp/scheduling/types/types.go +++ b/pkg/epp/scheduling/types/types.go @@ -33,6 +33,7 @@ type LLMRequest struct { // Resolved target model is the final target model after traffic split. ResolvedTargetModel string Critical bool + SessionId string } // Context holds contextual information during a scheduling operation. From bde57da9edec3c4b115027d3ed32948853f0ba45 Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Mon, 14 Apr 2025 17:32:47 +0300 Subject: [PATCH 02/73] Fixes in scores infrastructure & session aware scorer --- pkg/epp/handlers/request.go | 25 ++++++++++++++----------- pkg/epp/handlers/server.go | 26 +++++++++++++++++--------- pkg/epp/scheduling/scheduler.go | 13 ++++++++++--- pkg/epp/scheduling/scorer.go | 15 ++++++++------- 4 files changed, 49 insertions(+), 30 deletions(-) diff --git a/pkg/epp/handlers/request.go b/pkg/epp/handlers/request.go index 78c170ee..379a0941 100644 --- a/pkg/epp/handlers/request.go +++ b/pkg/epp/handlers/request.go @@ -21,9 +21,11 @@ import ( "encoding/json" "fmt" "strconv" + "strings" "time" extProcPb "github.com/envoyproxy/go-control-plane/envoy/service/ext_proc/v3" + "github.com/google/uuid" "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/gateway-api-inference-extension/api/v1alpha2" schedulingtypes "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" @@ -63,22 +65,13 @@ func (s *StreamingServer) HandleRequestBody( } } - // missing session id is OK, currently session id is not generated - sessionId := "" - if rawSession, ok := requestBodyMap[SessionIdHeader]; ok { - sessionId, ok = rawSession.(string) - if !ok { - return reqCtx, errutil.Error{Code: errutil.BadRequest, Msg: "session id is invalid"} - } - } - llmReq := &schedulingtypes.LLMRequest{ Model: model, ResolvedTargetModel: modelName, Critical: modelObj.Spec.Criticality != nil && *modelObj.Spec.Criticality == v1alpha2.Critical, - SessionId: sessionId, + SessionId: reqCtx.SessionId, } - logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical, "sessionId", sessionId) + logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical, "sessionId", reqCtx.SessionId) var err error // Update target models in the body. @@ -143,6 +136,16 @@ func (s *StreamingServer) HandleRequestBody( func (s *StreamingServer) HandleRequestHeaders(ctx context.Context, reqCtx *RequestContext, req *extProcPb.ProcessingRequest_RequestHeaders) error { reqCtx.RequestReceivedTimestamp = time.Now() + for _, header := range req.RequestHeaders.Headers.GetHeaders() { + value := string(header.RawValue) + if strings.ToLower(header.Key) == strings.ToLower(SessionIdHeader) && value != "" { + reqCtx.SessionId = value + } + } + if reqCtx.SessionId == "" { + reqCtx.SessionId = uuid.NewString() + } + // an EoS in the request headers means this request has no body or trailers. if req.RequestHeaders.EndOfStream { // We will route this request to a random pod as this is assumed to just be a GET diff --git a/pkg/epp/handlers/server.go b/pkg/epp/handlers/server.go index 41366eee..3bad397b 100644 --- a/pkg/epp/handlers/server.go +++ b/pkg/epp/handlers/server.go @@ -73,6 +73,7 @@ type RequestContext struct { TargetPod string TargetEndpoint string Model string + SessionId string ResolvedTargetModel string RequestReceivedTimestamp time.Time ResponseCompleteTimestamp time.Time @@ -108,7 +109,7 @@ const ( TrailerResponseResponsesComplete StreamRequestState = 7 ) -const SessionIdHeader = "session-id" +const SessionIdHeader = "x-session-id" func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) error { ctx := srv.Context() @@ -197,17 +198,18 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) } else if header.Key == "content-type" && strings.Contains(value, "text/event-stream") { reqCtx.modelServerStreaming = true loggerTrace.Info("model server is streaming response") - } else if header.Key == SessionIdHeader && value != "" { - allPods := s.datastore.PodGetAll() - - for _, pod := range allPods { - if pod.GetPod().NamespacedName.String() == reqCtx.TargetPod { - s.datastore.SetPodForSession(value, pod.GetPod()) - } - } } + } + // Save session is -> pod mapping + allPods := s.datastore.PodGetAll() + for _, pod := range allPods { + if pod.GetPod().NamespacedName.String() == reqCtx.TargetPod { + s.datastore.SetPodForSession(reqCtx.SessionId, pod.GetPod()) + break + } } + reqCtx.RequestState = ResponseRecieved reqCtx.respHeaderResp = &extProcPb.ProcessingResponse{ Response: &extProcPb.ProcessingResponse_ResponseHeaders{ @@ -222,6 +224,12 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) RawValue: []byte("true"), }, }, + { + Header: &configPb.HeaderValue{ + Key: SessionIdHeader, + RawValue: []byte(reqCtx.SessionId), + }, + }, }, }, }, diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index e889482b..94a22af1 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -159,7 +159,11 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target } // order filtered pods based on available scorers - selectedPod, err := s.scoreTargets(sCtx, pods) + if len(pods) == 0 { + return nil, fmt.Errorf("no available pods for request") + } + + selectedPod, err := s.scoreTargets(sCtx, pods, req) if err != nil { return nil, fmt.Errorf("failed to apply scorers: %w", err) } @@ -167,7 +171,9 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target return selectedPod, nil } -func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) (*types.PodMetrics, error) { +func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) (*types.PodMetrics, error) { + logger := log.FromContext(ctx) + podsTotalScore := make(map[*types.PodMetrics]float64) // initialize zero score for all pods @@ -177,8 +183,9 @@ func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) ( // add scores from all scorers for _, scorer := range s.scorers { - scoredPods, err := scorer.ScoreTargets(ctx, pods, s.datastore) + scoredPods, err := scorer.ScoreTargets(ctx, pods, s.datastore, req) if err != nil { + logger.Info(">>> In scoreTargets, score targets returned error", "error", err) return nil, err } diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index f86954d7..1189bd3c 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -27,7 +27,7 @@ type ScoredPod struct { // Scorer is the interface that scorers must implement type Scorer interface { - ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore) ([]ScoredPod, error) + ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore, req *types.LLMRequest) ([]ScoredPod, error) } // sessionAffinity is a routing scorer that routes subsequent @@ -39,17 +39,18 @@ type SessionAffinityScorer struct { } func NewSessionAffinityScorer(weight float64) Scorer { - return SessionAffinityScorer{} + return SessionAffinityScorer{ + weight: weight, + } } // ScoreTargets does the actual scoring of the target pods by the session affinity. -func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore) ([]ScoredPod, error) { - sessionID := ctx.Req.SessionId +func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore, req *types.LLMRequest) ([]ScoredPod, error) { scoredPods := make([]ScoredPod, len(pods)) selectedPodFullName := "" - if sessionID != "" { - selectedPod := datastore.GetPodForSession(sessionID) + if req.SessionId != "" { + selectedPod := datastore.GetPodForSession(req.SessionId) if selectedPod != nil { selectedPodFullName = selectedPod.NamespacedName.String() } @@ -57,7 +58,7 @@ func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.Po // session is not defined - no score for all pods for i, pod := range pods { - if selectedPodFullName != "" && selectedPodFullName == pod.NamespacedName.String() { + if selectedPodFullName == pod.NamespacedName.String() { scoredPods[i].score = s.weight } else { scoredPods[i].score = 0.0 From 8f9785ec494510997f3a045b1412bc703a3d6b1c Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Mon, 14 Apr 2025 21:50:14 +0300 Subject: [PATCH 03/73] - Add cleanup for session->pod map - Rename SessionId to SessionID - Remove datastore from scoreTargets, add datastore to SessionAffinityScorer - Rename ScoredPod to PodScore --- pkg/epp/datastore/datastore.go | 65 ++++++++++++++++++++++++++----- pkg/epp/handlers/request.go | 12 +++--- pkg/epp/handlers/server.go | 10 ++--- pkg/epp/scheduling/scheduler.go | 11 ++---- pkg/epp/scheduling/scorer.go | 22 +++++------ pkg/epp/scheduling/types/types.go | 2 +- 6 files changed, 82 insertions(+), 40 deletions(-) diff --git a/pkg/epp/datastore/datastore.go b/pkg/epp/datastore/datastore.go index 51a2ed31..db37c06b 100644 --- a/pkg/epp/datastore/datastore.go +++ b/pkg/epp/datastore/datastore.go @@ -21,6 +21,7 @@ import ( "errors" "fmt" "sync" + "time" corev1 "k8s.io/api/core/v1" "k8s.io/apimachinery/pkg/labels" @@ -34,7 +35,9 @@ import ( ) const ( - ModelNameIndexKey = "spec.modelName" + ModelNameIndexKey = "spec.modelName" + sessionKeepAliveTime = 60 * time.Minute // How long should an idle session be kept alive + sessionKeepAliveCheckFrequency = 15 * time.Minute // How often to check for overly idle sessions ) var ( @@ -65,8 +68,8 @@ type Datastore interface { PodDelete(namespacedName types.NamespacedName) PodResyncAll(ctx context.Context, ctrlClient client.Client, pool *v1alpha2.InferencePool) - SetPodForSession(sessionId string, pod *backendmetrics.Pod) - GetPodForSession(sessionId string) *backendmetrics.Pod + SetPodForSession(sessionID string, pod *backendmetrics.Pod) + GetPodForSession(sessionID string) *backendmetrics.Pod // Clears the store state, happens when the pool gets deleted. Clear() @@ -81,6 +84,9 @@ func NewDatastore(parentCtx context.Context, pmf *backendmetrics.PodMetricsFacto sessions: &sync.Map{}, pmf: pmf, } + + go store.cleanupSessions(sessionKeepAliveCheckFrequency, sessionKeepAliveTime, parentCtx) + return store } @@ -297,14 +303,55 @@ func (ds *datastore) PodDelete(namespacedName types.NamespacedName) { } } -func (ds *datastore) SetPodForSession(sessionId string, pod *backendmetrics.Pod) { - ds.sessions.Store(sessionId, pod) +type sessionInfo struct { + pod *backendmetrics.Pod + lru time.Time +} + +// cleanup Cleans up the set of stored session information by removing information +// of old sessions. +func (ds *datastore) cleanupSessions(keepAliveCheckFrequency time.Duration, sessionKeepAlive time.Duration, ctx context.Context) { + logger := log.FromContext(ctx) + + logger.Info("Session-affinity cleanup started") + ticker := time.NewTicker(keepAliveCheckFrequency) + defer ticker.Stop() + + for { + select { + case <-ctx.Done(): + logger.Info("Session-affinity cleanup stopped:") + return + case now := <-ticker.C: + logger.Info("Session affinity checking") + ds.sessions.Range( + func(sessionID any, rawSessionInfo any) bool { + if sessionInfo, ok := rawSessionInfo.(*sessionInfo); ok { + if now.Sub(sessionInfo.lru) > sessionKeepAlive { + // Session is stale, remove it + ds.sessions.Delete(sessionID) + } + } else { + // Value is not of the correct type, remove it + ds.sessions.Delete(sessionID) + } + return true + }) + } + } +} + +func (ds *datastore) SetPodForSession(sessionID string, pod *backendmetrics.Pod) { + ds.sessions.Store(sessionID, &sessionInfo{ + pod: pod, + lru: time.Now(), + }) } -func (ds *datastore) GetPodForSession(sessionId string) *backendmetrics.Pod { - if value, ok := ds.sessions.Load(sessionId); ok { - if pod, ok := value.(*backendmetrics.Pod); ok { - return pod +func (ds *datastore) GetPodForSession(sessionID string) *backendmetrics.Pod { + if value, ok := ds.sessions.Load(sessionID); ok { + if sessionInfo, ok := value.(*sessionInfo); ok { + return sessionInfo.pod } } diff --git a/pkg/epp/handlers/request.go b/pkg/epp/handlers/request.go index 379a0941..10b7c015 100644 --- a/pkg/epp/handlers/request.go +++ b/pkg/epp/handlers/request.go @@ -69,9 +69,9 @@ func (s *StreamingServer) HandleRequestBody( Model: model, ResolvedTargetModel: modelName, Critical: modelObj.Spec.Criticality != nil && *modelObj.Spec.Criticality == v1alpha2.Critical, - SessionId: reqCtx.SessionId, + SessionID: reqCtx.SessionID, } - logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical, "sessionId", reqCtx.SessionId) + logger.V(logutil.DEBUG).Info("LLM request assembled", "model", llmReq.Model, "targetModel", llmReq.ResolvedTargetModel, "critical", llmReq.Critical, "session id", reqCtx.SessionID) var err error // Update target models in the body. @@ -138,12 +138,12 @@ func (s *StreamingServer) HandleRequestHeaders(ctx context.Context, reqCtx *Requ for _, header := range req.RequestHeaders.Headers.GetHeaders() { value := string(header.RawValue) - if strings.ToLower(header.Key) == strings.ToLower(SessionIdHeader) && value != "" { - reqCtx.SessionId = value + if strings.ToLower(header.Key) == strings.ToLower(SessionIDHeader) && value != "" { + reqCtx.SessionID = value } } - if reqCtx.SessionId == "" { - reqCtx.SessionId = uuid.NewString() + if reqCtx.SessionID == "" { + reqCtx.SessionID = uuid.NewString() } // an EoS in the request headers means this request has no body or trailers. diff --git a/pkg/epp/handlers/server.go b/pkg/epp/handlers/server.go index 3bad397b..a765c8cc 100644 --- a/pkg/epp/handlers/server.go +++ b/pkg/epp/handlers/server.go @@ -73,7 +73,7 @@ type RequestContext struct { TargetPod string TargetEndpoint string Model string - SessionId string + SessionID string ResolvedTargetModel string RequestReceivedTimestamp time.Time ResponseCompleteTimestamp time.Time @@ -109,7 +109,7 @@ const ( TrailerResponseResponsesComplete StreamRequestState = 7 ) -const SessionIdHeader = "x-session-id" +const SessionIDHeader = "x-session-id" func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) error { ctx := srv.Context() @@ -205,7 +205,7 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) for _, pod := range allPods { if pod.GetPod().NamespacedName.String() == reqCtx.TargetPod { - s.datastore.SetPodForSession(reqCtx.SessionId, pod.GetPod()) + s.datastore.SetPodForSession(reqCtx.SessionID, pod.GetPod()) break } } @@ -226,8 +226,8 @@ func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) }, { Header: &configPb.HeaderValue{ - Key: SessionIdHeader, - RawValue: []byte(reqCtx.SessionId), + Key: SessionIDHeader, + RawValue: []byte(reqCtx.SessionID), }, }, }, diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index 94a22af1..a3650cbf 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -120,7 +120,7 @@ func NewScheduler(datastore Datastore) *Scheduler { datastore: datastore, criticalRequestFilter: lowLatencyFilter, sheddableRequestFilter: sheddableRequestFilter, - scorers: []Scorer{NewSessionAffinityScorer(1)}, + scorers: []Scorer{NewSessionAffinityScorer(1, datastore)}, } } @@ -133,7 +133,7 @@ type Scheduler struct { type Datastore interface { PodGetAll() []backendmetrics.PodMetrics - GetPodForSession(sessionId string) *backendmetrics.Pod + GetPodForSession(SessionID string) *backendmetrics.Pod } // Schedule finds the target pod based on metrics and the requested lora adapter. @@ -158,11 +158,6 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target return nil, fmt.Errorf("failed to apply filter, resulted %v pods, this should never happen: %w", len(pods), err) } - // order filtered pods based on available scorers - if len(pods) == 0 { - return nil, fmt.Errorf("no available pods for request") - } - selectedPod, err := s.scoreTargets(sCtx, pods, req) if err != nil { return nil, fmt.Errorf("failed to apply scorers: %w", err) @@ -183,7 +178,7 @@ func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, r // add scores from all scorers for _, scorer := range s.scorers { - scoredPods, err := scorer.ScoreTargets(ctx, pods, s.datastore, req) + scoredPods, err := scorer.ScoreTargets(ctx, pods, req) if err != nil { logger.Info(">>> In scoreTargets, score targets returned error", "error", err) return nil, err diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 1189bd3c..aea13a7f 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -20,14 +20,14 @@ import ( "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" ) -type ScoredPod struct { +type PodScore struct { score float64 pod *types.PodMetrics } // Scorer is the interface that scorers must implement type Scorer interface { - ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore, req *types.LLMRequest) ([]ScoredPod, error) + ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) } // sessionAffinity is a routing scorer that routes subsequent @@ -35,22 +35,24 @@ type Scorer interface { // session was sent to, by giving that pod the specified weight and assigning // zero score to the rest of the targets type SessionAffinityScorer struct { - weight float64 + weight float64 + datastore Datastore } -func NewSessionAffinityScorer(weight float64) Scorer { +func NewSessionAffinityScorer(weight float64, datastore Datastore) Scorer { return SessionAffinityScorer{ - weight: weight, + weight: weight, + datastore: datastore, } } // ScoreTargets does the actual scoring of the target pods by the session affinity. -func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, datastore Datastore, req *types.LLMRequest) ([]ScoredPod, error) { - scoredPods := make([]ScoredPod, len(pods)) +func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) { + scoredPods := make([]PodScore, len(pods)) selectedPodFullName := "" - if req.SessionId != "" { - selectedPod := datastore.GetPodForSession(req.SessionId) + if req.SessionID != "" { + selectedPod := s.datastore.GetPodForSession(req.SessionID) if selectedPod != nil { selectedPodFullName = selectedPod.NamespacedName.String() } @@ -60,8 +62,6 @@ func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.Po for i, pod := range pods { if selectedPodFullName == pod.NamespacedName.String() { scoredPods[i].score = s.weight - } else { - scoredPods[i].score = 0.0 } scoredPods[i].pod = pod } diff --git a/pkg/epp/scheduling/types/types.go b/pkg/epp/scheduling/types/types.go index 7fc3b731..2a060514 100644 --- a/pkg/epp/scheduling/types/types.go +++ b/pkg/epp/scheduling/types/types.go @@ -33,7 +33,7 @@ type LLMRequest struct { // Resolved target model is the final target model after traffic split. ResolvedTargetModel string Critical bool - SessionId string + SessionID string } // Context holds contextual information during a scheduling operation. From 52af66f6cfa967ecf1a1c0666e08031444338ec5 Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Mon, 14 Apr 2025 22:09:02 +0300 Subject: [PATCH 04/73] Export score and pod for external implementations --- pkg/epp/scheduling/scheduler.go | 2 +- pkg/epp/scheduling/scorer.go | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index a3650cbf..7e272331 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -185,7 +185,7 @@ func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, r } for _, scoredPod := range scoredPods { - podsTotalScore[scoredPod.pod] += scoredPod.score + podsTotalScore[scoredPod.Pod] += scoredPod.Score } } diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index aea13a7f..5b73f116 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -21,8 +21,8 @@ import ( ) type PodScore struct { - score float64 - pod *types.PodMetrics + Score float64 + Pod *types.PodMetrics } // Scorer is the interface that scorers must implement @@ -61,9 +61,9 @@ func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.Po // session is not defined - no score for all pods for i, pod := range pods { if selectedPodFullName == pod.NamespacedName.String() { - scoredPods[i].score = s.weight + scoredPods[i].Score = s.weight } - scoredPods[i].pod = pod + scoredPods[i].Pod = pod } return scoredPods, nil From 90e23bc3905d9f7f55a80d335179c84478527b03 Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 15 Apr 2025 10:44:36 +0300 Subject: [PATCH 05/73] Rename session id header --- pkg/epp/handlers/server.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pkg/epp/handlers/server.go b/pkg/epp/handlers/server.go index a765c8cc..1daed9b3 100644 --- a/pkg/epp/handlers/server.go +++ b/pkg/epp/handlers/server.go @@ -109,7 +109,7 @@ const ( TrailerResponseResponsesComplete StreamRequestState = 7 ) -const SessionIDHeader = "x-session-id" +const SessionIDHeader = "Session-ID" func (s *StreamingServer) Process(srv extProcPb.ExternalProcessor_ProcessServer) error { ctx := srv.Context() From c946accf5e30f0a5f07e8090a72dad2baf992a98 Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 15 Apr 2025 10:45:18 +0300 Subject: [PATCH 06/73] Separate code of Scorer interface and scorer implementations + add scorerManager --- pkg/epp/scheduling/scheduler.go | 55 ++------------ pkg/epp/scheduling/scorer.go | 74 ++++++++++++------- pkg/epp/scheduling/session_affinity_scorer.go | 59 +++++++++++++++ 3 files changed, 114 insertions(+), 74 deletions(-) create mode 100644 pkg/epp/scheduling/session_affinity_scorer.go diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index 7e272331..e2ee089b 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -20,7 +20,6 @@ package scheduling import ( "context" "fmt" - "math/rand/v2" "sigs.k8s.io/controller-runtime/pkg/log" backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics" @@ -116,11 +115,14 @@ var ( ) func NewScheduler(datastore Datastore) *Scheduler { + sMng := NewScorerMng() + sMng.addScorer(NewSessionAffinityScorer(1, datastore)) + return &Scheduler{ datastore: datastore, criticalRequestFilter: lowLatencyFilter, sheddableRequestFilter: sheddableRequestFilter, - scorers: []Scorer{NewSessionAffinityScorer(1, datastore)}, + scorerMng: sMng, } } @@ -128,7 +130,7 @@ type Scheduler struct { datastore Datastore criticalRequestFilter Filter sheddableRequestFilter Filter - scorers []Scorer + scorerMng *ScorerMng } type Datastore interface { @@ -158,55 +160,10 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target return nil, fmt.Errorf("failed to apply filter, resulted %v pods, this should never happen: %w", len(pods), err) } - selectedPod, err := s.scoreTargets(sCtx, pods, req) + selectedPod, err := s.scorerMng.scoreTargets(sCtx, pods, req) if err != nil { return nil, fmt.Errorf("failed to apply scorers: %w", err) } return selectedPod, nil } - -func (s *Scheduler) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) (*types.PodMetrics, error) { - logger := log.FromContext(ctx) - - podsTotalScore := make(map[*types.PodMetrics]float64) - - // initialize zero score for all pods - for _, pod := range pods { - podsTotalScore[pod] = 0.0 - } - - // add scores from all scorers - for _, scorer := range s.scorers { - scoredPods, err := scorer.ScoreTargets(ctx, pods, req) - if err != nil { - logger.Info(">>> In scoreTargets, score targets returned error", "error", err) - return nil, err - } - - for _, scoredPod := range scoredPods { - podsTotalScore[scoredPod.Pod] += scoredPod.Score - } - } - - // select pod with maximum score, if more than one with the max score - use random pods from the list - var highestScoreTargets []*types.PodMetrics - maxScore := -1.0 - - for pod, score := range podsTotalScore { - if score > maxScore { - maxScore = score - highestScoreTargets = []*types.PodMetrics{pod} - } else if score == maxScore { - highestScoreTargets = append(highestScoreTargets, pod) - } - } - - // single pod with max score - if len(highestScoreTargets) == 1 { - return highestScoreTargets[0], nil - } - - // select random pod from list of pods with max score - return highestScoreTargets[rand.IntN(len(highestScoreTargets))], nil -} diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 5b73f116..d26ccb2d 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -17,6 +17,9 @@ limitations under the License. package scheduling import ( + "math/rand/v2" + + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" ) @@ -30,41 +33,62 @@ type Scorer interface { ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) } -// sessionAffinity is a routing scorer that routes subsequent -// requests in a session to the same pod as the first request in the -// session was sent to, by giving that pod the specified weight and assigning -// zero score to the rest of the targets -type SessionAffinityScorer struct { - weight float64 - datastore Datastore +// Scorer is the interface that scorers must implement +type ScorerMng struct { + scorers []Scorer } -func NewSessionAffinityScorer(weight float64, datastore Datastore) Scorer { - return SessionAffinityScorer{ - weight: weight, - datastore: datastore, +func NewScorerMng() *ScorerMng { + return &ScorerMng{ + scorers: make([]Scorer, 0), } } -// ScoreTargets does the actual scoring of the target pods by the session affinity. -func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) { - scoredPods := make([]PodScore, len(pods)) - selectedPodFullName := "" +func (sm *ScorerMng) addScorer(scorer Scorer) { + sm.scorers = append(sm.scorers, scorer) +} + +func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) (*types.PodMetrics, error) { + logger := log.FromContext(ctx) + + podsTotalScore := make(map[*types.PodMetrics]float64) + + // initialize zero score for all pods + for _, pod := range pods { + podsTotalScore[pod] = 0.0 + } + + // add scores from all scorers + for _, scorer := range sm.scorers { + scoredPods, err := scorer.ScoreTargets(ctx, pods, req) + if err != nil { + logger.Info(">>> In scoreTargets, score targets returned error", "error", err) + return nil, err + } - if req.SessionID != "" { - selectedPod := s.datastore.GetPodForSession(req.SessionID) - if selectedPod != nil { - selectedPodFullName = selectedPod.NamespacedName.String() + for _, scoredPod := range scoredPods { + podsTotalScore[scoredPod.Pod] += scoredPod.Score } } - // session is not defined - no score for all pods - for i, pod := range pods { - if selectedPodFullName == pod.NamespacedName.String() { - scoredPods[i].Score = s.weight + // select pod with maximum score, if more than one with the max score - use random pods from the list + var highestScoreTargets []*types.PodMetrics + maxScore := -1.0 + + for pod, score := range podsTotalScore { + if score > maxScore { + maxScore = score + highestScoreTargets = []*types.PodMetrics{pod} + } else if score == maxScore { + highestScoreTargets = append(highestScoreTargets, pod) } - scoredPods[i].Pod = pod } - return scoredPods, nil + // single pod with max score + if len(highestScoreTargets) == 1 { + return highestScoreTargets[0], nil + } + + // select random pod from list of pods with max score + return highestScoreTargets[rand.IntN(len(highestScoreTargets))], nil } diff --git a/pkg/epp/scheduling/session_affinity_scorer.go b/pkg/epp/scheduling/session_affinity_scorer.go new file mode 100644 index 00000000..793b9b36 --- /dev/null +++ b/pkg/epp/scheduling/session_affinity_scorer.go @@ -0,0 +1,59 @@ +/* +Copyright 2025 The Kubernetes 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 scheduling + +import ( + "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" +) + +// sessionAffinity is a routing scorer that routes subsequent +// requests in a session to the same pod as the first request in the +// session was sent to, by giving that pod the specified weight and assigning +// zero score to the rest of the targets +type SessionAffinityScorer struct { + weight float64 + datastore Datastore +} + +func NewSessionAffinityScorer(weight float64, datastore Datastore) Scorer { + return SessionAffinityScorer{ + weight: weight, + datastore: datastore, + } +} + +// ScoreTargets does the actual scoring of the target pods by the session affinity. +func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) { + scoredPods := make([]PodScore, len(pods)) + selectedPodFullName := "" + + if req.SessionID != "" { + selectedPod := s.datastore.GetPodForSession(req.SessionID) + if selectedPod != nil { + selectedPodFullName = selectedPod.NamespacedName.String() + } + } + + // session is not defined - no score for all pods + for i, pod := range pods { + if selectedPodFullName == pod.NamespacedName.String() { + scoredPods[i].Score = s.weight + } + scoredPods[i].Pod = pod + } + + return scoredPods, nil +} From 137ca09ee5e52268b64508923f4cf98b6c93d90c Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 15 Apr 2025 14:45:47 +0300 Subject: [PATCH 07/73] Remove vllmRequest from scoreTargets API since it exists in the context --- pkg/epp/scheduling/scheduler.go | 2 +- pkg/epp/scheduling/scorer.go | 6 +++--- pkg/epp/scheduling/session_affinity_scorer.go | 10 +++++++--- 3 files changed, 11 insertions(+), 7 deletions(-) diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index e2ee089b..cdb03fc4 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -160,7 +160,7 @@ func (s *Scheduler) Schedule(ctx context.Context, req *types.LLMRequest) (target return nil, fmt.Errorf("failed to apply filter, resulted %v pods, this should never happen: %w", len(pods), err) } - selectedPod, err := s.scorerMng.scoreTargets(sCtx, pods, req) + selectedPod, err := s.scorerMng.scoreTargets(sCtx, pods) if err != nil { return nil, fmt.Errorf("failed to apply scorers: %w", err) } diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index d26ccb2d..910b3080 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -30,7 +30,7 @@ type PodScore struct { // Scorer is the interface that scorers must implement type Scorer interface { - ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) + ScoreTargets(ctx *types.Context, pods []*types.PodMetrics) ([]PodScore, error) } // Scorer is the interface that scorers must implement @@ -48,7 +48,7 @@ func (sm *ScorerMng) addScorer(scorer Scorer) { sm.scorers = append(sm.scorers, scorer) } -func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) (*types.PodMetrics, error) { +func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) (*types.PodMetrics, error) { logger := log.FromContext(ctx) podsTotalScore := make(map[*types.PodMetrics]float64) @@ -60,7 +60,7 @@ func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics, // add scores from all scorers for _, scorer := range sm.scorers { - scoredPods, err := scorer.ScoreTargets(ctx, pods, req) + scoredPods, err := scorer.ScoreTargets(ctx, pods) if err != nil { logger.Info(">>> In scoreTargets, score targets returned error", "error", err) return nil, err diff --git a/pkg/epp/scheduling/session_affinity_scorer.go b/pkg/epp/scheduling/session_affinity_scorer.go index 793b9b36..678bc069 100644 --- a/pkg/epp/scheduling/session_affinity_scorer.go +++ b/pkg/epp/scheduling/session_affinity_scorer.go @@ -16,6 +16,7 @@ limitations under the License. package scheduling import ( + "sigs.k8s.io/controller-runtime/pkg/log" "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" ) @@ -36,12 +37,14 @@ func NewSessionAffinityScorer(weight float64, datastore Datastore) Scorer { } // ScoreTargets does the actual scoring of the target pods by the session affinity. -func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics, req *types.LLMRequest) ([]PodScore, error) { +func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics) ([]PodScore, error) { + logger := log.FromContext(ctx) + scoredPods := make([]PodScore, len(pods)) selectedPodFullName := "" - if req.SessionID != "" { - selectedPod := s.datastore.GetPodForSession(req.SessionID) + if ctx.Req.SessionID != "" { + selectedPod := s.datastore.GetPodForSession(ctx.Req.SessionID) if selectedPod != nil { selectedPodFullName = selectedPod.NamespacedName.String() } @@ -50,6 +53,7 @@ func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.Po // session is not defined - no score for all pods for i, pod := range pods { if selectedPodFullName == pod.NamespacedName.String() { + logger.Info("Pod found for session", "session id", ctx.Req.SessionID, "pod", pod.NamespacedName.String()) scoredPods[i].Score = s.weight } scoredPods[i].Pod = pod From c42f72a8d37faf8a13e3580205a64b1c9e9ed41d Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 15 Apr 2025 16:42:47 +0300 Subject: [PATCH 08/73] Support negative score weights --- pkg/epp/scheduling/scorer.go | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 910b3080..1b565583 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -73,14 +73,21 @@ func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) // select pod with maximum score, if more than one with the max score - use random pods from the list var highestScoreTargets []*types.PodMetrics - maxScore := -1.0 + // score weights cound be negative + maxScore := 0.0 + isFirst := true for pod, score := range podsTotalScore { - if score > maxScore { + if isFirst { maxScore = score highestScoreTargets = []*types.PodMetrics{pod} - } else if score == maxScore { - highestScoreTargets = append(highestScoreTargets, pod) + } else { + if score > maxScore { + maxScore = score + highestScoreTargets = []*types.PodMetrics{pod} + } else if score == maxScore { + highestScoreTargets = append(highestScoreTargets, pod) + } } } From a05a573caa80e4d0563db0a892e1291d0a3dd94b Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 15 Apr 2025 18:42:44 +0300 Subject: [PATCH 09/73] Fix fakeDataStore to be compatible with DataStore intereface --- pkg/epp/scheduling/scheduler_test.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/pkg/epp/scheduling/scheduler_test.go b/pkg/epp/scheduling/scheduler_test.go index 3fd3fb24..64f609da 100644 --- a/pkg/epp/scheduling/scheduler_test.go +++ b/pkg/epp/scheduling/scheduler_test.go @@ -230,3 +230,7 @@ func (fds *fakeDataStore) PodGetAll() []backendmetrics.PodMetrics { } return pm } + +func (fds *fakeDataStore) GetPodForSession(sessionID string) *backendmetrics.Pod { + return nil +} From aca8e0702570eb05444ba44e0610b97bfd2c561a Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Wed, 16 Apr 2025 12:27:09 +0300 Subject: [PATCH 10/73] - Check for nils in list of available pods in main scoring function of ScoreMng - If some specific scorer failed to score pods - just log the problem, skip it and continue to the next scorer --- pkg/epp/scheduling/scorer.go | 29 ++++++++++++++++++++--------- 1 file changed, 20 insertions(+), 9 deletions(-) diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 1b565583..75a9d826 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -17,6 +17,7 @@ limitations under the License. package scheduling import ( + "fmt" "math/rand/v2" "sigs.k8s.io/controller-runtime/pkg/log" @@ -52,22 +53,32 @@ func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) logger := log.FromContext(ctx) podsTotalScore := make(map[*types.PodMetrics]float64) + validPods := make([]*types.PodMetrics, 0) - // initialize zero score for all pods + // initialize zero score for all pods + check that pods are valid for _, pod := range pods { - podsTotalScore[pod] = 0.0 + if pod == nil || pod.Pod == nil || pod.Metrics == nil { + logger.Info("Invalid/empty pod skipped in scoring process") + } else { + validPods = append(validPods, pod) + podsTotalScore[pod] = 0.0 + } + } + + if len(validPods) == 0 { + return nil, fmt.Errorf("Empty list of valid pods to score") } // add scores from all scorers for _, scorer := range sm.scorers { - scoredPods, err := scorer.ScoreTargets(ctx, pods) + scoredPods, err := scorer.ScoreTargets(ctx, validPods) if err != nil { - logger.Info(">>> In scoreTargets, score targets returned error", "error", err) - return nil, err - } - - for _, scoredPod := range scoredPods { - podsTotalScore[scoredPod.Pod] += scoredPod.Score + // in case scorer failed - don't use it in the total score, but continue to other scorers + logger.Error(err, "Score targets returned error in scorer") + } else { + for _, scoredPod := range scoredPods { + podsTotalScore[scoredPod.Pod] += scoredPod.Score + } } } From 170b1a3492d4ccbdf9b9b8323e4afd014c05f1bb Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Wed, 16 Apr 2025 22:37:43 +0300 Subject: [PATCH 11/73] Active loras scorer added --- pkg/epp/backend/metrics/metrics.go | 117 ++++++++++++++---- pkg/epp/scheduling/active_loras_scorer.go | 61 +++++++++ pkg/epp/scheduling/scheduler.go | 1 + pkg/epp/scheduling/scorer.go | 3 + pkg/epp/scheduling/session_affinity_scorer.go | 4 + 5 files changed, 161 insertions(+), 25 deletions(-) create mode 100644 pkg/epp/scheduling/active_loras_scorer.go diff --git a/pkg/epp/backend/metrics/metrics.go b/pkg/epp/backend/metrics/metrics.go index 96814b4b..647b07ee 100644 --- a/pkg/epp/backend/metrics/metrics.go +++ b/pkg/epp/backend/metrics/metrics.go @@ -26,6 +26,7 @@ import ( dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "go.uber.org/multierr" + "sigs.k8s.io/controller-runtime/pkg/log" ) const ( @@ -104,44 +105,110 @@ func (p *PodMetricsClientImpl) promToPodMetrics( // Handle LoRA metrics (only if all LoRA MetricSpecs are present) if p.MetricMapping.LoraRequestInfo != nil { - loraMetrics, err := p.getLatestLoraMetric(metricFamilies) + logger := log.FromContext(context.TODO()) + // 'vllm:lora_requests_info metrics contains list of different running loras permutations, + // each metric's value is the reporting timestamp + // we start from the most recent metric, if there are waiting loras - we are on the full capacity, no need to find less recent metric values + // if number of loras in running loras is less than max_lora value, go to next less recent metric and get running + waiting loras from it + // if number of loras achives max_loras - stop, otherwize continue the process untill we will have enough lora adapters + + latestLoraMetrics, latestTimestamp, err := p.getNextLatestLoraMetric(metricFamilies, 0.0) errs = multierr.Append(errs, err) - if loraMetrics != nil { - updated.ActiveModels = make(map[string]int) - updated.WaitingModels = make(map[string]int) - for _, label := range loraMetrics.GetLabel() { - if label.GetName() == LoraInfoRunningAdaptersMetricName { - if label.GetValue() != "" { - adapterList := strings.Split(label.GetValue(), ",") - for _, adapter := range adapterList { - updated.ActiveModels[adapter] = 0 - } - } - } - if label.GetName() == LoraInfoWaitingAdaptersMetricName { - if label.GetValue() != "" { - adapterList := strings.Split(label.GetValue(), ",") - for _, adapter := range adapterList { - updated.WaitingModels[adapter] = 0 + if latestLoraMetrics != nil && len(latestLoraMetrics) > 0 { + // first read max numbers of loras to use it while active loras reading + maxLoras, err := p.getMaxLoras(latestLoraMetrics[0]) + errs = multierr.Append(errs, err) + + if err == nil { + updated.ActiveModels = make(map[string]int) + updated.WaitingModels = make(map[string]int) + updated.MaxActiveModels = maxLoras + + // continue until collected all loras from the metrics or collected enough loras + // enough means that number of running+waiting loras is at least max loras + for latestLoraMetrics != nil && err == nil && len(latestLoraMetrics) > 0 { + // add loras from the latest metric to the collection of loras + for _, metric := range latestLoraMetrics { + // go over all labels, get running and waiting loras + for _, label := range metric.GetLabel() { + if label.GetName() == LoraInfoRunningAdaptersMetricName { + if label.GetValue() != "" { + adapterList := strings.Split(label.GetValue(), ",") + for _, adapter := range adapterList { + updated.ActiveModels[adapter] = 0 + } + } + } + if label.GetName() == LoraInfoWaitingAdaptersMetricName { + if label.GetValue() != "" { + adapterList := strings.Split(label.GetValue(), ",") + for _, adapter := range adapterList { + updated.WaitingModels[adapter] = 0 + } + } + } } } - } - if label.GetName() == LoraInfoMaxAdaptersMetricName { - if label.GetValue() != "" { - updated.MaxActiveModels, err = strconv.Atoi(label.GetValue()) - if err != nil { - errs = multierr.Append(errs, err) - } + + if len(updated.ActiveModels)+len(updated.WaitingModels) >= maxLoras { + // there are enough loras - stop + break } + + latestLoraMetrics, latestTimestamp, err = p.getNextLatestLoraMetric(metricFamilies, latestTimestamp) + errs = multierr.Append(errs, err) } } } + logger.Info(">>> In promToPodMetrics, updated loras", "active", updated.ActiveModels, "waiting", updated.WaitingModels) } return updated, errs } +// getNextLatestMetric finds the most recent metrics which timestamp (the value) is after the given prevLatestTimestamp +// Important note: return value is array of metrics because multiple metrics could exist for the same timestamp +// if prevLatestTimestamp is 0 - return the most recent metrics from the array +func (p *PodMetricsClientImpl) getNextLatestLoraMetric(metricFamilies map[string]*dto.MetricFamily, prevLatestTimestamp float64) ([]*dto.Metric, float64, error) { + var latestTimestamp float64 = 0.0 + var latestMetrics []*dto.Metric = make([]*dto.Metric, 0) + + if p.MetricMapping.LoraRequestInfo == nil { + return nil, 0, nil // No LoRA metrics configured + } + + loraRequests, ok := metricFamilies[p.MetricMapping.LoraRequestInfo.MetricName] + if !ok { + return nil, 0, fmt.Errorf("metric family %q not found", p.MetricMapping.LoraRequestInfo.MetricName) + } + + for _, metric := range loraRequests.GetMetric() { + if ((prevLatestTimestamp == 0) || (prevLatestTimestamp != 0 && (metric.Gauge.GetValue() < prevLatestTimestamp))) && + latestTimestamp < metric.Gauge.GetValue() { + // newer time found, use it + latestTimestamp = metric.Gauge.GetValue() + latestMetrics = []*dto.Metric{metric} + } else if ((prevLatestTimestamp == 0) || (prevLatestTimestamp != 0 && (metric.Gauge.GetValue() < prevLatestTimestamp))) && + latestTimestamp == metric.Gauge.GetValue() { + latestMetrics = append(latestMetrics, metric) + } + } + + return latestMetrics, latestTimestamp, nil +} + +func (p *PodMetricsClientImpl) getMaxLoras(metrics *dto.Metric) (int, error) { + for _, label := range metrics.GetLabel() { + if label.GetName() == LoraInfoMaxAdaptersMetricName { + if label.GetValue() != "" { + return strconv.Atoi(label.GetValue()) + } + } + } + return 0, fmt.Errorf("Lora max is not defined") +} + // getLatestLoraMetric gets latest lora metric series in gauge metric family `vllm:lora_requests_info` // reason its specially fetched is because each label key value pair permutation generates new series // and only most recent is useful. The value of each series is the creation timestamp so we can diff --git a/pkg/epp/scheduling/active_loras_scorer.go b/pkg/epp/scheduling/active_loras_scorer.go new file mode 100644 index 00000000..88a86252 --- /dev/null +++ b/pkg/epp/scheduling/active_loras_scorer.go @@ -0,0 +1,61 @@ +/* +Copyright 2025 The Kubernetes 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 scheduling + +import ( + "sigs.k8s.io/controller-runtime/pkg/log" + "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" +) + +// ActiveLorasScorer is a routing scorer that simply causes the +// request to be routed to one of the pods on which the specified +// model is one of currently active LoRA adapters. +// All pods that have this LoRA running now are returned as candidates +// to be the request target. +type ActiveLorasScorer struct { + weight float64 +} + +func NewActiveLorasScorer(weight float64) Scorer { + return ActiveLorasScorer{ + weight: weight, + } +} + +func (s ActiveLorasScorer) GetName() string { + return "active loras scorer" +} + +// ScoreTargets does the actual scoring of the target pods by the session affinity. +func (s ActiveLorasScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics) ([]PodScore, error) { + logger := log.FromContext(ctx) + + logger.Info(">>> Check lora on pods", "lora", ctx.Req.Model) + + scoredPods := make([]PodScore, len(pods)) + + for i, pod := range pods { + logger.Info(">>> Check lora on pod", "lora", ctx.Req.Model, "pod", pod.NamespacedName.String()) + if _, ok := pod.Metrics.ActiveModels[ctx.Req.Model]; ok { + // lora is running on this pod + scoredPods[i].Score = s.weight + logger.Info("Lora is running on a pod", "lora", ctx.Req.Model, "pod", pod.NamespacedName.String()) + } + scoredPods[i].Pod = pod + } + + return scoredPods, nil +} diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index cdb03fc4..8ec23547 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -117,6 +117,7 @@ var ( func NewScheduler(datastore Datastore) *Scheduler { sMng := NewScorerMng() sMng.addScorer(NewSessionAffinityScorer(1, datastore)) + sMng.addScorer(NewActiveLorasScorer(1)) return &Scheduler{ datastore: datastore, diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 75a9d826..5d6c09a4 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -32,6 +32,7 @@ type PodScore struct { // Scorer is the interface that scorers must implement type Scorer interface { ScoreTargets(ctx *types.Context, pods []*types.PodMetrics) ([]PodScore, error) + GetName() string } // Scorer is the interface that scorers must implement @@ -72,10 +73,12 @@ func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) // add scores from all scorers for _, scorer := range sm.scorers { scoredPods, err := scorer.ScoreTargets(ctx, validPods) + if err != nil { // in case scorer failed - don't use it in the total score, but continue to other scorers logger.Error(err, "Score targets returned error in scorer") } else { + logger.Info("Scorer results: ", "scorer", scorer.GetName(), "scores", scoredPods) for _, scoredPod := range scoredPods { podsTotalScore[scoredPod.Pod] += scoredPod.Score } diff --git a/pkg/epp/scheduling/session_affinity_scorer.go b/pkg/epp/scheduling/session_affinity_scorer.go index 678bc069..d7f42306 100644 --- a/pkg/epp/scheduling/session_affinity_scorer.go +++ b/pkg/epp/scheduling/session_affinity_scorer.go @@ -36,6 +36,10 @@ func NewSessionAffinityScorer(weight float64, datastore Datastore) Scorer { } } +func (s SessionAffinityScorer) GetName() string { + return "session affinity scorer" +} + // ScoreTargets does the actual scoring of the target pods by the session affinity. func (s SessionAffinityScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMetrics) ([]PodScore, error) { logger := log.FromContext(ctx) From bae2a662b9be22a258b6e1962e9e90532d1dbcfe Mon Sep 17 00:00:00 2001 From: ci-tag-bot Date: Wed, 16 Apr 2025 19:51:22 +0000 Subject: [PATCH 12/73] [version bump] Promote 0.0.2 to prod, bump dev to 0.0.3 --- .version.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.version.json b/.version.json index 905c3ab9..a188d258 100644 --- a/.version.json +++ b/.version.json @@ -1,6 +1,6 @@ { - "dev-version": "0.0.2", + "dev-version": "0.0.3", "dev-registry": "quay.io/vllm-d/gateway-api-inference-extension-dev", - "prod-version": "0.0.1", + "prod-version": "0.0.2", "prod-registry": "quay.io/vllm-d/gateway-api-inference-extension" } From c398f4b2693ff085a225933bb618182f10cd34b0 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 16:02:11 -0400 Subject: [PATCH 13/73] chore: move openshift router deployment to extra Signed-off-by: Shane Utt --- .../extra/openshift-router}/common/patch-service.yaml | 0 .../extra/openshift-router}/common/patch-statefulset.yaml | 0 .../{ => components/extra/openshift-router}/common/service.yaml | 0 .../extra/openshift-router}/common/statefulset.yaml | 0 deploy/{ => components/extra/openshift-router}/kustomization.yaml | 0 .../extra/openshift-router}/openshift/patch-route.yaml | 0 .../{ => components/extra/openshift-router}/openshift/route.yaml | 0 .../extra/openshift-router}/rbac/exec-rbac-role.yaml | 0 .../extra/openshift-router}/rbac/exec-rbac-rolebinding.yaml | 0 .../extra/openshift-router}/rbac/patch-rbac-role.yaml | 0 .../extra/openshift-router}/rbac/patch-rbac-rolebinding.yaml | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename deploy/{ => components/extra/openshift-router}/common/patch-service.yaml (100%) rename deploy/{ => components/extra/openshift-router}/common/patch-statefulset.yaml (100%) rename deploy/{ => components/extra/openshift-router}/common/service.yaml (100%) rename deploy/{ => components/extra/openshift-router}/common/statefulset.yaml (100%) rename deploy/{ => components/extra/openshift-router}/kustomization.yaml (100%) rename deploy/{ => components/extra/openshift-router}/openshift/patch-route.yaml (100%) rename deploy/{ => components/extra/openshift-router}/openshift/route.yaml (100%) rename deploy/{ => components/extra/openshift-router}/rbac/exec-rbac-role.yaml (100%) rename deploy/{ => components/extra/openshift-router}/rbac/exec-rbac-rolebinding.yaml (100%) rename deploy/{ => components/extra/openshift-router}/rbac/patch-rbac-role.yaml (100%) rename deploy/{ => components/extra/openshift-router}/rbac/patch-rbac-rolebinding.yaml (100%) diff --git a/deploy/common/patch-service.yaml b/deploy/components/extra/openshift-router/common/patch-service.yaml similarity index 100% rename from deploy/common/patch-service.yaml rename to deploy/components/extra/openshift-router/common/patch-service.yaml diff --git a/deploy/common/patch-statefulset.yaml b/deploy/components/extra/openshift-router/common/patch-statefulset.yaml similarity index 100% rename from deploy/common/patch-statefulset.yaml rename to deploy/components/extra/openshift-router/common/patch-statefulset.yaml diff --git a/deploy/common/service.yaml b/deploy/components/extra/openshift-router/common/service.yaml similarity index 100% rename from deploy/common/service.yaml rename to deploy/components/extra/openshift-router/common/service.yaml diff --git a/deploy/common/statefulset.yaml b/deploy/components/extra/openshift-router/common/statefulset.yaml similarity index 100% rename from deploy/common/statefulset.yaml rename to deploy/components/extra/openshift-router/common/statefulset.yaml diff --git a/deploy/kustomization.yaml b/deploy/components/extra/openshift-router/kustomization.yaml similarity index 100% rename from deploy/kustomization.yaml rename to deploy/components/extra/openshift-router/kustomization.yaml diff --git a/deploy/openshift/patch-route.yaml b/deploy/components/extra/openshift-router/openshift/patch-route.yaml similarity index 100% rename from deploy/openshift/patch-route.yaml rename to deploy/components/extra/openshift-router/openshift/patch-route.yaml diff --git a/deploy/openshift/route.yaml b/deploy/components/extra/openshift-router/openshift/route.yaml similarity index 100% rename from deploy/openshift/route.yaml rename to deploy/components/extra/openshift-router/openshift/route.yaml diff --git a/deploy/rbac/exec-rbac-role.yaml b/deploy/components/extra/openshift-router/rbac/exec-rbac-role.yaml similarity index 100% rename from deploy/rbac/exec-rbac-role.yaml rename to deploy/components/extra/openshift-router/rbac/exec-rbac-role.yaml diff --git a/deploy/rbac/exec-rbac-rolebinding.yaml b/deploy/components/extra/openshift-router/rbac/exec-rbac-rolebinding.yaml similarity index 100% rename from deploy/rbac/exec-rbac-rolebinding.yaml rename to deploy/components/extra/openshift-router/rbac/exec-rbac-rolebinding.yaml diff --git a/deploy/rbac/patch-rbac-role.yaml b/deploy/components/extra/openshift-router/rbac/patch-rbac-role.yaml similarity index 100% rename from deploy/rbac/patch-rbac-role.yaml rename to deploy/components/extra/openshift-router/rbac/patch-rbac-role.yaml diff --git a/deploy/rbac/patch-rbac-rolebinding.yaml b/deploy/components/extra/openshift-router/rbac/patch-rbac-rolebinding.yaml similarity index 100% rename from deploy/rbac/patch-rbac-rolebinding.yaml rename to deploy/components/extra/openshift-router/rbac/patch-rbac-rolebinding.yaml From 95e6bb1b6b96d0cb928b2c8b6965e12d01cbde65 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 17:44:45 -0400 Subject: [PATCH 14/73] feat: add deployment for sail operator Signed-off-by: Shane Utt --- deploy/components/sail-operator/.gitignore | 1 + .../sail-operator/kustomization.yaml | 32 +++++++++++++++++++ .../components/sail-operator/namespaces.yaml | 4 +++ 3 files changed, 37 insertions(+) create mode 100644 deploy/components/sail-operator/.gitignore create mode 100644 deploy/components/sail-operator/kustomization.yaml create mode 100644 deploy/components/sail-operator/namespaces.yaml diff --git a/deploy/components/sail-operator/.gitignore b/deploy/components/sail-operator/.gitignore new file mode 100644 index 00000000..ee3892e8 --- /dev/null +++ b/deploy/components/sail-operator/.gitignore @@ -0,0 +1 @@ +charts/ diff --git a/deploy/components/sail-operator/kustomization.yaml b/deploy/components/sail-operator/kustomization.yaml new file mode 100644 index 00000000..d50bcadc --- /dev/null +++ b/deploy/components/sail-operator/kustomization.yaml @@ -0,0 +1,32 @@ +# ------------------------------------------------------------------------------ +# Istio Sail Operator +# +# This deploys the Istio Sail Operator via Helm chart to enable the creation +# of Istio Control Planes, and ultimately Gateways. This will also deploy all +# the Istio and Gateway API CRDs. +# +# This is required on Kubernetes clusters, and OpenShift clusters versions +# below 4.19 (OpenShift 4.19+ includes all this by default). +# +# **Warning**: This needs to be deployed before, and separately from other +# components as it deploys CRDs. It can be deployed with: +# +# $ kubectl kustomize --enable-helm deploy/components/sail-operator/ \ +# | kubectl apply --server-side --force-conflicts -f - +# +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: sail-operator + +resources: +- https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1 +- namespaces.yaml + +helmCharts: +- name: sail-operator + namespace: sail-operator + repo: https://istio-ecosystem.github.io/sail-operator + version: 1.25.1 + includeCRDs: true diff --git a/deploy/components/sail-operator/namespaces.yaml b/deploy/components/sail-operator/namespaces.yaml new file mode 100644 index 00000000..ddc027d8 --- /dev/null +++ b/deploy/components/sail-operator/namespaces.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: sail-operator From 6d12b06417d6343f53af55f9bdcda4da57c2d796 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 17:50:13 -0400 Subject: [PATCH 15/73] feat: add istio control-plane deployment Signed-off-by: Shane Utt --- .../istio-control-plane/control-plane.yaml | 13 +++++++++++++ .../istio-control-plane/kustomization.yaml | 15 +++++++++++++++ .../istio-control-plane/namespaces.yaml | 4 ++++ 3 files changed, 32 insertions(+) create mode 100644 deploy/components/istio-control-plane/control-plane.yaml create mode 100644 deploy/components/istio-control-plane/kustomization.yaml create mode 100644 deploy/components/istio-control-plane/namespaces.yaml diff --git a/deploy/components/istio-control-plane/control-plane.yaml b/deploy/components/istio-control-plane/control-plane.yaml new file mode 100644 index 00000000..2dcf3fac --- /dev/null +++ b/deploy/components/istio-control-plane/control-plane.yaml @@ -0,0 +1,13 @@ +apiVersion: sailoperator.io/v1 +kind: Istio +metadata: + name: control-plane +spec: + version: v1.25-latest + values: + pilot: + resources: + requests: + cpu: 100m + memory: 1024Mi + diff --git a/deploy/components/istio-control-plane/kustomization.yaml b/deploy/components/istio-control-plane/kustomization.yaml new file mode 100644 index 00000000..89e9b06e --- /dev/null +++ b/deploy/components/istio-control-plane/kustomization.yaml @@ -0,0 +1,15 @@ +# ------------------------------------------------------------------------------ +# Istio Control Plane +# +# This deploys an Istio control-plane for the entire cluster. This enables the +# creation of Gateways. +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: istio-system +namePrefix: istio- + +resources: +- namespaces.yaml +- control-plane.yaml diff --git a/deploy/components/istio-control-plane/namespaces.yaml b/deploy/components/istio-control-plane/namespaces.yaml new file mode 100644 index 00000000..1ab3a725 --- /dev/null +++ b/deploy/components/istio-control-plane/namespaces.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: Namespace +metadata: + name: system From 8c4eb46917a812da05d7b845cef7932ef4f7009d Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 17:52:17 -0400 Subject: [PATCH 16/73] feat: add vllm simulator deployment Signed-off-by: Shane Utt --- deploy/components/vllm-sim/deployments.yaml | 86 +++++++++++++++++++ deploy/components/vllm-sim/kustomization.yaml | 17 ++++ deploy/components/vllm-sim/services.yaml | 38 ++++++++ 3 files changed, 141 insertions(+) create mode 100644 deploy/components/vllm-sim/deployments.yaml create mode 100644 deploy/components/vllm-sim/kustomization.yaml create mode 100644 deploy/components/vllm-sim/services.yaml diff --git a/deploy/components/vllm-sim/deployments.yaml b/deploy/components/vllm-sim/deployments.yaml new file mode 100644 index 00000000..e7c981cf --- /dev/null +++ b/deploy/components/vllm-sim/deployments.yaml @@ -0,0 +1,86 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vllm-30801 + labels: + app: vllm-30801 +spec: + replicas: 1 + selector: + matchLabels: + app: vllm-30801 + template: + metadata: + labels: + app: vllm-30801 + ai-aware-router-pod: "true" + annotations: + ai-aware-router-address: 127.0.0.1:30801 + spec: + containers: + - name: vllm + image: vllm-sim/vllm-sim:latest + args: + - "--port=30801" + - "--model=model1" + - "--lora=lora1,lora2" + ports: + - containerPort: 30801 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vllm-30802 + labels: + app: vllm-30802 +spec: + replicas: 1 + selector: + matchLabels: + app: vllm-30802 + template: + metadata: + labels: + app: vllm-30802 + ai-aware-router-pod: "true" + annotations: + ai-aware-router-address: 127.0.0.1:30802 + spec: + containers: + - name: vllm + image: vllm-sim/vllm-sim:latest + args: + - "--port=30802" + - "--model=model1" + - "--lora=lora1,lora2" + ports: + - containerPort: 30802 +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vllm-30803 + labels: + app: vllm-30803 +spec: + replicas: 1 + selector: + matchLabels: + app: vllm-30803 + template: + metadata: + labels: + app: vllm-30803 + ai-aware-router-pod: "true" + annotations: + ai-aware-router-address: 127.0.0.1:30803 + spec: + containers: + - name: vllm + image: vllm-sim/vllm-sim:latest + args: + - "--port=30803" + - "--model=model2" + - "--lora=lora3" + ports: + - containerPort: 30803 diff --git a/deploy/components/vllm-sim/kustomization.yaml b/deploy/components/vllm-sim/kustomization.yaml new file mode 100644 index 00000000..b49d7b63 --- /dev/null +++ b/deploy/components/vllm-sim/kustomization.yaml @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------------ +# VLLM Simulator +# +# This deploys a VLLM simulator which can be used to simulate inference for +# small environments (e.g. Kubernetes In Docker (KIND) clusters) or for simple +# tests. +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- deployments.yaml +- services.yaml + +images: +- name: vllm-sim/vllm-sim + newTag: 0.0.2 diff --git a/deploy/components/vllm-sim/services.yaml b/deploy/components/vllm-sim/services.yaml new file mode 100644 index 00000000..9e67d79a --- /dev/null +++ b/deploy/components/vllm-sim/services.yaml @@ -0,0 +1,38 @@ +kind: Service +apiVersion: v1 +metadata: + name: vllm-30801 +spec: + type: ClusterIP + selector: + app: vllm-30801 + ports: + - protocol: TCP + port: 30801 + targetPort: 30801 +--- +kind: Service +apiVersion: v1 +metadata: + name: vllm-30802 +spec: + type: ClusterIP + selector: + app: vllm-30802 + ports: + - protocol: TCP + port: 30802 + targetPort: 30802 +--- +kind: Service +apiVersion: v1 +metadata: + name: vllm-30803 +spec: + type: ClusterIP + selector: + app: vllm-30803 + ports: + - protocol: TCP + port: 30803 + targetPort: 30803 From 58ef159e887a1f6a90dc8fa5f03fd74ab3380124 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 17:54:47 -0400 Subject: [PATCH 17/73] feat: add inference-gateway deployment Signed-off-by: Shane Utt --- .../inference-gateway/configmaps.yaml | 18 +++++++++++ .../inference-gateway/deployments.yaml | 32 +++++++++++++++++++ .../inference-gateway/envoy-filters.yaml | 31 ++++++++++++++++++ .../inference-gateway/gateways.yaml | 14 ++++++++ .../inference-gateway/kustomization.yaml | 30 +++++++++++++++++ deploy/components/inference-gateway/rbac.yaml | 31 ++++++++++++++++++ .../inference-gateway/services.yaml | 13 ++++++++ 7 files changed, 169 insertions(+) create mode 100644 deploy/components/inference-gateway/configmaps.yaml create mode 100644 deploy/components/inference-gateway/deployments.yaml create mode 100644 deploy/components/inference-gateway/envoy-filters.yaml create mode 100644 deploy/components/inference-gateway/gateways.yaml create mode 100644 deploy/components/inference-gateway/kustomization.yaml create mode 100644 deploy/components/inference-gateway/rbac.yaml create mode 100644 deploy/components/inference-gateway/services.yaml diff --git a/deploy/components/inference-gateway/configmaps.yaml b/deploy/components/inference-gateway/configmaps.yaml new file mode 100644 index 00000000..73b3f022 --- /dev/null +++ b/deploy/components/inference-gateway/configmaps.yaml @@ -0,0 +1,18 @@ +apiVersion: v1 +kind: ConfigMap +metadata: + name: endpoint-picker-config +data: + config.yaml: | + pod_selector: + ai-aware-router-pod: true + routing_filters: + routing_scorers: + - name: session-affinity + weight: 60 + - name: route-by-active-lora + weight: 50 + routing_header: x-ai-aware-router-routing + session_id_header: x-ai-aware-router-session-id + listening_port: 9080 + inference_port: 8000 diff --git a/deploy/components/inference-gateway/deployments.yaml b/deploy/components/inference-gateway/deployments.yaml new file mode 100644 index 00000000..0ec22796 --- /dev/null +++ b/deploy/components/inference-gateway/deployments.yaml @@ -0,0 +1,32 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: endpoint-picker +spec: + replicas: 1 + selector: + matchLabels: + app: endpoint-picker + template: + metadata: + labels: + app: endpoint-picker + spec: + serviceAccountName: endpoint-picker + containers: + - name: endpoint-picker + image: inference-router/router-ext-proc:latest + args: + - "--config-file" + - "/etc/endpoint-picker/config.yaml" + ports: + - name: grpc + containerPort: 9080 + protocol: TCP + volumeMounts: + - name: endpoint-picker-config + mountPath: /etc/endpoint-picker + volumes: + - name: endpoint-picker-config + configMap: + name: endpoint-picker-config diff --git a/deploy/components/inference-gateway/envoy-filters.yaml b/deploy/components/inference-gateway/envoy-filters.yaml new file mode 100644 index 00000000..e9a4fec5 --- /dev/null +++ b/deploy/components/inference-gateway/envoy-filters.yaml @@ -0,0 +1,31 @@ +apiVersion: networking.istio.io/v1alpha3 +kind: EnvoyFilter +metadata: + name: endpoint-picker +spec: + configPatches: + - applyTo: HTTP_FILTER + match: + listener: + filterChain: + filter: + name: "envoy.filters.network.http_connection_manager" + patch: + operation: INSERT_FIRST + value: + name: envoy.filters.http.ext_proc + typed_config: + "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor + failure_mode_allow: false + allow_mode_override: true + processing_mode: + request_header_mode: "SEND" + response_header_mode: "SEND" + request_body_mode: "BUFFERED" + response_body_mode: "BUFFERED" + request_trailer_mode: "SEND" + response_trailer_mode: "SKIP" + grpc_service: + envoy_grpc: + cluster_name: outbound|9080||endpoint-picker.REPLACE_NAMESPACE.svc.cluster.local + timeout: 5s diff --git a/deploy/components/inference-gateway/gateways.yaml b/deploy/components/inference-gateway/gateways.yaml new file mode 100644 index 00000000..2a83b95e --- /dev/null +++ b/deploy/components/inference-gateway/gateways.yaml @@ -0,0 +1,14 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: inference-gateway + labels: + istio.io/rev: istio-control-plane + annotations: + networking.istio.io/service-type: ClusterIP +spec: + gatewayClassName: istio + listeners: + - name: default + port: 80 + protocol: HTTP diff --git a/deploy/components/inference-gateway/kustomization.yaml b/deploy/components/inference-gateway/kustomization.yaml new file mode 100644 index 00000000..10b898cb --- /dev/null +++ b/deploy/components/inference-gateway/kustomization.yaml @@ -0,0 +1,30 @@ +# ------------------------------------------------------------------------------ +# Inference Gateway +# +# This deploys a Gateway and the Endpoint Picker (EPP), and attaches the EPP to +# the Gateway with an EnvoyFilter. +# +# Add an HTTPRoute to route traffic to VLLM, or a VLLM simulator. +# +# **WARNING**: The EnvoyFilter contains a variable that needs to be replaced +# with the namespace to match the EPP's Service. For now use sed to replace it, +# e.g.: +# +# $ kubectl kustomize deploy/components/inference-gateway \ +# | sed 's/REPLACE_NAMESPACE/mynamespace/gI' \ +# | kubectl -n mynamespace apply -f - +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- configmaps.yaml +- deployments.yaml +- services.yaml +- rbac.yaml +- gateways.yaml +- envoy-filters.yaml + +images: +- name: inference-router/router-ext-proc + newTag: 0.0.1 diff --git a/deploy/components/inference-gateway/rbac.yaml b/deploy/components/inference-gateway/rbac.yaml new file mode 100644 index 00000000..1b457dc8 --- /dev/null +++ b/deploy/components/inference-gateway/rbac.yaml @@ -0,0 +1,31 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: endpoint-picker +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + name: endpoint-picker +rules: + - apiGroups: + - "" + resources: + - "pods" + verbs: + - "get" + - "list" + - "watch" +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + name: endpoint-picker-binding +subjects: + - kind: ServiceAccount + name: endpoint-picker +roleRef: + kind: Role + name: endpoint-picker + apiGroup: rbac.authorization.k8s.io + diff --git a/deploy/components/inference-gateway/services.yaml b/deploy/components/inference-gateway/services.yaml new file mode 100644 index 00000000..d8d5d5b1 --- /dev/null +++ b/deploy/components/inference-gateway/services.yaml @@ -0,0 +1,13 @@ +apiVersion: v1 +kind: Service +metadata: + name: endpoint-picker +spec: + type: ClusterIP + selector: + app: endpoint-picker + ports: + - name: grpc + protocol: TCP + port: 9080 + targetPort: 9080 From f606e0d163e7e4bddbf1c5cb61e2ef14d1250cb4 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 18:05:46 -0400 Subject: [PATCH 18/73] feat: add kind environment deployment Signed-off-by: Shane Utt --- deploy/environments/kind/httproutes.yaml | 19 +++++++++++++ deploy/environments/kind/kustomization.yaml | 31 +++++++++++++++++++++ 2 files changed, 50 insertions(+) create mode 100644 deploy/environments/kind/httproutes.yaml create mode 100644 deploy/environments/kind/kustomization.yaml diff --git a/deploy/environments/kind/httproutes.yaml b/deploy/environments/kind/httproutes.yaml new file mode 100644 index 00000000..7ff6e56b --- /dev/null +++ b/deploy/environments/kind/httproutes.yaml @@ -0,0 +1,19 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: inference-route +spec: + parentRefs: + - name: inference-gateway + rules: + - matches: + - path: + type: PathPrefix + value: /v1 + backendRefs: + - name: vllm-30801 + port: 30801 + - name: vllm-30802 + port: 30802 + - name: vllm-30802 + port: 30802 diff --git a/deploy/environments/kind/kustomization.yaml b/deploy/environments/kind/kustomization.yaml new file mode 100644 index 00000000..f5f8d76c --- /dev/null +++ b/deploy/environments/kind/kustomization.yaml @@ -0,0 +1,31 @@ +# ------------------------------------------------------------------------------ +# Kubernetes In Docker (KIND) Environment +# +# This will deploy the full development stack on a KIND cluster: +# +# * Istio Control Plane +# * VLLM Simulator +# * Inference Gateway +# +# **Note**: The Sail Operator must be deployed first. +# +# This will expose the VLLM simulator via an HTTPRoute. You can access the +# Gateway with a port-forward: +# +# $ kubectl port-forward service/inference-gateway-istio 8080:80 +# +# And the requests can be made: +# +# $ curl -v -w '\n' -X POST -H 'Content-Type: application/json' \ +# -d '{"model":"model1","messages":[{"role":"user","content":"Hello!"}]}' \ +# http://localhost:8080/v1/chat/completions +# +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../components/istio-control-plane/ +- ../../components/vllm-sim/ +- ../../components/inference-gateway/ +- httproutes.yaml From c679724849ad454498bfe0d724c9cb8a1ef26581 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Wed, 16 Apr 2025 18:23:18 -0400 Subject: [PATCH 19/73] feat: kind dev env deployment script Signed-off-by: Shane Utt --- scripts/run-kind.sh | 140 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 140 insertions(+) create mode 100755 scripts/run-kind.sh diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh new file mode 100755 index 00000000..a8d86c9e --- /dev/null +++ b/scripts/run-kind.sh @@ -0,0 +1,140 @@ +#!/bin/bash + +# This shell script deploys a kind cluster with an Istio-based Gateway API +# implementation fully configured. It deploys the vllm simulator, which it +# exposes with a Gateway and HTTPRoute. The Gateway is configured with the +# a filter for the ext_proc endpoint picker. + +set -eo pipefail + +# ------------------------------------------------------------------------------ +# Variables +# ------------------------------------------------------------------------------ + +# Set a default CLUSTER_NAME if not provided +: "${CLUSTER_NAME:=inference-gateway}" + +# Set a default VLLM_SIMULATOR_VERSION if not provided +: "${VLLM_SIMULATOR_VERSION:=0.0.2}" + +# Set a default ENDPOINT_PICKER_VERSION if not provided +: "${ENDPOINT_PICKER_VERSION:=0.0.1}" + +# ------------------------------------------------------------------------------ +# Setup & Requirement Checks +# ------------------------------------------------------------------------------ + +# Check for a supported container runtime if an explicit one was not set +if [ -z "${CONTAINER_RUNTIME}" ]; then + if command -v docker &> /dev/null; then + CONTAINER_RUNTIME="docker" + elif command -v podman &> /dev/null; then + CONTAINER_RUNTIME="podman" + else + echo "Neither docker nor podman could be found in PATH" >&2 + exit 1 + fi +fi + +set -u + +# Check for required programs +for cmd in kind kubectl ${CONTAINER_RUNTIME}; do + if ! command -v "$cmd" &> /dev/null; then + echo "Error: $cmd is not installed or not in the PATH." + exit 1 + fi +done + +# ------------------------------------------------------------------------------ +# Cluster Deployment +# ------------------------------------------------------------------------------ + +# Check if the cluster already exists +if kind get clusters 2>/dev/null | grep -q "^${CLUSTER_NAME}$"; then + echo "Cluster '${CLUSTER_NAME}' already exists, re-using" +else + kind create cluster --name "${CLUSTER_NAME}" +fi + +# Set the kubectl context to the kind cluster +KUBE_CONTEXT="kind-${CLUSTER_NAME}" + +set -x + +# Hotfix for https://github.com/kubernetes-sigs/kind/issues/3880 +CONTAINER_NAME="${CLUSTER_NAME}-control-plane" +${CONTAINER_RUNTIME} exec -it ${CONTAINER_NAME} /bin/bash -c "sysctl net.ipv4.conf.all.arp_ignore=0" + +# Wait for all pods to be ready +kubectl --context ${KUBE_CONTEXT} -n kube-system wait --for=condition=Ready --all pods --timeout=300s +kubectl --context ${KUBE_CONTEXT} -n local-path-storage wait --for=condition=Ready --all pods --timeout=300s + +# Load the vllm simulator image into the cluster +if [ "${CONTAINER_RUNTIME}" == "podman" ]; then + podman tag localhost/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} docker.io/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} + podman save docker.io/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin +else + kind --name ${CLUSTER_NAME} load docker-image vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} +fi + +# Load the ext_proc endpoint-picker image into the cluster +if [ "${CONTAINER_RUNTIME}" == "podman" ]; then + podman tag localhost/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} docker.io/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} + podman save docker.io/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin +else + kind --name ${CLUSTER_NAME} load docker-image inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} +fi + +# ------------------------------------------------------------------------------ +# Sail Operator Deployment +# ------------------------------------------------------------------------------ + +# Deploy the Sail Operator +kubectl kustomize --enable-helm deploy/components/sail-operator | + kubectl --context ${KUBE_CONTEXT} apply --server-side --force-conflicts -f - + +# Wait for the Sail Operator to be ready +kubectl --context ${KUBE_CONTEXT} -n sail-operator wait deployment/sail-operator --for=condition=Available --timeout=60s + +# ------------------------------------------------------------------------------ +# Development Environment +# ------------------------------------------------------------------------------ + +# Deploy the environment to the "default" namespace +kubectl kustomize deploy/environments/kind | sed 's/REPLACE_NAMESPACE/default/gI' \ + | kubectl --context ${KUBE_CONTEXT} apply -f - + +# Wait for all pods to be ready +kubectl --context ${KUBE_CONTEXT} wait --for=condition=Ready --all pods --timeout=300s + +# Wait for the gateway to be ready +kubectl --context ${KUBE_CONTEXT} wait gateway/inference-gateway --for=condition=Programmed --timeout=60s + +cat < Date: Wed, 16 Apr 2025 23:30:17 +0000 Subject: [PATCH 20/73] Bump golang.org/x/net from 0.37.0 to 0.38.0 Bumps [golang.org/x/net](https://github.com/golang/net) from 0.37.0 to 0.38.0. - [Commits](https://github.com/golang/net/compare/v0.37.0...v0.38.0) --- updated-dependencies: - dependency-name: golang.org/x/net dependency-version: 0.38.0 dependency-type: indirect ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/go.mod b/go.mod index 20cf017a..cb759537 100644 --- a/go.mod +++ b/go.mod @@ -108,7 +108,7 @@ require ( golang.org/x/crypto v0.36.0 // indirect golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.24.0 // indirect - golang.org/x/net v0.37.0 // indirect + golang.org/x/net v0.38.0 // indirect golang.org/x/oauth2 v0.25.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.32.0 // indirect diff --git a/go.sum b/go.sum index cd6cd380..d282464c 100644 --- a/go.sum +++ b/go.sum @@ -238,8 +238,8 @@ golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= -golang.org/x/net v0.37.0 h1:1zLorHbz+LYj7MQlSf1+2tPIIgibq2eL5xkrGk6f+2c= -golang.org/x/net v0.37.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= +golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= +golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From f6085269c4ef8ffb8e504fdc16609ed5a4d89302 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Thu, 17 Apr 2025 10:22:54 -0400 Subject: [PATCH 21/73] fix: basic container image builds for linux Signed-off-by: Shane Utt --- Dockerfile | 4 +--- Makefile | 11 +++++++---- 2 files changed, 8 insertions(+), 7 deletions(-) diff --git a/Dockerfile b/Dockerfile index ea9af50a..a92cbb71 100644 --- a/Dockerfile +++ b/Dockerfile @@ -33,6 +33,4 @@ WORKDIR / COPY --from=builder /workspace/bin/epp /app/epp USER 65532:65532 -CMD ["sleep", "infinity"] - - +ENTRYPOINT ["/app/epp"] diff --git a/Makefile b/Makefile index 1180b880..c610fb38 100644 --- a/Makefile +++ b/Makefile @@ -3,6 +3,9 @@ IMG ?= controller:latest # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.31.0 +TARGETOS ?= linux +TARGETARCH ?= amd64 + # Get the currently used golang install path (in GOPATH/bin, unless GOBIN is set) ifeq (,$(shell go env GOBIN)) GOBIN=$(shell go env GOPATH)/bin @@ -474,13 +477,13 @@ buildah-build: check-builder load-version-json ## Build and push image (multi-ar fi .PHONY: image-build -image-build: check-container-tool load-version-json ## Build Docker image ## Build Docker image using $(CONTAINER_TOOL) - @printf "\033[33;1m==== Building Docker image $(IMG) ====\033[0m\n" +image-build: check-container-tool load-version-json ## Build container image using $(CONTAINER_TOOL) + @printf "\033[33;1m==== Building container image $(IMG) ====\033[0m\n" $(CONTAINER_TOOL) build --build-arg TARGETOS=$(TARGETOS) --build-arg TARGETARCH=$(TARGETARCH) -t $(IMG) . .PHONY: image-push -image-push: check-container-tool load-version-json ## Push Docker image $(IMG) to registry - @printf "\033[33;1m==== Pushing Docker image $(IMG) ====\033[0m\n" +image-push: check-container-tool load-version-json ## Push container image $(IMG) to registry + @printf "\033[33;1m==== Pushing container image $(IMG) ====\033[0m\n" $(CONTAINER_TOOL) push $(IMG) ##@ Install/Uninstall Targets From 2dd2ee70b8436bbae4e228b42680644710dde833 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Thu, 17 Apr 2025 10:27:58 -0400 Subject: [PATCH 22/73] fix: lint fix Signed-off-by: Shane Utt --- pkg/epp/scheduling/scorer.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/pkg/epp/scheduling/scorer.go b/pkg/epp/scheduling/scorer.go index 75a9d826..384699d5 100644 --- a/pkg/epp/scheduling/scorer.go +++ b/pkg/epp/scheduling/scorer.go @@ -17,7 +17,7 @@ limitations under the License. package scheduling import ( - "fmt" + "errors" "math/rand/v2" "sigs.k8s.io/controller-runtime/pkg/log" @@ -66,7 +66,7 @@ func (sm *ScorerMng) scoreTargets(ctx *types.Context, pods []*types.PodMetrics) } if len(validPods) == 0 { - return nil, fmt.Errorf("Empty list of valid pods to score") + return nil, errors.New("Empty list of valid pods to score") } // add scores from all scorers From a24a8017c01cab28942e082ca8fc8c8a7b03b85e Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Thu, 17 Apr 2025 11:52:39 -0400 Subject: [PATCH 23/73] fix: move openshift deployment to environments Signed-off-by: Shane Utt --- .../openshift}/common/patch-service.yaml | 0 .../openshift}/common/patch-statefulset.yaml | 0 .../openshift}/common/service.yaml | 0 .../openshift}/common/statefulset.yaml | 0 .../openshift}/kustomization.yaml | 0 .../openshift}/openshift/patch-route.yaml | 0 .../openshift}/openshift/route.yaml | 0 .../openshift}/rbac/exec-rbac-role.yaml | 0 .../openshift}/rbac/exec-rbac-rolebinding.yaml | 0 .../openshift}/rbac/patch-rbac-role.yaml | 0 .../openshift}/rbac/patch-rbac-rolebinding.yaml | 0 11 files changed, 0 insertions(+), 0 deletions(-) rename deploy/{components/extra/openshift-router => environments/openshift}/common/patch-service.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/common/patch-statefulset.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/common/service.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/common/statefulset.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/kustomization.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/openshift/patch-route.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/openshift/route.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/rbac/exec-rbac-role.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/rbac/exec-rbac-rolebinding.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/rbac/patch-rbac-role.yaml (100%) rename deploy/{components/extra/openshift-router => environments/openshift}/rbac/patch-rbac-rolebinding.yaml (100%) diff --git a/deploy/components/extra/openshift-router/common/patch-service.yaml b/deploy/environments/openshift/common/patch-service.yaml similarity index 100% rename from deploy/components/extra/openshift-router/common/patch-service.yaml rename to deploy/environments/openshift/common/patch-service.yaml diff --git a/deploy/components/extra/openshift-router/common/patch-statefulset.yaml b/deploy/environments/openshift/common/patch-statefulset.yaml similarity index 100% rename from deploy/components/extra/openshift-router/common/patch-statefulset.yaml rename to deploy/environments/openshift/common/patch-statefulset.yaml diff --git a/deploy/components/extra/openshift-router/common/service.yaml b/deploy/environments/openshift/common/service.yaml similarity index 100% rename from deploy/components/extra/openshift-router/common/service.yaml rename to deploy/environments/openshift/common/service.yaml diff --git a/deploy/components/extra/openshift-router/common/statefulset.yaml b/deploy/environments/openshift/common/statefulset.yaml similarity index 100% rename from deploy/components/extra/openshift-router/common/statefulset.yaml rename to deploy/environments/openshift/common/statefulset.yaml diff --git a/deploy/components/extra/openshift-router/kustomization.yaml b/deploy/environments/openshift/kustomization.yaml similarity index 100% rename from deploy/components/extra/openshift-router/kustomization.yaml rename to deploy/environments/openshift/kustomization.yaml diff --git a/deploy/components/extra/openshift-router/openshift/patch-route.yaml b/deploy/environments/openshift/openshift/patch-route.yaml similarity index 100% rename from deploy/components/extra/openshift-router/openshift/patch-route.yaml rename to deploy/environments/openshift/openshift/patch-route.yaml diff --git a/deploy/components/extra/openshift-router/openshift/route.yaml b/deploy/environments/openshift/openshift/route.yaml similarity index 100% rename from deploy/components/extra/openshift-router/openshift/route.yaml rename to deploy/environments/openshift/openshift/route.yaml diff --git a/deploy/components/extra/openshift-router/rbac/exec-rbac-role.yaml b/deploy/environments/openshift/rbac/exec-rbac-role.yaml similarity index 100% rename from deploy/components/extra/openshift-router/rbac/exec-rbac-role.yaml rename to deploy/environments/openshift/rbac/exec-rbac-role.yaml diff --git a/deploy/components/extra/openshift-router/rbac/exec-rbac-rolebinding.yaml b/deploy/environments/openshift/rbac/exec-rbac-rolebinding.yaml similarity index 100% rename from deploy/components/extra/openshift-router/rbac/exec-rbac-rolebinding.yaml rename to deploy/environments/openshift/rbac/exec-rbac-rolebinding.yaml diff --git a/deploy/components/extra/openshift-router/rbac/patch-rbac-role.yaml b/deploy/environments/openshift/rbac/patch-rbac-role.yaml similarity index 100% rename from deploy/components/extra/openshift-router/rbac/patch-rbac-role.yaml rename to deploy/environments/openshift/rbac/patch-rbac-role.yaml diff --git a/deploy/components/extra/openshift-router/rbac/patch-rbac-rolebinding.yaml b/deploy/environments/openshift/rbac/patch-rbac-rolebinding.yaml similarity index 100% rename from deploy/components/extra/openshift-router/rbac/patch-rbac-rolebinding.yaml rename to deploy/environments/openshift/rbac/patch-rbac-rolebinding.yaml From 950e07bab1e2e1543a3a2045eeda7995cd643295 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Thu, 17 Apr 2025 11:54:52 -0400 Subject: [PATCH 24/73] fix: retarget kustomize deployments in Makefile Signed-off-by: Shane Utt --- Makefile | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/Makefile b/Makefile index c610fb38..bc3f0991 100644 --- a/Makefile +++ b/Makefile @@ -513,6 +513,8 @@ uninstall-docker: check-container-tool ## Uninstall app from $(CONTAINER_TOOL) ### Kubernetes Targets (kubectl) +# TODO: currently incorrect because it depends on OpenShift APIs. +# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14 .PHONY: install-k8s install-k8s: check-kubectl check-kustomize check-envsubst ## Install on Kubernetes export PROJECT_NAME=${PROJECT_NAME} @@ -522,7 +524,7 @@ install-k8s: check-kubectl check-kustomize check-envsubst ## Install on Kubernet kubectl config set-context --current --namespace=$(NAMESPACE) @echo "Deploying resources from deploy/ ..." # Build the kustomization from deploy, substitute variables, and apply the YAML - kustomize build deploy | envsubst | kubectl apply -f - + kustomize build deploy/environments/openshift | envsubst | kubectl apply -f - @echo "Waiting for pod to become ready..." sleep 5 @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ @@ -530,12 +532,14 @@ install-k8s: check-kubectl check-kustomize check-envsubst ## Install on Kubernet echo "To use the app, run:"; \ echo "alias $(PROJECT_NAME)='kubectl exec -n $(NAMESPACE) -it $$POD -- /app/$(PROJECT_NAME)'" +# TODO: currently incorrect because it depends on OpenShift APIs. +# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14 .PHONY: uninstall-k8s uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Kubernetes export PROJECT_NAME=${PROJECT_NAME} export NAMESPACE=${NAMESPACE} @echo "Removing resources from Kubernetes..." - kustomize build deploy | envsubst | kubectl delete --force -f - || true + kustomize build deploy/environments/openshift | envsubst | kubectl delete --force -f - || true POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ echo "Deleting pod: $$POD"; \ kubectl delete pod "$$POD" --force --grace-period=0 || true; \ @@ -550,7 +554,7 @@ install-openshift: check-kubectl check-kustomize check-envsubst ## Install on Op kubectl create namespace $(NAMESPACE) 2>/dev/null || true @echo "Deploying common resources from deploy/ ..." # Build and substitute the base manifests from deploy, then apply them - kustomize build deploy | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -n $(NAMESPACE) -f - + kustomize build deploy/environments/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -n $(NAMESPACE) -f - @echo "Waiting for pod to become ready..." sleep 5 @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}'); \ @@ -561,7 +565,7 @@ install-openshift: check-kubectl check-kustomize check-envsubst ## Install on Op .PHONY: uninstall-openshift uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall from OpenShift @echo "Removing resources from OpenShift..." - kustomize build deploy | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete --force -f - || true + kustomize build deploy/environments/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete --force -f - || true # @if kubectl api-resources --api-group=route.openshift.io | grep -q Route; then \ # envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' < deploy/openshift/route.yaml | kubectl delete --force -f - || true; \ # fi @@ -575,12 +579,12 @@ uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall f .PHONY: install-rbac install-rbac: check-kubectl check-kustomize check-envsubst ## Install RBAC @echo "Applying RBAC configuration from deploy/rbac..." - kustomize build deploy/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -f - + kustomize build deploy/environments/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -f - .PHONY: uninstall-rbac uninstall-rbac: check-kubectl check-kustomize check-envsubst ## Uninstall RBAC @echo "Removing RBAC configuration from deploy/rbac..." - kustomize build deploy/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete -f - || true + kustomize build deploy/environments/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete -f - || true ##@ Version Extraction From 47bed9de6735a0967a40f4987e4a49a959c341b7 Mon Sep 17 00:00:00 2001 From: Etai Lev Ran Date: Thu, 17 Apr 2025 19:05:15 +0300 Subject: [PATCH 25/73] empty top level kustomization.yaml - make CICD happy Signed-off-by: Etai Lev Ran --- deploy/kustomization.yaml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 deploy/kustomization.yaml diff --git a/deploy/kustomization.yaml b/deploy/kustomization.yaml new file mode 100644 index 00000000..cfed0773 --- /dev/null +++ b/deploy/kustomization.yaml @@ -0,0 +1,12 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +# Set the namespace for all resources using a placeholder. +namespace: ${NAMESPACE} + +# Use a prefix for all object names. You can substitute the PROJECT_NAME variable. +namePrefix: ${PROJECT_NAME}- + +# List all the resources (manifests) you want to deploy. + +# Include patches to update existing resources, if any From f36b10fb904595763e27cdf91c00978a7bbe8e3b Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Thu, 17 Apr 2025 14:32:10 -0400 Subject: [PATCH 26/73] feat: add infra targets for ocp to Makefile Signed-off-by: Shane Utt --- Makefile | 57 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/Makefile b/Makefile index bc3f0991..c94ad8d8 100644 --- a/Makefile +++ b/Makefile @@ -547,6 +547,57 @@ uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Ku ### OpenShift Targets (oc) +# ------------------------------------------------------------------------------ +# OpenShift Infrastructure Installer +# +# This target deploys infrastructure requirements for the entire cluster. +# Among other things, this includes CRDs and operators which all users of the +# cluster need for development (e.g. Gateway API, Istio, etc). +# +# **Warning**: Only run this if you're certain you should be running it. It +# has implications for all users of the cluster! +# ------------------------------------------------------------------------------ +.PHONY: install-openshift-infrastructure +install-openshift-infrastructure: +ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) + @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" + @echo "Installing the Istio Sail Operator and CRDs for Istio and Gateway API" + kustomize build --enable-helm deploy/components/sail-operator | kubectl apply --server-side --force-conflicts -f - + @echo "Installing the Istio Control Plane" + kustomize build deploy/components/istio-control-plane | kubectl apply -f - +else + $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") +endif + +# ------------------------------------------------------------------------------ +# OpenShift Infrastructure Uninstaller +# +# This target removes all infrastructure components (e.g. CRDs, operators, +# etc) for the entire cluster. +# +# **Warning**: Only run this if you're certain you should be running it. **This +# will disrupt everyone using the cluster**. Generally this should only be run +# when the infrastructure components have undergone very significant change, and +# you need to do a hard cleanup and re-deploy. +# ------------------------------------------------------------------------------ +.PHONY: uninstall-openshift-infrastructure +uninstall-openshift-infrastructure: +ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) + @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components" + @echo "Uninstalling the Istio Control Plane" + kustomize build deploy/components/istio-control-plane | kubectl delete -f - || true + @echo "Uninstalling the Istio Sail Operator and CRDs for Istio and Gateway API" + kustomize build --enable-helm deploy/components/sail-operator | kubectl delete -f - || true +else + $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") +endif + +# ------------------------------------------------------------------------------ +# OpenShift Installer +# +# This target deploys components in a namespace on an OpenShift cluster for +# a developer to do development and testing cycles. +# ------------------------------------------------------------------------------ .PHONY: install-openshift install-openshift: check-kubectl check-kustomize check-envsubst ## Install on OpenShift @echo $$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION @@ -562,6 +613,12 @@ install-openshift: check-kubectl check-kustomize check-envsubst ## Install on Op echo "To use the app, run:"; \ echo "alias $(PROJECT_NAME)='kubectl exec -n $(NAMESPACE) -it $$POD -- /app/$(PROJECT_NAME)'" +# ------------------------------------------------------------------------------ +# OpenShift Uninstaller +# +# This target cleans up a developer's testing and development namespace, +# removing all components therein. +# ------------------------------------------------------------------------------ .PHONY: uninstall-openshift uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall from OpenShift @echo "Removing resources from OpenShift..." From 320961c7d9c612496b6f278c267f0fbfe413ca21 Mon Sep 17 00:00:00 2001 From: Etai Lev Ran Date: Thu, 17 Apr 2025 23:18:13 +0300 Subject: [PATCH 27/73] Minor fixes to enable image building matching GIE - CONTAINER_TOOL setting commented out until can be fixed correctly (Ref #7) - image name was missing `epp` as last element in tag Signed-off-by: Etai Lev Ran --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index c94ad8d8..057dd975 100644 --- a/Makefile +++ b/Makefile @@ -396,11 +396,11 @@ SHELL := /usr/bin/env bash PROJECT_NAME ?= gateway-api-inference-extension DEV_VERSION ?= 0.0.1 PROD_VERSION ?= 0.0.0 -IMAGE_TAG_BASE ?= quay.io/vllm-d/$(PROJECT_NAME) +IMAGE_TAG_BASE ?= quay.io/vllm-d/$(PROJECT_NAME)/epp IMG = $(IMAGE_TAG_BASE):$(DEV_VERSION) NAMESPACE ?= hc4ai-operator -CONTAINER_TOOL := $(shell command -v docker >/dev/null 2>&1 && echo docker || command -v podman >/dev/null 2>&1 && echo podman || echo "") +# CONTAINER_TOOL := $(shell command -v docker >/dev/null 2>&1 && echo docker || command -v podman >/dev/null 2>&1 && echo podman || echo "") BUILDER := $(shell command -v buildah >/dev/null 2>&1 && echo buildah || echo $(CONTAINER_TOOL)) PLATFORMS ?= linux/amd64 # linux/arm64 # linux/s390x,linux/ppc64le From 1024f07a08b928f673a2776e422c21e89d4ce4fd Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Fri, 18 Apr 2025 13:13:47 +0300 Subject: [PATCH 28/73] Yamls for inference model and inference pool --- .../inference-gateway/inferencemodel.yaml | 9 ++ .../inference-gateway/inferencepool.yaml | 126 ++++++++++++++++++ 2 files changed, 135 insertions(+) create mode 100644 deploy/components/inference-gateway/inferencemodel.yaml create mode 100644 deploy/components/inference-gateway/inferencepool.yaml diff --git a/deploy/components/inference-gateway/inferencemodel.yaml b/deploy/components/inference-gateway/inferencemodel.yaml new file mode 100644 index 00000000..f729407e --- /dev/null +++ b/deploy/components/inference-gateway/inferencemodel.yaml @@ -0,0 +1,9 @@ +apiVersion: inference.networking.x-k8s.io/v1alpha2 +kind: InferenceModel +metadata: + name: food-review +spec: + modelName: food-review + criticality: Critical + poolRef: + name: vllm-llama3-8b-instruct diff --git a/deploy/components/inference-gateway/inferencepool.yaml b/deploy/components/inference-gateway/inferencepool.yaml new file mode 100644 index 00000000..e2fceaf1 --- /dev/null +++ b/deploy/components/inference-gateway/inferencepool.yaml @@ -0,0 +1,126 @@ +# Note: If you change this file, please also change the file used for e2e tests! +# +# https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/test/testdata/inferencepool-e2e.yaml +apiVersion: inference.networking.x-k8s.io/v1alpha2 +kind: InferencePool +metadata: + labels: + name: vllm-llama3-8b-instruct +spec: + targetPortNumber: 8000 + selector: + app: vllm-llama3-8b-instruct + extensionRef: + name: vllm-llama3-8b-instruct-epp +--- +apiVersion: v1 +kind: Service +metadata: + name: vllm-llama3-8b-instruct-epp + namespace: default +spec: + selector: + app: vllm-llama3-8b-instruct-epp + ports: + - protocol: TCP + port: 9002 + targetPort: 9002 + appProtocol: http2 + type: ClusterIP +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vllm-llama3-8b-instruct-epp + namespace: default + labels: + app: vllm-llama3-8b-instruct-epp +spec: + replicas: 1 + selector: + matchLabels: + app: vllm-llama3-8b-instruct-epp + template: + metadata: + labels: + app: vllm-llama3-8b-instruct-epp + spec: + # Conservatively, this timeout should mirror the longest grace period of the pods within the pool + terminationGracePeriodSeconds: 130 + containers: + - name: epp +# image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main + image: gateway-api-inference-extension/epp:demo + imagePullPolicy: IfNotPresent + args: + - -refreshMetricsInterval + - "500ms" + - -poolName + - "vllm-llama3-8b-instruct" + - -v + - "4" + - --zap-encoder + - "json" + - -grpcPort + - "9002" + - -grpcHealthPort + - "9003" + ports: + - containerPort: 9002 + - containerPort: 9003 + - name: metrics + containerPort: 9090 + livenessProbe: + grpc: + port: 9003 + service: inference-extension + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + grpc: + port: 9003 + service: inference-extension + initialDelaySeconds: 5 + periodSeconds: 10 +--- +kind: ClusterRole +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: pod-read +rules: +- apiGroups: ["inference.networking.x-k8s.io"] + resources: ["inferencemodels"] + verbs: ["get", "watch", "list"] +- apiGroups: [""] + resources: ["pods"] + verbs: ["get", "watch", "list"] +- apiGroups: ["inference.networking.x-k8s.io"] + resources: ["inferencepools"] + verbs: ["get", "watch", "list"] +- apiGroups: ["discovery.k8s.io"] + resources: ["endpointslices"] + verbs: ["get", "watch", "list"] +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +kind: ClusterRoleBinding +apiVersion: rbac.authorization.k8s.io/v1 +metadata: + name: pod-read-binding +subjects: +- kind: ServiceAccount + name: default + namespace: default +roleRef: + kind: ClusterRole + name: pod-read From 7655e3cce2816b4e54a5d929dd4f1a1e5c38cb34 Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Fri, 18 Apr 2025 13:20:11 +0300 Subject: [PATCH 29/73] update vllm-sim deployment yaml --- deploy/components/vllm-sim/deployments.yaml | 79 +++------------------ 1 file changed, 11 insertions(+), 68 deletions(-) diff --git a/deploy/components/vllm-sim/deployments.yaml b/deploy/components/vllm-sim/deployments.yaml index e7c981cf..16a299f6 100644 --- a/deploy/components/vllm-sim/deployments.yaml +++ b/deploy/components/vllm-sim/deployments.yaml @@ -1,86 +1,29 @@ -apiVersion: apps/v1 -kind: Deployment -metadata: - name: vllm-30801 - labels: - app: vllm-30801 -spec: - replicas: 1 - selector: - matchLabels: - app: vllm-30801 - template: - metadata: - labels: - app: vllm-30801 - ai-aware-router-pod: "true" - annotations: - ai-aware-router-address: 127.0.0.1:30801 - spec: - containers: - - name: vllm - image: vllm-sim/vllm-sim:latest - args: - - "--port=30801" - - "--model=model1" - - "--lora=lora1,lora2" - ports: - - containerPort: 30801 ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: vllm-30802 - labels: - app: vllm-30802 -spec: - replicas: 1 - selector: - matchLabels: - app: vllm-30802 - template: - metadata: - labels: - app: vllm-30802 - ai-aware-router-pod: "true" - annotations: - ai-aware-router-address: 127.0.0.1:30802 - spec: - containers: - - name: vllm - image: vllm-sim/vllm-sim:latest - args: - - "--port=30802" - - "--model=model1" - - "--lora=lora1,lora2" - ports: - - containerPort: 30802 --- apiVersion: apps/v1 kind: Deployment metadata: - name: vllm-30803 + name: vllm-sim labels: - app: vllm-30803 + app: vllm-llama3-8b-instruct spec: replicas: 1 selector: matchLabels: - app: vllm-30803 + app: vllm-llama3-8b-instruct template: metadata: labels: - app: vllm-30803 + app: vllm-llama3-8b-instruct ai-aware-router-pod: "true" - annotations: - ai-aware-router-address: 127.0.0.1:30803 spec: containers: - name: vllm - image: vllm-sim/vllm-sim:latest + image: quay.io/vllm-d/vllm-sim:0.0.1 + imagePullPolicy: IfNotPresent args: - - "--port=30803" - - "--model=model2" - - "--lora=lora3" + - "--port=8000" + - "--model=food-review" + # - "--lora=lora10,lora20,lora30" + # - "--time-to-first-token=500" ports: - - containerPort: 30803 + - containerPort: 8000 From c9fd65b5e8fc688aca2bdf65e9caa12dced325a6 Mon Sep 17 00:00:00 2001 From: Etai Lev Ran Date: Fri, 18 Apr 2025 14:20:53 +0300 Subject: [PATCH 30/73] draft changes in run-kind Signed-off-by: Etai Lev Ran --- .../inference-gateway/deployments.yaml | 2 +- scripts/run-kind.sh | 26 ++++++++++++++----- 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/deploy/components/inference-gateway/deployments.yaml b/deploy/components/inference-gateway/deployments.yaml index 0ec22796..55b595bd 100644 --- a/deploy/components/inference-gateway/deployments.yaml +++ b/deploy/components/inference-gateway/deployments.yaml @@ -15,7 +15,7 @@ spec: serviceAccountName: endpoint-picker containers: - name: endpoint-picker - image: inference-router/router-ext-proc:latest + image: quay.io/vllm-d/gateway-api-inference-extension/epp:0.0.1 args: - "--config-file" - "/etc/endpoint-picker/config.yaml" diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index a8d86c9e..8394992c 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -11,15 +11,23 @@ set -eo pipefail # Variables # ------------------------------------------------------------------------------ +# TODO: get image names, paths, versions, etc. from the .version.json file + # Set a default CLUSTER_NAME if not provided : "${CLUSTER_NAME:=inference-gateway}" +# Set the default IMAGE_REGISTRY if not provided +: "${IMAGE_REGISTRY:=quay.io/vllm-d}" + # Set a default VLLM_SIMULATOR_VERSION if not provided : "${VLLM_SIMULATOR_VERSION:=0.0.2}" # Set a default ENDPOINT_PICKER_VERSION if not provided : "${ENDPOINT_PICKER_VERSION:=0.0.1}" +# Set a default ENDPOINT_PICKER_IMAGE if not provided +: "${ENDPOINT_PICKER_IMAGE:=gateway-api-inference-extension/epp}" + # ------------------------------------------------------------------------------ # Setup & Requirement Checks # ------------------------------------------------------------------------------ @@ -46,6 +54,12 @@ for cmd in kind kubectl ${CONTAINER_RUNTIME}; do fi done +# @TODO Make sure the EPP and vllm-sim images are present or built +# EPP: `make image-load` in the GIE repo +# vllm-sim: `` +# note: you may need to retag the built images to match the expected path and +# versions listed above + # ------------------------------------------------------------------------------ # Cluster Deployment # ------------------------------------------------------------------------------ @@ -72,18 +86,18 @@ kubectl --context ${KUBE_CONTEXT} -n local-path-storage wait --for=condition=Rea # Load the vllm simulator image into the cluster if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman tag localhost/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} docker.io/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} - podman save docker.io/vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin + podman tag localhost/vllm-d/vllm-sim:${VLLM_SIMULATOR_VERSION} ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} + podman save ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin else - kind --name ${CLUSTER_NAME} load docker-image vllm-sim/vllm-sim:${VLLM_SIMULATOR_VERSION} + kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} fi # Load the ext_proc endpoint-picker image into the cluster if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman tag localhost/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} docker.io/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} - podman save docker.io/inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin + podman tag localhost/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} + podman save ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin else - kind --name ${CLUSTER_NAME} load docker-image inference-router/router-ext-proc:${ENDPOINT_PICKER_VERSION} + kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} fi # ------------------------------------------------------------------------------ From 5e0ad989d87f07a6ad04c7ccc18e2322618fd825 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 08:03:31 -0400 Subject: [PATCH 31/73] testing new deployment dev --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index e0ac0729..3b56a81b 100644 --- a/README.md +++ b/README.md @@ -53,3 +53,4 @@ Contributions are readily welcomed, follow the [dev guide](./docs/dev.md) to sta Participation in the Kubernetes community is governed by the [Kubernetes Code of Conduct](code-of-conduct.md). + From 9413ed04027b267f49f045ffc7269aa0aa5b7c0a Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 08:04:44 -0400 Subject: [PATCH 32/73] testing new deployment dev --- .tekton/pipelinerun.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.tekton/pipelinerun.yaml b/.tekton/pipelinerun.yaml index ed1c6538..c8fb0c38 100644 --- a/.tekton/pipelinerun.yaml +++ b/.tekton/pipelinerun.yaml @@ -6,7 +6,7 @@ metadata: pipelinesascode.tekton.dev/on-event: "[pull_request, push]" pipelinesascode.tekton.dev/on-target-branch: "[main, dev]" pipelinesascode.tekton.dev/task: "git-clone" - pipelinesascode.tekton.dev/max-keep-runs: "5" + pipelinesascode.tekton.dev/max-keep-runs: "3" pipelinesascode.tekton.dev/git-status: "true" pipelinesascode.tekton.dev/on-cel-expression: > (!has(body.ref) || body.ref == 'refs/heads/main' || body.ref == 'refs/heads/dev') && From e41f154c8661646e11d8264966761c55305ea14c Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 08:32:10 -0400 Subject: [PATCH 33/73] chore: inference-gateway component fixes for namespace-level deployment --- .../inference-gateway/inferencepool.yaml | 71 +++++++++++-------- 1 file changed, 43 insertions(+), 28 deletions(-) diff --git a/deploy/components/inference-gateway/inferencepool.yaml b/deploy/components/inference-gateway/inferencepool.yaml index e2fceaf1..76e19fb4 100644 --- a/deploy/components/inference-gateway/inferencepool.yaml +++ b/deploy/components/inference-gateway/inferencepool.yaml @@ -1,6 +1,3 @@ -# Note: If you change this file, please also change the file used for e2e tests! -# -# https://github.com/kubernetes-sigs/gateway-api-inference-extension/blob/main/test/testdata/inferencepool-e2e.yaml apiVersion: inference.networking.x-k8s.io/v1alpha2 kind: InferencePool metadata: @@ -17,7 +14,6 @@ apiVersion: v1 kind: Service metadata: name: vllm-llama3-8b-instruct-epp - namespace: default spec: selector: app: vllm-llama3-8b-instruct-epp @@ -32,7 +28,6 @@ apiVersion: apps/v1 kind: Deployment metadata: name: vllm-llama3-8b-instruct-epp - namespace: default labels: app: vllm-llama3-8b-instruct-epp spec: @@ -50,7 +45,7 @@ spec: containers: - name: epp # image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main - image: gateway-api-inference-extension/epp:demo + image: gateway-api-inference-extension/epp:latest imagePullPolicy: IfNotPresent args: - -refreshMetricsInterval @@ -83,44 +78,64 @@ spec: initialDelaySeconds: 5 periodSeconds: 10 --- -kind: ClusterRole +kind: Role apiVersion: rbac.authorization.k8s.io/v1 metadata: name: pod-read rules: -- apiGroups: ["inference.networking.x-k8s.io"] - resources: ["inferencemodels"] - verbs: ["get", "watch", "list"] -- apiGroups: [""] - resources: ["pods"] - verbs: ["get", "watch", "list"] -- apiGroups: ["inference.networking.x-k8s.io"] - resources: ["inferencepools"] - verbs: ["get", "watch", "list"] -- apiGroups: ["discovery.k8s.io"] - resources: ["endpointslices"] - verbs: ["get", "watch", "list"] - apiGroups: - - authentication.k8s.io + - "inference.networking.x-k8s.io" resources: - - tokenreviews + - "inferencemodels" verbs: - - create + - "get" + - "watch" + - "list" - apiGroups: - - authorization.k8s.io + - "" resources: - - subjectaccessreviews + - "pods" verbs: - - create + - "get" + - "watch" + - "list" +- apiGroups: + - "inference.networking.x-k8s.io" + resources: + - "inferencepools" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "discovery.k8s.io" + resources: + - "endpointslices" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "authentication.k8s.io" + resources: + - "tokenreviews" + verbs: + - "create" +- apiGroups: + - "authorization.k8s.io" + resources: + - "subjectaccessreviews" + verbs: + - "create" --- -kind: ClusterRoleBinding apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding metadata: name: pod-read-binding subjects: - kind: ServiceAccount name: default - namespace: default roleRef: - kind: ClusterRole + apiGroup: rbac.authorization.k8s.io + kind: Role name: pod-read From 84da7a575ef132e332e37aaa85cba7887e2ab582 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 08:47:56 -0400 Subject: [PATCH 34/73] docs: add issue links for some TODOs --- scripts/run-kind.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index 8394992c..5e08b0d4 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -12,6 +12,7 @@ set -eo pipefail # ------------------------------------------------------------------------------ # TODO: get image names, paths, versions, etc. from the .version.json file +# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/28 # Set a default CLUSTER_NAME if not provided : "${CLUSTER_NAME:=inference-gateway}" @@ -59,6 +60,7 @@ done # vllm-sim: `` # note: you may need to retag the built images to match the expected path and # versions listed above +# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/28 # ------------------------------------------------------------------------------ # Cluster Deployment From 6bd139f0c83363f47c385e67a38c4221002dd722 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 09:30:42 -0400 Subject: [PATCH 35/73] feat: add crd deployment component Signed-off-by: Shane Utt --- Makefile | 8 ++++++-- deploy/components/crds/kustomization.yaml | 17 +++++++++++++++++ .../components/sail-operator/kustomization.yaml | 5 ++--- scripts/run-kind.sh | 7 +++++++ 4 files changed, 32 insertions(+), 5 deletions(-) create mode 100644 deploy/components/crds/kustomization.yaml diff --git a/Makefile b/Makefile index 057dd975..0353b00b 100644 --- a/Makefile +++ b/Makefile @@ -561,7 +561,9 @@ uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Ku install-openshift-infrastructure: ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" - @echo "Installing the Istio Sail Operator and CRDs for Istio and Gateway API" + @echo "Installing CRDs for Gateway API & GIE" + kustomize build deploy/components/crds | kubectl apply --server-side --force-conflicts -f - + @echo "Installing the Istio Sail Operator and CRDs for Istio" kustomize build --enable-helm deploy/components/sail-operator | kubectl apply --server-side --force-conflicts -f - @echo "Installing the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl apply -f - @@ -586,8 +588,10 @@ ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components" @echo "Uninstalling the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl delete -f - || true - @echo "Uninstalling the Istio Sail Operator and CRDs for Istio and Gateway API" + @echo "Uninstalling the Istio Sail Operator and CRDs for Istio" kustomize build --enable-helm deploy/components/sail-operator | kubectl delete -f - || true + @echo "Uninstalling CRDs for Gateway API & GIE" + kustomize build deploy/components/crds | kubectl delete -f - || true else $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") endif diff --git a/deploy/components/crds/kustomization.yaml b/deploy/components/crds/kustomization.yaml new file mode 100644 index 00000000..55852af8 --- /dev/null +++ b/deploy/components/crds/kustomization.yaml @@ -0,0 +1,17 @@ +# ------------------------------------------------------------------------------ +# Custom Resource Definitions (CRDs) +# +# This deploys the CRDs needed for development environments (e.g. Gateway API). +# +# **Warning**: CRDs are cluster-level, so in a shared development environment +# this needs to be done in a controlled and communicated manner. +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +# Gateway API CRDs +- https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1 +# Gateway API Inference Extension (GIE) CRDs +# NOTE: deploys whatever is in the current branch +- ../../../config/crd # GIE CRDs diff --git a/deploy/components/sail-operator/kustomization.yaml b/deploy/components/sail-operator/kustomization.yaml index d50bcadc..e0737753 100644 --- a/deploy/components/sail-operator/kustomization.yaml +++ b/deploy/components/sail-operator/kustomization.yaml @@ -3,10 +3,10 @@ # # This deploys the Istio Sail Operator via Helm chart to enable the creation # of Istio Control Planes, and ultimately Gateways. This will also deploy all -# the Istio and Gateway API CRDs. +# the Istio CRDs. # # This is required on Kubernetes clusters, and OpenShift clusters versions -# below 4.19 (OpenShift 4.19+ includes all this by default). +# below 4.19, but OpenShift 4.19+ clusters include all this by default. # # **Warning**: This needs to be deployed before, and separately from other # components as it deploys CRDs. It can be deployed with: @@ -21,7 +21,6 @@ kind: Kustomization namespace: sail-operator resources: -- https://github.com/kubernetes-sigs/gateway-api/config/crd?ref=v1.2.1 - namespaces.yaml helmCharts: diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index 5e08b0d4..0ce9c75c 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -102,6 +102,13 @@ else kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} fi +# ------------------------------------------------------------------------------ +# CRD Deployment (Gateway API + GIE) +# ------------------------------------------------------------------------------ + +kubectl kustomize deploy/components/crds | + kubectl --context ${KUBE_CONTEXT} apply --server-side --force-conflicts -f - + # ------------------------------------------------------------------------------ # Sail Operator Deployment # ------------------------------------------------------------------------------ From 920246227c72fa5f5426f7e429e686707b200e9d Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 09:49:45 -0400 Subject: [PATCH 36/73] fix: remove podman load instructions that are no longer needed Signed-off-by: Shane Utt --- scripts/run-kind.sh | 2 -- 1 file changed, 2 deletions(-) diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index 0ce9c75c..30f9908f 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -88,7 +88,6 @@ kubectl --context ${KUBE_CONTEXT} -n local-path-storage wait --for=condition=Rea # Load the vllm simulator image into the cluster if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman tag localhost/vllm-d/vllm-sim:${VLLM_SIMULATOR_VERSION} ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} podman save ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin else kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} @@ -96,7 +95,6 @@ fi # Load the ext_proc endpoint-picker image into the cluster if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman tag localhost/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} podman save ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin else kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} From 8e46ea9719de6abe519505e09b3bca895d421dca Mon Sep 17 00:00:00 2001 From: Etai Lev Ran Date: Fri, 18 Apr 2025 16:53:54 +0300 Subject: [PATCH 37/73] upgrade golang.org/x/oauth2 to v0.27.0 Signed-off-by: Etai Lev Ran --- go.mod | 2 +- go.sum | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/go.mod b/go.mod index cb759537..ab80d153 100644 --- a/go.mod +++ b/go.mod @@ -109,7 +109,7 @@ require ( golang.org/x/exp v0.0.0-20240719175910-8a7402abbf56 // indirect golang.org/x/mod v0.24.0 // indirect golang.org/x/net v0.38.0 // indirect - golang.org/x/oauth2 v0.25.0 // indirect + golang.org/x/oauth2 v0.27.0 // indirect golang.org/x/sync v0.12.0 // indirect golang.org/x/sys v0.32.0 // indirect golang.org/x/term v0.30.0 // indirect diff --git a/go.sum b/go.sum index d282464c..fcfd3ebf 100644 --- a/go.sum +++ b/go.sum @@ -242,6 +242,8 @@ golang.org/x/net v0.38.0 h1:vRMAPTMaeGqVhG5QyLJHqNDwecKTomGeqbnfZyKlBI8= golang.org/x/net v0.38.0/go.mod h1:ivrbrMbzFq5J41QOQh0siUuly180yBYtLp+CKbEaFx8= golang.org/x/oauth2 v0.25.0 h1:CY4y7XT9v0cRI9oupztF8AgiIu99L/ksR/Xp/6jrZ70= golang.org/x/oauth2 v0.25.0/go.mod h1:XYTD2NtWslqkgxebSiOHnXEap4TF09sJSc7H1sXbhtI= +golang.org/x/oauth2 v0.27.0 h1:da9Vo7/tDv5RH/7nZDz1eMGS/q1Vv1N/7FCrBhI9I3M= +golang.org/x/oauth2 v0.27.0/go.mod h1:onh5ek6nERTohokkhCD/y2cV4Do3fxFHFuAejCkRWT8= golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= From 413c4a75ce1fdadebab0ae844d00a99387818464 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 15:58:48 -0400 Subject: [PATCH 38/73] feat: add istio crds to deployments Signed-off-by: Shane Utt --- deploy/components/crds/istio.yaml | 17255 ++++++++++++++++++++ deploy/components/crds/kustomization.yaml | 2 + 2 files changed, 17257 insertions(+) create mode 100644 deploy/components/crds/istio.yaml diff --git a/deploy/components/crds/istio.yaml b/deploy/components/crds/istio.yaml new file mode 100644 index 00000000..274d8d76 --- /dev/null +++ b/deploy/components/crds/istio.yaml @@ -0,0 +1,17255 @@ +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: authorizationpolicies.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: AuthorizationPolicy + listKind: AuthorizationPolicyList + plural: authorizationpolicies + shortNames: + - ap + singular: authorizationpolicy + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The operation to take. + jsonPath: .spec.action + name: Action + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration for access control on workloads. See more + details at: https://istio.io/docs/reference/config/security/authorization-policy.html' + oneOf: + - not: + anyOf: + - required: + - provider + - required: + - provider + properties: + action: + description: |- + Optional. + + Valid Options: ALLOW, DENY, AUDIT, CUSTOM + enum: + - ALLOW + - DENY + - AUDIT + - CUSTOM + type: string + provider: + description: Specifies detailed configuration of the CUSTOM action. + properties: + name: + description: Specifies the name of the extension provider. + type: string + type: object + rules: + description: Optional. + items: + properties: + from: + description: Optional. + items: + properties: + source: + description: Source specifies the source of a request. + properties: + ipBlocks: + description: Optional. + items: + type: string + type: array + namespaces: + description: Optional. + items: + type: string + type: array + notIpBlocks: + description: Optional. + items: + type: string + type: array + notNamespaces: + description: Optional. + items: + type: string + type: array + notPrincipals: + description: Optional. + items: + type: string + type: array + notRemoteIpBlocks: + description: Optional. + items: + type: string + type: array + notRequestPrincipals: + description: Optional. + items: + type: string + type: array + notServiceAccounts: + description: Optional. + items: + maxLength: 320 + type: string + maxItems: 16 + type: array + principals: + description: Optional. + items: + type: string + type: array + remoteIpBlocks: + description: Optional. + items: + type: string + type: array + requestPrincipals: + description: Optional. + items: + type: string + type: array + serviceAccounts: + description: Optional. + items: + maxLength: 320 + type: string + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: Cannot set serviceAccounts with namespaces + or principals + rule: |- + (has(self.serviceAccounts) || has(self.notServiceAccounts)) ? (!has(self.principals) && + !has(self.notPrincipals) && !has(self.namespaces) && !has(self.notNamespaces)) : true + type: object + maxItems: 512 + type: array + to: + description: Optional. + items: + properties: + operation: + description: Operation specifies the operation of a request. + properties: + hosts: + description: Optional. + items: + type: string + type: array + methods: + description: Optional. + items: + type: string + type: array + notHosts: + description: Optional. + items: + type: string + type: array + notMethods: + description: Optional. + items: + type: string + type: array + notPaths: + description: Optional. + items: + type: string + type: array + notPorts: + description: Optional. + items: + type: string + type: array + paths: + description: Optional. + items: + type: string + type: array + ports: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + when: + description: Optional. + items: + properties: + key: + description: The name of an Istio attribute. + type: string + notValues: + description: Optional. + items: + type: string + type: array + values: + description: Optional. + items: + type: string + type: array + required: + - key + type: object + type: array + type: object + maxItems: 512 + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The operation to take. + jsonPath: .spec.action + name: Action + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration for access control on workloads. See more + details at: https://istio.io/docs/reference/config/security/authorization-policy.html' + oneOf: + - not: + anyOf: + - required: + - provider + - required: + - provider + properties: + action: + description: |- + Optional. + + Valid Options: ALLOW, DENY, AUDIT, CUSTOM + enum: + - ALLOW + - DENY + - AUDIT + - CUSTOM + type: string + provider: + description: Specifies detailed configuration of the CUSTOM action. + properties: + name: + description: Specifies the name of the extension provider. + type: string + type: object + rules: + description: Optional. + items: + properties: + from: + description: Optional. + items: + properties: + source: + description: Source specifies the source of a request. + properties: + ipBlocks: + description: Optional. + items: + type: string + type: array + namespaces: + description: Optional. + items: + type: string + type: array + notIpBlocks: + description: Optional. + items: + type: string + type: array + notNamespaces: + description: Optional. + items: + type: string + type: array + notPrincipals: + description: Optional. + items: + type: string + type: array + notRemoteIpBlocks: + description: Optional. + items: + type: string + type: array + notRequestPrincipals: + description: Optional. + items: + type: string + type: array + notServiceAccounts: + description: Optional. + items: + maxLength: 320 + type: string + maxItems: 16 + type: array + principals: + description: Optional. + items: + type: string + type: array + remoteIpBlocks: + description: Optional. + items: + type: string + type: array + requestPrincipals: + description: Optional. + items: + type: string + type: array + serviceAccounts: + description: Optional. + items: + maxLength: 320 + type: string + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: Cannot set serviceAccounts with namespaces + or principals + rule: |- + (has(self.serviceAccounts) || has(self.notServiceAccounts)) ? (!has(self.principals) && + !has(self.notPrincipals) && !has(self.namespaces) && !has(self.notNamespaces)) : true + type: object + maxItems: 512 + type: array + to: + description: Optional. + items: + properties: + operation: + description: Operation specifies the operation of a request. + properties: + hosts: + description: Optional. + items: + type: string + type: array + methods: + description: Optional. + items: + type: string + type: array + notHosts: + description: Optional. + items: + type: string + type: array + notMethods: + description: Optional. + items: + type: string + type: array + notPaths: + description: Optional. + items: + type: string + type: array + notPorts: + description: Optional. + items: + type: string + type: array + paths: + description: Optional. + items: + type: string + type: array + ports: + description: Optional. + items: + type: string + type: array + type: object + type: object + type: array + when: + description: Optional. + items: + properties: + key: + description: The name of an Istio attribute. + type: string + notValues: + description: Optional. + items: + type: string + type: array + values: + description: Optional. + items: + type: string + type: array + required: + - key + type: object + type: array + type: object + maxItems: 512 + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: destinationrules.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: DestinationRule + listKind: DestinationRuleList + plural: destinationrules + shortNames: + - dr + singular: destinationrule + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The name of a service from the service registry + jsonPath: .spec.host + name: Host + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting load balancing, outlier detection, + etc. See more details at: https://istio.io/docs/reference/config/networking/destination-rule.html' + properties: + exportTo: + description: A list of namespaces to which this destination rule is + exported. + items: + type: string + type: array + host: + description: The name of a service from the service registry. + type: string + subsets: + description: One or more named sets that represent individual versions + of a service. + items: + properties: + labels: + additionalProperties: + type: string + description: Labels apply a filter over the endpoints of a service + in the service registry. + type: object + name: + description: Name of the subset. + type: string + trafficPolicy: + description: Traffic policies that apply to this subset. + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that + will be queued while waiting for a ready + connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests + to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream + connection pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent + streams allowed for a peer on one HTTP/2 + connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per + connection to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that + can be outstanding to all hosts in a cluster + at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and + TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive + probes to send without response before + deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer + algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP + header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP + query parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev + hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend + hosts. + properties: + minimumRingSize: + description: The minimum number of virtual + nodes to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' + separated, e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities + to traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the + traffic will fail over to when endpoints + in the 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered + list of labels used to sort endpoints to + do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration + of Service. + properties: + aggression: + description: This parameter controls the speed + of traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a + host is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally + originated failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep + analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled + as long as the associated load balancing pool + has at least `minHealthPercent` hosts in healthy + mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish + local origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the + destination service on which this policy is being + applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in + verifying a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use + in verifying a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds + the TLS certs for the client including the CA + certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature + and SAN for the server certificate corresponding + to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify + the subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream + connection is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream + connection is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + required: + - name + type: object + type: array + trafficPolicy: + description: Traffic policies to apply (load balancing policy, connection + pool sizes, outlier detection). + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to + send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query parameter. + type: string + maglev: + description: The Maglev load balancer implements consistent + hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer implements + consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes to + use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to traffic + distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic will + fail over to when endpoints in the 'from' region + becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list of labels + used to sort endpoints to do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of Service. + properties: + aggression: + description: This parameter controls the speed of traffic + increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing pool + for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long as + the associated load balancing pool has at least `minHealthPercent` + hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local origin + failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the destination + service on which this policy is being applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the upstream + service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing certificate + authority certificates to use in verifying a presented server + certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing the + certificate revocation list (CRL) to use in verifying a + presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS certs + for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether the proxy + should skip verifying the CA signature and SAN for the server + certificate corresponding to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during TLS + handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream connection + is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream connection + is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `DestinationRule` configuration should be applied. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + required: + - host + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The name of a service from the service registry + jsonPath: .spec.host + name: Host + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting load balancing, outlier detection, + etc. See more details at: https://istio.io/docs/reference/config/networking/destination-rule.html' + properties: + exportTo: + description: A list of namespaces to which this destination rule is + exported. + items: + type: string + type: array + host: + description: The name of a service from the service registry. + type: string + subsets: + description: One or more named sets that represent individual versions + of a service. + items: + properties: + labels: + additionalProperties: + type: string + description: Labels apply a filter over the endpoints of a service + in the service registry. + type: object + name: + description: Name of the subset. + type: string + trafficPolicy: + description: Traffic policies that apply to this subset. + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that + will be queued while waiting for a ready + connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests + to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream + connection pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent + streams allowed for a peer on one HTTP/2 + connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per + connection to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that + can be outstanding to all hosts in a cluster + at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and + TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive + probes to send without response before + deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer + algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP + header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP + query parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev + hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend + hosts. + properties: + minimumRingSize: + description: The minimum number of virtual + nodes to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' + separated, e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities + to traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the + traffic will fail over to when endpoints + in the 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered + list of labels used to sort endpoints to + do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration + of Service. + properties: + aggression: + description: This parameter controls the speed + of traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a + host is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally + originated failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep + analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled + as long as the associated load balancing pool + has at least `minHealthPercent` hosts in healthy + mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish + local origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the + destination service on which this policy is being + applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in + verifying a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use + in verifying a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds + the TLS certs for the client including the CA + certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature + and SAN for the server certificate corresponding + to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify + the subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream + connection is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream + connection is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + required: + - name + type: object + type: array + trafficPolicy: + description: Traffic policies to apply (load balancing policy, connection + pool sizes, outlier detection). + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to + send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query parameter. + type: string + maglev: + description: The Maglev load balancer implements consistent + hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer implements + consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes to + use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to traffic + distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic will + fail over to when endpoints in the 'from' region + becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list of labels + used to sort endpoints to do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of Service. + properties: + aggression: + description: This parameter controls the speed of traffic + increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing pool + for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long as + the associated load balancing pool has at least `minHealthPercent` + hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local origin + failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the destination + service on which this policy is being applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the upstream + service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing certificate + authority certificates to use in verifying a presented server + certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing the + certificate revocation list (CRL) to use in verifying a + presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS certs + for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether the proxy + should skip verifying the CA signature and SAN for the server + certificate corresponding to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during TLS + handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream connection + is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream connection + is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `DestinationRule` configuration should be applied. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + required: + - host + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The name of a service from the service registry + jsonPath: .spec.host + name: Host + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting load balancing, outlier detection, + etc. See more details at: https://istio.io/docs/reference/config/networking/destination-rule.html' + properties: + exportTo: + description: A list of namespaces to which this destination rule is + exported. + items: + type: string + type: array + host: + description: The name of a service from the service registry. + type: string + subsets: + description: One or more named sets that represent individual versions + of a service. + items: + properties: + labels: + additionalProperties: + type: string + description: Labels apply a filter over the endpoints of a service + in the service registry. + type: object + name: + description: Name of the subset. + type: string + trafficPolicy: + description: Traffic policies that apply to this subset. + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that + will be queued while waiting for a ready + connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests + to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream + connection pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent + streams allowed for a peer on one HTTP/2 + connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per + connection to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that + can be outstanding to all hosts in a cluster + at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol + will be preserved while initiating connection + to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and + TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP + connections to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE + on the socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between + keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive + probes to send without response before + deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer + algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP + header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP + query parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev + hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend + hosts. + properties: + minimumRingSize: + description: The minimum number of virtual + nodes to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' + separated, e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities + to traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the + traffic will fail over to when endpoints + in the 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered + list of labels used to sort endpoints to + do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration + of Service. + properties: + aggression: + description: This parameter controls the speed + of traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a + host is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally + originated failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep + analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled + as long as the associated load balancing pool + has at least `minHealthPercent` hosts in healthy + mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish + local origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the + destination service on which this policy is being + applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections + to the upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in + verifying a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use + in verifying a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds + the TLS certs for the client including the CA + certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature + and SAN for the server certificate corresponding + to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server + during TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify + the subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream + connection is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream + connection is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + required: + - name + type: object + type: array + trafficPolicy: + description: Traffic policies to apply (load balancing policy, connection + pool sizes, outlier detection). + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to + send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query parameter. + type: string + maglev: + description: The Maglev load balancer implements consistent + hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer implements + consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes to + use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to traffic + distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, failover + or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic will + fail over to when endpoints in the 'from' region + becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list of labels + used to sort endpoints to do priority based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of Service. + properties: + aggression: + description: This parameter controls the speed of traffic + increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing pool + for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long as + the associated load balancing pool has at least `minHealthPercent` + hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local origin + failures from external errors. + type: boolean + type: object + portLevelSettings: + description: Traffic policies specific to individual ports. + items: + properties: + connectionPool: + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will + be queued while waiting for a ready connection + pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to + a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can + be outstanding to all hosts in a cluster at a + given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will + be preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the + socket to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the + connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection + needs to be idle before keep-alive probes + start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater + than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + loadBalancer: + description: Settings controlling the load balancer algorithms. + oneOf: + - not: + anyOf: + - required: + - simple + - required: + - consistentHash + - required: + - simple + - required: + - consistentHash + properties: + consistentHash: + allOf: + - oneOf: + - not: + anyOf: + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - required: + - httpHeaderName + - required: + - httpCookie + - required: + - useSourceIp + - required: + - httpQueryParameterName + - oneOf: + - not: + anyOf: + - required: + - ringHash + - required: + - maglev + - required: + - ringHash + - required: + - maglev + properties: + httpCookie: + description: Hash based on HTTP cookie. + properties: + name: + description: Name of the cookie. + type: string + path: + description: Path to set for the cookie. + type: string + ttl: + description: Lifetime of the cookie. + type: string + required: + - name + type: object + httpHeaderName: + description: Hash based on a specific HTTP header. + type: string + httpQueryParameterName: + description: Hash based on a specific HTTP query + parameter. + type: string + maglev: + description: The Maglev load balancer implements + consistent hashing to backend hosts. + properties: + tableSize: + description: The table size for Maglev hashing. + minimum: 0 + type: integer + type: object + minimumRingSize: + description: Deprecated. + minimum: 0 + type: integer + ringHash: + description: The ring/modulo hash load balancer + implements consistent hashing to backend hosts. + properties: + minimumRingSize: + description: The minimum number of virtual nodes + to use for the hash ring. + minimum: 0 + type: integer + type: object + useSourceIp: + description: Hash based on the source IP address. + type: boolean + type: object + localityLbSetting: + properties: + distribute: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating locality, '/' separated, + e.g. + type: string + to: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + description: Map of upstream localities to + traffic distribution weights. + type: object + type: object + type: array + enabled: + description: Enable locality load balancing. + nullable: true + type: boolean + failover: + description: 'Optional: only one of distribute, + failover or failoverPriority can be set.' + items: + properties: + from: + description: Originating region. + type: string + to: + description: Destination region the traffic + will fail over to when endpoints in the + 'from' region becomes unhealthy. + type: string + type: object + type: array + failoverPriority: + description: failoverPriority is an ordered list + of labels used to sort endpoints to do priority + based load balancing. + items: + type: string + type: array + type: object + simple: + description: |2- + + + Valid Options: LEAST_CONN, RANDOM, PASSTHROUGH, ROUND_ROBIN, LEAST_REQUEST + enum: + - UNSPECIFIED + - LEAST_CONN + - RANDOM + - PASSTHROUGH + - ROUND_ROBIN + - LEAST_REQUEST + type: string + warmup: + description: Represents the warmup configuration of + Service. + properties: + aggression: + description: This parameter controls the speed of + traffic increase over the warmup duration. + format: double + minimum: 1 + nullable: true + type: number + duration: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + minimumPercent: + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + required: + - duration + type: object + warmupDurationSecs: + description: 'Deprecated: use `warmup` instead.' + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + outlierDetection: + properties: + baseEjectionTime: + description: Minimum ejection duration. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + consecutive5xxErrors: + description: Number of 5xx errors before a host is ejected + from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveErrors: + format: int32 + type: integer + consecutiveGatewayErrors: + description: Number of gateway errors before a host + is ejected from the connection pool. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + consecutiveLocalOriginFailures: + description: The number of consecutive locally originated + failures before ejection occurs. + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + interval: + description: Time interval between ejection sweep analysis. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxEjectionPercent: + description: Maximum % of hosts in the load balancing + pool for the upstream service that can be ejected. + format: int32 + type: integer + minHealthPercent: + description: Outlier detection will be enabled as long + as the associated load balancing pool has at least + `minHealthPercent` hosts in healthy mode. + format: int32 + type: integer + splitExternalLocalOriginErrors: + description: Determines whether to distinguish local + origin failures from external errors. + type: boolean + type: object + port: + description: Specifies the number of a port on the destination + service on which this policy is being applied. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: TLS related settings for connections to the + upstream service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing + certificate authority certificates to use in verifying + a presented server certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS + certs for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether + the proxy should skip verifying the CA signature and + SAN for the server certificate corresponding to the + host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during + TLS handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the + subject identity in the certificate. + items: + type: string + type: array + type: object + type: object + maxItems: 4096 + type: array + proxyProtocol: + description: The upstream PROXY protocol settings. + properties: + version: + description: |- + The PROXY protocol version to use. + + Valid Options: V1, V2 + enum: + - V1 + - V2 + type: string + type: object + tls: + description: TLS related settings for connections to the upstream + service. + properties: + caCertificates: + description: 'OPTIONAL: The path to the file containing certificate + authority certificates to use in verifying a presented server + certificate.' + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing the + certificate revocation list (CRL) to use in verifying a + presented server certificate.' + type: string + clientCertificate: + description: REQUIRED if mode is `MUTUAL`. + type: string + credentialName: + description: The name of the secret that holds the TLS certs + for the client including the CA certificates. + type: string + insecureSkipVerify: + description: '`insecureSkipVerify` specifies whether the proxy + should skip verifying the CA signature and SAN for the server + certificate corresponding to the host.' + nullable: true + type: boolean + mode: + description: |- + Indicates whether connections to this port should be secured using TLS. + + Valid Options: DISABLE, SIMPLE, MUTUAL, ISTIO_MUTUAL + enum: + - DISABLE + - SIMPLE + - MUTUAL + - ISTIO_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `MUTUAL`. + type: string + sni: + description: SNI string to present to the server during TLS + handshake. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate. + items: + type: string + type: array + type: object + tunnel: + description: Configuration of tunneling TCP over other transport + or application layers for the host configured in the DestinationRule. + properties: + protocol: + description: Specifies which protocol to use for tunneling + the downstream connection. + type: string + targetHost: + description: Specifies a host to which the downstream connection + is tunneled. + type: string + targetPort: + description: Specifies a port to which the downstream connection + is tunneled. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - targetHost + - targetPort + type: object + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `DestinationRule` configuration should be applied. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + required: + - host + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: envoyfilters.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: EnvoyFilter + listKind: EnvoyFilterList + plural: envoyfilters + singular: envoyfilter + scope: Namespaced + versions: + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Customizing Envoy configuration generated by Istio. See + more details at: https://istio.io/docs/reference/config/networking/envoy-filter.html' + properties: + configPatches: + description: One or more patches with match conditions. + items: + properties: + applyTo: + description: |- + Specifies where in the Envoy configuration, the patch should be applied. + + Valid Options: LISTENER, FILTER_CHAIN, NETWORK_FILTER, HTTP_FILTER, ROUTE_CONFIGURATION, VIRTUAL_HOST, HTTP_ROUTE, CLUSTER, EXTENSION_CONFIG, BOOTSTRAP, LISTENER_FILTER + enum: + - INVALID + - LISTENER + - FILTER_CHAIN + - NETWORK_FILTER + - HTTP_FILTER + - ROUTE_CONFIGURATION + - VIRTUAL_HOST + - HTTP_ROUTE + - CLUSTER + - EXTENSION_CONFIG + - BOOTSTRAP + - LISTENER_FILTER + type: string + match: + description: Match on listener/route configuration/cluster. + oneOf: + - not: + anyOf: + - required: + - listener + - required: + - routeConfiguration + - required: + - cluster + - required: + - listener + - required: + - routeConfiguration + - required: + - cluster + properties: + cluster: + description: Match on envoy cluster attributes. + properties: + name: + description: The exact name of the cluster to match. + type: string + portNumber: + description: The service port for which this cluster + was generated. + maximum: 4294967295 + minimum: 0 + type: integer + service: + description: The fully qualified service name for this + cluster. + type: string + subset: + description: The subset associated with the service. + type: string + type: object + context: + description: |- + The specific config generation context to match on. + + Valid Options: ANY, SIDECAR_INBOUND, SIDECAR_OUTBOUND, GATEWAY + enum: + - ANY + - SIDECAR_INBOUND + - SIDECAR_OUTBOUND + - GATEWAY + type: string + listener: + description: Match on envoy listener attributes. + properties: + filterChain: + description: Match a specific filter chain in a listener. + properties: + applicationProtocols: + description: Applies only to sidecars. + type: string + destinationPort: + description: The destination_port value used by + a filter chain's match condition. + maximum: 4294967295 + minimum: 0 + type: integer + filter: + description: The name of a specific filter to apply + the patch to. + properties: + name: + description: The filter name to match on. + type: string + subFilter: + description: The next level filter within this + filter to match upon. + properties: + name: + description: The filter name to match on. + type: string + type: object + type: object + name: + description: The name assigned to the filter chain. + type: string + sni: + description: The SNI value used by a filter chain's + match condition. + type: string + transportProtocol: + description: Applies only to `SIDECAR_INBOUND` context. + type: string + type: object + listenerFilter: + description: Match a specific listener filter. + type: string + name: + description: Match a specific listener by its name. + type: string + portName: + type: string + portNumber: + description: The service port/gateway port to which + traffic is being sent/received. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + proxy: + description: Match on properties associated with a proxy. + properties: + metadata: + additionalProperties: + type: string + description: Match on the node metadata supplied by + a proxy when connecting to istiod. + type: object + proxyVersion: + description: A regular expression in golang regex format + (RE2) that can be used to select proxies using a specific + version of istio proxy. + type: string + type: object + routeConfiguration: + description: Match on envoy HTTP route configuration attributes. + properties: + gateway: + description: The Istio gateway config's namespace/name + for which this route configuration was generated. + type: string + name: + description: Route configuration name to match on. + type: string + portName: + description: Applicable only for GATEWAY context. + type: string + portNumber: + description: The service port number or gateway server + port number for which this route configuration was + generated. + maximum: 4294967295 + minimum: 0 + type: integer + vhost: + description: Match a specific virtual host in a route + configuration and apply the patch to the virtual host. + properties: + domainName: + description: Match a domain name in a virtual host. + type: string + name: + description: The VirtualHosts objects generated + by Istio are named as host:port, where the host + typically corresponds to the VirtualService's + host field or the hostname of a service in the + registry. + type: string + route: + description: Match a specific route within the virtual + host. + properties: + action: + description: |- + Match a route with specific action type. + + Valid Options: ANY, ROUTE, REDIRECT, DIRECT_RESPONSE + enum: + - ANY + - ROUTE + - REDIRECT + - DIRECT_RESPONSE + type: string + name: + description: The Route objects generated by + default are named as default. + type: string + type: object + type: object + type: object + type: object + patch: + description: The patch to apply along with the operation. + properties: + filterClass: + description: |- + Determines the filter insertion order. + + Valid Options: AUTHN, AUTHZ, STATS + enum: + - UNSPECIFIED + - AUTHN + - AUTHZ + - STATS + type: string + operation: + description: |- + Determines how the patch should be applied. + + Valid Options: MERGE, ADD, REMOVE, INSERT_BEFORE, INSERT_AFTER, INSERT_FIRST, REPLACE + enum: + - INVALID + - MERGE + - ADD + - REMOVE + - INSERT_BEFORE + - INSERT_AFTER + - INSERT_FIRST + - REPLACE + type: string + value: + description: The JSON config of the object being patched. + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + type: object + type: array + priority: + description: Priority defines the order in which patch sets are applied + within a context. + format: int32 + type: integer + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this patch configuration should be applied. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + type: object + x-kubernetes-validations: + - message: only one of targetRefs or workloadSelector can be set + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.targetRefs) + ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: gateways.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: Gateway + listKind: GatewayList + plural: gateways + shortNames: + - gw + singular: gateway + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting edge load balancer. See more details + at: https://istio.io/docs/reference/config/networking/gateway.html' + properties: + selector: + additionalProperties: + type: string + description: One or more labels that indicate a specific set of pods/VMs + on which this gateway configuration should be applied. + type: object + servers: + description: A list of server specifications. + items: + properties: + bind: + description: The ip or the Unix domain socket to which the listener + should be bound to. + type: string + defaultEndpoint: + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + type: string + type: array + name: + description: An optional name of the server, when set must be + unique across all servers. + type: string + port: + description: The Port on which the proxy should listen for incoming + connections. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + required: + - number + - protocol + - name + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + - hosts + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting edge load balancer. See more details + at: https://istio.io/docs/reference/config/networking/gateway.html' + properties: + selector: + additionalProperties: + type: string + description: One or more labels that indicate a specific set of pods/VMs + on which this gateway configuration should be applied. + type: object + servers: + description: A list of server specifications. + items: + properties: + bind: + description: The ip or the Unix domain socket to which the listener + should be bound to. + type: string + defaultEndpoint: + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + type: string + type: array + name: + description: An optional name of the server, when set must be + unique across all servers. + type: string + port: + description: The Port on which the proxy should listen for incoming + connections. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + required: + - number + - protocol + - name + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + - hosts + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting edge load balancer. See more details + at: https://istio.io/docs/reference/config/networking/gateway.html' + properties: + selector: + additionalProperties: + type: string + description: One or more labels that indicate a specific set of pods/VMs + on which this gateway configuration should be applied. + type: object + servers: + description: A list of server specifications. + items: + properties: + bind: + description: The ip or the Unix domain socket to which the listener + should be bound to. + type: string + defaultEndpoint: + type: string + hosts: + description: One or more hosts exposed by this gateway. + items: + type: string + type: array + name: + description: An optional name of the server, when set must be + unique across all servers. + type: string + port: + description: The Port on which the proxy should listen for incoming + connections. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + required: + - number + - protocol + - name + type: object + tls: + description: Set of TLS related options that govern the server's + behavior. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + - hosts + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: peerauthentications.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: PeerAuthentication + listKind: PeerAuthenticationList + plural: peerauthentications + shortNames: + - pa + singular: peerauthentication + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: Defines the mTLS mode used for peer authentication. + jsonPath: .spec.mtls.mode + name: Mode + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Peer authentication configuration for workloads. See more + details at: https://istio.io/docs/reference/config/security/peer_authentication.html' + properties: + mtls: + description: Mutual TLS settings for workload. + properties: + mode: + description: |- + Defines the mTLS mode used for peer authentication. + + Valid Options: DISABLE, PERMISSIVE, STRICT + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + portLevelMtls: + additionalProperties: + properties: + mode: + description: |- + Defines the mTLS mode used for peer authentication. + + Valid Options: DISABLE, PERMISSIVE, STRICT + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + description: Port specific mutual TLS settings. + minProperties: 1 + type: object + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: self.all(key, 0 < int(key) && int(key) <= 65535) + selector: + description: The selector determines the workloads to apply the PeerAuthentication + on. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + type: object + x-kubernetes-validations: + - message: portLevelMtls requires selector + rule: 'has(self.portLevelMtls) ? (((has(self.selector) && has(self.selector.matchLabels)) + ? self.selector.matchLabels : {}).size() > 0) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: Defines the mTLS mode used for peer authentication. + jsonPath: .spec.mtls.mode + name: Mode + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Peer authentication configuration for workloads. See more + details at: https://istio.io/docs/reference/config/security/peer_authentication.html' + properties: + mtls: + description: Mutual TLS settings for workload. + properties: + mode: + description: |- + Defines the mTLS mode used for peer authentication. + + Valid Options: DISABLE, PERMISSIVE, STRICT + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + portLevelMtls: + additionalProperties: + properties: + mode: + description: |- + Defines the mTLS mode used for peer authentication. + + Valid Options: DISABLE, PERMISSIVE, STRICT + enum: + - UNSET + - DISABLE + - PERMISSIVE + - STRICT + type: string + type: object + description: Port specific mutual TLS settings. + minProperties: 1 + type: object + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: self.all(key, 0 < int(key) && int(key) <= 65535) + selector: + description: The selector determines the workloads to apply the PeerAuthentication + on. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + type: object + x-kubernetes-validations: + - message: portLevelMtls requires selector + rule: 'has(self.portLevelMtls) ? (((has(self.selector) && has(self.selector.matchLabels)) + ? self.selector.matchLabels : {}).size() > 0) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: proxyconfigs.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: ProxyConfig + listKind: ProxyConfigList + plural: proxyconfigs + singular: proxyconfig + scope: Namespaced + versions: + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Provides configuration for individual workloads. See more + details at: https://istio.io/docs/reference/config/networking/proxy-config.html' + properties: + concurrency: + description: The number of worker threads to run. + format: int32 + minimum: 0 + nullable: true + type: integer + environmentVariables: + additionalProperties: + maxLength: 2048 + type: string + description: Additional environment variables for the proxy. + type: object + image: + description: Specifies the details of the proxy image. + properties: + imageType: + description: The image type of the image. + type: string + type: object + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: requestauthentications.security.istio.io +spec: + group: security.istio.io + names: + categories: + - istio-io + - security-istio-io + kind: RequestAuthentication + listKind: RequestAuthenticationList + plural: requestauthentications + shortNames: + - ra + singular: requestauthentication + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Request authentication configuration for workloads. See + more details at: https://istio.io/docs/reference/config/security/request_authentication.html' + properties: + jwtRules: + description: Define the list of JWTs that can be validated at the + selected workloads' proxy. + items: + properties: + audiences: + description: The list of JWT [audiences](https://tools.ietf.org/html/rfc7519#section-4.1.3) + that are allowed to access. + items: + minLength: 1 + type: string + type: array + forwardOriginalToken: + description: If set to true, the original token will be kept + for the upstream request. + type: boolean + fromCookies: + description: List of cookie names from which JWT is expected. + items: + minLength: 1 + type: string + type: array + fromHeaders: + description: List of header locations from which JWT is expected. + items: + properties: + name: + description: The HTTP header name. + minLength: 1 + type: string + prefix: + description: The prefix that should be stripped before + decoding the token. + type: string + required: + - name + type: object + type: array + fromParams: + description: List of query parameters from which JWT is expected. + items: + minLength: 1 + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + minLength: 1 + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + type: string + jwks_uri: + description: URL of the provider's public key set to validate + signature of the JWT. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: url must have scheme http:// or https:// + rule: url(self).getScheme() in ["http", "https"] + jwksUri: + description: URL of the provider's public key set to validate + signature of the JWT. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: url must have scheme http:// or https:// + rule: url(self).getScheme() in ["http", "https"] + outputClaimToHeaders: + description: This field specifies a list of operations to copy + the claim to HTTP headers on a successfully verified token. + items: + properties: + claim: + description: The name of the claim to be copied from. + minLength: 1 + type: string + header: + description: The name of the header to be created. + minLength: 1 + pattern: ^[-_A-Za-z0-9]+$ + type: string + required: + - header + - claim + type: object + type: array + outputPayloadToHeader: + description: This field specifies the header name to output + a successfully verified JWT payload to the backend. + type: string + timeout: + description: The maximum amount of time that the resolver, determined + by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable, + will spend waiting for the JWKS to be fetched. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + required: + - issuer + type: object + x-kubernetes-validations: + - message: only one of jwks or jwksUri can be set + rule: '(has(self.jwksUri) ? 1 : 0) + (has(self.jwks_uri) ? 1 : + 0) + (has(self.jwks) ? 1 : 0) <= 1' + maxItems: 4096 + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Request authentication configuration for workloads. See + more details at: https://istio.io/docs/reference/config/security/request_authentication.html' + properties: + jwtRules: + description: Define the list of JWTs that can be validated at the + selected workloads' proxy. + items: + properties: + audiences: + description: The list of JWT [audiences](https://tools.ietf.org/html/rfc7519#section-4.1.3) + that are allowed to access. + items: + minLength: 1 + type: string + type: array + forwardOriginalToken: + description: If set to true, the original token will be kept + for the upstream request. + type: boolean + fromCookies: + description: List of cookie names from which JWT is expected. + items: + minLength: 1 + type: string + type: array + fromHeaders: + description: List of header locations from which JWT is expected. + items: + properties: + name: + description: The HTTP header name. + minLength: 1 + type: string + prefix: + description: The prefix that should be stripped before + decoding the token. + type: string + required: + - name + type: object + type: array + fromParams: + description: List of query parameters from which JWT is expected. + items: + minLength: 1 + type: string + type: array + issuer: + description: Identifies the issuer that issued the JWT. + minLength: 1 + type: string + jwks: + description: JSON Web Key Set of public keys to validate signature + of the JWT. + type: string + jwks_uri: + description: URL of the provider's public key set to validate + signature of the JWT. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: url must have scheme http:// or https:// + rule: url(self).getScheme() in ["http", "https"] + jwksUri: + description: URL of the provider's public key set to validate + signature of the JWT. + maxLength: 2048 + minLength: 1 + type: string + x-kubernetes-validations: + - message: url must have scheme http:// or https:// + rule: url(self).getScheme() in ["http", "https"] + outputClaimToHeaders: + description: This field specifies a list of operations to copy + the claim to HTTP headers on a successfully verified token. + items: + properties: + claim: + description: The name of the claim to be copied from. + minLength: 1 + type: string + header: + description: The name of the header to be created. + minLength: 1 + pattern: ^[-_A-Za-z0-9]+$ + type: string + required: + - header + - claim + type: object + type: array + outputPayloadToHeader: + description: This field specifies the header name to output + a successfully verified JWT payload to the backend. + type: string + timeout: + description: The maximum amount of time that the resolver, determined + by the PILOT_JWT_ENABLE_REMOTE_JWKS environment variable, + will spend waiting for the JWKS to be fetched. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + required: + - issuer + type: object + x-kubernetes-validations: + - message: only one of jwks or jwksUri can be set + rule: '(has(self.jwksUri) ? 1 : 0) + (has(self.jwks_uri) ? 1 : + 0) + (has(self.jwks) ? 1 : 0) <= 1' + maxItems: 4096 + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: serviceentries.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: ServiceEntry + listKind: ServiceEntryList + plural: serviceentries + shortNames: + - se + singular: serviceentry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The hosts associated with the ServiceEntry + jsonPath: .spec.hosts + name: Hosts + type: string + - description: Whether the service is external to the mesh or part of the mesh + (MESH_EXTERNAL or MESH_INTERNAL) + jsonPath: .spec.location + name: Location + type: string + - description: Service resolution mode for the hosts (NONE, STATIC, or DNS) + jsonPath: .spec.resolution + name: Resolution + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting service registry. See more details + at: https://istio.io/docs/reference/config/networking/service-entry.html' + properties: + addresses: + description: The virtual IP addresses associated with the service. + items: + maxLength: 64 + type: string + maxItems: 256 + type: array + endpoints: + description: One or more endpoints associated with the service. + items: + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + maxItems: 4096 + type: array + exportTo: + description: A list of namespaces to which this service is exported. + items: + type: string + type: array + hosts: + description: The hosts associated with the ServiceEntry. + items: + type: string + x-kubernetes-validations: + - message: hostname cannot be wildcard + rule: self != "*" + maxItems: 256 + minItems: 1 + type: array + location: + description: |- + Specify whether the service should be considered external to the mesh or part of the mesh. + + Valid Options: MESH_EXTERNAL, MESH_INTERNAL + enum: + - MESH_EXTERNAL + - MESH_INTERNAL + type: string + ports: + description: The ports associated with the external service. + items: + properties: + name: + description: Label assigned to the port. + maxLength: 256 + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + protocol: + description: The protocol exposed on the port. + maxLength: 256 + type: string + targetPort: + description: The port number on the endpoint where the traffic + will be received. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - number + - name + type: object + maxItems: 256 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: port number cannot be duplicated + rule: self.all(l1, self.exists_one(l2, l1.number == l2.number)) + resolution: + description: |- + Service resolution mode for the hosts. + + Valid Options: NONE, STATIC, DNS, DNS_ROUND_ROBIN + enum: + - NONE + - STATIC + - DNS + - DNS_ROUND_ROBIN + type: string + subjectAltNames: + description: If specified, the proxy will verify that the server certificate's + subject alternate name matches one of the specified values. + items: + type: string + type: array + workloadSelector: + description: Applicable only for MESH_INTERNAL services. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + required: + - hosts + type: object + x-kubernetes-validations: + - message: only one of WorkloadSelector or Endpoints can be set + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' + - message: CIDR addresses are allowed only for NONE/STATIC resolution + types + rule: '!((has(self.addresses) ? self.addresses : []).exists(k, k.contains("/")) + && !((has(self.resolution) ? self.resolution : "NONE") in ["STATIC", + "NONE"]))' + - message: NONE mode cannot set endpoints + rule: '((has(self.resolution) ? self.resolution : "NONE") == "NONE") + ? !has(self.endpoints) : true' + - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints + rule: '((has(self.resolution) ? self.resolution : "") == "DNS_ROUND_ROBIN") + ? ((has(self.endpoints) ? self.endpoints : []).size() <= 1) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The hosts associated with the ServiceEntry + jsonPath: .spec.hosts + name: Hosts + type: string + - description: Whether the service is external to the mesh or part of the mesh + (MESH_EXTERNAL or MESH_INTERNAL) + jsonPath: .spec.location + name: Location + type: string + - description: Service resolution mode for the hosts (NONE, STATIC, or DNS) + jsonPath: .spec.resolution + name: Resolution + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting service registry. See more details + at: https://istio.io/docs/reference/config/networking/service-entry.html' + properties: + addresses: + description: The virtual IP addresses associated with the service. + items: + maxLength: 64 + type: string + maxItems: 256 + type: array + endpoints: + description: One or more endpoints associated with the service. + items: + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + maxItems: 4096 + type: array + exportTo: + description: A list of namespaces to which this service is exported. + items: + type: string + type: array + hosts: + description: The hosts associated with the ServiceEntry. + items: + type: string + x-kubernetes-validations: + - message: hostname cannot be wildcard + rule: self != "*" + maxItems: 256 + minItems: 1 + type: array + location: + description: |- + Specify whether the service should be considered external to the mesh or part of the mesh. + + Valid Options: MESH_EXTERNAL, MESH_INTERNAL + enum: + - MESH_EXTERNAL + - MESH_INTERNAL + type: string + ports: + description: The ports associated with the external service. + items: + properties: + name: + description: Label assigned to the port. + maxLength: 256 + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + protocol: + description: The protocol exposed on the port. + maxLength: 256 + type: string + targetPort: + description: The port number on the endpoint where the traffic + will be received. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - number + - name + type: object + maxItems: 256 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: port number cannot be duplicated + rule: self.all(l1, self.exists_one(l2, l1.number == l2.number)) + resolution: + description: |- + Service resolution mode for the hosts. + + Valid Options: NONE, STATIC, DNS, DNS_ROUND_ROBIN + enum: + - NONE + - STATIC + - DNS + - DNS_ROUND_ROBIN + type: string + subjectAltNames: + description: If specified, the proxy will verify that the server certificate's + subject alternate name matches one of the specified values. + items: + type: string + type: array + workloadSelector: + description: Applicable only for MESH_INTERNAL services. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + required: + - hosts + type: object + x-kubernetes-validations: + - message: only one of WorkloadSelector or Endpoints can be set + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' + - message: CIDR addresses are allowed only for NONE/STATIC resolution + types + rule: '!((has(self.addresses) ? self.addresses : []).exists(k, k.contains("/")) + && !((has(self.resolution) ? self.resolution : "NONE") in ["STATIC", + "NONE"]))' + - message: NONE mode cannot set endpoints + rule: '((has(self.resolution) ? self.resolution : "NONE") == "NONE") + ? !has(self.endpoints) : true' + - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints + rule: '((has(self.resolution) ? self.resolution : "") == "DNS_ROUND_ROBIN") + ? ((has(self.endpoints) ? self.endpoints : []).size() <= 1) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The hosts associated with the ServiceEntry + jsonPath: .spec.hosts + name: Hosts + type: string + - description: Whether the service is external to the mesh or part of the mesh + (MESH_EXTERNAL or MESH_INTERNAL) + jsonPath: .spec.location + name: Location + type: string + - description: Service resolution mode for the hosts (NONE, STATIC, or DNS) + jsonPath: .spec.resolution + name: Resolution + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting service registry. See more details + at: https://istio.io/docs/reference/config/networking/service-entry.html' + properties: + addresses: + description: The virtual IP addresses associated with the service. + items: + maxLength: 64 + type: string + maxItems: 256 + type: array + endpoints: + description: One or more endpoints associated with the service. + items: + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) + == "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : + true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + maxItems: 4096 + type: array + exportTo: + description: A list of namespaces to which this service is exported. + items: + type: string + type: array + hosts: + description: The hosts associated with the ServiceEntry. + items: + type: string + x-kubernetes-validations: + - message: hostname cannot be wildcard + rule: self != "*" + maxItems: 256 + minItems: 1 + type: array + location: + description: |- + Specify whether the service should be considered external to the mesh or part of the mesh. + + Valid Options: MESH_EXTERNAL, MESH_INTERNAL + enum: + - MESH_EXTERNAL + - MESH_INTERNAL + type: string + ports: + description: The ports associated with the external service. + items: + properties: + name: + description: Label assigned to the port. + maxLength: 256 + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + protocol: + description: The protocol exposed on the port. + maxLength: 256 + type: string + targetPort: + description: The port number on the endpoint where the traffic + will be received. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - number + - name + type: object + maxItems: 256 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + x-kubernetes-validations: + - message: port number cannot be duplicated + rule: self.all(l1, self.exists_one(l2, l1.number == l2.number)) + resolution: + description: |- + Service resolution mode for the hosts. + + Valid Options: NONE, STATIC, DNS, DNS_ROUND_ROBIN + enum: + - NONE + - STATIC + - DNS + - DNS_ROUND_ROBIN + type: string + subjectAltNames: + description: If specified, the proxy will verify that the server certificate's + subject alternate name matches one of the specified values. + items: + type: string + type: array + workloadSelector: + description: Applicable only for MESH_INTERNAL services. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + required: + - hosts + type: object + x-kubernetes-validations: + - message: only one of WorkloadSelector or Endpoints can be set + rule: '(has(self.workloadSelector) ? 1 : 0) + (has(self.endpoints) ? + 1 : 0) <= 1' + - message: CIDR addresses are allowed only for NONE/STATIC resolution + types + rule: '!((has(self.addresses) ? self.addresses : []).exists(k, k.contains("/")) + && !((has(self.resolution) ? self.resolution : "NONE") in ["STATIC", + "NONE"]))' + - message: NONE mode cannot set endpoints + rule: '((has(self.resolution) ? self.resolution : "NONE") == "NONE") + ? !has(self.endpoints) : true' + - message: DNS_ROUND_ROBIN mode cannot have multiple endpoints + rule: '((has(self.resolution) ? self.resolution : "") == "DNS_ROUND_ROBIN") + ? ((has(self.endpoints) ? self.endpoints : []).size() <= 1) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: sidecars.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: Sidecar + listKind: SidecarList + plural: sidecars + singular: sidecar + scope: Namespaced + versions: + - name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting network reachability of a sidecar. + See more details at: https://istio.io/docs/reference/config/networking/sidecar.html' + properties: + egress: + description: Egress specifies the configuration of the sidecar for + processing outbound traffic from the attached workload instance + to other services in the mesh. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) or the Unix domain socket + to which the listener should be bound to. + type: string + captureMode: + description: |- + When the bind address is an IP, the captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + hosts: + description: One or more service hosts exposed by the listener + in `namespace/dnsName` format. + items: + type: string + type: array + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + required: + - hosts + type: object + type: array + inboundConnectionPool: + description: Settings controlling the volume of connections Envoy + will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection pool + connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams allowed + for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection to + a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections to a + destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket to + enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to send + without response before deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs to be + idle before keep-alive probes start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + ingress: + description: Ingress specifies the configuration of the sidecar for + processing inbound traffic to the attached workload instance. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) to which the listener should + be bound. + type: string + captureMode: + description: |- + The captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + connectionPool: + description: Settings controlling the volume of connections + Envoy will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be + queued while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a + destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be + preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + defaultEndpoint: + description: The IP endpoint or Unix domain socket to which + traffic should be forwarded to. + type: string + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: Set of TLS related options that will enable TLS + termination on the sidecar for requests originating from outside + the mesh. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + type: object + type: array + outboundTrafficPolicy: + description: Set the default behavior of the sidecar for handling + outbound traffic from the application. + properties: + egressProxy: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mode: + description: |2- + + + Valid Options: REGISTRY_ONLY, ALLOW_ANY + enum: + - REGISTRY_ONLY + - ALLOW_ANY + type: string + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `Sidecar` configuration should be applied. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting network reachability of a sidecar. + See more details at: https://istio.io/docs/reference/config/networking/sidecar.html' + properties: + egress: + description: Egress specifies the configuration of the sidecar for + processing outbound traffic from the attached workload instance + to other services in the mesh. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) or the Unix domain socket + to which the listener should be bound to. + type: string + captureMode: + description: |- + When the bind address is an IP, the captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + hosts: + description: One or more service hosts exposed by the listener + in `namespace/dnsName` format. + items: + type: string + type: array + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + required: + - hosts + type: object + type: array + inboundConnectionPool: + description: Settings controlling the volume of connections Envoy + will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection pool + connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams allowed + for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection to + a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections to a + destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket to + enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to send + without response before deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs to be + idle before keep-alive probes start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + ingress: + description: Ingress specifies the configuration of the sidecar for + processing inbound traffic to the attached workload instance. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) to which the listener should + be bound. + type: string + captureMode: + description: |- + The captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + connectionPool: + description: Settings controlling the volume of connections + Envoy will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be + queued while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a + destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be + preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + defaultEndpoint: + description: The IP endpoint or Unix domain socket to which + traffic should be forwarded to. + type: string + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: Set of TLS related options that will enable TLS + termination on the sidecar for requests originating from outside + the mesh. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + type: object + type: array + outboundTrafficPolicy: + description: Set the default behavior of the sidecar for handling + outbound traffic from the application. + properties: + egressProxy: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mode: + description: |2- + + + Valid Options: REGISTRY_ONLY, ALLOW_ANY + enum: + - REGISTRY_ONLY + - ALLOW_ANY + type: string + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `Sidecar` configuration should be applied. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting network reachability of a sidecar. + See more details at: https://istio.io/docs/reference/config/networking/sidecar.html' + properties: + egress: + description: Egress specifies the configuration of the sidecar for + processing outbound traffic from the attached workload instance + to other services in the mesh. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) or the Unix domain socket + to which the listener should be bound to. + type: string + captureMode: + description: |- + When the bind address is an IP, the captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + hosts: + description: One or more service hosts exposed by the listener + in `namespace/dnsName` format. + items: + type: string + type: array + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + required: + - hosts + type: object + type: array + inboundConnectionPool: + description: Settings controlling the volume of connections Envoy + will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be queued + while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection pool + connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams allowed + for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection to + a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be preserved + while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections to a + destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket to + enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes to send + without response before deciding the connection is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs to be + idle before keep-alive probes start being sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + ingress: + description: Ingress specifies the configuration of the sidecar for + processing inbound traffic to the attached workload instance. + items: + properties: + bind: + description: The IP(IPv4 or IPv6) to which the listener should + be bound. + type: string + captureMode: + description: |- + The captureMode option dictates how traffic to the listener is expected to be captured (or not). + + Valid Options: DEFAULT, IPTABLES, NONE + enum: + - DEFAULT + - IPTABLES + - NONE + type: string + connectionPool: + description: Settings controlling the volume of connections + Envoy will accept from the network. + properties: + http: + description: HTTP connection pool settings. + properties: + h2UpgradePolicy: + description: |- + Specify if http1.1 connection should be upgraded to http2 for the associated destination. + + Valid Options: DEFAULT, DO_NOT_UPGRADE, UPGRADE + enum: + - DEFAULT + - DO_NOT_UPGRADE + - UPGRADE + type: string + http1MaxPendingRequests: + description: Maximum number of requests that will be + queued while waiting for a ready connection pool connection. + format: int32 + type: integer + http2MaxRequests: + description: Maximum number of active requests to a + destination. + format: int32 + type: integer + idleTimeout: + description: The idle timeout for upstream connection + pool connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConcurrentStreams: + description: The maximum number of concurrent streams + allowed for a peer on one HTTP/2 connection. + format: int32 + type: integer + maxRequestsPerConnection: + description: Maximum number of requests per connection + to a backend. + format: int32 + type: integer + maxRetries: + description: Maximum number of retries that can be outstanding + to all hosts in a cluster at a given time. + format: int32 + type: integer + useClientProtocol: + description: If set to true, client protocol will be + preserved while initiating connection to backend. + type: boolean + type: object + tcp: + description: Settings common to both HTTP and TCP upstream + connections. + properties: + connectTimeout: + description: TCP connection timeout. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + idleTimeout: + description: The idle timeout for TCP connections. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnectionDuration: + description: The maximum duration of a connection. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + maxConnections: + description: Maximum number of HTTP1 /TCP connections + to a destination host. + format: int32 + type: integer + tcpKeepalive: + description: If set then set SO_KEEPALIVE on the socket + to enable TCP Keepalives. + properties: + interval: + description: The time duration between keep-alive + probes. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + probes: + description: Maximum number of keepalive probes + to send without response before deciding the connection + is dead. + maximum: 4294967295 + minimum: 0 + type: integer + time: + description: The time duration a connection needs + to be idle before keep-alive probes start being + sent. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than + 1ms + rule: duration(self) >= duration('1ms') + type: object + type: object + type: object + defaultEndpoint: + description: The IP endpoint or Unix domain socket to which + traffic should be forwarded to. + type: string + port: + description: The port associated with the listener. + properties: + name: + description: Label assigned to the port. + type: string + number: + description: A valid non-negative integer port number. + maximum: 4294967295 + minimum: 0 + type: integer + protocol: + description: The protocol exposed on the port. + type: string + targetPort: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + tls: + description: Set of TLS related options that will enable TLS + termination on the sidecar for requests originating from outside + the mesh. + properties: + caCertificates: + description: REQUIRED if mode is `MUTUAL` or `OPTIONAL_MUTUAL`. + type: string + caCrl: + description: 'OPTIONAL: The path to the file containing + the certificate revocation list (CRL) to use in verifying + a presented client side certificate.' + type: string + cipherSuites: + description: 'Optional: If specified, only support the specified + cipher list.' + items: + type: string + type: array + credentialName: + description: For gateways running on Kubernetes, the name + of the secret that holds the TLS certs including the CA + certificates. + type: string + httpsRedirect: + description: If set to true, the load balancer will send + a 301 redirect for all http connections, asking the clients + to use HTTPS. + type: boolean + maxProtocolVersion: + description: |- + Optional: Maximum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + minProtocolVersion: + description: |- + Optional: Minimum TLS protocol version. + + Valid Options: TLS_AUTO, TLSV1_0, TLSV1_1, TLSV1_2, TLSV1_3 + enum: + - TLS_AUTO + - TLSV1_0 + - TLSV1_1 + - TLSV1_2 + - TLSV1_3 + type: string + mode: + description: |- + Optional: Indicates whether connections to this port should be secured using TLS. + + Valid Options: PASSTHROUGH, SIMPLE, MUTUAL, AUTO_PASSTHROUGH, ISTIO_MUTUAL, OPTIONAL_MUTUAL + enum: + - PASSTHROUGH + - SIMPLE + - MUTUAL + - AUTO_PASSTHROUGH + - ISTIO_MUTUAL + - OPTIONAL_MUTUAL + type: string + privateKey: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + serverCertificate: + description: REQUIRED if mode is `SIMPLE` or `MUTUAL`. + type: string + subjectAltNames: + description: A list of alternate names to verify the subject + identity in the certificate presented by the client. + items: + type: string + type: array + verifyCertificateHash: + description: An optional list of hex-encoded SHA-256 hashes + of the authorized client certificates. + items: + type: string + type: array + verifyCertificateSpki: + description: An optional list of base64-encoded SHA-256 + hashes of the SPKIs of authorized client certificates. + items: + type: string + type: array + type: object + required: + - port + type: object + type: array + outboundTrafficPolicy: + description: Set the default behavior of the sidecar for handling + outbound traffic from the application. + properties: + egressProxy: + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mode: + description: |2- + + + Valid Options: REGISTRY_ONLY, ALLOW_ANY + enum: + - REGISTRY_ONLY + - ALLOW_ANY + type: string + type: object + workloadSelector: + description: Criteria used to select the specific set of pods/VMs + on which this `Sidecar` configuration should be applied. + properties: + labels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard is not supported in selector + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which the configuration should be applied. + maxProperties: 256 + type: object + type: object + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: telemetries.telemetry.istio.io +spec: + group: telemetry.istio.io + names: + categories: + - istio-io + - telemetry-istio-io + kind: Telemetry + listKind: TelemetryList + plural: telemetries + shortNames: + - telemetry + singular: telemetry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Telemetry configuration for workloads. See more details + at: https://istio.io/docs/reference/config/telemetry.html' + properties: + accessLogging: + description: Optional. + items: + properties: + disabled: + description: Controls logging. + nullable: true + type: boolean + filter: + description: Optional. + properties: + expression: + description: CEL expression for selecting when requests/connections + should be logged. + type: string + type: object + match: + description: Allows tailoring of logging behavior to specific + conditions. + properties: + mode: + description: |- + This determines whether or not to apply the access logging configuration based on the direction of traffic relative to the proxied workload. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + type: object + type: array + metrics: + description: Optional. + items: + properties: + overrides: + description: Optional. + items: + properties: + disabled: + description: Optional. + nullable: true + type: boolean + match: + description: Match allows providing the scope of the override. + oneOf: + - not: + anyOf: + - required: + - metric + - required: + - customMetric + - required: + - metric + - required: + - customMetric + properties: + customMetric: + description: Allows free-form specification of a metric. + minLength: 1 + type: string + metric: + description: |- + One of the well-known [Istio Standard Metrics](https://istio.io/latest/docs/reference/config/metrics/). + + Valid Options: ALL_METRICS, REQUEST_COUNT, REQUEST_DURATION, REQUEST_SIZE, RESPONSE_SIZE, TCP_OPENED_CONNECTIONS, TCP_CLOSED_CONNECTIONS, TCP_SENT_BYTES, TCP_RECEIVED_BYTES, GRPC_REQUEST_MESSAGES, GRPC_RESPONSE_MESSAGES + enum: + - ALL_METRICS + - REQUEST_COUNT + - REQUEST_DURATION + - REQUEST_SIZE + - RESPONSE_SIZE + - TCP_OPENED_CONNECTIONS + - TCP_CLOSED_CONNECTIONS + - TCP_SENT_BYTES + - TCP_RECEIVED_BYTES + - GRPC_REQUEST_MESSAGES + - GRPC_RESPONSE_MESSAGES + type: string + mode: + description: |- + Controls which mode of metrics generation is selected: `CLIENT`, `SERVER`, or `CLIENT_AND_SERVER`. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + tagOverrides: + additionalProperties: + properties: + operation: + description: |- + Operation controls whether or not to update/add a tag, or to remove it. + + Valid Options: UPSERT, REMOVE + enum: + - UPSERT + - REMOVE + type: string + value: + description: Value is only considered if the operation + is `UPSERT`. + type: string + type: object + x-kubernetes-validations: + - message: value must be set when operation is UPSERT + rule: '((has(self.operation) ? self.operation : "") + == "UPSERT") ? (self.value != "") : true' + - message: value must not be set when operation is REMOVE + rule: '((has(self.operation) ? self.operation : "") + == "REMOVE") ? !has(self.value) : true' + description: Optional. + type: object + type: object + type: array + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + reportingInterval: + description: Optional. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + tracing: + description: Optional. + items: + properties: + customTags: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - literal + - required: + - environment + - required: + - header + - required: + - literal + - required: + - environment + - required: + - header + properties: + environment: + description: Environment adds the value of an environment + variable to each span. + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the environment variable from + which to extract the tag value. + minLength: 1 + type: string + required: + - name + type: object + header: + description: RequestHeader adds the value of an header + from the request to each span. + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the header from which to extract + the tag value. + minLength: 1 + type: string + required: + - name + type: object + literal: + description: Literal adds the same, hard-coded value to + each span. + properties: + value: + description: The tag value to use. + minLength: 1 + type: string + required: + - value + type: object + type: object + description: Optional. + type: object + disableSpanReporting: + description: Controls span reporting. + nullable: true + type: boolean + enableIstioTags: + description: Determines whether or not trace spans generated + by Envoy will include Istio specific tags. + nullable: true + type: boolean + match: + description: Allows tailoring of behavior to specific conditions. + properties: + mode: + description: |- + This determines whether or not to apply the tracing configuration based on the direction of traffic relative to the proxied workload. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + randomSamplingPercentage: + description: Controls the rate at which traffic will be selected + for tracing if no prior sampling decision has been made. + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + useRequestIdForTraceSampling: + nullable: true + type: boolean + type: object + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Telemetry configuration for workloads. See more details + at: https://istio.io/docs/reference/config/telemetry.html' + properties: + accessLogging: + description: Optional. + items: + properties: + disabled: + description: Controls logging. + nullable: true + type: boolean + filter: + description: Optional. + properties: + expression: + description: CEL expression for selecting when requests/connections + should be logged. + type: string + type: object + match: + description: Allows tailoring of logging behavior to specific + conditions. + properties: + mode: + description: |- + This determines whether or not to apply the access logging configuration based on the direction of traffic relative to the proxied workload. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + type: object + type: array + metrics: + description: Optional. + items: + properties: + overrides: + description: Optional. + items: + properties: + disabled: + description: Optional. + nullable: true + type: boolean + match: + description: Match allows providing the scope of the override. + oneOf: + - not: + anyOf: + - required: + - metric + - required: + - customMetric + - required: + - metric + - required: + - customMetric + properties: + customMetric: + description: Allows free-form specification of a metric. + minLength: 1 + type: string + metric: + description: |- + One of the well-known [Istio Standard Metrics](https://istio.io/latest/docs/reference/config/metrics/). + + Valid Options: ALL_METRICS, REQUEST_COUNT, REQUEST_DURATION, REQUEST_SIZE, RESPONSE_SIZE, TCP_OPENED_CONNECTIONS, TCP_CLOSED_CONNECTIONS, TCP_SENT_BYTES, TCP_RECEIVED_BYTES, GRPC_REQUEST_MESSAGES, GRPC_RESPONSE_MESSAGES + enum: + - ALL_METRICS + - REQUEST_COUNT + - REQUEST_DURATION + - REQUEST_SIZE + - RESPONSE_SIZE + - TCP_OPENED_CONNECTIONS + - TCP_CLOSED_CONNECTIONS + - TCP_SENT_BYTES + - TCP_RECEIVED_BYTES + - GRPC_REQUEST_MESSAGES + - GRPC_RESPONSE_MESSAGES + type: string + mode: + description: |- + Controls which mode of metrics generation is selected: `CLIENT`, `SERVER`, or `CLIENT_AND_SERVER`. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + tagOverrides: + additionalProperties: + properties: + operation: + description: |- + Operation controls whether or not to update/add a tag, or to remove it. + + Valid Options: UPSERT, REMOVE + enum: + - UPSERT + - REMOVE + type: string + value: + description: Value is only considered if the operation + is `UPSERT`. + type: string + type: object + x-kubernetes-validations: + - message: value must be set when operation is UPSERT + rule: '((has(self.operation) ? self.operation : "") + == "UPSERT") ? (self.value != "") : true' + - message: value must not be set when operation is REMOVE + rule: '((has(self.operation) ? self.operation : "") + == "REMOVE") ? !has(self.value) : true' + description: Optional. + type: object + type: object + type: array + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + reportingInterval: + description: Optional. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: array + selector: + description: Optional. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + tracing: + description: Optional. + items: + properties: + customTags: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - literal + - required: + - environment + - required: + - header + - required: + - literal + - required: + - environment + - required: + - header + properties: + environment: + description: Environment adds the value of an environment + variable to each span. + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the environment variable from + which to extract the tag value. + minLength: 1 + type: string + required: + - name + type: object + header: + description: RequestHeader adds the value of an header + from the request to each span. + properties: + defaultValue: + description: Optional. + type: string + name: + description: Name of the header from which to extract + the tag value. + minLength: 1 + type: string + required: + - name + type: object + literal: + description: Literal adds the same, hard-coded value to + each span. + properties: + value: + description: The tag value to use. + minLength: 1 + type: string + required: + - value + type: object + type: object + description: Optional. + type: object + disableSpanReporting: + description: Controls span reporting. + nullable: true + type: boolean + enableIstioTags: + description: Determines whether or not trace spans generated + by Envoy will include Istio specific tags. + nullable: true + type: boolean + match: + description: Allows tailoring of behavior to specific conditions. + properties: + mode: + description: |- + This determines whether or not to apply the tracing configuration based on the direction of traffic relative to the proxied workload. + + Valid Options: CLIENT_AND_SERVER, CLIENT, SERVER + enum: + - CLIENT_AND_SERVER + - CLIENT + - SERVER + type: string + type: object + providers: + description: Optional. + items: + properties: + name: + description: Required. + minLength: 1 + type: string + required: + - name + type: object + type: array + randomSamplingPercentage: + description: Controls the rate at which traffic will be selected + for tracing if no prior sampling decision has been made. + format: double + maximum: 100 + minimum: 0 + nullable: true + type: number + useRequestIdForTraceSampling: + nullable: true + type: boolean + type: object + type: array + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: virtualservices.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: VirtualService + listKind: VirtualServiceList + plural: virtualservices + shortNames: + - vs + singular: virtualservice + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: The names of gateways and sidecars that should apply these routes + jsonPath: .spec.gateways + name: Gateways + type: string + - description: The destination hosts to which traffic is being sent + jsonPath: .spec.hosts + name: Hosts + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting label/content routing, sni routing, + etc. See more details at: https://istio.io/docs/reference/config/networking/virtual-service.html' + properties: + exportTo: + description: A list of namespaces to which this virtual service is + exported. + items: + type: string + type: array + gateways: + description: The names of gateways and sidecars that should apply + these routes. + items: + type: string + type: array + hosts: + description: The destination hosts to which traffic is being sent. + items: + type: string + type: array + http: + description: An ordered list of route rules for HTTP traffic. + items: + properties: + corsPolicy: + description: Cross-Origin Resource Sharing policy (CORS). + properties: + allowCredentials: + description: Indicates whether the caller is allowed to + send the actual request (not the preflight) using credentials. + nullable: true + type: boolean + allowHeaders: + description: List of HTTP headers that can be used when + requesting the resource. + items: + type: string + type: array + allowMethods: + description: List of HTTP methods allowed to access the + resource. + items: + type: string + type: array + allowOrigin: + items: + type: string + type: array + allowOrigins: + description: String patterns that match allowed origins. + items: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + type: array + exposeHeaders: + description: A list of HTTP headers that the browsers are + allowed to access. + items: + type: string + type: array + maxAge: + description: Specifies how long the results of a preflight + request can be cached. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + unmatchedPreflights: + description: |- + Indicates whether preflight requests not matching the configured allowed origin shouldn't be forwarded to the upstream. + + Valid Options: FORWARD, IGNORE + enum: + - UNSPECIFIED + - FORWARD + - IGNORE + type: string + type: object + delegate: + description: Delegate is used to specify the particular VirtualService + which can be used to define delegate HTTPRoute. + properties: + name: + description: Name specifies the name of the delegate VirtualService. + type: string + namespace: + description: Namespace specifies the namespace where the + delegate VirtualService resides. + type: string + type: object + directResponse: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + properties: + body: + description: Specifies the content of the response body. + oneOf: + - not: + anyOf: + - required: + - string + - required: + - bytes + - required: + - string + - required: + - bytes + properties: + bytes: + description: response body as base64 encoded bytes. + format: binary + type: string + string: + type: string + type: object + status: + description: Specifies the HTTP response status to be returned. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - status + type: object + fault: + description: Fault injection policy to apply on HTTP traffic + at the client side. + properties: + abort: + description: Abort Http request attempts and return error + codes back to downstream service, giving the impression + that the upstream service is faulty. + oneOf: + - not: + anyOf: + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + properties: + grpcStatus: + description: GRPC status code to use to abort the request. + type: string + http2Error: + type: string + httpStatus: + description: HTTP status code to use to abort the Http + request. + format: int32 + type: integer + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + format: double + type: number + type: object + type: object + delay: + description: Delay requests before forwarding, emulating + various failures such as network issues, overloaded upstream + service, etc. + oneOf: + - not: + anyOf: + - required: + - fixedDelay + - required: + - exponentialDelay + - required: + - fixedDelay + - required: + - exponentialDelay + properties: + exponentialDelay: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + fixedDelay: + description: Add a fixed delay before forwarding the + request. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + percent: + description: Percentage of requests on which the delay + will be injected (0-100). + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + format: double + type: number + type: object + type: object + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + authority: + description: 'HTTP Authority values are case-sensitive + and formatted as follows: - `exact: "value"` for exact + string match - `prefix: "value"` for prefix-based match + - `regex: "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + headers: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: The header keys must be lowercase and use + hyphen as the separator, e.g. + type: object + ignoreUriCase: + description: Flag to specify whether the URI matching + should be case-insensitive. + type: boolean + method: + description: 'HTTP Method values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + name: + description: The name assigned to a match. + type: string + port: + description: Specifies the ports on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + queryParams: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: Query parameters for matching. + type: object + scheme: + description: 'URI Scheme values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to source (client) workloads with the given + labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + statPrefix: + description: The human readable prefix to use when emitting + statistics for this route. + type: string + uri: + description: 'URI to match values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + withoutHeaders: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: withoutHeader has the same syntax with the + header, but has opposite meaning. + type: object + type: object + type: array + mirror: + description: Mirror HTTP traffic to a another destination in + addition to forwarding the requests to the intended destination. + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mirror_percent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercentage: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + properties: + value: + format: double + type: number + type: object + mirrors: + description: Specifies the destinations to mirror HTTP traffic + in addition to the original destination. + items: + properties: + destination: + description: Destination specifies the target of the mirror + operation. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + percentage: + description: Percentage of the traffic to be mirrored + by the `destination` field. + properties: + value: + format: double + type: number + type: object + required: + - destination + type: object + type: array + name: + description: The name assigned to the route for debugging purposes. + type: string + redirect: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + oneOf: + - not: + anyOf: + - required: + - port + - required: + - derivePort + - required: + - port + - required: + - derivePort + properties: + authority: + description: On a redirect, overwrite the Authority/Host + portion of the URL with this value. + type: string + derivePort: + description: |- + On a redirect, dynamically set the port: * FROM_PROTOCOL_DEFAULT: automatically set to 80 for HTTP and 443 for HTTPS. + + Valid Options: FROM_PROTOCOL_DEFAULT, FROM_REQUEST_PORT + enum: + - FROM_PROTOCOL_DEFAULT + - FROM_REQUEST_PORT + type: string + port: + description: On a redirect, overwrite the port portion of + the URL with this value. + maximum: 4294967295 + minimum: 0 + type: integer + redirectCode: + description: On a redirect, Specifies the HTTP status code + to use in the redirect response. + maximum: 4294967295 + minimum: 0 + type: integer + scheme: + description: On a redirect, overwrite the scheme portion + of the URL with this value. + type: string + uri: + description: On a redirect, overwrite the Path portion of + the URL with this value. + type: string + type: object + retries: + description: Retry policy for HTTP requests. + properties: + attempts: + description: Number of retries to be allowed for a given + request. + format: int32 + type: integer + perTryTimeout: + description: Timeout per attempt for a given request, including + the initial call and any retries. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + retryIgnorePreviousHosts: + description: Flag to specify whether the retries should + ignore previously tried hosts during retry. + nullable: true + type: boolean + retryOn: + description: Specifies the conditions under which retry + takes place. + type: string + retryRemoteLocalities: + description: Flag to specify whether the retries should + retry to other localities. + nullable: true + type: boolean + type: object + rewrite: + description: Rewrite HTTP URIs and Authority headers. + properties: + authority: + description: rewrite the Authority/Host header with this + value. + type: string + uri: + description: rewrite the path (or the prefix) portion of + the URI with this value. + type: string + uriRegexRewrite: + description: rewrite the path portion of the URI with the + specified regex. + properties: + match: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + rewrite: + description: The string that should replace into matching + portions of original URI. + type: string + type: object + type: object + route: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + timeout: + description: Timeout for HTTP requests, default is disabled. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: array + tcp: + description: An ordered list of route rules for opaque TCP traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + sourceSubnet: + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + type: object + type: array + tls: + description: An ordered list of route rule for non-terminated TLS + & HTTPS traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sniHosts: + description: SNI (server name indicator) to match on. + items: + type: string + type: array + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + required: + - sniHosts + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + required: + - match + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The names of gateways and sidecars that should apply these routes + jsonPath: .spec.gateways + name: Gateways + type: string + - description: The destination hosts to which traffic is being sent + jsonPath: .spec.hosts + name: Hosts + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting label/content routing, sni routing, + etc. See more details at: https://istio.io/docs/reference/config/networking/virtual-service.html' + properties: + exportTo: + description: A list of namespaces to which this virtual service is + exported. + items: + type: string + type: array + gateways: + description: The names of gateways and sidecars that should apply + these routes. + items: + type: string + type: array + hosts: + description: The destination hosts to which traffic is being sent. + items: + type: string + type: array + http: + description: An ordered list of route rules for HTTP traffic. + items: + properties: + corsPolicy: + description: Cross-Origin Resource Sharing policy (CORS). + properties: + allowCredentials: + description: Indicates whether the caller is allowed to + send the actual request (not the preflight) using credentials. + nullable: true + type: boolean + allowHeaders: + description: List of HTTP headers that can be used when + requesting the resource. + items: + type: string + type: array + allowMethods: + description: List of HTTP methods allowed to access the + resource. + items: + type: string + type: array + allowOrigin: + items: + type: string + type: array + allowOrigins: + description: String patterns that match allowed origins. + items: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + type: array + exposeHeaders: + description: A list of HTTP headers that the browsers are + allowed to access. + items: + type: string + type: array + maxAge: + description: Specifies how long the results of a preflight + request can be cached. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + unmatchedPreflights: + description: |- + Indicates whether preflight requests not matching the configured allowed origin shouldn't be forwarded to the upstream. + + Valid Options: FORWARD, IGNORE + enum: + - UNSPECIFIED + - FORWARD + - IGNORE + type: string + type: object + delegate: + description: Delegate is used to specify the particular VirtualService + which can be used to define delegate HTTPRoute. + properties: + name: + description: Name specifies the name of the delegate VirtualService. + type: string + namespace: + description: Namespace specifies the namespace where the + delegate VirtualService resides. + type: string + type: object + directResponse: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + properties: + body: + description: Specifies the content of the response body. + oneOf: + - not: + anyOf: + - required: + - string + - required: + - bytes + - required: + - string + - required: + - bytes + properties: + bytes: + description: response body as base64 encoded bytes. + format: binary + type: string + string: + type: string + type: object + status: + description: Specifies the HTTP response status to be returned. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - status + type: object + fault: + description: Fault injection policy to apply on HTTP traffic + at the client side. + properties: + abort: + description: Abort Http request attempts and return error + codes back to downstream service, giving the impression + that the upstream service is faulty. + oneOf: + - not: + anyOf: + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + properties: + grpcStatus: + description: GRPC status code to use to abort the request. + type: string + http2Error: + type: string + httpStatus: + description: HTTP status code to use to abort the Http + request. + format: int32 + type: integer + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + format: double + type: number + type: object + type: object + delay: + description: Delay requests before forwarding, emulating + various failures such as network issues, overloaded upstream + service, etc. + oneOf: + - not: + anyOf: + - required: + - fixedDelay + - required: + - exponentialDelay + - required: + - fixedDelay + - required: + - exponentialDelay + properties: + exponentialDelay: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + fixedDelay: + description: Add a fixed delay before forwarding the + request. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + percent: + description: Percentage of requests on which the delay + will be injected (0-100). + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + format: double + type: number + type: object + type: object + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + authority: + description: 'HTTP Authority values are case-sensitive + and formatted as follows: - `exact: "value"` for exact + string match - `prefix: "value"` for prefix-based match + - `regex: "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + headers: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: The header keys must be lowercase and use + hyphen as the separator, e.g. + type: object + ignoreUriCase: + description: Flag to specify whether the URI matching + should be case-insensitive. + type: boolean + method: + description: 'HTTP Method values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + name: + description: The name assigned to a match. + type: string + port: + description: Specifies the ports on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + queryParams: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: Query parameters for matching. + type: object + scheme: + description: 'URI Scheme values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to source (client) workloads with the given + labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + statPrefix: + description: The human readable prefix to use when emitting + statistics for this route. + type: string + uri: + description: 'URI to match values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + withoutHeaders: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: withoutHeader has the same syntax with the + header, but has opposite meaning. + type: object + type: object + type: array + mirror: + description: Mirror HTTP traffic to a another destination in + addition to forwarding the requests to the intended destination. + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mirror_percent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercentage: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + properties: + value: + format: double + type: number + type: object + mirrors: + description: Specifies the destinations to mirror HTTP traffic + in addition to the original destination. + items: + properties: + destination: + description: Destination specifies the target of the mirror + operation. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + percentage: + description: Percentage of the traffic to be mirrored + by the `destination` field. + properties: + value: + format: double + type: number + type: object + required: + - destination + type: object + type: array + name: + description: The name assigned to the route for debugging purposes. + type: string + redirect: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + oneOf: + - not: + anyOf: + - required: + - port + - required: + - derivePort + - required: + - port + - required: + - derivePort + properties: + authority: + description: On a redirect, overwrite the Authority/Host + portion of the URL with this value. + type: string + derivePort: + description: |- + On a redirect, dynamically set the port: * FROM_PROTOCOL_DEFAULT: automatically set to 80 for HTTP and 443 for HTTPS. + + Valid Options: FROM_PROTOCOL_DEFAULT, FROM_REQUEST_PORT + enum: + - FROM_PROTOCOL_DEFAULT + - FROM_REQUEST_PORT + type: string + port: + description: On a redirect, overwrite the port portion of + the URL with this value. + maximum: 4294967295 + minimum: 0 + type: integer + redirectCode: + description: On a redirect, Specifies the HTTP status code + to use in the redirect response. + maximum: 4294967295 + minimum: 0 + type: integer + scheme: + description: On a redirect, overwrite the scheme portion + of the URL with this value. + type: string + uri: + description: On a redirect, overwrite the Path portion of + the URL with this value. + type: string + type: object + retries: + description: Retry policy for HTTP requests. + properties: + attempts: + description: Number of retries to be allowed for a given + request. + format: int32 + type: integer + perTryTimeout: + description: Timeout per attempt for a given request, including + the initial call and any retries. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + retryIgnorePreviousHosts: + description: Flag to specify whether the retries should + ignore previously tried hosts during retry. + nullable: true + type: boolean + retryOn: + description: Specifies the conditions under which retry + takes place. + type: string + retryRemoteLocalities: + description: Flag to specify whether the retries should + retry to other localities. + nullable: true + type: boolean + type: object + rewrite: + description: Rewrite HTTP URIs and Authority headers. + properties: + authority: + description: rewrite the Authority/Host header with this + value. + type: string + uri: + description: rewrite the path (or the prefix) portion of + the URI with this value. + type: string + uriRegexRewrite: + description: rewrite the path portion of the URI with the + specified regex. + properties: + match: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + rewrite: + description: The string that should replace into matching + portions of original URI. + type: string + type: object + type: object + route: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + timeout: + description: Timeout for HTTP requests, default is disabled. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: array + tcp: + description: An ordered list of route rules for opaque TCP traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + sourceSubnet: + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + type: object + type: array + tls: + description: An ordered list of route rule for non-terminated TLS + & HTTPS traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sniHosts: + description: SNI (server name indicator) to match on. + items: + type: string + type: array + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + required: + - sniHosts + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + required: + - match + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: The names of gateways and sidecars that should apply these routes + jsonPath: .spec.gateways + name: Gateways + type: string + - description: The destination hosts to which traffic is being sent + jsonPath: .spec.hosts + name: Hosts + type: string + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting label/content routing, sni routing, + etc. See more details at: https://istio.io/docs/reference/config/networking/virtual-service.html' + properties: + exportTo: + description: A list of namespaces to which this virtual service is + exported. + items: + type: string + type: array + gateways: + description: The names of gateways and sidecars that should apply + these routes. + items: + type: string + type: array + hosts: + description: The destination hosts to which traffic is being sent. + items: + type: string + type: array + http: + description: An ordered list of route rules for HTTP traffic. + items: + properties: + corsPolicy: + description: Cross-Origin Resource Sharing policy (CORS). + properties: + allowCredentials: + description: Indicates whether the caller is allowed to + send the actual request (not the preflight) using credentials. + nullable: true + type: boolean + allowHeaders: + description: List of HTTP headers that can be used when + requesting the resource. + items: + type: string + type: array + allowMethods: + description: List of HTTP methods allowed to access the + resource. + items: + type: string + type: array + allowOrigin: + items: + type: string + type: array + allowOrigins: + description: String patterns that match allowed origins. + items: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + type: array + exposeHeaders: + description: A list of HTTP headers that the browsers are + allowed to access. + items: + type: string + type: array + maxAge: + description: Specifies how long the results of a preflight + request can be cached. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + unmatchedPreflights: + description: |- + Indicates whether preflight requests not matching the configured allowed origin shouldn't be forwarded to the upstream. + + Valid Options: FORWARD, IGNORE + enum: + - UNSPECIFIED + - FORWARD + - IGNORE + type: string + type: object + delegate: + description: Delegate is used to specify the particular VirtualService + which can be used to define delegate HTTPRoute. + properties: + name: + description: Name specifies the name of the delegate VirtualService. + type: string + namespace: + description: Namespace specifies the namespace where the + delegate VirtualService resides. + type: string + type: object + directResponse: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + properties: + body: + description: Specifies the content of the response body. + oneOf: + - not: + anyOf: + - required: + - string + - required: + - bytes + - required: + - string + - required: + - bytes + properties: + bytes: + description: response body as base64 encoded bytes. + format: binary + type: string + string: + type: string + type: object + status: + description: Specifies the HTTP response status to be returned. + maximum: 4294967295 + minimum: 0 + type: integer + required: + - status + type: object + fault: + description: Fault injection policy to apply on HTTP traffic + at the client side. + properties: + abort: + description: Abort Http request attempts and return error + codes back to downstream service, giving the impression + that the upstream service is faulty. + oneOf: + - not: + anyOf: + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + - required: + - httpStatus + - required: + - grpcStatus + - required: + - http2Error + properties: + grpcStatus: + description: GRPC status code to use to abort the request. + type: string + http2Error: + type: string + httpStatus: + description: HTTP status code to use to abort the Http + request. + format: int32 + type: integer + percentage: + description: Percentage of requests to be aborted with + the error code provided. + properties: + value: + format: double + type: number + type: object + type: object + delay: + description: Delay requests before forwarding, emulating + various failures such as network issues, overloaded upstream + service, etc. + oneOf: + - not: + anyOf: + - required: + - fixedDelay + - required: + - exponentialDelay + - required: + - fixedDelay + - required: + - exponentialDelay + properties: + exponentialDelay: + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + fixedDelay: + description: Add a fixed delay before forwarding the + request. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + percent: + description: Percentage of requests on which the delay + will be injected (0-100). + format: int32 + type: integer + percentage: + description: Percentage of requests on which the delay + will be injected. + properties: + value: + format: double + type: number + type: object + type: object + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + authority: + description: 'HTTP Authority values are case-sensitive + and formatted as follows: - `exact: "value"` for exact + string match - `prefix: "value"` for prefix-based match + - `regex: "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + headers: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: The header keys must be lowercase and use + hyphen as the separator, e.g. + type: object + ignoreUriCase: + description: Flag to specify whether the URI matching + should be case-insensitive. + type: boolean + method: + description: 'HTTP Method values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + name: + description: The name assigned to a match. + type: string + port: + description: Specifies the ports on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + queryParams: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: Query parameters for matching. + type: object + scheme: + description: 'URI Scheme values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to source (client) workloads with the given + labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + statPrefix: + description: The human readable prefix to use when emitting + statistics for this route. + type: string + uri: + description: 'URI to match values are case-sensitive and + formatted as follows: - `exact: "value"` for exact string + match - `prefix: "value"` for prefix-based match - `regex: + "value"` for [RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + withoutHeaders: + additionalProperties: + oneOf: + - not: + anyOf: + - required: + - exact + - required: + - prefix + - required: + - regex + - required: + - exact + - required: + - prefix + - required: + - regex + properties: + exact: + type: string + prefix: + type: string + regex: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + type: object + description: withoutHeader has the same syntax with the + header, but has opposite meaning. + type: object + type: object + type: array + mirror: + description: Mirror HTTP traffic to a another destination in + addition to forwarding the requests to the intended destination. + properties: + host: + description: The name of a service from the service registry. + type: string + port: + description: Specifies the port on the host that is being + addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + mirror_percent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercent: + maximum: 4294967295 + minimum: 0 + nullable: true + type: integer + mirrorPercentage: + description: Percentage of the traffic to be mirrored by the + `mirror` field. + properties: + value: + format: double + type: number + type: object + mirrors: + description: Specifies the destinations to mirror HTTP traffic + in addition to the original destination. + items: + properties: + destination: + description: Destination specifies the target of the mirror + operation. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + percentage: + description: Percentage of the traffic to be mirrored + by the `destination` field. + properties: + value: + format: double + type: number + type: object + required: + - destination + type: object + type: array + name: + description: The name assigned to the route for debugging purposes. + type: string + redirect: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + oneOf: + - not: + anyOf: + - required: + - port + - required: + - derivePort + - required: + - port + - required: + - derivePort + properties: + authority: + description: On a redirect, overwrite the Authority/Host + portion of the URL with this value. + type: string + derivePort: + description: |- + On a redirect, dynamically set the port: * FROM_PROTOCOL_DEFAULT: automatically set to 80 for HTTP and 443 for HTTPS. + + Valid Options: FROM_PROTOCOL_DEFAULT, FROM_REQUEST_PORT + enum: + - FROM_PROTOCOL_DEFAULT + - FROM_REQUEST_PORT + type: string + port: + description: On a redirect, overwrite the port portion of + the URL with this value. + maximum: 4294967295 + minimum: 0 + type: integer + redirectCode: + description: On a redirect, Specifies the HTTP status code + to use in the redirect response. + maximum: 4294967295 + minimum: 0 + type: integer + scheme: + description: On a redirect, overwrite the scheme portion + of the URL with this value. + type: string + uri: + description: On a redirect, overwrite the Path portion of + the URL with this value. + type: string + type: object + retries: + description: Retry policy for HTTP requests. + properties: + attempts: + description: Number of retries to be allowed for a given + request. + format: int32 + type: integer + perTryTimeout: + description: Timeout per attempt for a given request, including + the initial call and any retries. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + retryIgnorePreviousHosts: + description: Flag to specify whether the retries should + ignore previously tried hosts during retry. + nullable: true + type: boolean + retryOn: + description: Specifies the conditions under which retry + takes place. + type: string + retryRemoteLocalities: + description: Flag to specify whether the retries should + retry to other localities. + nullable: true + type: boolean + type: object + rewrite: + description: Rewrite HTTP URIs and Authority headers. + properties: + authority: + description: rewrite the Authority/Host header with this + value. + type: string + uri: + description: rewrite the path (or the prefix) portion of + the URI with this value. + type: string + uriRegexRewrite: + description: rewrite the path portion of the URI with the + specified regex. + properties: + match: + description: '[RE2 style regex-based match](https://github.com/google/re2/wiki/Syntax).' + type: string + rewrite: + description: The string that should replace into matching + portions of original URI. + type: string + type: object + type: object + route: + description: A HTTP rule can either return a direct_response, + redirect or forward (default) traffic. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + headers: + properties: + request: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + response: + properties: + add: + additionalProperties: + type: string + type: object + remove: + items: + type: string + type: array + set: + additionalProperties: + type: string + type: object + type: object + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + timeout: + description: Timeout for HTTP requests, default is disabled. + type: string + x-kubernetes-validations: + - message: must be a valid duration greater than 1ms + rule: duration(self) >= duration('1ms') + type: object + type: array + tcp: + description: An ordered list of route rules for opaque TCP traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + sourceSubnet: + type: string + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + type: object + type: array + tls: + description: An ordered list of route rule for non-terminated TLS + & HTTPS traffic. + items: + properties: + match: + description: Match conditions to be satisfied for the rule to + be activated. + items: + properties: + destinationSubnets: + description: IPv4 or IPv6 ip addresses of destination + with optional subnet. + items: + type: string + type: array + gateways: + description: Names of gateways where the rule should be + applied. + items: + type: string + type: array + port: + description: Specifies the port on the host that is being + addressed. + maximum: 4294967295 + minimum: 0 + type: integer + sniHosts: + description: SNI (server name indicator) to match on. + items: + type: string + type: array + sourceLabels: + additionalProperties: + type: string + description: One or more labels that constrain the applicability + of a rule to workloads with the given labels. + type: object + sourceNamespace: + description: Source namespace constraining the applicability + of a rule to workloads in that namespace. + type: string + required: + - sniHosts + type: object + type: array + route: + description: The destination to which the connection should + be forwarded to. + items: + properties: + destination: + description: Destination uniquely identifies the instances + of a service to which the request/connection should + be forwarded to. + properties: + host: + description: The name of a service from the service + registry. + type: string + port: + description: Specifies the port on the host that is + being addressed. + properties: + number: + maximum: 4294967295 + minimum: 0 + type: integer + type: object + subset: + description: The name of a subset within the service. + type: string + required: + - host + type: object + weight: + description: Weight specifies the relative proportion + of traffic to be forwarded to the destination. + format: int32 + type: integer + required: + - destination + type: object + type: array + required: + - match + type: object + type: array + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: wasmplugins.extensions.istio.io +spec: + group: extensions.istio.io + names: + categories: + - istio-io + - extensions-istio-io + kind: WasmPlugin + listKind: WasmPluginList + plural: wasmplugins + singular: wasmplugin + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Extend the functionality provided by the Istio proxy through + WebAssembly filters. See more details at: https://istio.io/docs/reference/config/proxy_extensions/wasm-plugin.html' + properties: + failStrategy: + description: |- + Specifies the failure behavior for the plugin due to fatal errors. + + Valid Options: FAIL_CLOSE, FAIL_OPEN + enum: + - FAIL_CLOSE + - FAIL_OPEN + type: string + imagePullPolicy: + description: |- + The pull behaviour to be applied when fetching Wasm module by either OCI image or `http/https`. + + Valid Options: IfNotPresent, Always + enum: + - UNSPECIFIED_POLICY + - IfNotPresent + - Always + type: string + imagePullSecret: + description: Credentials to use for OCI image pulling. + maxLength: 253 + minLength: 1 + type: string + match: + description: Specifies the criteria to determine which traffic is + passed to WasmPlugin. + items: + properties: + mode: + description: |- + Criteria for selecting traffic by their direction. + + Valid Options: CLIENT, SERVER, CLIENT_AND_SERVER + enum: + - UNDEFINED + - CLIENT + - SERVER + - CLIENT_AND_SERVER + type: string + ports: + description: Criteria for selecting traffic by their destination + port. + items: + properties: + number: + maximum: 65535 + minimum: 1 + type: integer + required: + - number + type: object + type: array + x-kubernetes-list-map-keys: + - number + x-kubernetes-list-type: map + type: object + type: array + phase: + description: |- + Determines where in the filter chain this `WasmPlugin` is to be injected. + + Valid Options: AUTHN, AUTHZ, STATS + enum: + - UNSPECIFIED_PHASE + - AUTHN + - AUTHZ + - STATS + type: string + pluginConfig: + description: The configuration that will be passed on to the plugin. + type: object + x-kubernetes-preserve-unknown-fields: true + pluginName: + description: The plugin name to be used in the Envoy configuration + (used to be called `rootID`). + maxLength: 256 + minLength: 1 + type: string + priority: + description: Determines ordering of `WasmPlugins` in the same `phase`. + format: int32 + nullable: true + type: integer + selector: + description: Criteria used to select the specific set of pods/VMs + on which this plugin configuration should be applied. + properties: + matchLabels: + additionalProperties: + maxLength: 63 + type: string + x-kubernetes-validations: + - message: wildcard not allowed in label value match + rule: '!self.contains("*")' + description: One or more labels that indicate a specific set of + pods/VMs on which a policy should be applied. + maxProperties: 4096 + type: object + x-kubernetes-validations: + - message: wildcard not allowed in label key match + rule: self.all(key, !key.contains("*")) + - message: key must not be empty + rule: self.all(key, key.size() != 0) + type: object + sha256: + description: SHA256 checksum that will be used to verify Wasm module + or OCI container. + pattern: (^$|^[a-f0-9]{64}$) + type: string + targetRef: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + targetRefs: + description: Optional. + items: + properties: + group: + description: group is the group of the target resource. + maxLength: 253 + pattern: ^$|^[a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*$ + type: string + kind: + description: kind is kind of the target resource. + maxLength: 63 + minLength: 1 + pattern: ^[a-zA-Z]([-a-zA-Z0-9]*[a-zA-Z0-9])?$ + type: string + name: + description: name is the name of the target resource. + maxLength: 253 + minLength: 1 + type: string + namespace: + description: namespace is the namespace of the referent. + type: string + x-kubernetes-validations: + - message: cross namespace referencing is not currently supported + rule: self.size() == 0 + required: + - kind + - name + type: object + maxItems: 16 + type: array + type: + description: |- + Specifies the type of Wasm Extension to be used. + + Valid Options: HTTP, NETWORK + enum: + - UNSPECIFIED_PLUGIN_TYPE + - HTTP + - NETWORK + type: string + url: + description: URL of a Wasm module or OCI container. + minLength: 1 + type: string + x-kubernetes-validations: + - message: url must have schema one of [http, https, file, oci] + rule: |- + isURL(self) ? (url(self).getScheme() in ["", "http", "https", "oci", "file"]) : (isURL("http://" + self) && + url("http://" + self).getScheme() in ["", "http", "https", "oci", "file"]) + verificationKey: + type: string + vmConfig: + description: Configuration for a Wasm VM. + properties: + env: + description: Specifies environment variables to be injected to + this VM. + items: + properties: + name: + description: Name of the environment variable. + maxLength: 256 + minLength: 1 + type: string + value: + description: Value for the environment variable. + maxLength: 2048 + type: string + valueFrom: + description: |- + Source for the environment variable's value. + + Valid Options: INLINE, HOST + enum: + - INLINE + - HOST + type: string + required: + - name + type: object + x-kubernetes-validations: + - message: value may only be set when valueFrom is INLINE + rule: '(has(self.valueFrom) ? self.valueFrom : "") != "HOST" + || !has(self.value)' + maxItems: 256 + type: array + x-kubernetes-list-map-keys: + - name + x-kubernetes-list-type: map + type: object + required: + - url + type: object + x-kubernetes-validations: + - message: only one of targetRefs or selector can be set + rule: '(has(self.selector) ? 1 : 0) + (has(self.targetRef) ? 1 : 0) + + (has(self.targetRefs) ? 1 : 0) <= 1' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + helm.sh/resource-policy: keep + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: workloadentries.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: WorkloadEntry + listKind: WorkloadEntryList + plural: workloadentries + shortNames: + - we + singular: workloadentry + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Address associated with the network endpoint. + jsonPath: .spec.address + name: Address + type: string + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting VMs onboarded into the mesh. See + more details at: https://istio.io/docs/reference/config/networking/workload-entry.html' + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident in + the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload if a + sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Address associated with the network endpoint. + jsonPath: .spec.address + name: Address + type: string + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting VMs onboarded into the mesh. See + more details at: https://istio.io/docs/reference/config/networking/workload-entry.html' + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident in + the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload if a + sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + - description: Address associated with the network endpoint. + jsonPath: .spec.address + name: Address + type: string + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Configuration affecting VMs onboarded into the mesh. See + more details at: https://istio.io/docs/reference/config/networking/workload-entry.html' + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == "/" + || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident in + the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload if a + sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: Address is required + rule: has(self.address) || has(self.network) + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: workloadgroups.networking.istio.io +spec: + group: networking.istio.io + names: + categories: + - istio-io + - networking-istio-io + kind: WorkloadGroup + listKind: WorkloadGroupList + plural: workloadgroups + shortNames: + - wg + singular: workloadgroup + scope: Namespaced + versions: + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Describes a collection of workload instances. See more details + at: https://istio.io/docs/reference/config/networking/workload-group.html' + properties: + metadata: + description: Metadata that will be used for all corresponding `WorkloadEntries`. + properties: + annotations: + additionalProperties: + type: string + maxProperties: 256 + type: object + labels: + additionalProperties: + type: string + maxProperties: 256 + type: object + type: object + probe: + description: '`ReadinessProbe` describes the configuration the user + must provide for healthchecking on their workload.' + oneOf: + - not: + anyOf: + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + properties: + exec: + description: Health is determined by how the command that is executed + exited. + properties: + command: + description: Command to run. + items: + minLength: 1 + type: string + type: array + required: + - command + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. + format: int32 + minimum: 0 + type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object + httpGet: + description: '`httpGet` is performed to a given endpoint and the + status/able to connect determines health.' + properties: + host: + description: Host name to connect to, defaults to the pod + IP. + type: string + httpHeaders: + description: Headers the proxy will pass on to make the request. + items: + properties: + name: + pattern: ^[-_A-Za-z0-9]+$ + type: string + value: + type: string + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + scheme: + type: string + x-kubernetes-validations: + - message: scheme must be one of [HTTP, HTTPS] + rule: self in ["", "HTTP", "HTTPS"] + required: + - port + type: object + initialDelaySeconds: + description: Number of seconds after the container has started + before readiness probes are initiated. + format: int32 + minimum: 0 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 0 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. + format: int32 + minimum: 0 + type: integer + tcpSocket: + description: Health is determined by if the proxy is able to connect. + properties: + host: + type: string + port: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - port + type: object + timeoutSeconds: + description: Number of seconds after which the probe times out. + format: int32 + minimum: 0 + type: integer + type: object + template: + description: Template to be used for the generation of `WorkloadEntry` + resources that belong to this `WorkloadGroup`. + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + required: + - template + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1alpha3 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Describes a collection of workload instances. See more details + at: https://istio.io/docs/reference/config/networking/workload-group.html' + properties: + metadata: + description: Metadata that will be used for all corresponding `WorkloadEntries`. + properties: + annotations: + additionalProperties: + type: string + maxProperties: 256 + type: object + labels: + additionalProperties: + type: string + maxProperties: 256 + type: object + type: object + probe: + description: '`ReadinessProbe` describes the configuration the user + must provide for healthchecking on their workload.' + oneOf: + - not: + anyOf: + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + properties: + exec: + description: Health is determined by how the command that is executed + exited. + properties: + command: + description: Command to run. + items: + minLength: 1 + type: string + type: array + required: + - command + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. + format: int32 + minimum: 0 + type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object + httpGet: + description: '`httpGet` is performed to a given endpoint and the + status/able to connect determines health.' + properties: + host: + description: Host name to connect to, defaults to the pod + IP. + type: string + httpHeaders: + description: Headers the proxy will pass on to make the request. + items: + properties: + name: + pattern: ^[-_A-Za-z0-9]+$ + type: string + value: + type: string + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + scheme: + type: string + x-kubernetes-validations: + - message: scheme must be one of [HTTP, HTTPS] + rule: self in ["", "HTTP", "HTTPS"] + required: + - port + type: object + initialDelaySeconds: + description: Number of seconds after the container has started + before readiness probes are initiated. + format: int32 + minimum: 0 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 0 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. + format: int32 + minimum: 0 + type: integer + tcpSocket: + description: Health is determined by if the proxy is able to connect. + properties: + host: + type: string + port: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - port + type: object + timeoutSeconds: + description: Number of seconds after which the probe times out. + format: int32 + minimum: 0 + type: integer + type: object + template: + description: Template to be used for the generation of `WorkloadEntry` + resources that belong to this `WorkloadGroup`. + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + required: + - template + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: false + subresources: + status: {} + - additionalPrinterColumns: + - description: 'CreationTimestamp is a timestamp representing the server time + when this object was created. It is not guaranteed to be set in happens-before + order across separate operations. Clients may not set this value. It is represented + in RFC3339 form and is in UTC. Populated by the system. Read-only. Null for + lists. More info: https://git.k8s.io/community/contributors/devel/api-conventions.md#metadata' + jsonPath: .metadata.creationTimestamp + name: Age + type: date + name: v1beta1 + schema: + openAPIV3Schema: + properties: + spec: + description: 'Describes a collection of workload instances. See more details + at: https://istio.io/docs/reference/config/networking/workload-group.html' + properties: + metadata: + description: Metadata that will be used for all corresponding `WorkloadEntries`. + properties: + annotations: + additionalProperties: + type: string + maxProperties: 256 + type: object + labels: + additionalProperties: + type: string + maxProperties: 256 + type: object + type: object + probe: + description: '`ReadinessProbe` describes the configuration the user + must provide for healthchecking on their workload.' + oneOf: + - not: + anyOf: + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + - required: + - httpGet + - required: + - tcpSocket + - required: + - exec + - required: + - grpc + properties: + exec: + description: Health is determined by how the command that is executed + exited. + properties: + command: + description: Command to run. + items: + minLength: 1 + type: string + type: array + required: + - command + type: object + failureThreshold: + description: Minimum consecutive failures for the probe to be + considered failed after having succeeded. + format: int32 + minimum: 0 + type: integer + grpc: + description: GRPC call is made and response/error is used to determine + health. + properties: + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + service: + type: string + type: object + httpGet: + description: '`httpGet` is performed to a given endpoint and the + status/able to connect determines health.' + properties: + host: + description: Host name to connect to, defaults to the pod + IP. + type: string + httpHeaders: + description: Headers the proxy will pass on to make the request. + items: + properties: + name: + pattern: ^[-_A-Za-z0-9]+$ + type: string + value: + type: string + type: object + type: array + path: + description: Path to access on the HTTP server. + type: string + port: + description: Port on which the endpoint lives. + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + scheme: + type: string + x-kubernetes-validations: + - message: scheme must be one of [HTTP, HTTPS] + rule: self in ["", "HTTP", "HTTPS"] + required: + - port + type: object + initialDelaySeconds: + description: Number of seconds after the container has started + before readiness probes are initiated. + format: int32 + minimum: 0 + type: integer + periodSeconds: + description: How often (in seconds) to perform the probe. + format: int32 + minimum: 0 + type: integer + successThreshold: + description: Minimum consecutive successes for the probe to be + considered successful after having failed. + format: int32 + minimum: 0 + type: integer + tcpSocket: + description: Health is determined by if the proxy is able to connect. + properties: + host: + type: string + port: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + required: + - port + type: object + timeoutSeconds: + description: Number of seconds after which the probe times out. + format: int32 + minimum: 0 + type: integer + type: object + template: + description: Template to be used for the generation of `WorkloadEntry` + resources that belong to this `WorkloadGroup`. + properties: + address: + description: Address associated with the network endpoint without + the port. + maxLength: 256 + type: string + x-kubernetes-validations: + - message: UDS must be an absolute path or abstract socket + rule: 'self.startsWith("unix://") ? (self.substring(7, 8) == + "/" || self.substring(7, 8) == "@") : true' + - message: UDS may not be a dir + rule: 'self.startsWith("unix://") ? !self.endsWith("/") : true' + labels: + additionalProperties: + type: string + description: One or more labels associated with the endpoint. + maxProperties: 256 + type: object + locality: + description: The locality associated with the endpoint. + maxLength: 2048 + type: string + network: + description: Network enables Istio to group endpoints resident + in the same L3 domain/network. + maxLength: 2048 + type: string + ports: + additionalProperties: + maximum: 4294967295 + minimum: 0 + type: integer + x-kubernetes-validations: + - message: port must be between 1-65535 + rule: 0 < self && self <= 65535 + description: Set of ports associated with the endpoint. + maxProperties: 128 + type: object + x-kubernetes-validations: + - message: port name must be valid + rule: self.all(key, size(key) < 63 && key.matches("^[a-zA-Z0-9](?:[-a-zA-Z0-9]*[a-zA-Z0-9])?$")) + serviceAccount: + description: The service account associated with the workload + if a sidecar is present in the workload. + maxLength: 253 + type: string + weight: + description: The load balancing weight associated with the endpoint. + maximum: 4294967295 + minimum: 0 + type: integer + type: object + x-kubernetes-validations: + - message: UDS may not include ports + rule: '(has(self.address) ? self.address : "").startsWith("unix://") + ? !has(self.ports) : true' + required: + - template + type: object + status: + properties: + conditions: + description: Current service state of the resource. + items: + properties: + lastProbeTime: + description: Last time we probed the condition. + format: date-time + type: string + lastTransitionTime: + description: Last time the condition transitioned from one status + to another. + format: date-time + type: string + message: + description: Human-readable message indicating details about + last transition. + type: string + observedGeneration: + anyOf: + - type: integer + - type: string + description: Resource Generation to which the Condition refers. + x-kubernetes-int-or-string: true + reason: + description: Unique, one-word, CamelCase reason for the condition's + last transition. + type: string + status: + description: Status is the status of the condition. + type: string + type: + description: Type is the type of the condition. + type: string + type: object + type: array + observedGeneration: + anyOf: + - type: integer + - type: string + x-kubernetes-int-or-string: true + validationMessages: + description: Includes any errors or warnings detected by Istio's analyzers. + items: + properties: + documentationUrl: + description: A url pointing to the Istio documentation for this + specific error type. + type: string + level: + description: |- + Represents how severe a message is. + + Valid Options: UNKNOWN, ERROR, WARNING, INFO + enum: + - UNKNOWN + - ERROR + - WARNING + - INFO + type: string + type: + properties: + code: + description: A 7 character code matching `^IST[0-9]{4}$` + intended to uniquely identify the message type. + type: string + name: + description: A human-readable name for the message type. + type: string + type: object + type: object + type: array + type: object + x-kubernetes-preserve-unknown-fields: true + required: + - spec + type: object + served: true + storage: true + subresources: + status: {} diff --git a/deploy/components/crds/kustomization.yaml b/deploy/components/crds/kustomization.yaml index 55852af8..975bbe4f 100644 --- a/deploy/components/crds/kustomization.yaml +++ b/deploy/components/crds/kustomization.yaml @@ -15,3 +15,5 @@ resources: # Gateway API Inference Extension (GIE) CRDs # NOTE: deploys whatever is in the current branch - ../../../config/crd # GIE CRDs +# Istio CRDs +- istio.yaml From 43ab7c1eaffb83a50596bf34e98aae43e9b70925 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:00:44 -0400 Subject: [PATCH 39/73] chore: add custom build for istio-control-plane This is required for full GIE support Signed-off-by: Shane Utt --- .../istio-control-plane/configmaps.yaml | 2025 +++++++++++++++++ .../istio-control-plane/control-plane.yaml | 13 - .../istio-control-plane/deployments.yaml | 183 ++ .../components/istio-control-plane/hpa.yaml | 31 + .../istio-control-plane/kustomization.yaml | 18 +- .../istio-control-plane/namespaces.yaml | 2 +- .../istio-control-plane/policies.yaml | 49 + .../components/istio-control-plane/rbac.yaml | 591 +++++ .../istio-control-plane/service-accounts.yaml | 29 + .../istio-control-plane/services.yaml | 36 + .../istio-control-plane/webhooks.yaml | 203 ++ 11 files changed, 3162 insertions(+), 18 deletions(-) create mode 100644 deploy/components/istio-control-plane/configmaps.yaml delete mode 100644 deploy/components/istio-control-plane/control-plane.yaml create mode 100644 deploy/components/istio-control-plane/deployments.yaml create mode 100644 deploy/components/istio-control-plane/hpa.yaml create mode 100644 deploy/components/istio-control-plane/policies.yaml create mode 100644 deploy/components/istio-control-plane/rbac.yaml create mode 100644 deploy/components/istio-control-plane/service-accounts.yaml create mode 100644 deploy/components/istio-control-plane/services.yaml create mode 100644 deploy/components/istio-control-plane/webhooks.yaml diff --git a/deploy/components/istio-control-plane/configmaps.yaml b/deploy/components/istio-control-plane/configmaps.yaml new file mode 100644 index 00000000..27c56e8a --- /dev/null +++ b/deploy/components/istio-control-plane/configmaps.yaml @@ -0,0 +1,2025 @@ +apiVersion: v1 +data: + mesh: |- + defaultConfig: + discoveryAddress: istiod.istio-system.svc:15012 + defaultProviders: + metrics: + - prometheus + enablePrometheusMerge: true + rootNamespace: istio-system + trustDomain: cluster.local + meshNetworks: 'networks: {}' +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istio + namespace: istio-system +--- +apiVersion: v1 +data: + config: |- + # defaultTemplates defines the default template to use for pods that do not explicitly specify a template + defaultTemplates: [sidecar] + policy: enabled + alwaysInjectSelector: + [] + neverInjectSelector: + [] + injectedAnnotations: + template: "{{ Template_Version_And_Istio_Version_Mismatched_Check_Installation }}" + templates: + sidecar: | + {{- define "resources" }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} + requests: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" + {{ end }} + {{- end }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + limits: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" + {{ end }} + {{- end }} + {{- else }} + {{- if .Values.global.proxy.resources }} + {{ toYaml .Values.global.proxy.resources | indent 6 }} + {{- end }} + {{- end }} + {{- end }} + {{ $nativeSidecar := (or (and (not (isset .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`)) (eq (env "ENABLE_NATIVE_SIDECARS" "false") "true")) (eq (index .ObjectMeta.Annotations `sidecar.istio.io/nativeSidecar`) "true")) }} + {{- $containers := list }} + {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} + metadata: + labels: + security.istio.io/tlsMode: {{ index .ObjectMeta.Labels `security.istio.io/tlsMode` | default "istio" | quote }} + {{- if eq (index .ProxyConfig.ProxyMetadata "ISTIO_META_ENABLE_HBONE") "true" }} + networking.istio.io/tunnel: {{ index .ObjectMeta.Labels `networking.istio.io/tunnel` | default "http" | quote }} + {{- end }} + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | trunc 63 | trimSuffix "-" | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: { + istio.io/rev: {{ .Revision | default "default" | quote }}, + {{- if ge (len $containers) 1 }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", + {{- end }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", + {{- end }} + {{- end }} + {{- if .Values.pilot.cni.enabled }} + {{- if eq .Values.pilot.cni.provider "multus" }} + k8s.v1.cni.cncf.io/networks: '{{ appendMultusNetwork (index .ObjectMeta.Annotations `k8s.v1.cni.cncf.io/networks`) `default/istio-cni` }}', + {{- end }} + sidecar.istio.io/interceptionMode: "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}", + {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}traffic.sidecar.istio.io/includeOutboundIPRanges: "{{.}}",{{ end }} + {{ with annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}traffic.sidecar.istio.io/excludeOutboundIPRanges: "{{.}}",{{ end }} + traffic.sidecar.istio.io/includeInboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}", + traffic.sidecar.istio.io/excludeInboundPorts: "{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}", + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") }} + traffic.sidecar.istio.io/includeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}", + {{- end }} + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne .Values.global.proxy.excludeOutboundPorts "") }} + traffic.sidecar.istio.io/excludeOutboundPorts: "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}", + {{- end }} + {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}traffic.sidecar.istio.io/kubevirtInterfaces: "{{.}}",{{ end }} + {{ with index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}istio.io/reroute-virtual-interfaces: "{{.}}",{{ end }} + {{ with index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}traffic.sidecar.istio.io/excludeInterfaces: "{{.}}",{{ end }} + {{- end }} + } + spec: + {{- $holdProxy := and + (or .ProxyConfig.HoldApplicationUntilProxyStarts.GetValue .Values.global.proxy.holdApplicationUntilProxyStarts) + (not $nativeSidecar) }} + {{- $noInitContainer := and + (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE`) + (not $nativeSidecar) }} + {{ if $noInitContainer }} + initContainers: [] + {{ else -}} + initContainers: + {{ if ne (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `NONE` }} + {{ if .Values.pilot.cni.enabled -}} + - name: istio-validation + {{ else -}} + - name: istio-init + {{ end -}} + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy_init.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + args: + - istio-iptables + - "-p" + - {{ .MeshConfig.ProxyListenPort | default "15001" | quote }} + - "-z" + - {{ .MeshConfig.ProxyInboundListenPort | default "15006" | quote }} + - "-u" + - {{ .ProxyUID | default "1337" | quote }} + - "-m" + - "{{ annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode }}" + - "-i" + - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundIPRanges` .Values.global.proxy.includeIPRanges }}" + - "-x" + - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundIPRanges` .Values.global.proxy.excludeIPRanges }}" + - "-b" + - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeInboundPorts` .Values.global.proxy.includeInboundPorts }}" + - "-d" + {{- if excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }} + - "15090,15021,{{ excludeInboundPort (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) (annotation .ObjectMeta `traffic.sidecar.istio.io/excludeInboundPorts` .Values.global.proxy.excludeInboundPorts) }}" + {{- else }} + - "15090,15021" + {{- end }} + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/includeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.includeOutboundPorts "") "") -}} + - "-q" + - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/includeOutboundPorts` .Values.global.proxy.includeOutboundPorts }}" + {{ end -}} + {{ if or (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeOutboundPorts`) (ne (valueOrDefault .Values.global.proxy.excludeOutboundPorts "") "") -}} + - "-o" + - "{{ annotation .ObjectMeta `traffic.sidecar.istio.io/excludeOutboundPorts` .Values.global.proxy.excludeOutboundPorts }}" + {{ end -}} + {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/kubevirtInterfaces` }}" + {{ end -}} + {{ if (isset .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces`) -}} + - "-k" + - "{{ index .ObjectMeta.Annotations `istio.io/reroute-virtual-interfaces` }}" + {{ end -}} + {{ if (isset .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces`) -}} + - "-c" + - "{{ index .ObjectMeta.Annotations `traffic.sidecar.istio.io/excludeInterfaces` }}" + {{ end -}} + - "--log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }}" + {{ if .Values.global.logAsJson -}} + - "--log_as_json" + {{ end -}} + {{ if .Values.pilot.cni.enabled -}} + - "--run-validation" + - "--skip-rule-apply" + {{ else if .Values.global.proxy_init.forceApplyIptables -}} + - "--force-apply" + {{ end -}} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + {{- if .ProxyConfig.ProxyMetadata }} + env: + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- end }} + resources: + {{ template "resources" . }} + securityContext: + allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} + privileged: {{ .Values.global.proxy.privileged }} + capabilities: + {{- if not .Values.pilot.cni.enabled }} + add: + - NET_ADMIN + - NET_RAW + {{- end }} + drop: + - ALL + {{- if not .Values.pilot.cni.enabled }} + readOnlyRootFilesystem: false + runAsGroup: 0 + runAsNonRoot: false + runAsUser: 0 + {{- else }} + readOnlyRootFilesystem: true + runAsGroup: {{ .ProxyGID | default "1337" }} + runAsUser: {{ .ProxyUID | default "1337" }} + runAsNonRoot: true + {{- end }} + {{ end -}} + {{ end -}} + {{ if not $nativeSidecar }} + containers: + {{ end }} + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + {{ if $nativeSidecar }}restartPolicy: Always{{end}} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.outlierLogPath }} + - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} + {{- end}} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- else if $holdProxy }} + lifecycle: + postStart: + exec: + command: + - pilot-agent + - wait + {{- else if $nativeSidecar }} + {{- /* preStop is called when the pod starts shutdown. Initialize drain. We will get SIGTERM once applications are torn down. */}} + lifecycle: + preStop: + exec: + command: + - pilot-agent + - request + - --debug-port={{(annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort)}} + - POST + - drain + {{- end }} + env: + {{- if eq .InboundTrafficPolicyMode "localhost" }} + - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION + value: "true" + {{- end }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + resource: limits.cpu + {{- if .CompliancePolicy }} + - name: COMPLIANCE_POLICY + value: "{{ .CompliancePolicy }}" + {{- end }} + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ or (index .ObjectMeta.Annotations `sidecar.istio.io/interceptionMode`) .ProxyConfig.InterceptionMode.String }}" + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- with (index .ObjectMeta.Labels `service.istio.io/workload-name` | default .DeploymentMeta.Name) }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ . }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: ISTIO_BOOTSTRAP_OVERRIDE + value: "/etc/istio/custom-bootstrap/custom_bootstrap.json" + {{- end }} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- if and (eq .Values.global.proxy.tracer "datadog") (isset .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} + {{- range $key, $value := fromJSON (index .ObjectMeta.Annotations `apm.datadoghq.com/env`) }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} + {{ if .Values.global.proxy.startupProbe.enabled }} + startupProbe: + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: 0 + periodSeconds: 1 + timeoutSeconds: 3 + failureThreshold: {{ .Values.global.proxy.startupProbe.failureThreshold }} + {{ end }} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} + {{ end -}} + securityContext: + {{- if eq (index .ProxyConfig.ProxyMetadata "IPTABLES_TRACE_LOGGING") "true" }} + allowPrivilegeEscalation: true + capabilities: + add: + - NET_ADMIN + drop: + - ALL + privileged: true + readOnlyRootFilesystem: true + runAsGroup: {{ .ProxyGID | default "1337" }} + runAsNonRoot: false + runAsUser: 0 + {{- else }} + allowPrivilegeEscalation: {{ .Values.global.proxy.privileged }} + capabilities: + {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} + add: + {{ if eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY` -}} + - NET_ADMIN + {{- end }} + {{ if eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true` -}} + - NET_BIND_SERVICE + {{- end }} + {{- end }} + drop: + - ALL + privileged: {{ .Values.global.proxy.privileged }} + readOnlyRootFilesystem: true + runAsGroup: {{ .ProxyGID | default "1337" }} + {{ if or (eq (annotation .ObjectMeta `sidecar.istio.io/interceptionMode` .ProxyConfig.InterceptionMode) `TPROXY`) (eq (annotation .ObjectMeta `sidecar.istio.io/capNetBindService` .Values.global.proxy.capNetBindService) `true`) -}} + runAsNonRoot: false + runAsUser: 0 + {{- else -}} + runAsNonRoot: true + runAsUser: {{ .ProxyUID | default "1337" }} + {{- end }} + {{- end }} + resources: + {{ template "resources" . }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - mountPath: /etc/istio/custom-bootstrap + name: custom-bootstrap-volume + {{- end }} + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} + - mountPath: {{ directory .ProxyConfig.GetTracing.GetTlsSettings.GetCaCertificates }} + name: lightstep-certs + readOnly: true + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} + {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 6 }} + {{ end }} + {{- end }} + volumes: + - emptyDir: + name: workload-socket + - emptyDir: + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else }} + - emptyDir: + name: workload-certs + {{- end }} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: custom-bootstrap-volume + configMap: + name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} + {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 4 }} + {{ end }} + {{ end }} + {{- if and (eq .Values.global.proxy.tracer "lightstep") .ProxyConfig.GetTracing.GetTlsSettings }} + - name: lightstep-certs + secret: + optional: true + secretName: lightstep.cacert + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + gateway: | + {{- $containers := list }} + {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} + metadata: + labels: + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: + istio.io/rev: {{ .Revision | default "default" | quote }} + {{- if ge (len $containers) 1 }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}" + {{- end }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}" + {{- end }} + {{- end }} + spec: + securityContext: + {{- if .Values.gateways.securityContext }} + {{- toYaml .Values.gateways.securityContext | nindent 4 }} + {{- else }} + sysctls: + - name: net.ipv4.ip_unprivileged_port_start + value: "0" + {{- end }} + containers: + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + ports: + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{ toYaml .Values.global.proxy.lifecycle | indent 6 }} + {{- end }} + securityContext: + runAsUser: {{ .ProxyUID | default "1337" }} + runAsGroup: {{ .ProxyGID | default "1337" }} + env: + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + resource: limits.cpu + {{- if .CompliancePolicy }} + - name: COMPLIANCE_POLICY + value: "{{ .CompliancePolicy }}" + {{- end }} + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ .ProxyConfig.InterceptionMode.String }}" + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .DeploymentMeta.Name }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ .DeploymentMeta.Name }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15021 + initialDelaySeconds: {{.Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ .Values.global.proxy.readinessFailureThreshold }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else}} + - emptyDir: {} + name: workload-certs + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + grpc-simple: | + metadata: + annotations: + sidecar.istio.io/rewriteAppHTTPProbers: "false" + spec: + initContainers: + - name: grpc-bootstrap-init + image: busybox:1.28 + volumeMounts: + - mountPath: /var/lib/grpc/data/ + name: grpc-io-proxyless-bootstrap + env: + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: ISTIO_NAMESPACE + value: | + {{ .Values.global.istioNamespace }} + command: + - sh + - "-c" + - |- + NODE_ID="sidecar~${INSTANCE_IP}~${POD_NAME}.${POD_NAMESPACE}~cluster.local" + SERVER_URI="dns:///istiod.${ISTIO_NAMESPACE}.svc:15010" + echo ' + { + "xds_servers": [ + { + "server_uri": "'${SERVER_URI}'", + "channel_creds": [{"type": "insecure"}], + "server_features" : ["xds_v3"] + } + ], + "node": { + "id": "'${NODE_ID}'", + "metadata": { + "GENERATOR": "grpc" + } + } + }' > /var/lib/grpc/data/bootstrap.json + containers: + {{- range $index, $container := .Spec.Containers }} + - name: {{ $container.Name }} + env: + - name: GRPC_XDS_BOOTSTRAP + value: /var/lib/grpc/data/bootstrap.json + - name: GRPC_GO_LOG_VERBOSITY_LEVEL + value: "99" + - name: GRPC_GO_LOG_SEVERITY_LEVEL + value: info + volumeMounts: + - mountPath: /var/lib/grpc/data/ + name: grpc-io-proxyless-bootstrap + {{- end }} + volumes: + - name: grpc-io-proxyless-bootstrap + emptyDir: {} + grpc-agent: | + {{- define "resources" }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) }} + requests: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPU` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemory` }}" + {{ end }} + {{- end }} + {{- if or (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) }} + limits: + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit`) -}} + cpu: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyCPULimit` }}" + {{ end }} + {{ if (isset .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit`) -}} + memory: "{{ index .ObjectMeta.Annotations `sidecar.istio.io/proxyMemoryLimit` }}" + {{ end }} + {{- end }} + {{- else }} + {{- if .Values.global.proxy.resources }} + {{ toYaml .Values.global.proxy.resources | indent 6 }} + {{- end }} + {{- end }} + {{- end }} + {{- $containers := list }} + {{- range $index, $container := .Spec.Containers }}{{ if not (eq $container.Name "istio-proxy") }}{{ $containers = append $containers $container.Name }}{{end}}{{- end}} + metadata: + labels: + {{/* security.istio.io/tlsMode: istio must be set by user, if gRPC is using mTLS initialization code. We can't set it automatically. */}} + service.istio.io/canonical-name: {{ index .ObjectMeta.Labels `service.istio.io/canonical-name` | default (index .ObjectMeta.Labels `app.kubernetes.io/name`) | default (index .ObjectMeta.Labels `app`) | default .DeploymentMeta.Name | quote }} + service.istio.io/canonical-revision: {{ index .ObjectMeta.Labels `service.istio.io/canonical-revision` | default (index .ObjectMeta.Labels `app.kubernetes.io/version`) | default (index .ObjectMeta.Labels `version`) | default "latest" | quote }} + annotations: { + istio.io/rev: {{ .Revision | default "default" | quote }}, + {{- if ge (len $containers) 1 }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-logs-container`) }} + kubectl.kubernetes.io/default-logs-container: "{{ index $containers 0 }}", + {{- end }} + {{- if not (isset .ObjectMeta.Annotations `kubectl.kubernetes.io/default-container`) }} + kubectl.kubernetes.io/default-container: "{{ index $containers 0 }}", + {{- end }} + {{- end }} + sidecar.istio.io/rewriteAppHTTPProbers: "false", + } + spec: + containers: + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + ports: + - containerPort: 15020 + protocol: TCP + name: mesh-metrics + args: + - proxy + - sidecar + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel }} + - --proxyComponentLogLevel={{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel }} + - --log_output_level={{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level }} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + lifecycle: + postStart: + exec: + command: + - pilot-agent + - wait + - --url=http://localhost:15020/healthz/ready + env: + - name: ISTIO_META_GENERATOR + value: grpc + - name: OUTPUT_CERTS + value: /var/lib/istio/data + {{- if eq .InboundTrafficPolicyMode "localhost" }} + - name: REWRITE_PROBE_LEGACY_LOCALHOST_DESTINATION + value: "true" + {{- end }} + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: |- + [ + {{- $first := true }} + {{- range $index1, $c := .Spec.Containers }} + {{- range $index2, $p := $c.Ports }} + {{- if (structToJSON $p) }} + {{if not $first}},{{end}}{{ structToJSON $p }} + {{- $first = false }} + {{- end }} + {{- end}} + {{- end}} + ] + - name: ISTIO_META_APP_CONTAINERS + value: "{{ $containers | join "," }}" + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + {{- if .Values.global.network }} + - name: ISTIO_META_NETWORK + value: "{{ .Values.global.network }}" + {{- end }} + {{- if .DeploymentMeta.Name }} + - name: ISTIO_META_WORKLOAD_NAME + value: "{{ .DeploymentMeta.Name }}" + {{ end }} + {{- if and .TypeMeta.APIVersion .DeploymentMeta.Name }} + - name: ISTIO_META_OWNER + value: kubernetes://apis/{{ .TypeMeta.APIVersion }}/namespaces/{{ valueOrDefault .DeploymentMeta.Namespace `default` }}/{{ toLower .TypeMeta.Kind}}s/{{ .DeploymentMeta.Name }} + {{- end}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + # grpc uses xds:/// to resolve – no need to resolve VIP + - name: ISTIO_META_DNS_CAPTURE + value: "false" + - name: DISABLE_ENVOY + value: "true" + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + {{ if ne (annotation .ObjectMeta `status.sidecar.istio.io/port` .Values.global.proxy.statusPort) `0` }} + readinessProbe: + httpGet: + path: /healthz/ready + port: 15020 + initialDelaySeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/initialDelaySeconds` .Values.global.proxy.readinessInitialDelaySeconds }} + periodSeconds: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/periodSeconds` .Values.global.proxy.readinessPeriodSeconds }} + timeoutSeconds: 3 + failureThreshold: {{ annotation .ObjectMeta `readiness.status.sidecar.istio.io/failureThreshold` .Values.global.proxy.readinessFailureThreshold }} + resources: + {{ template "resources" . }} + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # UDS channel between istioagent and gRPC client for XDS/SDS + - mountPath: /etc/istio/proxy + name: istio-xds + - mountPath: /var/run/secrets/tokens + name: istio-token + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - mountPath: /etc/certs/ + name: istio-certs + readOnly: true + {{- end }} + - name: istio-podinfo + mountPath: /etc/istio/pod + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount` }} + {{ range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolumeMount`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 6 }} + {{ end }} + {{- end }} + {{- range $index, $container := .Spec.Containers }} + {{ if not (eq $container.Name "istio-proxy") }} + - name: {{ $container.Name }} + env: + - name: "GRPC_XDS_EXPERIMENTAL_SECURITY_SUPPORT" + value: "true" + - name: "GRPC_XDS_BOOTSTRAP" + value: "/etc/istio/proxy/grpc-bootstrap.json" + volumeMounts: + - mountPath: /var/lib/istio/data + name: istio-data + # UDS channel between istioagent and gRPC client for XDS/SDS + - mountPath: /etc/istio/proxy + name: istio-xds + {{- if eq $.Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- end }} + {{- end }} + volumes: + - emptyDir: + name: workload-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else }} + - emptyDir: + name: workload-certs + {{- end }} + {{- if (isset .ObjectMeta.Annotations `sidecar.istio.io/bootstrapOverride`) }} + - name: custom-bootstrap-volume + configMap: + name: {{ annotation .ObjectMeta `sidecar.istio.io/bootstrapOverride` "" }} + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-xds + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.mountMtlsCerts }} + # Use the key and cert mounted to /etc/certs/ for the in-cluster mTLS communications. + - name: istio-certs + secret: + optional: true + {{ if eq .Spec.ServiceAccountName "" }} + secretName: istio.default + {{ else -}} + secretName: {{ printf "istio.%s" .Spec.ServiceAccountName }} + {{ end -}} + {{- end }} + {{- if isset .ObjectMeta.Annotations `sidecar.istio.io/userVolume` }} + {{range $index, $value := fromJSON (index .ObjectMeta.Annotations `sidecar.istio.io/userVolume`) }} + - name: "{{ $index }}" + {{ toYaml $value | indent 4 }} + {{ end }} + {{ end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + waypoint: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: {{.ServiceAccount | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + ) | nindent 4 }} + {{- if ge .KubeVersion 128 }} + # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" + {{- end }} + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + "gateway.istio.io/managed" "istio.io-mesh-controller" + ) | nindent 4 }} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" + spec: + selector: + matchLabels: + "{{.GatewayNameLabel}}": "{{.Name}}" + template: + metadata: + annotations: + {{- toJsonMap + (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") + (strdict "istio.io/rev" (.Revision | default "default")) + (strdict + "prometheus.io/path" "/stats/prometheus" + "prometheus.io/port" "15020" + "prometheus.io/scrape" "true" + ) | nindent 8 }} + labels: + {{- toJsonMap + (strdict + "sidecar.istio.io/inject" "false" + "istio.io/dataplane-mode" "none" + "service.istio.io/canonical-name" .DeploymentName + "service.istio.io/canonical-revision" "latest" + ) + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + "gateway.istio.io/managed" "istio.io-mesh-controller" + ) | nindent 8}} + spec: + {{- if .Values.global.waypoint.affinity }} + affinity: + {{- toYaml .Values.global.waypoint.affinity | nindent 8 }} + {{- end }} + {{- if .Values.global.waypoint.topologySpreadConstraints }} + topologySpreadConstraints: + {{- toYaml .Values.global.waypoint.topologySpreadConstraints | nindent 8 }} + {{- end }} + {{- if .Values.global.waypoint.nodeSelector }} + nodeSelector: + {{- toYaml .Values.global.waypoint.nodeSelector | nindent 8 }} + {{- end }} + {{- if .Values.global.waypoint.tolerations }} + tolerations: + {{- toYaml .Values.global.waypoint.tolerations | nindent 8 }} + {{- end }} + terminationGracePeriodSeconds: 2 + serviceAccountName: {{.ServiceAccount | quote}} + containers: + - name: istio-proxy + ports: + - containerPort: 15020 + name: metrics + protocol: TCP + - containerPort: 15021 + name: status-port + protocol: TCP + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + args: + - proxy + - waypoint + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --serviceCluster + - {{.ServiceAccount}}.$(POD_NAMESPACE) + - --proxyLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} + - --proxyComponentLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} + - --log_output_level + - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.outlierLogPath }} + - --outlierLogPath={{ .Values.global.proxy.outlierLogPath }} + {{- end}} + env: + - name: ISTIO_META_SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + {{- if .ProxyConfig.ProxyMetadata }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- end }} + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName `Kubernetes` }}" + {{- $network := valueOrDefault (index .InfrastructureLabels `topology.istio.io/network`) .Values.global.network }} + {{- if $network }} + - name: ISTIO_META_NETWORK + value: "{{ $network }}" + {{- end }} + - name: ISTIO_META_INTERCEPTION_MODE + value: REDIRECT + - name: ISTIO_META_WORKLOAD_NAME + value: {{.DeploymentName}} + - name: ISTIO_META_OWNER + value: kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}} + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- if .Values.global.waypoint.resources }} + resources: + {{- toYaml .Values.global.waypoint.resources | nindent 10 }} + {{- end }} + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 1 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 + securityContext: + privileged: false + {{- if not (eq .Values.global.platform "openshift") }} + runAsGroup: 1337 + runAsUser: 1337 + {{- end }} + allowPrivilegeEscalation: false + readOnlyRootFilesystem: true + runAsNonRoot: true + capabilities: + drop: + - ALL + {{- if .Values.gateways.seccompProfile }} + seccompProfile: + {{- toYaml .Values.gateways.seccompProfile | nindent 12 }} + {{- end }} + volumeMounts: + - mountPath: /var/run/secrets/workload-spiffe-uds + name: workload-socket + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + - mountPath: /var/lib/istio/data + name: istio-data + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - mountPath: /etc/istio/pod + name: istio-podinfo + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: + medium: Memory + name: istio-envoy + - emptyDir: + medium: Memory + name: go-proxy-envoy + - emptyDir: {} + name: istio-data + - emptyDir: {} + name: go-proxy-data + - downwardAPI: + items: + - fieldRef: + fieldPath: metadata.labels + path: labels + - fieldRef: + fieldPath: metadata.annotations + path: annotations + name: istio-podinfo + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - configMap: + name: istio-ca-root-cert + name: istiod-ca-cert + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + --- + apiVersion: v1 + kind: Service + metadata: + annotations: + {{ toJsonMap + (strdict "networking.istio.io/traffic-distribution" "PreferClose") + (omit .InfrastructureAnnotations + "kubectl.kubernetes.io/last-applied-configuration" + "gateway.istio.io/name-override" + "gateway.istio.io/service-account" + "gateway.istio.io/controller-version" + ) | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + ) | nindent 4 }} + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" + spec: + ipFamilyPolicy: PreferDualStack + ports: + {{- range $key, $val := .Ports }} + - name: {{ $val.Name | quote }} + port: {{ $val.Port }} + protocol: TCP + appProtocol: {{ $val.AppProtocol }} + {{- end }} + selector: + "{{.GatewayNameLabel}}": "{{.Name}}" + {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} + loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} + {{- end }} + type: {{ .ServiceType | quote }} + --- + kube-gateway: | + apiVersion: v1 + kind: ServiceAccount + metadata: + name: {{.ServiceAccount | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + ) | nindent 4 }} + {{- if ge .KubeVersion 128 }} + # Safe since 1.28: https://github.com/kubernetes/kubernetes/pull/117412 + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: "{{.Name}}" + uid: "{{.UID}}" + {{- end }} + --- + apiVersion: apps/v1 + kind: Deployment + metadata: + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + annotations: + {{- toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + "gateway.istio.io/managed" "istio.io-gateway-controller" + ) | nindent 4 }} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: {{.Name}} + uid: "{{.UID}}" + spec: + selector: + matchLabels: + "{{.GatewayNameLabel}}": {{.Name}} + template: + metadata: + annotations: + {{- toJsonMap + (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") + (strdict "istio.io/rev" (.Revision | default "default")) + (strdict + "prometheus.io/path" "/stats/prometheus" + "prometheus.io/port" "15020" + "prometheus.io/scrape" "true" + ) | nindent 8 }} + labels: + {{- toJsonMap + (strdict + "sidecar.istio.io/inject" "false" + "service.istio.io/canonical-name" .DeploymentName + "service.istio.io/canonical-revision" "latest" + ) + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + "gateway.istio.io/managed" "istio.io-gateway-controller" + ) | nindent 8 }} + spec: + securityContext: + {{- if .Values.gateways.securityContext }} + {{- toYaml .Values.gateways.securityContext | nindent 8 }} + {{- else }} + sysctls: + - name: net.ipv4.ip_unprivileged_port_start + value: "0" + {{- if .Values.gateways.seccompProfile }} + seccompProfile: + {{- toYaml .Values.gateways.seccompProfile | nindent 10 }} + {{- end }} + {{- end }} + serviceAccountName: {{.ServiceAccount | quote}} + containers: + - name: istio-proxy + {{- if contains "/" (annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image) }} + image: "{{ annotation .ObjectMeta `sidecar.istio.io/proxyImage` .Values.global.proxy.image }}" + {{- else }} + image: "{{ .ProxyImage }}" + {{- end }} + {{- if .Values.global.proxy.resources }} + resources: + {{- toYaml .Values.global.proxy.resources | nindent 10 }} + {{- end }} + {{with .Values.global.imagePullPolicy }}imagePullPolicy: "{{.}}"{{end}} + securityContext: + capabilities: + drop: + - ALL + allowPrivilegeEscalation: false + privileged: false + readOnlyRootFilesystem: true + runAsUser: {{ .ProxyUID | default "1337" }} + runAsGroup: {{ .ProxyGID | default "1337" }} + runAsNonRoot: true + ports: + - containerPort: 15020 + name: metrics + protocol: TCP + - containerPort: 15021 + name: status-port + protocol: TCP + - containerPort: 15090 + protocol: TCP + name: http-envoy-prom + args: + - proxy + - router + - --domain + - $(POD_NAMESPACE).svc.{{ .Values.global.proxy.clusterDomain }} + - --proxyLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/logLevel` .Values.global.proxy.logLevel | quote}} + - --proxyComponentLogLevel + - {{ annotation .ObjectMeta `sidecar.istio.io/componentLogLevel` .Values.global.proxy.componentLogLevel | quote}} + - --log_output_level + - {{ annotation .ObjectMeta `sidecar.istio.io/agentLogLevel` .Values.global.logging.level | quote}} + {{- if .Values.global.sts.servicePort }} + - --stsPort={{ .Values.global.sts.servicePort }} + {{- end }} + {{- if .Values.global.logAsJson }} + - --log_as_json + {{- end }} + {{- if .Values.global.proxy.lifecycle }} + lifecycle: + {{- toYaml .Values.global.proxy.lifecycle | nindent 10 }} + {{- end }} + env: + - name: PILOT_CERT_PROVIDER + value: {{ .Values.global.pilotCertProvider }} + - name: CA_ADDR + {{- if .Values.global.caAddress }} + value: {{ .Values.global.caAddress }} + {{- else }} + value: istiod{{- if not (eq .Values.revision "") }}-{{ .Values.revision }}{{- end }}.{{ .Values.global.istioNamespace }}.svc:15012 + {{- end }} + - name: POD_NAME + valueFrom: + fieldRef: + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + fieldPath: metadata.namespace + - name: INSTANCE_IP + valueFrom: + fieldRef: + fieldPath: status.podIP + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + fieldPath: spec.serviceAccountName + - name: HOST_IP + valueFrom: + fieldRef: + fieldPath: status.hostIP + - name: ISTIO_CPU_LIMIT + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: PROXY_CONFIG + value: | + {{ protoToJSON .ProxyConfig }} + - name: ISTIO_META_POD_PORTS + value: "[]" + - name: ISTIO_META_APP_CONTAINERS + value: "" + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + resource: limits.cpu + - name: ISTIO_META_CLUSTER_ID + value: "{{ valueOrDefault .Values.global.multiCluster.clusterName .ClusterID }}" + - name: ISTIO_META_NODE_NAME + valueFrom: + fieldRef: + fieldPath: spec.nodeName + - name: ISTIO_META_INTERCEPTION_MODE + value: "{{ .ProxyConfig.InterceptionMode.String }}" + {{- with (valueOrDefault (index .InfrastructureLabels "topology.istio.io/network") .Values.global.network) }} + - name: ISTIO_META_NETWORK + value: {{.|quote}} + {{- end }} + - name: ISTIO_META_WORKLOAD_NAME + value: {{.DeploymentName|quote}} + - name: ISTIO_META_OWNER + value: "kubernetes://apis/apps/v1/namespaces/{{.Namespace}}/deployments/{{.DeploymentName}}" + {{- if .Values.global.meshID }} + - name: ISTIO_META_MESH_ID + value: "{{ .Values.global.meshID }}" + {{- else if (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: ISTIO_META_MESH_ID + value: "{{ (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }}" + {{- end }} + {{- with (valueOrDefault .MeshConfig.TrustDomain .Values.global.trustDomain) }} + - name: TRUST_DOMAIN + value: "{{ . }}" + {{- end }} + {{- range $key, $value := .ProxyConfig.ProxyMetadata }} + - name: {{ $key }} + value: "{{ $value }}" + {{- end }} + {{- with (index .InfrastructureLabels "topology.istio.io/network") }} + - name: ISTIO_META_REQUESTED_NETWORK_VIEW + value: {{.|quote}} + {{- end }} + startupProbe: + failureThreshold: 30 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 1 + periodSeconds: 1 + successThreshold: 1 + timeoutSeconds: 1 + readinessProbe: + failureThreshold: 4 + httpGet: + path: /healthz/ready + port: 15021 + scheme: HTTP + initialDelaySeconds: 0 + periodSeconds: 15 + successThreshold: 1 + timeoutSeconds: 1 + volumeMounts: + - name: workload-socket + mountPath: /var/run/secrets/workload-spiffe-uds + - name: credential-socket + mountPath: /var/run/secrets/credential-uds + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + mountPath: /var/run/secrets/workload-spiffe-credentials + readOnly: true + {{- else }} + - name: workload-certs + mountPath: /var/run/secrets/workload-spiffe-credentials + {{- end }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - mountPath: /var/run/secrets/istio + name: istiod-ca-cert + {{- end }} + - mountPath: /var/lib/istio/data + name: istio-data + # SDS channel between istioagent and Envoy + - mountPath: /etc/istio/proxy + name: istio-envoy + - mountPath: /var/run/secrets/tokens + name: istio-token + - name: istio-podinfo + mountPath: /etc/istio/pod + volumes: + - emptyDir: {} + name: workload-socket + - emptyDir: {} + name: credential-socket + {{- if eq .Values.global.caName "GkeWorkloadCertificate" }} + - name: gke-workload-certificate + csi: + driver: workloadcertificates.security.cloud.google.com + {{- else}} + - emptyDir: {} + name: workload-certs + {{- end }} + # SDS channel between istioagent and Envoy + - emptyDir: + medium: Memory + name: istio-envoy + - name: istio-data + emptyDir: {} + - name: istio-podinfo + downwardAPI: + items: + - path: "labels" + fieldRef: + fieldPath: metadata.labels + - path: "annotations" + fieldRef: + fieldPath: metadata.annotations + - name: istio-token + projected: + sources: + - serviceAccountToken: + path: istio-token + expirationSeconds: 43200 + audience: {{ .Values.global.sds.token.aud }} + {{- if eq .Values.global.pilotCertProvider "istiod" }} + - name: istiod-ca-cert + configMap: + name: istio-ca-root-cert + {{- end }} + {{- if .Values.global.imagePullSecrets }} + imagePullSecrets: + {{- range .Values.global.imagePullSecrets }} + - name: {{ . }} + {{- end }} + {{- end }} + --- + apiVersion: v1 + kind: Service + metadata: + annotations: + {{ toJsonMap (omit .InfrastructureAnnotations "kubectl.kubernetes.io/last-applied-configuration" "gateway.istio.io/name-override" "gateway.istio.io/service-account" "gateway.istio.io/controller-version") | nindent 4 }} + labels: + {{- toJsonMap + .InfrastructureLabels + (strdict + "gateway.networking.k8s.io/gateway-name" .Name + ) | nindent 4 }} + name: {{.DeploymentName | quote}} + namespace: {{.Namespace | quote}} + ownerReferences: + - apiVersion: gateway.networking.k8s.io/v1beta1 + kind: Gateway + name: {{.Name}} + uid: {{.UID}} + spec: + ipFamilyPolicy: PreferDualStack + ports: + {{- range $key, $val := .Ports }} + - name: {{ $val.Name | quote }} + port: {{ $val.Port }} + protocol: TCP + appProtocol: {{ $val.AppProtocol }} + {{- end }} + selector: + "{{.GatewayNameLabel}}": {{.Name}} + {{- if and (.Spec.Addresses) (eq .ServiceType "LoadBalancer") }} + loadBalancerIP: {{ (index .Spec.Addresses 0).Value | quote}} + {{- end }} + type: {{ .ServiceType | quote }} + --- + values: |- + { + "gateways": { + "seccompProfile": {}, + "securityContext": {} + }, + "global": { + "caAddress": "", + "caName": "", + "certSigners": [], + "configCluster": false, + "configValidation": true, + "defaultPodDisruptionBudget": { + "enabled": true + }, + "defaultResources": { + "requests": { + "cpu": "10m" + } + }, + "externalIstiod": false, + "hub": "gcr.io/istio-testing", + "imagePullPolicy": "", + "imagePullSecrets": [], + "istioNamespace": "istio-system", + "istiod": { + "enableAnalysis": false + }, + "logAsJson": false, + "logging": { + "level": "default:info" + }, + "meshID": "", + "meshNetworks": {}, + "mountMtlsCerts": false, + "multiCluster": { + "clusterName": "", + "enabled": false + }, + "network": "", + "omitSidecarInjectorConfigMap": false, + "operatorManageWebhooks": false, + "pilotCertProvider": "istiod", + "priorityClassName": "", + "proxy": { + "autoInject": "enabled", + "clusterDomain": "cluster.local", + "componentLogLevel": "misc:error", + "excludeIPRanges": "", + "excludeInboundPorts": "", + "excludeOutboundPorts": "", + "image": "proxyv2", + "includeIPRanges": "*", + "includeInboundPorts": "*", + "includeOutboundPorts": "", + "logLevel": "warning", + "outlierLogPath": "", + "privileged": false, + "readinessFailureThreshold": 4, + "readinessInitialDelaySeconds": 0, + "readinessPeriodSeconds": 15, + "resources": { + "limits": { + "cpu": "2000m", + "memory": "1024Mi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + }, + "startupProbe": { + "enabled": true, + "failureThreshold": 600 + }, + "statusPort": 15020, + "tracer": "none" + }, + "proxy_init": { + "forceApplyIptables": false, + "image": "proxyv2" + }, + "remotePilotAddress": "", + "sds": { + "token": { + "aud": "istio-ca" + } + }, + "sts": { + "servicePort": 0 + }, + "tag": "1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f", + "variant": "", + "waypoint": { + "affinity": {}, + "nodeSelector": {}, + "resources": { + "limits": { + "cpu": "2", + "memory": "1Gi" + }, + "requests": { + "cpu": "100m", + "memory": "128Mi" + } + }, + "tolerations": [], + "topologySpreadConstraints": [] + } + }, + "pilot": { + "cni": { + "enabled": false, + "provider": "default" + } + }, + "revision": "", + "sidecarInjectorWebhook": { + "alwaysInjectSelector": [], + "defaultTemplates": [], + "enableNamespacesByDefault": false, + "injectedAnnotations": {}, + "neverInjectSelector": [], + "reinvocationPolicy": "Never", + "rewriteAppHTTPProbe": true, + "templates": {} + } + } +kind: ConfigMap +metadata: + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istio-sidecar-injector + namespace: istio-system diff --git a/deploy/components/istio-control-plane/control-plane.yaml b/deploy/components/istio-control-plane/control-plane.yaml deleted file mode 100644 index 2dcf3fac..00000000 --- a/deploy/components/istio-control-plane/control-plane.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: sailoperator.io/v1 -kind: Istio -metadata: - name: control-plane -spec: - version: v1.25-latest - values: - pilot: - resources: - requests: - cpu: 100m - memory: 1024Mi - diff --git a/deploy/components/istio-control-plane/deployments.yaml b/deploy/components/istio-control-plane/deployments.yaml new file mode 100644 index 00000000..49de6b61 --- /dev/null +++ b/deploy/components/istio-control-plane/deployments.yaml @@ -0,0 +1,183 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio: pilot + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istiod + namespace: istio-system +spec: + selector: + matchLabels: + istio: pilot + strategy: + rollingUpdate: + maxSurge: 100% + maxUnavailable: 25% + template: + metadata: + annotations: + prometheus.io/port: "15014" + prometheus.io/scrape: "true" + sidecar.istio.io/inject: "false" + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio: pilot + istio.io/dataplane-mode: none + istio.io/rev: default + operator.istio.io/component: Pilot + sidecar.istio.io/inject: "false" + spec: + containers: + - args: + - discovery + - --monitoringAddr=:15014 + - --log_output_level=default:info + - --domain + - cluster.local + - --keepaliveMaxServerConnectionAge + - 30m + env: + - name: REVISION + value: default + - name: PILOT_CERT_PROVIDER + value: istiod + - name: POD_NAME + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.name + - name: POD_NAMESPACE + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: metadata.namespace + - name: SERVICE_ACCOUNT + valueFrom: + fieldRef: + apiVersion: v1 + fieldPath: spec.serviceAccountName + - name: KUBECONFIG + value: /var/run/secrets/remote/config + - name: CA_TRUSTED_NODE_ACCOUNTS + value: istio-system/ztunnel + - name: PILOT_TRACE_SAMPLING + value: "1" + - name: PILOT_ENABLE_ANALYSIS + value: "false" + - name: CLUSTER_ID + value: Kubernetes + - name: GOMEMLIMIT + valueFrom: + resourceFieldRef: + resource: limits.memory + - name: GOMAXPROCS + valueFrom: + resourceFieldRef: + divisor: "1" + resource: limits.cpu + - name: PLATFORM + value: "" + image: gcr.io/istio-testing/pilot:1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + name: discovery + ports: + - containerPort: 8080 + name: http-debug + protocol: TCP + - containerPort: 15010 + name: grpc-xds + protocol: TCP + - containerPort: 15012 + name: tls-xds + protocol: TCP + - containerPort: 15017 + name: https-webhooks + protocol: TCP + - containerPort: 15014 + name: http-monitoring + protocol: TCP + readinessProbe: + httpGet: + path: /ready + port: 8080 + initialDelaySeconds: 1 + periodSeconds: 3 + timeoutSeconds: 5 + resources: + requests: + cpu: 500m + memory: 2048Mi + securityContext: + allowPrivilegeEscalation: false + capabilities: + drop: + - ALL + readOnlyRootFilesystem: true + runAsNonRoot: true + volumeMounts: + - mountPath: /var/run/secrets/tokens + name: istio-token + readOnly: true + - mountPath: /var/run/secrets/istio-dns + name: local-certs + - mountPath: /etc/cacerts + name: cacerts + readOnly: true + - mountPath: /var/run/secrets/remote + name: istio-kubeconfig + readOnly: true + - mountPath: /var/run/secrets/istiod/tls + name: istio-csr-dns-cert + readOnly: true + - mountPath: /var/run/secrets/istiod/ca + name: istio-csr-ca-configmap + readOnly: true + serviceAccountName: istiod + tolerations: + - key: cni.istio.io/not-ready + operator: Exists + volumes: + - emptyDir: + medium: Memory + name: local-certs + - name: istio-token + projected: + sources: + - serviceAccountToken: + audience: istio-ca + expirationSeconds: 43200 + path: istio-token + - name: cacerts + secret: + optional: true + secretName: cacerts + - name: istio-kubeconfig + secret: + optional: true + secretName: istio-kubeconfig + - name: istio-csr-dns-cert + secret: + optional: true + secretName: istiod-tls + - configMap: + defaultMode: 420 + name: istio-ca-root-cert + optional: true + name: istio-csr-ca-configmap diff --git a/deploy/components/istio-control-plane/hpa.yaml b/deploy/components/istio-control-plane/hpa.yaml new file mode 100644 index 00000000..4c12098f --- /dev/null +++ b/deploy/components/istio-control-plane/hpa.yaml @@ -0,0 +1,31 @@ +apiVersion: autoscaling/v2 +kind: HorizontalPodAutoscaler +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istiod + namespace: istio-system +spec: + maxReplicas: 5 + metrics: + - resource: + name: cpu + target: + averageUtilization: 80 + type: Utilization + type: Resource + minReplicas: 1 + scaleTargetRef: + apiVersion: apps/v1 + kind: Deployment + name: istiod diff --git a/deploy/components/istio-control-plane/kustomization.yaml b/deploy/components/istio-control-plane/kustomization.yaml index 89e9b06e..8ebad207 100644 --- a/deploy/components/istio-control-plane/kustomization.yaml +++ b/deploy/components/istio-control-plane/kustomization.yaml @@ -1,15 +1,25 @@ # ------------------------------------------------------------------------------ # Istio Control Plane # -# This deploys an Istio control-plane for the entire cluster. This enables the -# creation of Gateways. +# **WARNING**: This is currently using a custom build which supports GIE. +# +# This deploys the Istio Control Plane to enable the creation of Gateways. +# It is expected that the CRDs are deployed separately, before deploying +# this. +# # ------------------------------------------------------------------------------ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization namespace: istio-system -namePrefix: istio- resources: - namespaces.yaml -- control-plane.yaml +- configmaps.yaml +- policies.yaml +- service-accounts.yaml +- rbac.yaml +- services.yaml +- webhooks.yaml +- deployments.yaml +- hpa.yaml diff --git a/deploy/components/istio-control-plane/namespaces.yaml b/deploy/components/istio-control-plane/namespaces.yaml index 1ab3a725..f394e916 100644 --- a/deploy/components/istio-control-plane/namespaces.yaml +++ b/deploy/components/istio-control-plane/namespaces.yaml @@ -1,4 +1,4 @@ apiVersion: v1 kind: Namespace metadata: - name: system + name: istio-system diff --git a/deploy/components/istio-control-plane/policies.yaml b/deploy/components/istio-control-plane/policies.yaml new file mode 100644 index 00000000..20402365 --- /dev/null +++ b/deploy/components/istio-control-plane/policies.yaml @@ -0,0 +1,49 @@ +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app: istio-ingressgateway + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-ingressgateway + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istio-ingress-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a7 + install.operator.istio.io/owning-resource: unknown + istio: ingressgateway + istio.io/rev: default + operator.istio.io/component: IngressGateways + release: istio + name: istio-ingressgateway + namespace: istio-system +spec: + minAvailable: 1 + selector: + matchLabels: + app: istio-ingressgateway + istio: ingressgateway +--- +apiVersion: policy/v1 +kind: PodDisruptionBudget +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio: pilot + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istiod + namespace: istio-system +spec: + minAvailable: 1 + selector: + matchLabels: + app: istiod + istio: pilot diff --git a/deploy/components/istio-control-plane/rbac.yaml b/deploy/components/istio-control-plane/rbac.yaml new file mode 100644 index 00000000..db744c8b --- /dev/null +++ b/deploy/components/istio-control-plane/rbac.yaml @@ -0,0 +1,591 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: istio-reader + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-reader + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istio-reader-clusterrole-istio-system +rules: +- apiGroups: + - config.istio.io + - security.istio.io + - networking.istio.io + - authentication.istio.io + - rbac.istio.io + - telemetry.istio.io + - extensions.istio.io + resources: + - '*' + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - endpoints + - pods + - services + - nodes + - replicationcontrollers + - namespaces + - secrets + verbs: + - get + - list + - watch +- apiGroups: + - networking.istio.io + resources: + - workloadentries + verbs: + - get + - watch + - list +- apiGroups: + - networking.x-k8s.io + - gateway.networking.k8s.io + resources: + - gateways + verbs: + - get + - watch + - list +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +- apiGroups: + - multicluster.x-k8s.io + resources: + - serviceexports + verbs: + - get + - list + - watch + - create + - delete +- apiGroups: + - multicluster.x-k8s.io + resources: + - serviceimports + verbs: + - get + - list + - watch +- apiGroups: + - apps + resources: + - replicasets + verbs: + - get + - list + - watch +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod-clusterrole-istio-system +rules: +- apiGroups: + - admissionregistration.k8s.io + resources: + - mutatingwebhookconfigurations + verbs: + - get + - list + - watch + - update + - patch +- apiGroups: + - admissionregistration.k8s.io + resources: + - validatingwebhookconfigurations + verbs: + - get + - list + - watch + - update +- apiGroups: + - config.istio.io + - security.istio.io + - networking.istio.io + - authentication.istio.io + - rbac.istio.io + - telemetry.istio.io + - extensions.istio.io + resources: + - '*' + verbs: + - get + - watch + - list +- apiGroups: + - networking.istio.io + resources: + - workloadentries + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - networking.istio.io + resources: + - workloadentries/status + - serviceentries/status + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - security.istio.io + resources: + - authorizationpolicies/status + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - "" + resources: + - services/status + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - apiextensions.k8s.io + resources: + - customresourcedefinitions + verbs: + - get + - list + - watch +- apiGroups: + - "" + resources: + - pods + - nodes + - services + - namespaces + - endpoints + verbs: + - get + - list + - watch +- apiGroups: + - discovery.k8s.io + resources: + - endpointslices + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses + - ingressclasses + verbs: + - get + - list + - watch +- apiGroups: + - networking.k8s.io + resources: + - ingresses/status + verbs: + - '*' +- apiGroups: + - "" + resources: + - configmaps + verbs: + - create + - get + - list + - watch + - update +- apiGroups: + - authentication.k8s.io + resources: + - tokenreviews + verbs: + - create +- apiGroups: + - authorization.k8s.io + resources: + - subjectaccessreviews + verbs: + - create +- apiGroups: + - gateway.networking.k8s.io + resources: + - '*' + verbs: + - get + - watch + - list +- apiGroups: + - gateway.networking.k8s.io + resources: + - backendtlspolicies/status + - gatewayclasses/status + - gateways/status + - grpcroutes/status + - httproutes/status + - referencegrants/status + - tcproutes/status + - tlsroutes/status + - udproutes/status + verbs: + - update + - patch +- apiGroups: + - gateway.networking.k8s.io + resources: + - gatewayclasses + verbs: + - create + - update + - patch + - delete +- apiGroups: + - inference.networking.x-k8s.io + resources: + - inferencepools + verbs: + - get + - watch + - list +- apiGroups: + - inference.networking.x-k8s.io + resources: + - inferencepools/status + verbs: + - update + - patch +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - watch + - list +- apiGroups: + - multicluster.x-k8s.io + resources: + - serviceexports + verbs: + - get + - watch + - list + - create + - delete +- apiGroups: + - multicluster.x-k8s.io + resources: + - serviceimports + verbs: + - get + - watch + - list +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod-gateway-controller-istio-system +rules: +- apiGroups: + - apps + resources: + - deployments + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - "" + resources: + - services + verbs: + - get + - watch + - list + - update + - patch + - create + - delete +- apiGroups: + - "" + resources: + - serviceaccounts + verbs: + - get + - watch + - list + - update + - patch + - create + - delete + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: istio-reader + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-reader + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istio-reader-clusterrole-istio-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istio-reader-clusterrole-istio-system +subjects: +- kind: ServiceAccount + name: istio-reader-service-account + namespace: istio-system + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod-clusterrole-istio-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istiod-clusterrole-istio-system +subjects: +- kind: ServiceAccount + name: istiod + namespace: istio-system + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod-gateway-controller-istio-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: ClusterRole + name: istiod-gateway-controller-istio-system +subjects: +- kind: ServiceAccount + name: istiod + namespace: istio-system +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-ingressgateway + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istio-ingress-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a7 + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: IngressGateways + release: istio + name: istio-ingressgateway-sds + namespace: istio-system +rules: +- apiGroups: + - "" + resources: + - secrets + verbs: + - get + - watch + - list + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: Role +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod + namespace: istio-system +rules: +- apiGroups: + - networking.istio.io + resources: + - gateways + verbs: + - create +- apiGroups: + - "" + resources: + - secrets + verbs: + - create + - get + - watch + - list + - update + - delete +- apiGroups: + - "" + resources: + - configmaps + verbs: + - delete +- apiGroups: + - coordination.k8s.io + resources: + - leases + verbs: + - get + - update + - patch + - create + +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-ingressgateway + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istio-ingress-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a7 + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: IngressGateways + release: istio + name: istio-ingressgateway-sds + namespace: istio-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: istio-ingressgateway-sds +subjects: +- kind: ServiceAccount + name: istio-ingressgateway-service-account +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: RoleBinding +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod + namespace: istio-system +roleRef: + apiGroup: rbac.authorization.k8s.io + kind: Role + name: istiod +subjects: +- kind: ServiceAccount + name: istiod + namespace: istio-system diff --git a/deploy/components/istio-control-plane/service-accounts.yaml b/deploy/components/istio-control-plane/service-accounts.yaml new file mode 100644 index 00000000..da977b80 --- /dev/null +++ b/deploy/components/istio-control-plane/service-accounts.yaml @@ -0,0 +1,29 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: istio-reader + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istio-reader + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: base-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istio-reader-service-account + namespace: istio-system +--- +apiVersion: v1 +kind: ServiceAccount +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + release: istio + name: istiod + namespace: istio-system diff --git a/deploy/components/istio-control-plane/services.yaml b/deploy/components/istio-control-plane/services.yaml new file mode 100644 index 00000000..5132adb3 --- /dev/null +++ b/deploy/components/istio-control-plane/services.yaml @@ -0,0 +1,36 @@ +apiVersion: v1 +kind: Service +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio: pilot + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istiod + namespace: istio-system +spec: + ports: + - name: grpc-xds + port: 15010 + protocol: TCP + - name: https-dns + port: 15012 + protocol: TCP + - name: https-webhook + port: 443 + protocol: TCP + targetPort: 15017 + - name: http-monitoring + port: 15014 + protocol: TCP + selector: + app: istiod + istio: pilot diff --git a/deploy/components/istio-control-plane/webhooks.yaml b/deploy/components/istio-control-plane/webhooks.yaml new file mode 100644 index 00000000..863c79a8 --- /dev/null +++ b/deploy/components/istio-control-plane/webhooks.yaml @@ -0,0 +1,203 @@ +apiVersion: admissionregistration.k8s.io/v1 +kind: ValidatingWebhookConfiguration +metadata: + labels: + app: istiod + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + istio: istiod + istio.io/rev: default + release: istio + name: istio-validator-istio-system +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: istiod + namespace: istio-system + path: /validate + failurePolicy: Ignore + name: rev.validation.istio.io + objectSelector: + matchExpressions: + - key: istio.io/rev + operator: In + values: + - default + rules: + - apiGroups: + - security.istio.io + - networking.istio.io + - telemetry.istio.io + - extensions.istio.io + apiVersions: + - '*' + operations: + - CREATE + - UPDATE + resources: + - '*' + sideEffects: None +--- +apiVersion: admissionregistration.k8s.io/v1 +kind: MutatingWebhookConfiguration +metadata: + labels: + app: sidecar-injector + app.kubernetes.io/instance: istio + app.kubernetes.io/managed-by: Helm + app.kubernetes.io/name: istiod + app.kubernetes.io/part-of: istio + app.kubernetes.io/version: 1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + helm.sh/chart: istiod-1.26-alpha.80c74f7f43482c226f4f4b10b4dda6261b67a71f + install.operator.istio.io/owning-resource: unknown + istio.io/rev: default + operator.istio.io/component: Pilot + release: istio + name: istio-sidecar-injector +webhooks: +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: istiod + namespace: istio-system + path: /inject + port: 443 + failurePolicy: Fail + name: rev.namespace.sidecar-injector.istio.io + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: In + values: + - default + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + reinvocationPolicy: Never + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: istiod + namespace: istio-system + path: /inject + port: 443 + failurePolicy: Fail + name: rev.object.sidecar-injector.istio.io + namespaceSelector: + matchExpressions: + - key: istio.io/rev + operator: DoesNotExist + - key: istio-injection + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + - key: istio.io/rev + operator: In + values: + - default + reinvocationPolicy: Never + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: istiod + namespace: istio-system + path: /inject + port: 443 + failurePolicy: Fail + name: namespace.sidecar-injector.istio.io + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: In + values: + - enabled + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: NotIn + values: + - "false" + reinvocationPolicy: Never + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None +- admissionReviewVersions: + - v1 + clientConfig: + service: + name: istiod + namespace: istio-system + path: /inject + port: 443 + failurePolicy: Fail + name: object.sidecar-injector.istio.io + namespaceSelector: + matchExpressions: + - key: istio-injection + operator: DoesNotExist + - key: istio.io/rev + operator: DoesNotExist + objectSelector: + matchExpressions: + - key: sidecar.istio.io/inject + operator: In + values: + - "true" + - key: istio.io/rev + operator: DoesNotExist + reinvocationPolicy: Never + rules: + - apiGroups: + - "" + apiVersions: + - v1 + operations: + - CREATE + resources: + - pods + sideEffects: None From a3355b39644ef50f5063af6f0696db152eec53ed Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:01:04 -0400 Subject: [PATCH 40/73] chore: cleanup vllm-sim deployments Signed-off-by: Shane Utt --- deploy/components/vllm-sim/deployments.yaml | 3 +- deploy/components/vllm-sim/kustomization.yaml | 7 ++-- deploy/components/vllm-sim/services.yaml | 38 ------------------- 3 files changed, 4 insertions(+), 44 deletions(-) delete mode 100644 deploy/components/vllm-sim/services.yaml diff --git a/deploy/components/vllm-sim/deployments.yaml b/deploy/components/vllm-sim/deployments.yaml index 16a299f6..308d97dd 100644 --- a/deploy/components/vllm-sim/deployments.yaml +++ b/deploy/components/vllm-sim/deployments.yaml @@ -1,4 +1,3 @@ ---- apiVersion: apps/v1 kind: Deployment metadata: @@ -18,7 +17,7 @@ spec: spec: containers: - name: vllm - image: quay.io/vllm-d/vllm-sim:0.0.1 + image: quay.io/vllm-d/vllm-sim:latest imagePullPolicy: IfNotPresent args: - "--port=8000" diff --git a/deploy/components/vllm-sim/kustomization.yaml b/deploy/components/vllm-sim/kustomization.yaml index b49d7b63..594d4ba8 100644 --- a/deploy/components/vllm-sim/kustomization.yaml +++ b/deploy/components/vllm-sim/kustomization.yaml @@ -2,16 +2,15 @@ # VLLM Simulator # # This deploys a VLLM simulator which can be used to simulate inference for -# small environments (e.g. Kubernetes In Docker (KIND) clusters) or for simple -# tests. +# small environments (e.g. Kubernetes In Docker (KIND) clusters), or for when +# all that is needed is some basic functionality. # ------------------------------------------------------------------------------ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: - deployments.yaml -- services.yaml images: -- name: vllm-sim/vllm-sim +- name: quay.io/vllm-d/vllm-sim newTag: 0.0.2 diff --git a/deploy/components/vllm-sim/services.yaml b/deploy/components/vllm-sim/services.yaml deleted file mode 100644 index 9e67d79a..00000000 --- a/deploy/components/vllm-sim/services.yaml +++ /dev/null @@ -1,38 +0,0 @@ -kind: Service -apiVersion: v1 -metadata: - name: vllm-30801 -spec: - type: ClusterIP - selector: - app: vllm-30801 - ports: - - protocol: TCP - port: 30801 - targetPort: 30801 ---- -kind: Service -apiVersion: v1 -metadata: - name: vllm-30802 -spec: - type: ClusterIP - selector: - app: vllm-30802 - ports: - - protocol: TCP - port: 30802 - targetPort: 30802 ---- -kind: Service -apiVersion: v1 -metadata: - name: vllm-30803 -spec: - type: ClusterIP - selector: - app: vllm-30803 - ports: - - protocol: TCP - port: 30803 - targetPort: 30803 From f699eb72960603a6a15a4141560c7dca46705ab8 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:02:17 -0400 Subject: [PATCH 41/73] chore: update gateway deployment for gie compat Signed-off-by: Shane Utt --- .../inference-gateway/configmaps.yaml | 18 --- .../inference-gateway/deployments.yaml | 52 +++++-- .../inference-gateway/destination-rules.yaml | 11 ++ .../inference-gateway/envoy-filters.yaml | 31 ---- .../inference-gateway/gateways.yaml | 2 +- .../inference-gateway/httproutes.yaml | 17 +++ ...erencemodel.yaml => inference-models.yaml} | 0 .../inference-gateway/inference-pools.yaml | 10 ++ .../inference-gateway/inferencepool.yaml | 141 ------------------ .../inference-gateway/kustomization.yaml | 12 +- deploy/components/inference-gateway/rbac.yaml | 68 ++++++--- .../inference-gateway/service-accounts.yaml | 4 + .../inference-gateway/services.yaml | 13 -- deploy/environments/kind/httproutes.yaml | 12 +- 14 files changed, 140 insertions(+), 251 deletions(-) delete mode 100644 deploy/components/inference-gateway/configmaps.yaml create mode 100644 deploy/components/inference-gateway/destination-rules.yaml delete mode 100644 deploy/components/inference-gateway/envoy-filters.yaml create mode 100644 deploy/components/inference-gateway/httproutes.yaml rename deploy/components/inference-gateway/{inferencemodel.yaml => inference-models.yaml} (100%) create mode 100644 deploy/components/inference-gateway/inference-pools.yaml delete mode 100644 deploy/components/inference-gateway/inferencepool.yaml create mode 100644 deploy/components/inference-gateway/service-accounts.yaml delete mode 100644 deploy/components/inference-gateway/services.yaml diff --git a/deploy/components/inference-gateway/configmaps.yaml b/deploy/components/inference-gateway/configmaps.yaml deleted file mode 100644 index 73b3f022..00000000 --- a/deploy/components/inference-gateway/configmaps.yaml +++ /dev/null @@ -1,18 +0,0 @@ -apiVersion: v1 -kind: ConfigMap -metadata: - name: endpoint-picker-config -data: - config.yaml: | - pod_selector: - ai-aware-router-pod: true - routing_filters: - routing_scorers: - - name: session-affinity - weight: 60 - - name: route-by-active-lora - weight: 50 - routing_header: x-ai-aware-router-routing - session_id_header: x-ai-aware-router-session-id - listening_port: 9080 - inference_port: 8000 diff --git a/deploy/components/inference-gateway/deployments.yaml b/deploy/components/inference-gateway/deployments.yaml index 55b595bd..8f5ab9fc 100644 --- a/deploy/components/inference-gateway/deployments.yaml +++ b/deploy/components/inference-gateway/deployments.yaml @@ -2,6 +2,8 @@ apiVersion: apps/v1 kind: Deployment metadata: name: endpoint-picker + labels: + app: endpoint-picker spec: replicas: 1 selector: @@ -13,20 +15,38 @@ spec: app: endpoint-picker spec: serviceAccountName: endpoint-picker + terminationGracePeriodSeconds: 130 containers: - - name: endpoint-picker - image: quay.io/vllm-d/gateway-api-inference-extension/epp:0.0.1 - args: - - "--config-file" - - "/etc/endpoint-picker/config.yaml" - ports: - - name: grpc - containerPort: 9080 - protocol: TCP - volumeMounts: - - name: endpoint-picker-config - mountPath: /etc/endpoint-picker - volumes: - - name: endpoint-picker-config - configMap: - name: endpoint-picker-config + - name: epp + image: quay.io/vllm-d/gateway-api-inference-extension/epp:latest + imagePullPolicy: IfNotPresent + args: + - -refreshMetricsInterval + - "500ms" + - -poolName + - "vllm-llama3-8b-instruct" + - -v + - "4" + - --zap-encoder + - "json" + - -grpcPort + - "9002" + - -grpcHealthPort + - "9003" + ports: + - containerPort: 9002 + - containerPort: 9003 + - name: metrics + containerPort: 9090 + livenessProbe: + grpc: + port: 9003 + service: inference-extension + initialDelaySeconds: 5 + periodSeconds: 10 + readinessProbe: + grpc: + port: 9003 + service: inference-extension + initialDelaySeconds: 5 + periodSeconds: 10 diff --git a/deploy/components/inference-gateway/destination-rules.yaml b/deploy/components/inference-gateway/destination-rules.yaml new file mode 100644 index 00000000..20a91a6f --- /dev/null +++ b/deploy/components/inference-gateway/destination-rules.yaml @@ -0,0 +1,11 @@ +# **WARNING** Only use in testing scenarios +apiVersion: networking.istio.io/v1 +kind: DestinationRule +metadata: + name: endpoint-picker-insecure-tls +spec: + host: endpoint-picker + trafficPolicy: + tls: + mode: SIMPLE + insecureSkipVerify: true diff --git a/deploy/components/inference-gateway/envoy-filters.yaml b/deploy/components/inference-gateway/envoy-filters.yaml deleted file mode 100644 index e9a4fec5..00000000 --- a/deploy/components/inference-gateway/envoy-filters.yaml +++ /dev/null @@ -1,31 +0,0 @@ -apiVersion: networking.istio.io/v1alpha3 -kind: EnvoyFilter -metadata: - name: endpoint-picker -spec: - configPatches: - - applyTo: HTTP_FILTER - match: - listener: - filterChain: - filter: - name: "envoy.filters.network.http_connection_manager" - patch: - operation: INSERT_FIRST - value: - name: envoy.filters.http.ext_proc - typed_config: - "@type": type.googleapis.com/envoy.extensions.filters.http.ext_proc.v3.ExternalProcessor - failure_mode_allow: false - allow_mode_override: true - processing_mode: - request_header_mode: "SEND" - response_header_mode: "SEND" - request_body_mode: "BUFFERED" - response_body_mode: "BUFFERED" - request_trailer_mode: "SEND" - response_trailer_mode: "SKIP" - grpc_service: - envoy_grpc: - cluster_name: outbound|9080||endpoint-picker.REPLACE_NAMESPACE.svc.cluster.local - timeout: 5s diff --git a/deploy/components/inference-gateway/gateways.yaml b/deploy/components/inference-gateway/gateways.yaml index 2a83b95e..98a8c7f1 100644 --- a/deploy/components/inference-gateway/gateways.yaml +++ b/deploy/components/inference-gateway/gateways.yaml @@ -3,7 +3,7 @@ kind: Gateway metadata: name: inference-gateway labels: - istio.io/rev: istio-control-plane + istio.io/enable-inference-extproc: "true" annotations: networking.istio.io/service-type: ClusterIP spec: diff --git a/deploy/components/inference-gateway/httproutes.yaml b/deploy/components/inference-gateway/httproutes.yaml new file mode 100644 index 00000000..4ef4c04f --- /dev/null +++ b/deploy/components/inference-gateway/httproutes.yaml @@ -0,0 +1,17 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: HTTPRoute +metadata: + name: inference-route +spec: + parentRefs: + - name: inference-gateway + rules: + - matches: + - path: + type: PathPrefix + value: / + backendRefs: + - group: inference.networking.x-k8s.io + kind: InferencePool + name: vllm-llama3-8b-instruct + port: 8000 diff --git a/deploy/components/inference-gateway/inferencemodel.yaml b/deploy/components/inference-gateway/inference-models.yaml similarity index 100% rename from deploy/components/inference-gateway/inferencemodel.yaml rename to deploy/components/inference-gateway/inference-models.yaml diff --git a/deploy/components/inference-gateway/inference-pools.yaml b/deploy/components/inference-gateway/inference-pools.yaml new file mode 100644 index 00000000..ece6e500 --- /dev/null +++ b/deploy/components/inference-gateway/inference-pools.yaml @@ -0,0 +1,10 @@ +apiVersion: inference.networking.x-k8s.io/v1alpha2 +kind: InferencePool +metadata: + name: vllm-llama3-8b-instruct +spec: + targetPortNumber: 8000 + selector: + app: vllm-llama3-8b-instruct + extensionRef: + name: endpoint-picker diff --git a/deploy/components/inference-gateway/inferencepool.yaml b/deploy/components/inference-gateway/inferencepool.yaml deleted file mode 100644 index 76e19fb4..00000000 --- a/deploy/components/inference-gateway/inferencepool.yaml +++ /dev/null @@ -1,141 +0,0 @@ -apiVersion: inference.networking.x-k8s.io/v1alpha2 -kind: InferencePool -metadata: - labels: - name: vllm-llama3-8b-instruct -spec: - targetPortNumber: 8000 - selector: - app: vllm-llama3-8b-instruct - extensionRef: - name: vllm-llama3-8b-instruct-epp ---- -apiVersion: v1 -kind: Service -metadata: - name: vllm-llama3-8b-instruct-epp -spec: - selector: - app: vllm-llama3-8b-instruct-epp - ports: - - protocol: TCP - port: 9002 - targetPort: 9002 - appProtocol: http2 - type: ClusterIP ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: vllm-llama3-8b-instruct-epp - labels: - app: vllm-llama3-8b-instruct-epp -spec: - replicas: 1 - selector: - matchLabels: - app: vllm-llama3-8b-instruct-epp - template: - metadata: - labels: - app: vllm-llama3-8b-instruct-epp - spec: - # Conservatively, this timeout should mirror the longest grace period of the pods within the pool - terminationGracePeriodSeconds: 130 - containers: - - name: epp -# image: us-central1-docker.pkg.dev/k8s-staging-images/gateway-api-inference-extension/epp:main - image: gateway-api-inference-extension/epp:latest - imagePullPolicy: IfNotPresent - args: - - -refreshMetricsInterval - - "500ms" - - -poolName - - "vllm-llama3-8b-instruct" - - -v - - "4" - - --zap-encoder - - "json" - - -grpcPort - - "9002" - - -grpcHealthPort - - "9003" - ports: - - containerPort: 9002 - - containerPort: 9003 - - name: metrics - containerPort: 9090 - livenessProbe: - grpc: - port: 9003 - service: inference-extension - initialDelaySeconds: 5 - periodSeconds: 10 - readinessProbe: - grpc: - port: 9003 - service: inference-extension - initialDelaySeconds: 5 - periodSeconds: 10 ---- -kind: Role -apiVersion: rbac.authorization.k8s.io/v1 -metadata: - name: pod-read -rules: -- apiGroups: - - "inference.networking.x-k8s.io" - resources: - - "inferencemodels" - verbs: - - "get" - - "watch" - - "list" -- apiGroups: - - "" - resources: - - "pods" - verbs: - - "get" - - "watch" - - "list" -- apiGroups: - - "inference.networking.x-k8s.io" - resources: - - "inferencepools" - verbs: - - "get" - - "watch" - - "list" -- apiGroups: - - "discovery.k8s.io" - resources: - - "endpointslices" - verbs: - - "get" - - "watch" - - "list" -- apiGroups: - - "authentication.k8s.io" - resources: - - "tokenreviews" - verbs: - - "create" -- apiGroups: - - "authorization.k8s.io" - resources: - - "subjectaccessreviews" - verbs: - - "create" ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: pod-read-binding -subjects: -- kind: ServiceAccount - name: default -roleRef: - apiGroup: rbac.authorization.k8s.io - kind: Role - name: pod-read diff --git a/deploy/components/inference-gateway/kustomization.yaml b/deploy/components/inference-gateway/kustomization.yaml index 10b898cb..96278338 100644 --- a/deploy/components/inference-gateway/kustomization.yaml +++ b/deploy/components/inference-gateway/kustomization.yaml @@ -18,13 +18,15 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- configmaps.yaml -- deployments.yaml -- services.yaml +- service-accounts.yaml - rbac.yaml +- destination-rules.yaml +- inference-pools.yaml +- inference-models.yaml +- deployments.yaml - gateways.yaml -- envoy-filters.yaml +- httproutes.yaml images: -- name: inference-router/router-ext-proc +- name: quay.io/vllm-d/gateway-api-inference-extension/epp newTag: 0.0.1 diff --git a/deploy/components/inference-gateway/rbac.yaml b/deploy/components/inference-gateway/rbac.yaml index 1b457dc8..8414d893 100644 --- a/deploy/components/inference-gateway/rbac.yaml +++ b/deploy/components/inference-gateway/rbac.yaml @@ -1,31 +1,61 @@ -apiVersion: v1 -kind: ServiceAccount -metadata: - name: endpoint-picker ---- -apiVersion: rbac.authorization.k8s.io/v1 kind: Role +apiVersion: rbac.authorization.k8s.io/v1 metadata: name: endpoint-picker rules: - - apiGroups: - - "" - resources: - - "pods" - verbs: - - "get" - - "list" - - "watch" ---- +- apiGroups: + - "inference.networking.x-k8s.io" + resources: + - "inferencemodels" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "" + resources: + - "pods" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "inference.networking.x-k8s.io" + resources: + - "inferencepools" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "discovery.k8s.io" + resources: + - "endpointslices" + verbs: + - "get" + - "watch" + - "list" +- apiGroups: + - "authentication.k8s.io" + resources: + - "tokenreviews" + verbs: + - "create" +- apiGroups: + - "authorization.k8s.io" + resources: + - "subjectaccessreviews" + verbs: + - "create" +--- apiVersion: rbac.authorization.k8s.io/v1 kind: RoleBinding metadata: name: endpoint-picker-binding subjects: - - kind: ServiceAccount - name: endpoint-picker +- kind: ServiceAccount + name: endpoint-picker roleRef: + apiGroup: rbac.authorization.k8s.io kind: Role name: endpoint-picker - apiGroup: rbac.authorization.k8s.io - diff --git a/deploy/components/inference-gateway/service-accounts.yaml b/deploy/components/inference-gateway/service-accounts.yaml new file mode 100644 index 00000000..18cf4570 --- /dev/null +++ b/deploy/components/inference-gateway/service-accounts.yaml @@ -0,0 +1,4 @@ +apiVersion: v1 +kind: ServiceAccount +metadata: + name: endpoint-picker diff --git a/deploy/components/inference-gateway/services.yaml b/deploy/components/inference-gateway/services.yaml deleted file mode 100644 index d8d5d5b1..00000000 --- a/deploy/components/inference-gateway/services.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: endpoint-picker -spec: - type: ClusterIP - selector: - app: endpoint-picker - ports: - - name: grpc - protocol: TCP - port: 9080 - targetPort: 9080 diff --git a/deploy/environments/kind/httproutes.yaml b/deploy/environments/kind/httproutes.yaml index 7ff6e56b..4ef4c04f 100644 --- a/deploy/environments/kind/httproutes.yaml +++ b/deploy/environments/kind/httproutes.yaml @@ -9,11 +9,9 @@ spec: - matches: - path: type: PathPrefix - value: /v1 + value: / backendRefs: - - name: vllm-30801 - port: 30801 - - name: vllm-30802 - port: 30802 - - name: vllm-30802 - port: 30802 + - group: inference.networking.x-k8s.io + kind: InferencePool + name: vllm-llama3-8b-instruct + port: 8000 From 760414ed8262eb79b09e351afbe9157bf6cc6564 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:02:48 -0400 Subject: [PATCH 42/73] chore: kind env script cleanup Signed-off-by: Shane Utt --- scripts/run-kind.sh | 26 ++++++++++++-------------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index 30f9908f..ac649543 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -2,8 +2,8 @@ # This shell script deploys a kind cluster with an Istio-based Gateway API # implementation fully configured. It deploys the vllm simulator, which it -# exposes with a Gateway and HTTPRoute. The Gateway is configured with the -# a filter for the ext_proc endpoint picker. +# exposes with a Gateway -> HTTPRoute -> InferencePool. The Gateway is +# configured with the a filter for the ext_proc endpoint picker. set -eo pipefail @@ -15,7 +15,7 @@ set -eo pipefail # See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/28 # Set a default CLUSTER_NAME if not provided -: "${CLUSTER_NAME:=inference-gateway}" +: "${CLUSTER_NAME:=gie-dev-env}" # Set the default IMAGE_REGISTRY if not provided : "${IMAGE_REGISTRY:=quay.io/vllm-d}" @@ -29,6 +29,9 @@ set -eo pipefail # Set a default ENDPOINT_PICKER_IMAGE if not provided : "${ENDPOINT_PICKER_IMAGE:=gateway-api-inference-extension/epp}" +# Set the namespace to deploy the Gateway stack to +: "${PROJECT_NAMESPACE:=default}" + # ------------------------------------------------------------------------------ # Setup & Requirement Checks # ------------------------------------------------------------------------------ @@ -108,22 +111,17 @@ kubectl kustomize deploy/components/crds | kubectl --context ${KUBE_CONTEXT} apply --server-side --force-conflicts -f - # ------------------------------------------------------------------------------ -# Sail Operator Deployment +# Istio Control Plane Deployment # ------------------------------------------------------------------------------ -# Deploy the Sail Operator -kubectl kustomize --enable-helm deploy/components/sail-operator | - kubectl --context ${KUBE_CONTEXT} apply --server-side --force-conflicts -f - - -# Wait for the Sail Operator to be ready -kubectl --context ${KUBE_CONTEXT} -n sail-operator wait deployment/sail-operator --for=condition=Available --timeout=60s +kubectl kustomize deploy/components/istio-control-plane | kubectl --context ${KUBE_CONTEXT} apply -f - # ------------------------------------------------------------------------------ # Development Environment # ------------------------------------------------------------------------------ # Deploy the environment to the "default" namespace -kubectl kustomize deploy/environments/kind | sed 's/REPLACE_NAMESPACE/default/gI' \ +kubectl kustomize deploy/environments/kind | sed "s/REPLACE_NAMESPACE/${PROJECT_NAMESPACE}/gI" \ | kubectl --context ${KUBE_CONTEXT} apply -f - # Wait for all pods to be ready @@ -141,8 +139,8 @@ Deployment completed! Status: -* The vllm simulator is running -* The Gateway is exposing the simulator +* The vllm simulator is running and exposed via InferencePool +* The Gateway is exposing the InferencePool via HTTPRoute * The Endpoint Picker is loaded into the Gateway via ext_proc You can watch the Endpoint Picker logs with: @@ -155,7 +153,7 @@ You can use a port-forward to access the Gateway: With that running in the background, you can make requests: - $ curl -v -w '\n' -X POST -H 'Content-Type: application/json' -d '{"model":"model1","messages":[{"role":"user","content":"help"}]}' http://localhost:8080 + $ curl -v http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' ----------------------------------------- EOF From 5659f22cfdbee9bf7c70dd2e59aa3106f812cb12 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:20:40 -0400 Subject: [PATCH 43/73] chore: cleanup sail operator deployment Signed-off-by: Shane Utt --- Makefile | 4 ---- deploy/components/sail-operator/kustomization.yaml | 3 --- 2 files changed, 7 deletions(-) diff --git a/Makefile b/Makefile index 0353b00b..577642a2 100644 --- a/Makefile +++ b/Makefile @@ -563,8 +563,6 @@ ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" @echo "Installing CRDs for Gateway API & GIE" kustomize build deploy/components/crds | kubectl apply --server-side --force-conflicts -f - - @echo "Installing the Istio Sail Operator and CRDs for Istio" - kustomize build --enable-helm deploy/components/sail-operator | kubectl apply --server-side --force-conflicts -f - @echo "Installing the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl apply -f - else @@ -588,8 +586,6 @@ ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components" @echo "Uninstalling the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl delete -f - || true - @echo "Uninstalling the Istio Sail Operator and CRDs for Istio" - kustomize build --enable-helm deploy/components/sail-operator | kubectl delete -f - || true @echo "Uninstalling CRDs for Gateway API & GIE" kustomize build deploy/components/crds | kubectl delete -f - || true else diff --git a/deploy/components/sail-operator/kustomization.yaml b/deploy/components/sail-operator/kustomization.yaml index e0737753..125a1c82 100644 --- a/deploy/components/sail-operator/kustomization.yaml +++ b/deploy/components/sail-operator/kustomization.yaml @@ -5,9 +5,6 @@ # of Istio Control Planes, and ultimately Gateways. This will also deploy all # the Istio CRDs. # -# This is required on Kubernetes clusters, and OpenShift clusters versions -# below 4.19, but OpenShift 4.19+ clusters include all this by default. -# # **Warning**: This needs to be deployed before, and separately from other # components as it deploys CRDs. It can be deployed with: # From 1ef859f02d19287cec8523aaad8f5674ff9ae6b3 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:28:26 -0400 Subject: [PATCH 44/73] chore: cleanup kind dev env deployment Signed-off-by: Shane Utt --- deploy/environments/kind/httproutes.yaml | 17 ----------------- deploy/environments/kind/kustomization.yaml | 15 +-------------- 2 files changed, 1 insertion(+), 31 deletions(-) delete mode 100644 deploy/environments/kind/httproutes.yaml diff --git a/deploy/environments/kind/httproutes.yaml b/deploy/environments/kind/httproutes.yaml deleted file mode 100644 index 4ef4c04f..00000000 --- a/deploy/environments/kind/httproutes.yaml +++ /dev/null @@ -1,17 +0,0 @@ -apiVersion: gateway.networking.k8s.io/v1 -kind: HTTPRoute -metadata: - name: inference-route -spec: - parentRefs: - - name: inference-gateway - rules: - - matches: - - path: - type: PathPrefix - value: / - backendRefs: - - group: inference.networking.x-k8s.io - kind: InferencePool - name: vllm-llama3-8b-instruct - port: 8000 diff --git a/deploy/environments/kind/kustomization.yaml b/deploy/environments/kind/kustomization.yaml index f5f8d76c..bd9a903d 100644 --- a/deploy/environments/kind/kustomization.yaml +++ b/deploy/environments/kind/kustomization.yaml @@ -7,19 +7,7 @@ # * VLLM Simulator # * Inference Gateway # -# **Note**: The Sail Operator must be deployed first. -# -# This will expose the VLLM simulator via an HTTPRoute. You can access the -# Gateway with a port-forward: -# -# $ kubectl port-forward service/inference-gateway-istio 8080:80 -# -# And the requests can be made: -# -# $ curl -v -w '\n' -X POST -H 'Content-Type: application/json' \ -# -d '{"model":"model1","messages":[{"role":"user","content":"Hello!"}]}' \ -# http://localhost:8080/v1/chat/completions -# +# This will expose the VLLM simulator via InferencePool and an HTTPRoute. # ------------------------------------------------------------------------------ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization @@ -28,4 +16,3 @@ resources: - ../../components/istio-control-plane/ - ../../components/vllm-sim/ - ../../components/inference-gateway/ -- httproutes.yaml From 322a42102f67312a64c0f1b9a865e1896fee018b Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:30:43 -0400 Subject: [PATCH 45/73] chore: move kind dev env deploys Signed-off-by: Shane Utt --- deploy/environments/{ => dev}/kind/kustomization.yaml | 6 +++--- scripts/run-kind.sh | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) rename deploy/environments/{ => dev}/kind/kustomization.yaml (80%) diff --git a/deploy/environments/kind/kustomization.yaml b/deploy/environments/dev/kind/kustomization.yaml similarity index 80% rename from deploy/environments/kind/kustomization.yaml rename to deploy/environments/dev/kind/kustomization.yaml index bd9a903d..57fa4b31 100644 --- a/deploy/environments/kind/kustomization.yaml +++ b/deploy/environments/dev/kind/kustomization.yaml @@ -13,6 +13,6 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: -- ../../components/istio-control-plane/ -- ../../components/vllm-sim/ -- ../../components/inference-gateway/ +- ../../../components/istio-control-plane/ +- ../../../components/vllm-sim/ +- ../../../components/inference-gateway/ diff --git a/scripts/run-kind.sh b/scripts/run-kind.sh index ac649543..ce4a8730 100755 --- a/scripts/run-kind.sh +++ b/scripts/run-kind.sh @@ -121,7 +121,7 @@ kubectl kustomize deploy/components/istio-control-plane | kubectl --context ${KU # ------------------------------------------------------------------------------ # Deploy the environment to the "default" namespace -kubectl kustomize deploy/environments/kind | sed "s/REPLACE_NAMESPACE/${PROJECT_NAMESPACE}/gI" \ +kubectl kustomize deploy/environments/dev/kind | sed "s/REPLACE_NAMESPACE/${PROJECT_NAMESPACE}/gI" \ | kubectl --context ${KUBE_CONTEXT} apply -f - # Wait for all pods to be ready From 383d2db21c80b820aeaa1a25ec6733a127fb83a0 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:30:59 -0400 Subject: [PATCH 46/73] chore: move openshift dev env deploys Signed-off-by: Shane Utt --- Makefile | 12 ++++++------ .../{ => dev}/openshift/common/patch-service.yaml | 0 .../openshift/common/patch-statefulset.yaml | 0 .../{ => dev}/openshift/common/service.yaml | 0 .../{ => dev}/openshift/common/statefulset.yaml | 0 .../{ => dev}/openshift/kustomization.yaml | 0 .../{ => dev}/openshift/openshift/patch-route.yaml | 0 .../{ => dev}/openshift/openshift/route.yaml | 0 .../{ => dev}/openshift/rbac/exec-rbac-role.yaml | 0 .../openshift/rbac/exec-rbac-rolebinding.yaml | 0 .../{ => dev}/openshift/rbac/patch-rbac-role.yaml | 0 .../openshift/rbac/patch-rbac-rolebinding.yaml | 0 12 files changed, 6 insertions(+), 6 deletions(-) rename deploy/environments/{ => dev}/openshift/common/patch-service.yaml (100%) rename deploy/environments/{ => dev}/openshift/common/patch-statefulset.yaml (100%) rename deploy/environments/{ => dev}/openshift/common/service.yaml (100%) rename deploy/environments/{ => dev}/openshift/common/statefulset.yaml (100%) rename deploy/environments/{ => dev}/openshift/kustomization.yaml (100%) rename deploy/environments/{ => dev}/openshift/openshift/patch-route.yaml (100%) rename deploy/environments/{ => dev}/openshift/openshift/route.yaml (100%) rename deploy/environments/{ => dev}/openshift/rbac/exec-rbac-role.yaml (100%) rename deploy/environments/{ => dev}/openshift/rbac/exec-rbac-rolebinding.yaml (100%) rename deploy/environments/{ => dev}/openshift/rbac/patch-rbac-role.yaml (100%) rename deploy/environments/{ => dev}/openshift/rbac/patch-rbac-rolebinding.yaml (100%) diff --git a/Makefile b/Makefile index 577642a2..b835aaff 100644 --- a/Makefile +++ b/Makefile @@ -524,7 +524,7 @@ install-k8s: check-kubectl check-kustomize check-envsubst ## Install on Kubernet kubectl config set-context --current --namespace=$(NAMESPACE) @echo "Deploying resources from deploy/ ..." # Build the kustomization from deploy, substitute variables, and apply the YAML - kustomize build deploy/environments/openshift | envsubst | kubectl apply -f - + kustomize build deploy/environments/dev/openshift | envsubst | kubectl apply -f - @echo "Waiting for pod to become ready..." sleep 5 @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ @@ -539,7 +539,7 @@ uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Ku export PROJECT_NAME=${PROJECT_NAME} export NAMESPACE=${NAMESPACE} @echo "Removing resources from Kubernetes..." - kustomize build deploy/environments/openshift | envsubst | kubectl delete --force -f - || true + kustomize build deploy/environments/dev/openshift | envsubst | kubectl delete --force -f - || true POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ echo "Deleting pod: $$POD"; \ kubectl delete pod "$$POD" --force --grace-period=0 || true; \ @@ -605,7 +605,7 @@ install-openshift: check-kubectl check-kustomize check-envsubst ## Install on Op kubectl create namespace $(NAMESPACE) 2>/dev/null || true @echo "Deploying common resources from deploy/ ..." # Build and substitute the base manifests from deploy, then apply them - kustomize build deploy/environments/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -n $(NAMESPACE) -f - + kustomize build deploy/environments/dev/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -n $(NAMESPACE) -f - @echo "Waiting for pod to become ready..." sleep 5 @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}'); \ @@ -622,7 +622,7 @@ install-openshift: check-kubectl check-kustomize check-envsubst ## Install on Op .PHONY: uninstall-openshift uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall from OpenShift @echo "Removing resources from OpenShift..." - kustomize build deploy/environments/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete --force -f - || true + kustomize build deploy/environments/dev/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete --force -f - || true # @if kubectl api-resources --api-group=route.openshift.io | grep -q Route; then \ # envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' < deploy/openshift/route.yaml | kubectl delete --force -f - || true; \ # fi @@ -636,12 +636,12 @@ uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall f .PHONY: install-rbac install-rbac: check-kubectl check-kustomize check-envsubst ## Install RBAC @echo "Applying RBAC configuration from deploy/rbac..." - kustomize build deploy/environments/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -f - + kustomize build deploy/environments/dev/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -f - .PHONY: uninstall-rbac uninstall-rbac: check-kubectl check-kustomize check-envsubst ## Uninstall RBAC @echo "Removing RBAC configuration from deploy/rbac..." - kustomize build deploy/environments/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete -f - || true + kustomize build deploy/environments/dev/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete -f - || true ##@ Version Extraction diff --git a/deploy/environments/openshift/common/patch-service.yaml b/deploy/environments/dev/openshift/common/patch-service.yaml similarity index 100% rename from deploy/environments/openshift/common/patch-service.yaml rename to deploy/environments/dev/openshift/common/patch-service.yaml diff --git a/deploy/environments/openshift/common/patch-statefulset.yaml b/deploy/environments/dev/openshift/common/patch-statefulset.yaml similarity index 100% rename from deploy/environments/openshift/common/patch-statefulset.yaml rename to deploy/environments/dev/openshift/common/patch-statefulset.yaml diff --git a/deploy/environments/openshift/common/service.yaml b/deploy/environments/dev/openshift/common/service.yaml similarity index 100% rename from deploy/environments/openshift/common/service.yaml rename to deploy/environments/dev/openshift/common/service.yaml diff --git a/deploy/environments/openshift/common/statefulset.yaml b/deploy/environments/dev/openshift/common/statefulset.yaml similarity index 100% rename from deploy/environments/openshift/common/statefulset.yaml rename to deploy/environments/dev/openshift/common/statefulset.yaml diff --git a/deploy/environments/openshift/kustomization.yaml b/deploy/environments/dev/openshift/kustomization.yaml similarity index 100% rename from deploy/environments/openshift/kustomization.yaml rename to deploy/environments/dev/openshift/kustomization.yaml diff --git a/deploy/environments/openshift/openshift/patch-route.yaml b/deploy/environments/dev/openshift/openshift/patch-route.yaml similarity index 100% rename from deploy/environments/openshift/openshift/patch-route.yaml rename to deploy/environments/dev/openshift/openshift/patch-route.yaml diff --git a/deploy/environments/openshift/openshift/route.yaml b/deploy/environments/dev/openshift/openshift/route.yaml similarity index 100% rename from deploy/environments/openshift/openshift/route.yaml rename to deploy/environments/dev/openshift/openshift/route.yaml diff --git a/deploy/environments/openshift/rbac/exec-rbac-role.yaml b/deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml similarity index 100% rename from deploy/environments/openshift/rbac/exec-rbac-role.yaml rename to deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml diff --git a/deploy/environments/openshift/rbac/exec-rbac-rolebinding.yaml b/deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml similarity index 100% rename from deploy/environments/openshift/rbac/exec-rbac-rolebinding.yaml rename to deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml diff --git a/deploy/environments/openshift/rbac/patch-rbac-role.yaml b/deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml similarity index 100% rename from deploy/environments/openshift/rbac/patch-rbac-role.yaml rename to deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml diff --git a/deploy/environments/openshift/rbac/patch-rbac-rolebinding.yaml b/deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml similarity index 100% rename from deploy/environments/openshift/rbac/patch-rbac-rolebinding.yaml rename to deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml From 55bf0f851ba3169ff054db6b3d45523520c1d65a Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 17:30:59 -0400 Subject: [PATCH 47/73] feat: add environment.dev.kind makefile target Signed-off-by: Shane Utt --- Makefile | 33 +++++++++++ scripts/{run-kind.sh => kind-dev-env.sh} | 35 +++-------- scripts/kind-load-images.sh | 74 ++++++++++++++++++++++++ 3 files changed, 114 insertions(+), 28 deletions(-) rename scripts/{run-kind.sh => kind-dev-env.sh} (78%) create mode 100755 scripts/kind-load-images.sh diff --git a/Makefile b/Makefile index b835aaff..416e02b7 100644 --- a/Makefile +++ b/Makefile @@ -785,3 +785,36 @@ print-namespace: ## Print the current namespace .PHONY: print-project-name print-project-name: ## Print the current project name @echo "$(PROJECT_NAME)" + +# +# Development Environments +# + +KIND_CLUSTER_NAME ?= gie-dev + +# ------------------------------------------------------------------------------ +# Development Environment: Kubernetes In Docker (KIND) +# +# This target will deploy a local kind cluster with the GIE stack deployed into +# the default namespace for development and testing. +# +# ------------------------------------------------------------------------------ +.PHONY: environment.dev.kind +environment.dev.kind: + CLUSTER_NAME=$(KIND_CLUSTER_NAME) ./scripts/kind-dev-env.sh + +# ------------------------------------------------------------------------------ +# Development Environment Update: Kubernetes In Docker (KIND) +# +# This target will build the current changes into an image, load them into an +# existing kind cluster and perform a rollout so that the new changes are +# reflected in the environment. +# +# ------------------------------------------------------------------------------ +.PHONY: environment.dev.kind.update +environment.dev.kind.update: image-build + @echo "INFO: Loading images into cluster" + CLUSTER_NAME=$(KIND_CLUSTER_NAME) ./scripts/kind-load-images.sh 2>&1 + @echo "INFO: Restarting the Endpoint Picker Deployment" + kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout restart deployment endpoint-picker + kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout status deployment endpoint-picker diff --git a/scripts/run-kind.sh b/scripts/kind-dev-env.sh similarity index 78% rename from scripts/run-kind.sh rename to scripts/kind-dev-env.sh index ce4a8730..3cad7fba 100755 --- a/scripts/run-kind.sh +++ b/scripts/kind-dev-env.sh @@ -11,23 +11,13 @@ set -eo pipefail # Variables # ------------------------------------------------------------------------------ +SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" + # TODO: get image names, paths, versions, etc. from the .version.json file # See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/28 # Set a default CLUSTER_NAME if not provided -: "${CLUSTER_NAME:=gie-dev-env}" - -# Set the default IMAGE_REGISTRY if not provided -: "${IMAGE_REGISTRY:=quay.io/vllm-d}" - -# Set a default VLLM_SIMULATOR_VERSION if not provided -: "${VLLM_SIMULATOR_VERSION:=0.0.2}" - -# Set a default ENDPOINT_PICKER_VERSION if not provided -: "${ENDPOINT_PICKER_VERSION:=0.0.1}" - -# Set a default ENDPOINT_PICKER_IMAGE if not provided -: "${ENDPOINT_PICKER_IMAGE:=gateway-api-inference-extension/epp}" +: "${CLUSTER_NAME:=gie-dev}" # Set the namespace to deploy the Gateway stack to : "${PROJECT_NAMESPACE:=default}" @@ -81,6 +71,9 @@ KUBE_CONTEXT="kind-${CLUSTER_NAME}" set -x +# Load the required container images +"${SCRIPT_DIR}/kind-load-images.sh" + # Hotfix for https://github.com/kubernetes-sigs/kind/issues/3880 CONTAINER_NAME="${CLUSTER_NAME}-control-plane" ${CONTAINER_RUNTIME} exec -it ${CONTAINER_NAME} /bin/bash -c "sysctl net.ipv4.conf.all.arp_ignore=0" @@ -89,20 +82,6 @@ ${CONTAINER_RUNTIME} exec -it ${CONTAINER_NAME} /bin/bash -c "sysctl net.ipv4.co kubectl --context ${KUBE_CONTEXT} -n kube-system wait --for=condition=Ready --all pods --timeout=300s kubectl --context ${KUBE_CONTEXT} -n local-path-storage wait --for=condition=Ready --all pods --timeout=300s -# Load the vllm simulator image into the cluster -if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman save ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin -else - kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/vllm-sim:${VLLM_SIMULATOR_VERSION} -fi - -# Load the ext_proc endpoint-picker image into the cluster -if [ "${CONTAINER_RUNTIME}" == "podman" ]; then - podman save ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin -else - kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_VERSION} -fi - # ------------------------------------------------------------------------------ # CRD Deployment (Gateway API + GIE) # ------------------------------------------------------------------------------ @@ -153,7 +132,7 @@ You can use a port-forward to access the Gateway: With that running in the background, you can make requests: - $ curl -v http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' + $ curl -s -w '\n' http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq ----------------------------------------- EOF diff --git a/scripts/kind-load-images.sh b/scripts/kind-load-images.sh new file mode 100755 index 00000000..b152f959 --- /dev/null +++ b/scripts/kind-load-images.sh @@ -0,0 +1,74 @@ +#!/bin/bash + +# ------------------------------------------------------------------------------ +# This shell script loads images into a kind cluster that are needed for a +# development environment including the vllm simulator and the GIE itself. +# ------------------------------------------------------------------------------ + +set -eo pipefail + +# ------------------------------------------------------------------------------ +# Variables +# ------------------------------------------------------------------------------ + +# Set a default CLUSTER_NAME if not provided +: "${CLUSTER_NAME:=gie-dev}" + +# Set the default IMAGE_REGISTRY if not provided +: "${IMAGE_REGISTRY:=quay.io/vllm-d}" + +# Set a default VLLM_SIMULATOR_IMAGE if not provided +: "${VLLM_SIMULATOR_IMAGE:=vllm-sim}" + +# Set a default VLLM_SIMULATOR_TAG if not provided +: "${VLLM_SIMULATOR_TAG:=0.0.2}" + +# Set a default ENDPOINT_PICKER_IMAGE if not provided +: "${ENDPOINT_PICKER_IMAGE:=gateway-api-inference-extension/epp}" + +# Set a default ENDPOINT_PICKER_TAG if not provided +: "${ENDPOINT_PICKER_TAG:=0.0.1}" + +# ------------------------------------------------------------------------------ +# Setup & Requirement Checks +# ------------------------------------------------------------------------------ + +# Check for a supported container runtime if an explicit one was not set +if [ -z "${CONTAINER_RUNTIME}" ]; then + if command -v docker &> /dev/null; then + CONTAINER_RUNTIME="docker" + elif command -v podman &> /dev/null; then + CONTAINER_RUNTIME="podman" + else + echo "Neither docker nor podman could be found in PATH" >&2 + exit 1 + fi +fi + +set -u + +# Check for required programs +for cmd in kind ${CONTAINER_RUNTIME}; do + if ! command -v "$cmd" &> /dev/null; then + echo "Error: $cmd is not installed or not in the PATH." + exit 1 + fi +done + +# ------------------------------------------------------------------------------ +# Load Container Images +# ------------------------------------------------------------------------------ + +# Load the vllm simulator image into the cluster +if [ "${CONTAINER_RUNTIME}" == "podman" ]; then + podman save ${IMAGE_REGISTRY}/${VLLM_SIMULATOR_IMAGE}:${VLLM_SIMULATOR_TAG} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin +else + kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${VLLM_SIMULATOR_IMAGE}:${VLLM_SIMULATOR_TAG} +fi + +# Load the ext_proc endpoint-picker image into the cluster +if [ "${CONTAINER_RUNTIME}" == "podman" ]; then + podman save ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_TAG} -o /dev/stdout | kind --name ${CLUSTER_NAME} load image-archive /dev/stdin +else + kind --name ${CLUSTER_NAME} load docker-image ${IMAGE_REGISTRY}/${ENDPOINT_PICKER_IMAGE}:${ENDPOINT_PICKER_TAG} +fi From 896270fd431a77d99cd7875e073018a81e75cca9 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 16:03:01 -0400 Subject: [PATCH 48/73] docs: add development documentation Signed-off-by: Shane Utt --- DEVELOPMENT.md | 73 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) create mode 100644 DEVELOPMENT.md diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md new file mode 100644 index 00000000..b1a5c409 --- /dev/null +++ b/DEVELOPMENT.md @@ -0,0 +1,73 @@ +# Development + +Developing and testing the Gateway API Inference Extension (GIE) is done by +building your Endpoint Picker (EPP) image and attaching that to a `Gateway` on a +development cluster, with some model serving backend to route traffic to. + +We provide `Makefile` targets and development environment deployment manifests +under the `deploy/environments` directory, which include support for +multiple kinds of clusters: + +* Kubernetes In Docker (KIND) +* Kubernetes (WIP: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14) +* OpenShift (WIP: https://github.com/neuralmagic/gateway-api-inference-extension/issues/22) + +We support multiple different model serving platforms for testing: + +* VLLM +* VLLM-Simulator + +In the following sections we will cover how to use the different development +environment options. + +## Kubernetes In Docker (KIND) + +A [KIND] cluster can be used for basic development and testing on a local +system. This environment will generally be limited to using a model serving +simulator and as such is very limited compared to clusters with full model +serving resources. + +[KIND]:https://github.com/kubernetes-sigs/kind + +### Setup + +> **WARNING**: This current requires you to have manually built the vllm +> simulator separately on your local system. In a future iteration this will +> be handled automatically and will not be required. + +Run the following: + +```console +make environment.dev.kind +``` + +This will create a `kind` cluster (or re-use an existing one) using the system's +local container runtime and deploy the development stack into the `default` +namespace. Instrutions will be provided on how to access the `Gateway` and send +requests for testing. + +> **NOTE**: If you require significant customization of this environment beyond +> what the standard deployment provides, you can use the `deploy/components` +> with `kustomize` to build your own highly customized environment. You can use +> the `deploy/environments/kind` deployment as a reference for your own. + +#### Development Cycle + +To test your changes to the GIE in this environment, make your changes locally +and then run the following: + +```console +make environment.dev.kind.update +``` + +This will build images with your recent changes and load the new images to the +cluster. Then a rollout the `Deployments` will be performed so that your +recent changes are refleted. + +## Kubernetes + +WIP + +## OpenShift + +WIP From a83015ba8e8da85d458f0a01440a9d4501fc2a27 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Fri, 18 Apr 2025 18:09:46 -0400 Subject: [PATCH 49/73] chore: cleanup some language in the Makefile Signed-off-by: Shane Utt --- Makefile | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index 416e02b7..e1870ccc 100644 --- a/Makefile +++ b/Makefile @@ -561,7 +561,7 @@ uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Ku install-openshift-infrastructure: ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" - @echo "Installing CRDs for Gateway API & GIE" + @echo "Installing CRDs" kustomize build deploy/components/crds | kubectl apply --server-side --force-conflicts -f - @echo "Installing the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl apply -f - @@ -586,7 +586,7 @@ ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components" @echo "Uninstalling the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl delete -f - || true - @echo "Uninstalling CRDs for Gateway API & GIE" + @echo "Uninstalling CRDs" kustomize build deploy/components/crds | kubectl delete -f - || true else $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") From 175fbeced4e4edcc9bce2805599df8a202636b50 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 20:36:19 -0400 Subject: [PATCH 50/73] added infra pipeline run stuff --- .tekton/deploy-infra-to-openshift.yaml | 88 ++++++++++++ .tekton/infra-pipelinerun.yaml | 182 +++++++++++++++++++++++++ 2 files changed, 270 insertions(+) create mode 100644 .tekton/deploy-infra-to-openshift.yaml create mode 100644 .tekton/infra-pipelinerun.yaml diff --git a/.tekton/deploy-infra-to-openshift.yaml b/.tekton/deploy-infra-to-openshift.yaml new file mode 100644 index 00000000..73f08db6 --- /dev/null +++ b/.tekton/deploy-infra-to-openshift.yaml @@ -0,0 +1,88 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: openshift-redeploy-infra-task +spec: + params: + - name: source-branch + type: string + description: "Git branch name" + - name: prod-version + type: string + - name: dev-version + type: string + - name: prod_image_tag_base + type: string + - name: dev_image_tag_base + type: string + workspaces: + - name: source + steps: + - name: redeploy + image: quay.io/projectquay/golang:1.24 + imagePullPolicy: IfNotPresent + securityContext: + privileged: true + workingDir: $(workspaces.source.path) + env: + - name: STORAGE_DRIVER + value: vfs + script: | + #!/bin/bash + set -e + + echo "📦 Installing dependencies with dnf..." + dnf install -y make jq curl gettext && dnf clean all + + echo "📥 Installing kubectl..." + curl -LO "https://dl.k8s.io/release/$(curl -L -s https://dl.k8s.io/release/stable.txt)/bin/linux/amd64/kubectl" + install -o root -g root -m 0755 kubectl /usr/local/bin/kubectl + + echo "📥 Installing kustomize..." + KUSTOMIZE_TAG=$(curl -s https://api.github.com/repos/kubernetes-sigs/kustomize/releases/latest | jq -r '.tag_name') + KUSTOMIZE_VERSION="${KUSTOMIZE_TAG##*/}" # strips prefix like 'kustomize/' from tag + + curl -LO "https://github.com/kubernetes-sigs/kustomize/releases/download/${KUSTOMIZE_TAG}/kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" + + tar -xzf "kustomize_${KUSTOMIZE_VERSION}_linux_amd64.tar.gz" -C /usr/local/bin + chmod +x /usr/local/bin/kustomize + kustomize version + + echo "🔧 Getting namespace and project_name from Makefile..." + DEFAULT_NAMESPACE=$(make -s print-namespace) + PROJECT_NAME=$(make -s print-project-name) + + if [ "$(params.source-branch)" = "main" ]; then + NS="${DEFAULT_NAMESPACE}" + IMAGE_TAG_BASE=$(params.prod_image_tag_base) + VERSION=$(params.prod-version) + else + NS="${DEFAULT_NAMESPACE}-dev" + IMAGE_TAG_BASE=$(params.dev_image_tag_base) + VERSION=$(params.dev-version) + fi + + echo "🔧 Using namespace: $NS" + echo "🔧 Using project_name: $PROJECT_NAME" + echo "🔧 Using image_tag_base: $IMAGE_TAG_BASE" + echo "🔧 Using version: $VERSION" + + # echo "🧹 Uninstalling existing deployment..." + # # make uninstall-openshift NAMESPACE=$NS PROJECT_NAME=$PROJECT_NAME IMAGE_TAG_BASE=$IMAGE_TAG_BASE VERSION=$VERSION || echo "❗️ Failed to uninstall deployment" + + # (make uninstall || echo "❗️ Failed to uninstall") && (make undeploy IMG=$IMAGE_TAG_BASE:$VERSION || echo "❗️ Failed to uninstall deployment") + + # echo "⏳ Waiting 3 seconds before reinstall..." + # sleep 3 + + echo "🚀 Reinstalling OpenShift deployment..." + INFRASTRUCTURE_OVERRIDE=true make install-openshift-infrastructure + + echo "⏳ Waiting 20 seconds before verifying resources..." + sleep 20 + + echo "🔍 Checking status of resources in namespace: $NS" + kubectl get pods -n $NS || echo "❗️ Failed to get pods" + kubectl get deploy -n $NS || echo "❗️ Failed to get deployments" + kubectl get svc -n $NS || echo "❗️ Failed to get services" + kubectl get routes -n $NS || echo "❗️ Failed to get routes" diff --git a/.tekton/infra-pipelinerun.yaml b/.tekton/infra-pipelinerun.yaml new file mode 100644 index 00000000..6d904782 --- /dev/null +++ b/.tekton/infra-pipelinerun.yaml @@ -0,0 +1,182 @@ +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: modelservice-infra + annotations: + pipelinesascode.tekton.dev/on-event: "[push]" + pipelinesascode.tekton.dev/on-target-branch: "[infra]" + pipelinesascode.tekton.dev/task: "git-clone" + pipelinesascode.tekton.dev/max-keep-runs: "3" + pipelinesascode.tekton.dev/git-status: "true" + pipelinesascode.tekton.dev/on-cel-expression: > + (!has(body.ref) || body.ref == 'refs/heads/infra') && + (!has(body.head_commit) || !has(body.head_commit.author) || !body.head_commit.author.name.matches("(?i).*ci-tag-bot.*")) && + (!has(body.pull_request) || body.pull_request.base.ref == 'infra') +spec: + podTemplate: + serviceAccountName: pipeline + securityContext: + fsGroup: 0 + imagePullSecrets: + - name: icr-secret + params: + - name: runOptional + value: "true" + - name: repo_url + value: "{{ repo_url }}" + - name: revision + value: "{{ revision }}" + - name: deleteExisting + value: "true" + - name: source_branch + value: "{{ source_branch }}" + pipelineSpec: + params: + - name: repo_url + - name: revision + - name: deleteExisting + - name: source_branch + workspaces: + - name: source + - name: basic-auth + - name: git-auth + - name: registry-secret + tasks: + - name: fix-permissions + taskSpec: + workspaces: + - name: source + workspace: source + steps: + - name: fix + image: quay.io/projectquay/golang:1.24 + script: | + #!/bin/sh + echo "Fixing permissions on /workspace/source..." + chmod -R 777 /workspace/source || true + workspaces: + - name: source + workspace: source + + - name: which-branch + taskRef: + name: print-branch-task + runAfter: + - fix-permissions + params: + - name: source-branch + value: "$(params.source_branch)" + workspaces: + - name: source + workspace: source + + - name: fetch-repository + taskRef: + name: git-clone + runAfter: + - which-branch + workspaces: + - name: output + workspace: source + - name: basic-auth + workspace: basic-auth + params: + - name: url + value: $(params.repo_url) + - name: revision + value: $(params.revision) + - name: deleteExisting + value: "$(params.deleteExisting)" + + - name: extract-version-and-registry + params: + - name: source-branch + value: "$(params.source_branch)" + runAfter: + - fetch-repository + taskRef: + name: extract-version-and-registry-task + workspaces: + - name: source + workspace: source + + - name: tag-version + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(params.source_branch)" + operator: in + values: ["infra"] + taskRef: + name: tag-version-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + runAfter: + - extract-version-and-registry + workspaces: + - name: source + workspace: source + - name: git-auth + workspace: git-auth + + - name: openshift-redeploy + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(params.source_branch)" + operator: in + values: ["infra"] + taskRef: + name: openshift-redeploy-infra-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + - name: prod_image_tag_base + value: "$(tasks.extract-version-and-registry.results.prod-image-tag-base)" + - name: dev_image_tag_base + value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" + runAfter: + - tag-version + workspaces: + - name: source + workspace: source + + - name: pipeline-complete-infra + when: + - input: "$(params.source_branch)" + operator: in + values: ["infra"] + runAfter: + - openshift-redeploy + taskRef: + name: noop-task + + workspaces: + - name: source + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi + - name: basic-auth + secret: + secretName: "{{ git_auth_secret }}" + - name: git-auth + secret: + secretName: "git-auth-secret-neuralmagic" + - name: registry-secret + secret: + secretName: quay-secret \ No newline at end of file From b7bcf73f0218cf28913bf06f1bfc8e9a224497b2 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 20:50:18 -0400 Subject: [PATCH 51/73] added infra pipeline run stuff --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 3b56a81b..ac15fd87 100644 --- a/README.md +++ b/README.md @@ -54,3 +54,4 @@ Participation in the Kubernetes community is governed by the [Kubernetes Code of + From eea72e4e4ba590b012c211f347f7f0943d05dc2d Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 20:54:20 -0400 Subject: [PATCH 52/73] added infra pipeline run stuff --- README.md | 1 - 1 file changed, 1 deletion(-) diff --git a/README.md b/README.md index ac15fd87..3b56a81b 100644 --- a/README.md +++ b/README.md @@ -54,4 +54,3 @@ Participation in the Kubernetes community is governed by the [Kubernetes Code of - From 72a432815ff39e344bd33814c8bfba767288a267 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Fri, 18 Apr 2025 21:04:32 -0400 Subject: [PATCH 53/73] pre-commit hook added --- Makefile | 4 ++++ hooks/pre-commit | 10 ++++++++++ 2 files changed, 14 insertions(+) create mode 100755 hooks/pre-commit diff --git a/Makefile b/Makefile index e1870ccc..cbafde83 100644 --- a/Makefile +++ b/Makefile @@ -818,3 +818,7 @@ environment.dev.kind.update: image-build @echo "INFO: Restarting the Endpoint Picker Deployment" kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout restart deployment endpoint-picker kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout status deployment endpoint-picker + +.PHONY: install-hooks +install-hooks: ## Install git hooks + git config core.hooksPath hooks diff --git a/hooks/pre-commit b/hooks/pre-commit new file mode 100755 index 00000000..aa065a73 --- /dev/null +++ b/hooks/pre-commit @@ -0,0 +1,10 @@ +#!/usr/bin/env bash +set -e + +echo "▶️ Running lint…" +make lint + +echo "▶️ Running tests…" +make test + +echo "✔️ All checks passed!" From 04a0e2512f178bf282ae1bfefc199967aeea0375 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Sun, 20 Apr 2025 23:55:05 -0400 Subject: [PATCH 54/73] test trivy scan --- .tekton/benchmark.yaml | 43 ++++++++++++ .tekton/buildah-build.yaml | 4 ++ .tekton/pipelinerun.yaml | 120 ++++++++++++++++++++++++++------- .tekton/read-cluster-name.yaml | 20 ++++++ .tekton/vuln-scan-trivy.yaml | 67 ++++++++++++++++++ 5 files changed, 230 insertions(+), 24 deletions(-) create mode 100644 .tekton/benchmark.yaml create mode 100644 .tekton/read-cluster-name.yaml create mode 100644 .tekton/vuln-scan-trivy.yaml diff --git a/.tekton/benchmark.yaml b/.tekton/benchmark.yaml new file mode 100644 index 00000000..56b02b24 --- /dev/null +++ b/.tekton/benchmark.yaml @@ -0,0 +1,43 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: benchmark-task +spec: + params: + - name: openshift_host + description: "The OpenShift API server URL" + type: string + - name: openshift_namespace + description: "The OpenShift namespace to use" + type: string + steps: + - name: clone-and-install-fmperf + image: continuumio/miniconda3:latest + script: | + #!/bin/bash + set -ex + + # Initialize conda (this sets up the environment for conda commands) + source /opt/conda/etc/profile.d/conda.sh + + echo "Cloning fmperf repository..." + git clone https://github.com/fmperf-project/fmperf.git + cd fmperf + + echo "Creating conda environment 'fmperf-env' with Python 3.11..." + conda create -y -n fmperf-env python=3.11 + + echo "Activating the conda environment..." + conda activate fmperf-env + + echo "Installing required dependencies..." + pip install -r requirements.txt + pip install -e . + + echo "Setting up environment variables for OpenShift connection..." + export OPENSHIFT_HOST="$(params.openshift_host)" + export OPENSHIFT_TOKEN=$(cat /var/run/secrets/kubernetes.io/serviceaccount/token) + export OPENSHIFT_NAMESPACE="$(params.openshift_namespace)" + + echo "Running fmperf benchmark..." + python examples/example_vllm.py || true diff --git a/.tekton/buildah-build.yaml b/.tekton/buildah-build.yaml index d985db8a..a77fa699 100644 --- a/.tekton/buildah-build.yaml +++ b/.tekton/buildah-build.yaml @@ -8,6 +8,9 @@ spec: description: "Application version" - name: image_tag_base description: "Image tag base" + results: + - name: image-url + description: "The full image URL including tag" workspaces: - name: source - name: registry @@ -65,3 +68,4 @@ spec: echo "🚀 Calling make buildah-build with IMG=$IMG..." make buildah-build IMG=$IMG + echo "$IMG" > /tekton/results/image-url diff --git a/.tekton/pipelinerun.yaml b/.tekton/pipelinerun.yaml index c8fb0c38..c02df962 100644 --- a/.tekton/pipelinerun.yaml +++ b/.tekton/pipelinerun.yaml @@ -12,6 +12,14 @@ metadata: (!has(body.ref) || body.ref == 'refs/heads/main' || body.ref == 'refs/heads/dev') && (!has(body.head_commit) || !has(body.head_commit.author) || !body.head_commit.author.name.matches("(?i).*ci-tag-bot.*")) && (!has(body.pull_request) || (body.pull_request.base.ref == 'main' || body.pull_request.base.ref == 'dev')) + results.tekton.dev/columns: | + [ + { + "name": "Vulnerabilities", + "type": "string", + "jsonPath": ".status.pipelineResults[?(@.name==\"vulnerabilities\")].value" + } + ] spec: podTemplate: serviceAccountName: pipeline @@ -58,31 +66,17 @@ spec: - name: source workspace: source - # - name: debug-user - # taskSpec: - # workspaces: - # - name: source - # workspace: source - # steps: - # - name: show-user-info - # image: busybox - # script: | - # #!/bin/sh - # echo "Current UID:" - # id -u - # echo "Current GID:" - # id -g - # echo "Permissions on /workspace/source:" - # ls -ld /workspace/source - # workspaces: - # - name: source - # workspace: source + - name: read-cluster-name + taskRef: + name: read-cluster-name + runAfter: + - fix-permissions - name: which-branch taskRef: name: print-branch-task runAfter: - - fix-permissions + - read-cluster-name params: - name: source-branch value: "$(params.source_branch)" @@ -113,6 +107,9 @@ spec: - input: "$(params.runOptional)" operator: in values: ["true"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: go-lint-task runAfter: @@ -126,11 +123,13 @@ spec: - input: "$(params.runOptional)" operator: in values: ["true"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: go-test-task runAfter: - go-lint - # - fetch-repository workspaces: - name: source workspace: source @@ -140,6 +139,9 @@ spec: - input: "$(params.runOptional)" operator: in values: ["true"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: go-build-task runAfter: @@ -168,6 +170,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: promote-to-prod-task params: @@ -193,6 +198,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] params: - name: dev-version value: "$(tasks.extract-version-and-registry.results.dev-version)" @@ -210,10 +218,40 @@ spec: - name: registry workspace: registry-secret + - name: vulnerability-scan + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] + runAfter: + - buildah-build + taskRef: + name: trivy-scan + params: + - name: IMAGE_URL + value: "$(tasks.buildah-build.results.image-url)" + - name: SEVERITY + value: "CRITICAL,HIGH" + - name: ARGS + value: "--exit-code 0" + workspaces: + - name: registry-secret + workspace: registry-secret + - name: output + workspace: output + - name: sync-after-promote-or-build + when: + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] runAfter: - promote-to-prod - - buildah-build + # - buildah-build + - vulnerability-scan taskRef: name: noop-task @@ -240,6 +278,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["main", "dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: tag-version-task params: @@ -310,12 +351,35 @@ spec: workspaces: - name: source workspace: source - + + - name: benchmark + when: + - input: "$(params.source_branch)" + operator: in + values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] + continueOn: + errors: true + params: + - name: openshift_host + value: "https://api.fmaas-platform-eval.fmaas.res.ibm.com:6443" + - name: openshift_namespace + value: "hc4ai-operator-dev" + taskRef: + name: benchmark-task + runAfter: + - go-test-post-deploy + - name: increment-versions when: - input: "$(params.source_branch)" operator: in values: ["main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] params: - name: source-branch value: "$(params.source_branch)" @@ -347,7 +411,7 @@ spec: operator: in values: ["dev"] runAfter: - - go-test-post-deploy + - benchmark taskRef: name: noop-task @@ -360,6 +424,14 @@ spec: resources: requests: storage: 1Gi + - name: output + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 1Gi - name: basic-auth secret: secretName: "{{ git_auth_secret }}" diff --git a/.tekton/read-cluster-name.yaml b/.tekton/read-cluster-name.yaml new file mode 100644 index 00000000..376db287 --- /dev/null +++ b/.tekton/read-cluster-name.yaml @@ -0,0 +1,20 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: read-cluster-name +spec: + results: + - name: cluster-name + steps: + - name: get-cluster-name + image: registry.access.redhat.com/ubi8/ubi-minimal + script: | + #!/bin/sh + cat /etc/config/cluster-name | tee $(results.cluster-name.path) + volumeMounts: + - name: config-vol + mountPath: /etc/config + volumes: + - name: config-vol + configMap: + name: cluster-info diff --git a/.tekton/vuln-scan-trivy.yaml b/.tekton/vuln-scan-trivy.yaml new file mode 100644 index 00000000..9c008345 --- /dev/null +++ b/.tekton/vuln-scan-trivy.yaml @@ -0,0 +1,67 @@ +apiVersion: tekton.dev/v1 +kind: Task +metadata: + name: trivy-scan +spec: + params: + - name: IMAGE_URL + type: string + description: Full image URL (e.g., quay.io/org/image:tag) + - name: SEVERITY + type: string + default: "CRITICAL,HIGH" + description: Comma-separated severity levels + - name: ARGS + type: string + default: "" + description: Additional Trivy arguments + workspaces: + - name: registry-secret + description: Workspace with Docker config.json (auth for private registries) + - name: output + results: + - name: vulnerabilities + type: string + steps: + - name: trivy-scan + image: docker:20.10.24-dind + securityContext: + privileged: true + script: | + #!/bin/sh + set -e + + echo "🔧 Starting Docker daemon..." + dockerd-entrypoint.sh & + + echo "⏳ Waiting for Docker daemon to be ready..." + until docker info > /dev/null 2>&1; do + sleep 1 + done + + echo "🔐 Setting up Docker credentials..." + mkdir -p /root/.docker + cp /workspace/registry-secret/.dockerconfigjson /root/.docker/config.json + + echo "⬇️ Installing Trivy..." + apk add --no-cache curl jq + curl -sfL https://raw.githubusercontent.com/aquasecurity/trivy/main/contrib/install.sh | sh -s -- -b /usr/local/bin + + IMAGE="$(echo $(params.IMAGE_URL))" + IMAGE=$(echo "$IMAGE" | tr -d '\n\r' | xargs) + + echo "🔍 Running Trivy remote scan on: $IMAGE" + if ! trivy image \ + --severity "$(params.SEVERITY)" \ + --format json \ + $(params.ARGS) \ + "$IMAGE" > /workspace/output/trivy-results.json; then + echo "❌ Trivy scan failed" + echo -n "-1" > $(results.vulnerabilities.path) + exit 1 + fi + + echo "📊 Counting vulnerabilities..." + vuln_count=$(jq '[.Results[].Vulnerabilities[]?] | length' /workspace/output/trivy-results.json) + echo "📊 Found $vuln_count vulnerabilities" + echo -n "$vuln_count" > /tekton/results/vulnerabilities From 5098332dfe67d4f431844687c867a6dbb4be4ea1 Mon Sep 17 00:00:00 2001 From: Shmuel Kallner Date: Mon, 21 Apr 2025 14:56:47 +0300 Subject: [PATCH 55/73] Setup the Istio service to be a NodePort service and not a ClusterIP service --- deploy/environments/dev/kind/gateway.yaml | 6 ++++ .../environments/dev/kind/kustomization.yaml | 4 +++ deploy/environments/dev/kind/services.yaml | 28 +++++++++++++++++++ scripts/kind-dev-env.sh | 20 +++++++++---- 4 files changed, 52 insertions(+), 6 deletions(-) create mode 100644 deploy/environments/dev/kind/gateway.yaml create mode 100644 deploy/environments/dev/kind/services.yaml diff --git a/deploy/environments/dev/kind/gateway.yaml b/deploy/environments/dev/kind/gateway.yaml new file mode 100644 index 00000000..bf85e826 --- /dev/null +++ b/deploy/environments/dev/kind/gateway.yaml @@ -0,0 +1,6 @@ +apiVersion: gateway.networking.k8s.io/v1 +kind: Gateway +metadata: + name: inference-gateway + annotations: + networking.istio.io/service-type: NodePort \ No newline at end of file diff --git a/deploy/environments/dev/kind/kustomization.yaml b/deploy/environments/dev/kind/kustomization.yaml index 57fa4b31..34d2a821 100644 --- a/deploy/environments/dev/kind/kustomization.yaml +++ b/deploy/environments/dev/kind/kustomization.yaml @@ -13,6 +13,10 @@ apiVersion: kustomize.config.k8s.io/v1beta1 kind: Kustomization resources: +- services.yaml - ../../../components/istio-control-plane/ - ../../../components/vllm-sim/ - ../../../components/inference-gateway/ + +patches: +- path: gateway.yaml \ No newline at end of file diff --git a/deploy/environments/dev/kind/services.yaml b/deploy/environments/dev/kind/services.yaml new file mode 100644 index 00000000..853bfcca --- /dev/null +++ b/deploy/environments/dev/kind/services.yaml @@ -0,0 +1,28 @@ +apiVersion: v1 +kind: Service +metadata: + annotations: + networking.istio.io/service-type: NodePort + labels: + gateway.istio.io/managed: istio.io-gateway-controller + gateway.networking.k8s.io/gateway-name: inference-gateway + istio.io/enable-inference-extproc: "true" + name: inference-gateway-istio + namespace: default +spec: + type: NodePort + selector: + gateway.networking.k8s.io/gateway-name: inference-gateway + ports: + - appProtocol: tcp + name: status-port + port: 15021 + protocol: TCP + targetPort: 15021 + nodePort: 32021 + - appProtocol: http + name: default + port: 80 + protocol: TCP + targetPort: 80 + nodePort: 30080 diff --git a/scripts/kind-dev-env.sh b/scripts/kind-dev-env.sh index 3cad7fba..89eb1119 100755 --- a/scripts/kind-dev-env.sh +++ b/scripts/kind-dev-env.sh @@ -22,6 +22,9 @@ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" # Set the namespace to deploy the Gateway stack to : "${PROJECT_NAMESPACE:=default}" +# Set the host port to map to the Gateway's inbound port (30080) +: "${GATEWAY_HOST_PORT:=30080}" + # ------------------------------------------------------------------------------ # Setup & Requirement Checks # ------------------------------------------------------------------------------ @@ -63,7 +66,16 @@ done if kind get clusters 2>/dev/null | grep -q "^${CLUSTER_NAME}$"; then echo "Cluster '${CLUSTER_NAME}' already exists, re-using" else - kind create cluster --name "${CLUSTER_NAME}" + kind create cluster --name "${CLUSTER_NAME}" --config - << EOF +kind: Cluster +apiVersion: kind.x-k8s.io/v1alpha4 +nodes: +- role: control-plane + extraPortMappings: + - containerPort: 30080 + hostPort: ${GATEWAY_HOST_PORT} + protocol: TCP +EOF fi # Set the kubectl context to the kind cluster @@ -126,13 +138,9 @@ You can watch the Endpoint Picker logs with: $ kubectl --context ${KUBE_CONTEXT} logs -f deployments/endpoint-picker -You can use a port-forward to access the Gateway: - - $ kubectl --context ${KUBE_CONTEXT} port-forward service/inference-gateway-istio 8080:80 - With that running in the background, you can make requests: - $ curl -s -w '\n' http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq + $ curl -s -w '\n' http://localhost:${GATEWAY_HOST_PORT}/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq ----------------------------------------- EOF From 84ff88c06f58848c4dd9d5bf758798d6b7c4960b Mon Sep 17 00:00:00 2001 From: Ricardo Noriega De Soto Date: Mon, 21 Apr 2025 14:03:04 +0200 Subject: [PATCH 56/73] Merge pull request #37 from oglok/istio-mem Patch Istio deployment to use 1Gi of mem --- deploy/components/istio-control-plane/deployments.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/deploy/components/istio-control-plane/deployments.yaml b/deploy/components/istio-control-plane/deployments.yaml index 49de6b61..45b8e645 100644 --- a/deploy/components/istio-control-plane/deployments.yaml +++ b/deploy/components/istio-control-plane/deployments.yaml @@ -123,7 +123,7 @@ spec: resources: requests: cpu: 500m - memory: 2048Mi + memory: 1024Mi securityContext: allowPrivilegeEscalation: false capabilities: From c65cacb60d71f4dd4ea15516a60a0d6f8215dbb6 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 12:35:39 -0400 Subject: [PATCH 57/73] chore: move install-hooks target into tools section Signed-off-by: Shane Utt --- Makefile | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/Makefile b/Makefile index cbafde83..1e02af11 100644 --- a/Makefile +++ b/Makefile @@ -563,6 +563,8 @@ ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" @echo "Installing CRDs" kustomize build deploy/components/crds | kubectl apply --server-side --force-conflicts -f - + @echo "Installing RBAC" + kustomize build deploy/components/ @echo "Installing the Istio Control Plane" kustomize build deploy/components/istio-control-plane | kubectl apply -f - else @@ -786,6 +788,9 @@ print-namespace: ## Print the current namespace print-project-name: ## Print the current project name @echo "$(PROJECT_NAME)" +.PHONY: install-hooks +install-hooks: ## Install git hooks + git config core.hooksPath hooks # # Development Environments # @@ -818,7 +823,3 @@ environment.dev.kind.update: image-build @echo "INFO: Restarting the Endpoint Picker Deployment" kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout restart deployment endpoint-picker kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout status deployment endpoint-picker - -.PHONY: install-hooks -install-hooks: ## Install git hooks - git config core.hooksPath hooks From 64cc8fa9bb45d045db67be5a189b5b7da8d7a917 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 21 Apr 2025 12:50:43 -0400 Subject: [PATCH 58/73] implementing vuln scanner and h100 cluster deployment --- .tekton/README.md | 38 +++++++++----- .tekton/pipelinerun.yaml | 99 ++++++++++++++++++++++++++++++++---- .tekton/vuln-scan-trivy.yaml | 38 +++++++++++--- 3 files changed, 145 insertions(+), 30 deletions(-) diff --git a/.tekton/README.md b/.tekton/README.md index 4b51d0ca..19a34c3a 100644 --- a/.tekton/README.md +++ b/.tekton/README.md @@ -1,6 +1,10 @@ ## 🛠️ CI/CD Pipeline Overview – Your Project -This pipeline is designed to support safe, efficient, and traceable development and deployment workflows using OpenShift Pipelines-as-Code, GitHub, and Quay.io. + + +This pipeline is designed to support safe, efficient, and traceable development and deployment workflows using [OpenShift Pipelines-as-Code](https://pipelinesascode.com/), [Tekton](https://tekton.dev/), [buildah](https://buildah.io/), GitHub, and Quay.io. + +This pipeline is used for CI/CD of the `dev` and `main` branches. This pipeline runs from source through container image build to deployment and testing in the hc4ai cluster. --- @@ -24,19 +28,28 @@ Each repo includes a `.version.json` file at its root. This file controls: #### 🔑 Fields: - **dev-version**: Current version of the dev branch. Used to tag dev images. -- **dev-registry**: Container registry location for development image pushes. +- **dev-registry**: Container repository location for development image pushes. - **prod-version**: Managed by automation. Updated during promotion to match the dev-version. -- **prod-registry**: Container registry for production image pushes. The promoted dev image is re-tagged and pushed here. +- **prod-registry**: Container repository for production image pushes. The promoted dev image is re-tagged and pushed here. The pipeline reads this file to: - Extract the appropriate version tag -- Determine the correct registry for image pushes +- Determine the correct repository for image pushes - Promote and tag dev images for prod --- +### Container Repositories + +This pipeline maintains two container repositories for this GitHub repository, as follows. + +- `quay.io/vllm-d/-dev`. Hold builds from the `dev` branch as described below. +- `quay.io/vllm-d/`. Holds promotions to prod, as described below. + +--- + ### ⚙️ Pipeline Triggers -Triggered on `push` and `pull_request` events targeting the `dev` or `main` branches. +Triggered on `push` and `pull_request` events targeting the `dev` or `main` branches. The following workflows are the two behaviors of this pipeline. ### 🔧 dev Branch Workflow 1. Checkout repository @@ -47,9 +60,9 @@ Triggered on `push` and `pull_request` events targeting the `dev` or `main` bran - prod-version - prod-registry 4. Build and push container image to: - → `:` + → `:` 5. Tag the Git commit using the `dev-version` -6. Optionally redeploy objects to OpenShift in `hc4ai-operator-dev` +6. Optionally redeploy objects to OpenShift in the `hc4ai-operator-dev` namespace. ✅ This process ensures that all code merged into dev is validated and deployed for testing. @@ -57,10 +70,10 @@ Triggered on `push` and `pull_request` events targeting the `dev` or `main` bran 1. Checkout, lint, test, and parse `.version.json` 2. Skip image rebuild 3. Promote image by copying from: - → `` → `:` + → `` → `:` 4. Tag the Git commit using the `prod-version` 5. Update the upstream repo’s submodule to reference the new tag -6. Redeploy to OpenShift in `hc4ai-operator` +6. Redeploy to OpenShift in the `hc4ai-operator` namespace. ✅ No image rebuilds occur on main. Only validated dev images are promoted, ensuring reproducibility. @@ -84,8 +97,8 @@ Tags are created using the configured Git credentials and pushed to the remote r ### ☸️ OpenShift Deployment The pipeline includes automated deployment: -- On `dev`: Deploys to `hc4ai-operator-dev` -- On `main`: Deploys to `hc4ai-operator` +- On `dev`: Deploys to the `hc4ai-operator-dev` namespace. The Pod is named `-major-minor`, using the `dev-version` from `.version.json`. +- On `main`: Deploys to `hc4ai-operator` namespace. The Pod is named `-major-minor`, using the `prod-version` from `.version.json`. Using `make uninstall-openshift` and `make install-openshift`, resources are cleanly reset. @@ -112,6 +125,7 @@ After deployment, the pipeline: ### 🧠 Why `.version.json` Matters - Decouples versioning from Git commit hashes -- Provides a single source of truth for version and registry info +- Provides a single source of truth for version and repository info - Enables deterministic builds and controlled releases - Simplifies debugging and auditing across environments + diff --git a/.tekton/pipelinerun.yaml b/.tekton/pipelinerun.yaml index c02df962..d3e7af67 100644 --- a/.tekton/pipelinerun.yaml +++ b/.tekton/pipelinerun.yaml @@ -12,14 +12,6 @@ metadata: (!has(body.ref) || body.ref == 'refs/heads/main' || body.ref == 'refs/heads/dev') && (!has(body.head_commit) || !has(body.head_commit.author) || !body.head_commit.author.name.matches("(?i).*ci-tag-bot.*")) && (!has(body.pull_request) || (body.pull_request.base.ref == 'main' || body.pull_request.base.ref == 'dev')) - results.tekton.dev/columns: | - [ - { - "name": "Vulnerabilities", - "type": "string", - "jsonPath": ".status.pipelineResults[?(@.name==\"vulnerabilities\")].value" - } - ] spec: podTemplate: serviceAccountName: pipeline @@ -39,6 +31,10 @@ spec: - name: source_branch value: "{{ source_branch }}" pipelineSpec: + results: + - description: The common vulnerabilities and exposures (CVE) result + name: SCAN_OUTPUT + value: $(tasks.vulnerability-scan.results.SCAN_OUTPUT) params: - name: repo_url - name: revision @@ -162,6 +158,90 @@ spec: - name: source workspace: source + - name: openshift-redeploy-h100 + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(params.source_branch)" + operator: in + values: ["dev", "main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: notin + values: ["cluster-platform-eval"] + taskRef: + name: openshift-redeploy-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + - name: prod_image_tag_base + value: "$(tasks.extract-version-and-registry.results.prod-image-tag-base)" + - name: dev_image_tag_base + value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" + runAfter: + - extract-version-and-registry + workspaces: + - name: source + workspace: source + + - name: go-test-post-deploy-h100 + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(params.source_branch)" + operator: in + values: ["dev", "main"] + taskRef: + name: go-test-post-deploy-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + - name: prod_image_tag_base + value: "$(tasks.extract-version-and-registry.results.prod-image-tag-base)" + - name: dev_image_tag_base + value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" + runAfter: + - openshift-redeploy-h100 + workspaces: + - name: source + workspace: source + + - name: benchmark-h100 + when: + - input: "$(params.source_branch)" + operator: in + values: ["dev"] + continueOn: + errors: true + params: + - name: openshift_host + value: "https://api.fmaas-vllm-d.fmaas.res.ibm.com:6443" + - name: openshift_namespace + value: "hc4ai-operator-dev" + taskRef: + name: benchmark-task + runAfter: + - go-test-post-deploy-h100 + + - name: pipeline-complete-dev-h100 + when: + - input: "$(params.source_branch)" + operator: in + values: ["dev"] + runAfter: + - benchmark-h100 + taskRef: + name: noop-task + - name: promote-to-prod when: - input: "$(params.runOptional)" @@ -234,7 +314,7 @@ spec: - name: IMAGE_URL value: "$(tasks.buildah-build.results.image-url)" - name: SEVERITY - value: "CRITICAL,HIGH" + value: "CRITICAL,HIGH,MEDIUM,LOW" - name: ARGS value: "--exit-code 0" workspaces: @@ -250,7 +330,6 @@ spec: values: ["cluster-platform-eval"] runAfter: - promote-to-prod - # - buildah-build - vulnerability-scan taskRef: name: noop-task diff --git a/.tekton/vuln-scan-trivy.yaml b/.tekton/vuln-scan-trivy.yaml index 9c008345..aba3789d 100644 --- a/.tekton/vuln-scan-trivy.yaml +++ b/.tekton/vuln-scan-trivy.yaml @@ -2,6 +2,10 @@ apiVersion: tekton.dev/v1 kind: Task metadata: name: trivy-scan + annotations: + task.output.location: results + task.results.format: application/json + task.results.key: SCAN_OUTPUT spec: params: - name: IMAGE_URL @@ -9,19 +13,19 @@ spec: description: Full image URL (e.g., quay.io/org/image:tag) - name: SEVERITY type: string - default: "CRITICAL,HIGH" + default: "CRITICAL,HIGH,MEDIUM" description: Comma-separated severity levels - name: ARGS type: string default: "" description: Additional Trivy arguments + results: + - name: SCAN_OUTPUT + description: CVE result format workspaces: - name: registry-secret description: Workspace with Docker config.json (auth for private registries) - name: output - results: - - name: vulnerabilities - type: string steps: - name: trivy-scan image: docker:20.10.24-dind @@ -57,11 +61,29 @@ spec: $(params.ARGS) \ "$IMAGE" > /workspace/output/trivy-results.json; then echo "❌ Trivy scan failed" - echo -n "-1" > $(results.vulnerabilities.path) + echo -n "-1" > /tekton/results/vulnerabilities exit 1 fi - echo "📊 Counting vulnerabilities..." - vuln_count=$(jq '[.Results[].Vulnerabilities[]?] | length' /workspace/output/trivy-results.json) + echo "📋 Trivy scan result:" + cat /workspace/output/trivy-results.json + + echo "📊 Parsing vulnerabilities..." + + vuln_count=$(jq '[.Results[].Vulnerabilities[]?] | length // 0' /workspace/output/trivy-results.json) echo "📊 Found $vuln_count vulnerabilities" - echo -n "$vuln_count" > /tekton/results/vulnerabilities + + if [ "$vuln_count" -gt 0 ]; then + # Parse the vulnerabilities and ensure that missing categories are assigned zero count + jq -rce ' + { + vulnerabilities: { + critical: ([.Results[].Vulnerabilities[]? | select(.Severity == "CRITICAL")] | length), + high: ([.Results[].Vulnerabilities[]? | select(.Severity == "HIGH")] | length), + medium: ([.Results[].Vulnerabilities[]? | select(.Severity == "MEDIUM")] | length), + low: ([.Results[].Vulnerabilities[]? | select(.Severity == "LOW")] | length) + } + }' /workspace/output/trivy-results.json > /tekton/results/SCAN_OUTPUT + else + echo "📊 No vulnerabilities found, skipping parsing." + fi From 5bb12eeefbec670d87aa60b1bbb0887ce0a6f00a Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 12:57:57 -0400 Subject: [PATCH 59/73] feat: add openshift-infra deployment w/ RBAC for dev envs Signed-off-by: Shane Utt --- Makefile | 19 +++--- .../dev/openshift-infra/kustomization.yaml | 19 ++++++ .../dev/openshift-infra/rbac.yaml | 66 +++++++++++++++++++ 3 files changed, 93 insertions(+), 11 deletions(-) create mode 100644 deploy/environments/dev/openshift-infra/kustomization.yaml create mode 100644 deploy/environments/dev/openshift-infra/rbac.yaml diff --git a/Makefile b/Makefile index 1e02af11..adf1ee65 100644 --- a/Makefile +++ b/Makefile @@ -561,12 +561,8 @@ uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Ku install-openshift-infrastructure: ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" - @echo "Installing CRDs" - kustomize build deploy/components/crds | kubectl apply --server-side --force-conflicts -f - - @echo "Installing RBAC" - kustomize build deploy/components/ - @echo "Installing the Istio Control Plane" - kustomize build deploy/components/istio-control-plane | kubectl apply -f - + @echo "Installing OpenShift Infrastructure" + kustomize build deploy/environments/dev/openshift-infra | kubectl apply --server-side --force-conflicts -f - else $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") endif @@ -585,11 +581,12 @@ endif .PHONY: uninstall-openshift-infrastructure uninstall-openshift-infrastructure: ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) - @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components" - @echo "Uninstalling the Istio Control Plane" - kustomize build deploy/components/istio-control-plane | kubectl delete -f - || true - @echo "Uninstalling CRDs" - kustomize build deploy/components/crds | kubectl delete -f - || true + @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components (this is extremely destructive)" + @echo "This is extremely destructive. We'll provide a few seconds before starting to give you a chance to cancel." + sleep 3 + @echo "Uninstalling OpenShift Infrastructure Components" + @echo "Installing OpenShift Infrastructure" + kustomize build deploy/environments/dev/openshift-infra | kubectl delete -f - || true else $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") endif diff --git a/deploy/environments/dev/openshift-infra/kustomization.yaml b/deploy/environments/dev/openshift-infra/kustomization.yaml new file mode 100644 index 00000000..e3a63a5d --- /dev/null +++ b/deploy/environments/dev/openshift-infra/kustomization.yaml @@ -0,0 +1,19 @@ +# ------------------------------------------------------------------------------ +# OpenShift Environment - Infrastructure +# +# This provides the infrastructure-level requirements that individual +# development environments (see `deploy/environments/dev/openshift`) will need +# (e.g. CRDs, Operators, RBAC, etc). +# +# **WARNING**: Needs to be run once, and regularly updated on an OpenShift +# cluster by an administrator prior to deploying individual environments on +# that cluster with `deploy/environments/dev/openshift`. +# +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../../components/crds/ +- ../../../components/istio-control-plane/ +- rbac.yaml diff --git a/deploy/environments/dev/openshift-infra/rbac.yaml b/deploy/environments/dev/openshift-infra/rbac.yaml new file mode 100644 index 00000000..4998bccd --- /dev/null +++ b/deploy/environments/dev/openshift-infra/rbac.yaml @@ -0,0 +1,66 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gateway-management +rules: + # --------------------------------------------------------------------------- + # Gateway API + # --------------------------------------------------------------------------- + - apiGroups: + - gateway.networking.k8s.io + resources: + - gateways + - httproutes + - grpcroutes + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + # --------------------------------------------------------------------------- + # Gateway API Inference Extension (GIE) + # --------------------------------------------------------------------------- + - apiGroups: + - inference.networking.x-k8s.io + resources: + - inferencepools + - inferencemodels + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + # --------------------------------------------------------------------------- + # Istio + # --------------------------------------------------------------------------- + - apiGroups: + - networking.istio.io + resources: + - destinationrules + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: authenticated-gateway-management +subjects: + - kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: gateway-management + apiGroup: rbac.authorization.k8s.io From 9df4be1ab39e7adf811ae28e7d30a8faca8b7fc1 Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 21 Apr 2025 13:10:00 -0400 Subject: [PATCH 60/73] implementing vuln scanner and h100 cluster deployment --- .tekton/pipelinerun.yaml | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/.tekton/pipelinerun.yaml b/.tekton/pipelinerun.yaml index d3e7af67..45c8a07f 100644 --- a/.tekton/pipelinerun.yaml +++ b/.tekton/pipelinerun.yaml @@ -196,6 +196,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["dev", "main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: notin + values: ["cluster-platform-eval"] taskRef: name: go-test-post-deploy-task params: @@ -220,6 +223,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: notin + values: ["cluster-platform-eval"] continueOn: errors: true params: @@ -237,6 +243,9 @@ spec: - input: "$(params.source_branch)" operator: in values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: notin + values: ["cluster-platform-eval"] runAfter: - benchmark-h100 taskRef: From d187ce7a4292bf71ee8c318260a88f71ada2e160 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:56:00 -0400 Subject: [PATCH 61/73] chore: remove openshift dev environment Signed-off-by: Shane Utt --- .../dev/openshift-infra/kustomization.yaml | 19 ------ .../dev/openshift-infra/rbac.yaml | 66 ------------------- .../dev/openshift/common/patch-service.yaml | 13 ---- .../openshift/common/patch-statefulset.yaml | 20 ------ .../dev/openshift/common/service.yaml | 12 ---- .../dev/openshift/common/statefulset.yaml | 20 ------ .../dev/openshift/kustomization.yaml | 36 ---------- .../dev/openshift/openshift/patch-route.yaml | 7 -- .../dev/openshift/openshift/route.yaml | 12 ---- .../dev/openshift/rbac/exec-rbac-role.yaml | 9 --- .../openshift/rbac/exec-rbac-rolebinding.yaml | 13 ---- .../dev/openshift/rbac/patch-rbac-role.yaml | 10 --- .../rbac/patch-rbac-rolebinding.yaml | 12 ---- 13 files changed, 249 deletions(-) delete mode 100644 deploy/environments/dev/openshift-infra/kustomization.yaml delete mode 100644 deploy/environments/dev/openshift-infra/rbac.yaml delete mode 100644 deploy/environments/dev/openshift/common/patch-service.yaml delete mode 100644 deploy/environments/dev/openshift/common/patch-statefulset.yaml delete mode 100644 deploy/environments/dev/openshift/common/service.yaml delete mode 100644 deploy/environments/dev/openshift/common/statefulset.yaml delete mode 100644 deploy/environments/dev/openshift/kustomization.yaml delete mode 100644 deploy/environments/dev/openshift/openshift/patch-route.yaml delete mode 100644 deploy/environments/dev/openshift/openshift/route.yaml delete mode 100644 deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml delete mode 100644 deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml delete mode 100644 deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml delete mode 100644 deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml diff --git a/deploy/environments/dev/openshift-infra/kustomization.yaml b/deploy/environments/dev/openshift-infra/kustomization.yaml deleted file mode 100644 index e3a63a5d..00000000 --- a/deploy/environments/dev/openshift-infra/kustomization.yaml +++ /dev/null @@ -1,19 +0,0 @@ -# ------------------------------------------------------------------------------ -# OpenShift Environment - Infrastructure -# -# This provides the infrastructure-level requirements that individual -# development environments (see `deploy/environments/dev/openshift`) will need -# (e.g. CRDs, Operators, RBAC, etc). -# -# **WARNING**: Needs to be run once, and regularly updated on an OpenShift -# cluster by an administrator prior to deploying individual environments on -# that cluster with `deploy/environments/dev/openshift`. -# -# ------------------------------------------------------------------------------ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -resources: -- ../../../components/crds/ -- ../../../components/istio-control-plane/ -- rbac.yaml diff --git a/deploy/environments/dev/openshift-infra/rbac.yaml b/deploy/environments/dev/openshift-infra/rbac.yaml deleted file mode 100644 index 4998bccd..00000000 --- a/deploy/environments/dev/openshift-infra/rbac.yaml +++ /dev/null @@ -1,66 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRole -metadata: - name: gateway-management -rules: - # --------------------------------------------------------------------------- - # Gateway API - # --------------------------------------------------------------------------- - - apiGroups: - - gateway.networking.k8s.io - resources: - - gateways - - httproutes - - grpcroutes - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - # --------------------------------------------------------------------------- - # Gateway API Inference Extension (GIE) - # --------------------------------------------------------------------------- - - apiGroups: - - inference.networking.x-k8s.io - resources: - - inferencepools - - inferencemodels - verbs: - - get - - list - - watch - - create - - update - - patch - - delete - # --------------------------------------------------------------------------- - # Istio - # --------------------------------------------------------------------------- - - apiGroups: - - networking.istio.io - resources: - - destinationrules - verbs: - - get - - list - - watch - - create - - update - - patch - - delete ---- -apiVersion: rbac.authorization.k8s.io/v1 -kind: ClusterRoleBinding -metadata: - name: authenticated-gateway-management -subjects: - - kind: Group - name: system:authenticated - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: ClusterRole - name: gateway-management - apiGroup: rbac.authorization.k8s.io diff --git a/deploy/environments/dev/openshift/common/patch-service.yaml b/deploy/environments/dev/openshift/common/patch-service.yaml deleted file mode 100644 index d15ea23f..00000000 --- a/deploy/environments/dev/openshift/common/patch-service.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: service -spec: - selector: - app: ${PROJECT_NAME}-service - ports: - - protocol: TCP - port: 8080 - targetPort: 8080 - type: ClusterIP - \ No newline at end of file diff --git a/deploy/environments/dev/openshift/common/patch-statefulset.yaml b/deploy/environments/dev/openshift/common/patch-statefulset.yaml deleted file mode 100644 index 5b7676ff..00000000 --- a/deploy/environments/dev/openshift/common/patch-statefulset.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: 0 -spec: - serviceName: ${PROJECT_NAME}-service - replicas: 1 - selector: - matchLabels: - app: ${PROJECT_NAME}-statefulset - template: - metadata: - labels: - app: ${PROJECT_NAME}-statefulset - spec: - serviceAccountName: operator-controller-manager - containers: - - name: cmd - image: ${IMAGE_TAG_BASE}:${VERSION} - imagePullPolicy: Always diff --git a/deploy/environments/dev/openshift/common/service.yaml b/deploy/environments/dev/openshift/common/service.yaml deleted file mode 100644 index 8abb7e7e..00000000 --- a/deploy/environments/dev/openshift/common/service.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: v1 -kind: Service -metadata: - name: service -spec: - selector: - app: placeholder - ports: - - protocol: TCP - port: 8080 - targetPort: 8080 - type: ClusterIP diff --git a/deploy/environments/dev/openshift/common/statefulset.yaml b/deploy/environments/dev/openshift/common/statefulset.yaml deleted file mode 100644 index 9e742f1d..00000000 --- a/deploy/environments/dev/openshift/common/statefulset.yaml +++ /dev/null @@ -1,20 +0,0 @@ -apiVersion: apps/v1 -kind: StatefulSet -metadata: - name: "0" -spec: - serviceName: placeholder - replicas: 1 - selector: - matchLabels: - app: placeholder - template: - metadata: - labels: - app: placeholder - spec: - serviceAccountName: operator-controller-manager - containers: - - name: cmd - image: quay.io/vllm-d/placeholder:placeholder - imagePullPolicy: Always diff --git a/deploy/environments/dev/openshift/kustomization.yaml b/deploy/environments/dev/openshift/kustomization.yaml deleted file mode 100644 index e242bdae..00000000 --- a/deploy/environments/dev/openshift/kustomization.yaml +++ /dev/null @@ -1,36 +0,0 @@ -apiVersion: kustomize.config.k8s.io/v1beta1 -kind: Kustomization - -# Set the namespace for all resources using a placeholder. -namespace: ${NAMESPACE} - -# Use a prefix for all object names. You can substitute the PROJECT_NAME variable. -namePrefix: ${PROJECT_NAME}- - -# List all the resources (manifests) you want to deploy. -resources: -- common/statefulset.yaml -- common/service.yaml -- openshift/route.yaml -- rbac/exec-rbac-role.yaml -- rbac/exec-rbac-rolebinding.yaml - -# Generate the ConfigMap with a variable name. -configMapGenerator: -- name: config - options: - disableNameSuffixHash: true - -# Include patches to update the Service, StatefulSet, Route, and RBAC resources. - -# Define the image to be updated. -# images: -# - name: quay.io/vllm-d/placeholder -# newName: quay.io/vllm-d/${IMAGE_TAG_BASE} -# newTag: ${VERSION} -patches: -- path: common/patch-service.yaml -- path: common/patch-statefulset.yaml -- path: openshift/patch-route.yaml -- path: rbac/patch-rbac-role.yaml -- path: rbac/patch-rbac-rolebinding.yaml diff --git a/deploy/environments/dev/openshift/openshift/patch-route.yaml b/deploy/environments/dev/openshift/openshift/patch-route.yaml deleted file mode 100644 index 0b7d63ff..00000000 --- a/deploy/environments/dev/openshift/openshift/patch-route.yaml +++ /dev/null @@ -1,7 +0,0 @@ -apiVersion: route.openshift.io/v1 -kind: Route -metadata: - name: route -spec: - to: - name: "${PROJECT_NAME}-service" diff --git a/deploy/environments/dev/openshift/openshift/route.yaml b/deploy/environments/dev/openshift/openshift/route.yaml deleted file mode 100644 index d1404516..00000000 --- a/deploy/environments/dev/openshift/openshift/route.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: route.openshift.io/v1 -kind: Route -metadata: - name: route -spec: - to: - kind: Service - name: placeholder - port: - targetPort: 8080 - tls: - termination: edge diff --git a/deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml b/deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml deleted file mode 100644 index fb6ac88b..00000000 --- a/deploy/environments/dev/openshift/rbac/exec-rbac-role.yaml +++ /dev/null @@ -1,9 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: exec-role -rules: - - apiGroups: [""] - resources: ["pods/exec"] - resourceNames: ["placeholder-0-0"] - verbs: ["create"] diff --git a/deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml b/deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml deleted file mode 100644 index 4c6ccf97..00000000 --- a/deploy/environments/dev/openshift/rbac/exec-rbac-rolebinding.yaml +++ /dev/null @@ -1,13 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: exec-rolebinding -subjects: - - kind: Group - name: system:authenticated - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: Role - name: exec-role - apiGroup: rbac.authorization.k8s.io - diff --git a/deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml b/deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml deleted file mode 100644 index 2ac6fcd3..00000000 --- a/deploy/environments/dev/openshift/rbac/patch-rbac-role.yaml +++ /dev/null @@ -1,10 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: Role -metadata: - name: exec-role -rules: - - apiGroups: [""] - resources: ["pods/exec"] - resourceNames: - - "${PROJECT_NAME}-0-0" - verbs: ["create"] diff --git a/deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml b/deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml deleted file mode 100644 index 57e8df1d..00000000 --- a/deploy/environments/dev/openshift/rbac/patch-rbac-rolebinding.yaml +++ /dev/null @@ -1,12 +0,0 @@ -apiVersion: rbac.authorization.k8s.io/v1 -kind: RoleBinding -metadata: - name: exec-rolebinding -subjects: - - kind: Group - name: system:authenticated - apiGroup: rbac.authorization.k8s.io -roleRef: - kind: Role - name: ${PROJECT_NAME}-exec-role - apiGroup: rbac.authorization.k8s.io From 2e3c9c80b7c58376fa5b1fb1a46435d3a7dd756e Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:56:28 -0400 Subject: [PATCH 62/73] feat: add kubernetes-infra deployment Signed-off-by: Shane Utt --- .../dev/kubernetes-infra/kustomization.yaml | 19 ++++++ .../dev/kubernetes-infra/rbac.yaml | 66 +++++++++++++++++++ 2 files changed, 85 insertions(+) create mode 100644 deploy/environments/dev/kubernetes-infra/kustomization.yaml create mode 100644 deploy/environments/dev/kubernetes-infra/rbac.yaml diff --git a/deploy/environments/dev/kubernetes-infra/kustomization.yaml b/deploy/environments/dev/kubernetes-infra/kustomization.yaml new file mode 100644 index 00000000..3d48a33b --- /dev/null +++ b/deploy/environments/dev/kubernetes-infra/kustomization.yaml @@ -0,0 +1,19 @@ +# ------------------------------------------------------------------------------ +# OpenShift Environment - Infrastructure +# +# This provides the infrastructure-level requirements that individual +# development environments (see `deploy/environments/dev/kubernetes`) will need +# (e.g. CRDs, Operators, RBAC, etc). +# +# **WARNING**: Needs to be run once, and regularly updated on an OpenShift +# cluster by an administrator prior to deploying individual environments on +# that cluster with `deploy/environments/dev/kubernetes`. +# +# ------------------------------------------------------------------------------ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +resources: +- ../../../components/crds/ +- ../../../components/istio-control-plane/ +- rbac.yaml diff --git a/deploy/environments/dev/kubernetes-infra/rbac.yaml b/deploy/environments/dev/kubernetes-infra/rbac.yaml new file mode 100644 index 00000000..4998bccd --- /dev/null +++ b/deploy/environments/dev/kubernetes-infra/rbac.yaml @@ -0,0 +1,66 @@ +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: gateway-management +rules: + # --------------------------------------------------------------------------- + # Gateway API + # --------------------------------------------------------------------------- + - apiGroups: + - gateway.networking.k8s.io + resources: + - gateways + - httproutes + - grpcroutes + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + # --------------------------------------------------------------------------- + # Gateway API Inference Extension (GIE) + # --------------------------------------------------------------------------- + - apiGroups: + - inference.networking.x-k8s.io + resources: + - inferencepools + - inferencemodels + verbs: + - get + - list + - watch + - create + - update + - patch + - delete + # --------------------------------------------------------------------------- + # Istio + # --------------------------------------------------------------------------- + - apiGroups: + - networking.istio.io + resources: + - destinationrules + verbs: + - get + - list + - watch + - create + - update + - patch + - delete +--- +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRoleBinding +metadata: + name: authenticated-gateway-management +subjects: + - kind: Group + name: system:authenticated + apiGroup: rbac.authorization.k8s.io +roleRef: + kind: ClusterRole + name: gateway-management + apiGroup: rbac.authorization.k8s.io From c3732efe857e54a46a1a4f0a7f20802a66b74ec3 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:56:38 -0400 Subject: [PATCH 63/73] feat: add kubernetes dev deployment Signed-off-by: Shane Utt --- .../dev/kubernetes/kustomization.yaml | 19 ++++++++++ .../dev/kubernetes/patch-deployments.yaml | 36 +++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 deploy/environments/dev/kubernetes/kustomization.yaml create mode 100644 deploy/environments/dev/kubernetes/patch-deployments.yaml diff --git a/deploy/environments/dev/kubernetes/kustomization.yaml b/deploy/environments/dev/kubernetes/kustomization.yaml new file mode 100644 index 00000000..ef6f3939 --- /dev/null +++ b/deploy/environments/dev/kubernetes/kustomization.yaml @@ -0,0 +1,19 @@ +apiVersion: kustomize.config.k8s.io/v1beta1 +kind: Kustomization + +namespace: ${NAMESPACE} + +resources: +- ../../../components/vllm-sim/ +- ../../../components/inference-gateway/ + +images: +- name: quay.io/vllm-d/vllm-sim + newName: ${VLLM_SIM_IMAGE} + newTag: ${VLLM_SIM_TAG} +- name: quay.io/vllm-d/gateway-api-inference-extension/epp + newName: ${EPP_IMAGE} + newTag: ${EPP_TAG} + +patches: +- path: patch-deployments.yaml diff --git a/deploy/environments/dev/kubernetes/patch-deployments.yaml b/deploy/environments/dev/kubernetes/patch-deployments.yaml new file mode 100644 index 00000000..f199072e --- /dev/null +++ b/deploy/environments/dev/kubernetes/patch-deployments.yaml @@ -0,0 +1,36 @@ +apiVersion: apps/v1 +kind: Deployment +metadata: + name: endpoint-picker +spec: + template: + spec: + imagePullSecrets: + - name: ${REGISTRY_SECRET} + containers: + - name: epp + args: + - -poolNamespace + - ${NAMESPACE} + - -refreshMetricsInterval + - "500ms" + - -poolName + - "vllm-llama3-8b-instruct" + - -v + - "4" + - --zap-encoder + - "json" + - -grpcPort + - "9002" + - -grpcHealthPort + - "9003" +--- +apiVersion: apps/v1 +kind: Deployment +metadata: + name: vllm-sim +spec: + template: + spec: + imagePullSecrets: + - name: ${REGISTRY_SECRET} From a6ca97ace27f12553cce7cda74d42a4f6f318a04 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:57:05 -0400 Subject: [PATCH 64/73] fix: remove hardcoded namespace in makefile Signed-off-by: Shane Utt --- Makefile | 1 - 1 file changed, 1 deletion(-) diff --git a/Makefile b/Makefile index adf1ee65..c17b9d18 100644 --- a/Makefile +++ b/Makefile @@ -398,7 +398,6 @@ DEV_VERSION ?= 0.0.1 PROD_VERSION ?= 0.0.0 IMAGE_TAG_BASE ?= quay.io/vllm-d/$(PROJECT_NAME)/epp IMG = $(IMAGE_TAG_BASE):$(DEV_VERSION) -NAMESPACE ?= hc4ai-operator # CONTAINER_TOOL := $(shell command -v docker >/dev/null 2>&1 && echo docker || command -v podman >/dev/null 2>&1 && echo podman || echo "") BUILDER := $(shell command -v buildah >/dev/null 2>&1 && echo buildah || echo $(CONTAINER_TOOL)) From aa5e24ba9a0631c94b568580e5f23f3ca035634b Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:57:25 -0400 Subject: [PATCH 65/73] chore: remove old dev env targets in makefile Signed-off-by: Shane Utt --- Makefile | 131 ------------------------------------------------------- 1 file changed, 131 deletions(-) diff --git a/Makefile b/Makefile index c17b9d18..ab0baf04 100644 --- a/Makefile +++ b/Makefile @@ -510,137 +510,6 @@ uninstall-docker: check-container-tool ## Uninstall app from $(CONTAINER_TOOL) -$(CONTAINER_TOOL) stop $(PROJECT_NAME)-container && $(CONTAINER_TOOL) rm $(PROJECT_NAME)-container @echo "$(CONTAINER_TOOL) uninstallation complete. Remove alias if set: unalias $(PROJECT_NAME)" -### Kubernetes Targets (kubectl) - -# TODO: currently incorrect because it depends on OpenShift APIs. -# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14 -.PHONY: install-k8s -install-k8s: check-kubectl check-kustomize check-envsubst ## Install on Kubernetes - export PROJECT_NAME=${PROJECT_NAME} - export NAMESPACE=${NAMESPACE} - @echo "Creating namespace (if needed) and setting context to $(NAMESPACE)..." - kubectl create namespace $(NAMESPACE) 2>/dev/null || true - kubectl config set-context --current --namespace=$(NAMESPACE) - @echo "Deploying resources from deploy/ ..." - # Build the kustomization from deploy, substitute variables, and apply the YAML - kustomize build deploy/environments/dev/openshift | envsubst | kubectl apply -f - - @echo "Waiting for pod to become ready..." - sleep 5 - @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ - echo "Kubernetes installation complete."; \ - echo "To use the app, run:"; \ - echo "alias $(PROJECT_NAME)='kubectl exec -n $(NAMESPACE) -it $$POD -- /app/$(PROJECT_NAME)'" - -# TODO: currently incorrect because it depends on OpenShift APIs. -# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14 -.PHONY: uninstall-k8s -uninstall-k8s: check-kubectl check-kustomize check-envsubst ## Uninstall from Kubernetes - export PROJECT_NAME=${PROJECT_NAME} - export NAMESPACE=${NAMESPACE} - @echo "Removing resources from Kubernetes..." - kustomize build deploy/environments/dev/openshift | envsubst | kubectl delete --force -f - || true - POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -o jsonpath='{.items[0].metadata.name}'); \ - echo "Deleting pod: $$POD"; \ - kubectl delete pod "$$POD" --force --grace-period=0 || true; \ - echo "Kubernetes uninstallation complete. Remove alias if set: unalias $(PROJECT_NAME)" - -### OpenShift Targets (oc) - -# ------------------------------------------------------------------------------ -# OpenShift Infrastructure Installer -# -# This target deploys infrastructure requirements for the entire cluster. -# Among other things, this includes CRDs and operators which all users of the -# cluster need for development (e.g. Gateway API, Istio, etc). -# -# **Warning**: Only run this if you're certain you should be running it. It -# has implications for all users of the cluster! -# ------------------------------------------------------------------------------ -.PHONY: install-openshift-infrastructure -install-openshift-infrastructure: -ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) - @echo "INFRASTRUCTURE_OVERRIDE is set to true, deploying infrastructure components" - @echo "Installing OpenShift Infrastructure" - kustomize build deploy/environments/dev/openshift-infra | kubectl apply --server-side --force-conflicts -f - -else - $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") -endif - -# ------------------------------------------------------------------------------ -# OpenShift Infrastructure Uninstaller -# -# This target removes all infrastructure components (e.g. CRDs, operators, -# etc) for the entire cluster. -# -# **Warning**: Only run this if you're certain you should be running it. **This -# will disrupt everyone using the cluster**. Generally this should only be run -# when the infrastructure components have undergone very significant change, and -# you need to do a hard cleanup and re-deploy. -# ------------------------------------------------------------------------------ -.PHONY: uninstall-openshift-infrastructure -uninstall-openshift-infrastructure: -ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) - @echo "INFRASTRUCTURE_OVERRIDE is set to true, removing infrastructure components (this is extremely destructive)" - @echo "This is extremely destructive. We'll provide a few seconds before starting to give you a chance to cancel." - sleep 3 - @echo "Uninstalling OpenShift Infrastructure Components" - @echo "Installing OpenShift Infrastructure" - kustomize build deploy/environments/dev/openshift-infra | kubectl delete -f - || true -else - $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") -endif - -# ------------------------------------------------------------------------------ -# OpenShift Installer -# -# This target deploys components in a namespace on an OpenShift cluster for -# a developer to do development and testing cycles. -# ------------------------------------------------------------------------------ -.PHONY: install-openshift -install-openshift: check-kubectl check-kustomize check-envsubst ## Install on OpenShift - @echo $$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION - @echo "Creating namespace $(NAMESPACE)..." - kubectl create namespace $(NAMESPACE) 2>/dev/null || true - @echo "Deploying common resources from deploy/ ..." - # Build and substitute the base manifests from deploy, then apply them - kustomize build deploy/environments/dev/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -n $(NAMESPACE) -f - - @echo "Waiting for pod to become ready..." - sleep 5 - @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}'); \ - echo "OpenShift installation complete."; \ - echo "To use the app, run:"; \ - echo "alias $(PROJECT_NAME)='kubectl exec -n $(NAMESPACE) -it $$POD -- /app/$(PROJECT_NAME)'" - -# ------------------------------------------------------------------------------ -# OpenShift Uninstaller -# -# This target cleans up a developer's testing and development namespace, -# removing all components therein. -# ------------------------------------------------------------------------------ -.PHONY: uninstall-openshift -uninstall-openshift: check-kubectl check-kustomize check-envsubst ## Uninstall from OpenShift - @echo "Removing resources from OpenShift..." - kustomize build deploy/environments/dev/openshift | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete --force -f - || true - # @if kubectl api-resources --api-group=route.openshift.io | grep -q Route; then \ - # envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' < deploy/openshift/route.yaml | kubectl delete --force -f - || true; \ - # fi - @POD=$$(kubectl get pod -l app=$(PROJECT_NAME)-statefulset -n $(NAMESPACE) -o jsonpath='{.items[0].metadata.name}'); \ - echo "Deleting pod: $$POD"; \ - kubectl delete pod "$$POD" --force --grace-period=0 || true; \ - echo "OpenShift uninstallation complete. Remove alias if set: unalias $(PROJECT_NAME)" - -### RBAC Targets (using kustomize and envsubst) - -.PHONY: install-rbac -install-rbac: check-kubectl check-kustomize check-envsubst ## Install RBAC - @echo "Applying RBAC configuration from deploy/rbac..." - kustomize build deploy/environments/dev/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl apply -f - - -.PHONY: uninstall-rbac -uninstall-rbac: check-kubectl check-kustomize check-envsubst ## Uninstall RBAC - @echo "Removing RBAC configuration from deploy/rbac..." - kustomize build deploy/environments/dev/openshift/rbac | envsubst '$$PROJECT_NAME $$NAMESPACE $$IMAGE_TAG_BASE $$VERSION' | kubectl delete -f - || true - ##@ Version Extraction .PHONY: version dev-registry prod-registry extract-version-info From 6c1c7d0fd745a4c8360036ff8921ec942340d2a6 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:57:47 -0400 Subject: [PATCH 66/73] chore: cleanup kind dev env in makefile Signed-off-by: Shane Utt --- Makefile | 27 ++++++++++++++++++--------- 1 file changed, 18 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index ab0baf04..e7b93db5 100644 --- a/Makefile +++ b/Makefile @@ -656,35 +656,44 @@ print-project-name: ## Print the current project name .PHONY: install-hooks install-hooks: ## Install git hooks git config core.hooksPath hooks -# -# Development Environments -# + +# ============================================================================== +# Development Environments - Kubernetes in Docker (KIND) +# ============================================================================== KIND_CLUSTER_NAME ?= gie-dev # ------------------------------------------------------------------------------ -# Development Environment: Kubernetes In Docker (KIND) +# Kind Development Environment - Deploy # # This target will deploy a local kind cluster with the GIE stack deployed into # the default namespace for development and testing. -# # ------------------------------------------------------------------------------ .PHONY: environment.dev.kind environment.dev.kind: CLUSTER_NAME=$(KIND_CLUSTER_NAME) ./scripts/kind-dev-env.sh # ------------------------------------------------------------------------------ -# Development Environment Update: Kubernetes In Docker (KIND) +# Kind Development Environment - Update # # This target will build the current changes into an image, load them into an # existing kind cluster and perform a rollout so that the new changes are # reflected in the environment. -# # ------------------------------------------------------------------------------ .PHONY: environment.dev.kind.update environment.dev.kind.update: image-build @echo "INFO: Loading images into cluster" CLUSTER_NAME=$(KIND_CLUSTER_NAME) ./scripts/kind-load-images.sh 2>&1 @echo "INFO: Restarting the Endpoint Picker Deployment" - kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout restart deployment endpoint-picker - kubectl --context kind-$(KIND_CLUSTER_NAME) -n default rollout status deployment endpoint-picker + $(KUBECTL) --context kind-$(KIND_CLUSTER_NAME) -n default rollout restart deployment endpoint-picker + $(KUBECTL) --context kind-$(KIND_CLUSTER_NAME) -n default rollout status deployment endpoint-picker + +# ------------------------------------------------------------------------------ +# Kind Development Environment - Teardown +# +# This target will tear down the entire Kind cluster. +# ------------------------------------------------------------------------------ +.PHONY: clean.environment.dev.kind +clean.environment.dev.kind: + @echo "INFO: cleaning up kind cluster $(KIND_CLUSTER_NAME)" + kind delete cluster --name $(KIND_CLUSTER_NAME) From 214f6498f3bbc5606501343cc805a8a27ceda0a0 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 16:58:10 -0400 Subject: [PATCH 67/73] feat: add kubernetes dev env makefile targets Signed-off-by: Shane Utt --- Makefile | 123 +++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 123 insertions(+) diff --git a/Makefile b/Makefile index e7b93db5..1205ca9a 100644 --- a/Makefile +++ b/Makefile @@ -697,3 +697,126 @@ environment.dev.kind.update: image-build clean.environment.dev.kind: @echo "INFO: cleaning up kind cluster $(KIND_CLUSTER_NAME)" kind delete cluster --name $(KIND_CLUSTER_NAME) + +# ============================================================================== +# Development Environments - Kubernetes +# ============================================================================== + +# ------------------------------------------------------------------------------ +# Kubernetes Development Environment - Deploy Infrastructure +# +# This target deploys infrastructure requirements for the entire cluster. +# Among other things, this includes CRDs and operators which all users of the +# cluster need for development (e.g. Gateway API, Istio, etc). +# +# **Warning**: This needs to be run and regularly updated by an admin to +# support the individual development environments on the cluster. +# +# **Warning**: Only run this if you're certain you should be running it. It +# has implications for all users of the cluster! +# ------------------------------------------------------------------------------ +.PHONY: environment.dev.kubernetes.infrastructure +environment.dev.kubernetes.infrastructure: +ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) + @echo "Deploying OpenShift Infrastructure Components" + kustomize build deploy/environments/dev/kubernetes-infra | kubectl apply --server-side --force-conflicts -f - +else + $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") +endif + +# ------------------------------------------------------------------------------ +# Kubernetes Development Environment - Teardown Infrastructure +# +# This target removes all infrastructure components (e.g. CRDs, operators, +# etc) for the entire cluster. +# +# **Warning**: Only run this if you're certain you should be running it. **This +# will disrupt everyone using the cluster**. Generally this should only be run +# when the infrastructure components have undergone very significant change, and +# you need to do a hard cleanup and re-deploy. +# ------------------------------------------------------------------------------ +.PHONY: clean.environment.dev.kubernetes.infrastructure +clean.environment.dev.kubernetes.infrastructure: +ifeq ($(strip $(INFRASTRUCTURE_OVERRIDE)),true) + @echo "This is extremely destructive. We'll provide 5 seconds before starting to give you a chance to cancel." + sleep 5 + @echo "Tearing Down OpenShift Infrastructure Components" + kustomize build deploy/environments/dev/kubernetes-infra | kubectl delete -f - || true +else + $(error "Error: The environment variable INFRASTRUCTURE_OVERRIDE must be set to true in order to run this target.") +endif + +# ------------------------------------------------------------------------------ +# Kubernetes Development Environment - Deploy +# +# This target deploys the GIE stack in a specific namespace for development and +# testing. +# ------------------------------------------------------------------------------ +.PHONY: environment.dev.kubernetes +environment.dev.kubernetes: check-kubectl check-kustomize check-envsubst + @echo "INFO: checking required vars" +ifndef NAMESPACE + $(error "Error: NAMESPACE is required but not set) +endif + export NAMESPACE=${NAMESPACE} +ifndef REGISTRY_SECRET + $(error "Error: REGISTRY_SECRET is required but not set) +endif + export REGISTRY_SECRET=${REGISTRY_SECRET} +ifndef VLLM_SIM_IMAGE + $(error "Error: VLLM_SIM_IMAGE is required but not set) +endif + export VLLM_SIM_IMAGE=${VLLM_SIM_IMAGE} +ifndef VLLM_SIM_TAG + $(error "Error: VLLM_SIM_TAG is required but not set) +endif + export VLLM_SIM_TAG=${VLLM_SIM_TAG} +ifndef EPP_IMAGE + $(error "Error: EPP_IMAGE is required but not set) +endif + export EPP_IMAGE=${EPP_IMAGE} +ifndef EPP_TAG + $(error "Error: EPP_TAG is required but not set) +endif + export EPP_TAG=${EPP_TAG} + @echo "INFO: Creating namespace (if needed) and setting context to $(NAMESPACE)..." + kubectl create namespace $(NAMESPACE) 2>/dev/null || true + kubectl config set-context --current --namespace=$(NAMESPACE) + @echo "INFO: Deploying Development Environment in namespace $(NAMESPACE)" + kustomize build deploy/environments/dev/kubernetes | envsubst | kubectl -n $(NAMESPACE) apply -f - + @echo "INFO: Waiting for Pods in namespace $(NAMESPACE) to become ready" + kubectl -n $(NAMESPACE) wait --for=condition=Ready --all pods --timeout=300s + @echo "INFO: Waiting for Gateway in namespace $(NAMESPACE) to become ready" + kubectl -n $(NAMESPACE) wait gateway/inference-gateway --for=condition=Programmed --timeout=60s + +# ------------------------------------------------------------------------------ +# Kubernetes Development Environment - Teardown +# +# Tears down the namespace, and therefore the development environment. +# ------------------------------------------------------------------------------ +.PHONY: clean.environment.dev.kubernetes +clean.environment.dev.kubernetes: check-kubectl check-kustomize check-envsubst +ifndef NAMESPACE + $(error "Error: NAMESPACE is required but not set) +endif + @echo "INFO: deleting namespace $(NAMESPACE)" + kubectl delete namespace $(NAMESPACE) + +# ----------------------------------------------------------------------------- +# TODO: these are old aliases that we still need for the moment, but will be +# cleaned up later. +# +# See: https://github.com/neuralmagic/gateway-api-inference-extension/issues/28 +# ----------------------------------------------------------------------------- + +.PHONY: install-openshift-infrastructure +install-openshift-infrastructure: environment.dev.kubernetes.infrastructure + +.PHONY: uninstall-openshift-infrastructure +uninstall-openshift-infrastructure: clean.environment.dev.kubernetes.infrastructure + +.PHONY: install-openshift +install-openshift: environment.dev.kubernetes + +.PHONY: uninstall-openshift +uninstall-openshift: clean.environment.dev.kubernetes From 6bedb47f226051a7acd1743c14dd6ffbd2eab1ec Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 17:29:42 -0400 Subject: [PATCH 68/73] docs: update DEVELOPMENT.md with k8s dev env Signed-off-by: Shane Utt --- DEVELOPMENT.md | 136 +++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 133 insertions(+), 3 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index b1a5c409..6260db43 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -66,8 +66,138 @@ recent changes are refleted. ## Kubernetes -WIP +A Kubernetes (or OpenShift) cluster can be used for development and testing. +There is a cluster-level infrastructure deployment that needs to be managed, +and then development environments can be created on a per-namespace basis to +enable sharing the cluster with multiple developers if desired. -## OpenShift +### Setup - Infrastructure -WIP +> **WARNING**: In shared cluster situations you should probably not be +> running this unless you're the cluster admin and you're _certain_ it's you +> that should be running this. + +The following will deploy all the infrastructure-level requirements (e.g. CRDs, +Operators, etc) to support the namespace-level development environments: + +```console +make environment.dev.kubernetes.infrastructure +``` + +When the `deploy/environments/dev/kubernetes-infra` deployment's components are +updated, this will need to be re-deployed. + +### Setup - Developer Environment + +> **WARNING**: This setup is currently very manual in regards to container +> images for the VLLM simulator and the EPP. It is expected that you build and +> push images for both to your own private registry. In future iterations, we +> will be automating this further to make it simpler. + +To deploy a development environment to the cluster you'll need to explicitly +provide a namespace. This can be `default` if this is your personal cluster, +but on a shared cluster you should pick something unique. For example: + +```console +export NAMESPACE=annas-dev-environment +``` + +Create the namespace: + +```console +kubectl create namespace ${NAMESPACE} +``` + +You'll need to provide a `Secret` with the login credentials for your private +repository (e.g. quay.io). It should look something like this: + +```yaml +apiVersion: v1 +kind: Secret +metadata: + name: anna-pull-secret +data: + .dockerconfigjson: +type: kubernetes.io/dockerconfigjson +``` + +Apply that to your namespace: + +```console +kubectl -n ${NAMESPACE} apply -f secret.yaml +``` + +Export the name of the secret to the environment: + +```console +export REGISTRY_SECRET=anna-pull-secret +``` + +Now you need to provide several other environment variables. You'll need to +indicate the location and tag of the `vllm-sim` image: + +```console +export VLLM_SIM_IMAGE="/" +export VLLM_SIM_TAG="" +``` + +The same thing will need to be done for the EPP: + +```console +export EPP_IMAGE="/" +export EPP_TAG="" +``` + +Once all this is set up, you can deploy the environment: + +```console +make environment.dev.kubernetes +``` + +This will deploy the entire stack to whatever namespace you chose. You can test +by exposing the inference `Gateway` via port-forward: + +```console +kubectl -n ${NAMESPACE} port-forward service/inference-gateway-istio 8080:80 +``` + +And making requests with `curl`: + +```console +curl -s -w '\n' http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq +``` + +#### Development Cycle + +> **WARNING**: This is a very manual process at the moment. We expect to make +> this more automated in future iterations. + +Make your changes locally and commit them. Then select an image tag based on +the `git` SHA: + +```console +export EPP_TAG=$(git rev-parse HEAD) +``` + +Build the image: + +```console +DEV_VERSION=$EPP_TAG make image-build +``` + +Tag the image for your private registry and push it: + +```console +$CONTAINER_RUNTIME tag quay.io/vllm-d/gateway-api-inference-extension/epp:$TAG \ + /:$EPP_TAG +$CONTAINER_RUNTIME push /:$EPP_TAG +``` + +Then you can re-deploy the environment with the new changes (don't forget all +the required env vars): + +```console +make environment.dev.kubernetes +``` + +And test the changes. From 893541a017710da98579a73131ce0dc46a78ec66 Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 20:40:26 -0400 Subject: [PATCH 69/73] docs: remove WIPs from dev envs that are now complete --- DEVELOPMENT.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 6260db43..9f75eb88 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -8,9 +8,9 @@ We provide `Makefile` targets and development environment deployment manifests under the `deploy/environments` directory, which include support for multiple kinds of clusters: -* Kubernetes In Docker (KIND) -* Kubernetes (WIP: https://github.com/neuralmagic/gateway-api-inference-extension/issues/14) -* OpenShift (WIP: https://github.com/neuralmagic/gateway-api-inference-extension/issues/22) +* [Kubernetes In Docker (KIND)](#kubernetes-in-docker-(kind)) +* [Kubernetes](#kubernetes) +* [OpenShift](#kubernetes) We support multiple different model serving platforms for testing: From d277cab60cf80f8b1209646a28158a48ad09acce Mon Sep 17 00:00:00 2001 From: Shane Utt Date: Mon, 21 Apr 2025 20:47:09 -0400 Subject: [PATCH 70/73] docs: language cleanup and updates for DEVELOPMENT.md --- DEVELOPMENT.md | 25 +++++++++++++++++-------- 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/DEVELOPMENT.md b/DEVELOPMENT.md index 9f75eb88..2e903ce5 100644 --- a/DEVELOPMENT.md +++ b/DEVELOPMENT.md @@ -69,13 +69,15 @@ recent changes are refleted. A Kubernetes (or OpenShift) cluster can be used for development and testing. There is a cluster-level infrastructure deployment that needs to be managed, and then development environments can be created on a per-namespace basis to -enable sharing the cluster with multiple developers if desired. +enable sharing the cluster with multiple developers (or feel free to just use +the `default` namespace if the cluster is private/personal). ### Setup - Infrastructure > **WARNING**: In shared cluster situations you should probably not be > running this unless you're the cluster admin and you're _certain_ it's you -> that should be running this. +> that should be running this, as this can be disruptive to other developers +> in the cluster. The following will deploy all the infrastructure-level requirements (e.g. CRDs, Operators, etc) to support the namespace-level development environments: @@ -84,15 +86,15 @@ Operators, etc) to support the namespace-level development environments: make environment.dev.kubernetes.infrastructure ``` -When the `deploy/environments/dev/kubernetes-infra` deployment's components are -updated, this will need to be re-deployed. +Whenever the `deploy/environments/dev/kubernetes-infra` deployment's components +are updated, this will need to be re-deployed. ### Setup - Developer Environment > **WARNING**: This setup is currently very manual in regards to container > images for the VLLM simulator and the EPP. It is expected that you build and > push images for both to your own private registry. In future iterations, we -> will be automating this further to make it simpler. +> will be providing automation around this to make it simpler. To deploy a development environment to the cluster you'll need to explicitly provide a namespace. This can be `default` if this is your personal cluster, @@ -102,6 +104,9 @@ but on a shared cluster you should pick something unique. For example: export NAMESPACE=annas-dev-environment ``` +> **NOTE**: You could also use a tool like `uuidgen` to come up with a unique +> name (e.g. `anna-0d03d66c-8880-4000-88b7-22f1d430f7d0`). + Create the namespace: ```console @@ -117,7 +122,7 @@ kind: Secret metadata: name: anna-pull-secret data: - .dockerconfigjson: + .dockerconfigjson: type: kubernetes.io/dockerconfigjson ``` @@ -127,7 +132,7 @@ Apply that to your namespace: kubectl -n ${NAMESPACE} apply -f secret.yaml ``` -Export the name of the secret to the environment: +Export the name of the `Secret` to the environment: ```console export REGISTRY_SECRET=anna-pull-secret @@ -164,7 +169,8 @@ kubectl -n ${NAMESPACE} port-forward service/inference-gateway-istio 8080:80 And making requests with `curl`: ```console -curl -s -w '\n' http://localhost:8080/v1/completions -H 'Content-Type: application/json' -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq +curl -s -w '\n' http://localhost:8080/v1/completions -H 'Content-Type: application/json' \ + -d '{"model":"food-review","prompt":"hi","max_tokens":10,"temperature":0}' | jq ``` #### Development Cycle @@ -193,6 +199,9 @@ $CONTAINER_RUNTIME tag quay.io/vllm-d/gateway-api-inference-extension/epp:$TAG \ $CONTAINER_RUNTIME push /:$EPP_TAG ``` +> **NOTE**: `$CONTAINER_RUNTIME` can be configured or replaced with whatever your +> environment's standard container runtime is (e.g. `podman`, `docker`). + Then you can re-deploy the environment with the new changes (don't forget all the required env vars): From f9afbfdd7a7e459cfbd9251fa5e8c4a1f17c884e Mon Sep 17 00:00:00 2001 From: Andrew Anderson Date: Mon, 21 Apr 2025 21:40:09 -0400 Subject: [PATCH 71/73] implementing vuln scanner and h100 cluster deployment --- .tekton/pipelinerun.yaml | 180 +++++++++++++++++++++++++++-------- .tekton/promote-to-prod.yaml | 4 +- 2 files changed, 143 insertions(+), 41 deletions(-) diff --git a/.tekton/pipelinerun.yaml b/.tekton/pipelinerun.yaml index 45c8a07f..02a57af3 100644 --- a/.tekton/pipelinerun.yaml +++ b/.tekton/pipelinerun.yaml @@ -68,6 +68,26 @@ spec: runAfter: - fix-permissions + # - name: debug-user + # taskSpec: + # workspaces: + # - name: source + # workspace: source + # steps: + # - name: show-user-info + # image: busybox + # script: | + # #!/bin/sh + # echo "Current UID:" + # id -u + # echo "Current GID:" + # id -g + # echo "Permissions on /workspace/source:" + # ls -ld /workspace/source + # workspaces: + # - name: source + # workspace: source + - name: which-branch taskRef: name: print-branch-task @@ -157,7 +177,7 @@ spec: workspaces: - name: source workspace: source - + - name: openshift-redeploy-h100 when: - input: "$(params.runOptional)" @@ -276,7 +296,7 @@ spec: runAfter: - extract-version-and-registry workspaces: - - name: registry + - name: registry-secret workspace: registry-secret - name: buildah-build @@ -306,7 +326,7 @@ spec: workspace: source - name: registry workspace: registry-secret - + - name: vulnerability-scan when: - input: "$(params.runOptional)" @@ -332,45 +352,69 @@ spec: - name: output workspace: output - - name: sync-after-promote-or-build + - name: tag-version-after-promotion when: + - input: "$(params.source_branch)" + operator: in + values: ["main"] - input: "$(tasks.read-cluster-name.results.cluster-name)" operator: in values: ["cluster-platform-eval"] + taskRef: + name: tag-version-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" runAfter: - promote-to-prod - - vulnerability-scan - taskRef: - name: noop-task + workspaces: + - name: source + workspace: source + - name: git-auth + workspace: git-auth - # - name: update-submodule - # when: - # - input: "$(params.source_branch)" - # operator: in - # values: ["main"] - # taskRef: - # name: update-submodule-task - # runAfter: - # - promote-to-prod - # workspaces: - # - name: source - # workspace: source - # - name: git-auth - # workspace: git-auth + - name: tag-version-after-scan + when: + - input: "$(params.source_branch)" + operator: in + values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] + taskRef: + name: tag-version-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + runAfter: + - vulnerability-scan + workspaces: + - name: source + workspace: source + - name: git-auth + workspace: git-auth - - name: tag-version + - name: openshift-redeploy-after-promotion when: - input: "$(params.runOptional)" operator: in values: ["true"] - input: "$(params.source_branch)" operator: in - values: ["main", "dev"] + values: ["main"] - input: "$(tasks.read-cluster-name.results.cluster-name)" operator: in values: ["cluster-platform-eval"] taskRef: - name: tag-version-task + name: openshift-redeploy-task params: - name: source-branch value: "$(params.source_branch)" @@ -378,22 +422,27 @@ spec: value: "$(tasks.extract-version-and-registry.results.prod-version)" - name: dev-version value: "$(tasks.extract-version-and-registry.results.dev-version)" + - name: prod_image_tag_base + value: "$(tasks.extract-version-and-registry.results.prod-image-tag-base)" + - name: dev_image_tag_base + value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" runAfter: - - sync-after-promote-or-build + - tag-version-after-promotion workspaces: - name: source workspace: source - - name: git-auth - workspace: git-auth - - name: openshift-redeploy + - name: openshift-redeploy-after-scan when: - input: "$(params.runOptional)" operator: in values: ["true"] - input: "$(params.source_branch)" operator: in - values: ["dev", "main"] + values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: openshift-redeploy-task params: @@ -408,19 +457,52 @@ spec: - name: dev_image_tag_base value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" runAfter: - - tag-version + - tag-version-after-scan workspaces: - name: source workspace: source - - name: go-test-post-deploy + - name: go-test-post-deploy-after-promotion when: - input: "$(params.runOptional)" operator: in values: ["true"] - input: "$(params.source_branch)" operator: in - values: ["dev", "main"] + values: ["main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] + taskRef: + name: go-test-post-deploy-task + params: + - name: source-branch + value: "$(params.source_branch)" + - name: prod-version + value: "$(tasks.extract-version-and-registry.results.prod-version)" + - name: dev-version + value: "$(tasks.extract-version-and-registry.results.dev-version)" + - name: prod_image_tag_base + value: "$(tasks.extract-version-and-registry.results.prod-image-tag-base)" + - name: dev_image_tag_base + value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" + runAfter: + - openshift-redeploy-after-promotion + workspaces: + - name: source + workspace: source + + - name: go-test-post-deploy-after-scan + when: + - input: "$(params.runOptional)" + operator: in + values: ["true"] + - input: "$(params.source_branch)" + operator: in + values: ["dev"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] taskRef: name: go-test-post-deploy-task params: @@ -435,12 +517,32 @@ spec: - name: dev_image_tag_base value: "$(tasks.extract-version-and-registry.results.dev-image-tag-base)" runAfter: - - openshift-redeploy + - openshift-redeploy-after-scan workspaces: - name: source workspace: source - - name: benchmark + - name: benchmark-after-promotion + when: + - input: "$(params.source_branch)" + operator: in + values: ["main"] + - input: "$(tasks.read-cluster-name.results.cluster-name)" + operator: in + values: ["cluster-platform-eval"] + continueOn: + errors: true + params: + - name: openshift_host + value: "https://api.fmaas-platform-eval.fmaas.res.ibm.com:6443" + - name: openshift_namespace + value: "hc4ai-operator-dev" + taskRef: + name: benchmark-task + runAfter: + - go-test-post-deploy-after-promotion + + - name: benchmark-after-scan when: - input: "$(params.source_branch)" operator: in @@ -458,9 +560,9 @@ spec: taskRef: name: benchmark-task runAfter: - - go-test-post-deploy + - go-test-post-deploy-after-scan - - name: increment-versions + - name: increment-versions-after-promotion when: - input: "$(params.source_branch)" operator: in @@ -476,7 +578,7 @@ spec: taskRef: name: increment-versions-task runAfter: - - openshift-redeploy + - benchmark-after-promotion workspaces: - name: source workspace: source @@ -489,7 +591,7 @@ spec: operator: in values: ["main"] runAfter: - - increment-versions + - increment-versions-after-promotion taskRef: name: noop-task @@ -499,7 +601,7 @@ spec: operator: in values: ["dev"] runAfter: - - benchmark + - benchmark-after-scan taskRef: name: noop-task diff --git a/.tekton/promote-to-prod.yaml b/.tekton/promote-to-prod.yaml index 7c4c1910..4746848b 100644 --- a/.tekton/promote-to-prod.yaml +++ b/.tekton/promote-to-prod.yaml @@ -13,13 +13,13 @@ spec: - name: dev_image_tag_base description: "Development image tag base" workspaces: - - name: registry + - name: registry-secret description: "Registry secret workspace (must include .dockerconfigjson)" steps: - name: promote image: quay.io/skopeo/stable:latest imagePullPolicy: IfNotPresent - workingDir: /workspace/registry + workingDir: /workspace/registry-secret script: | #!/bin/sh set -e From ed6c239d2cc4a6e8908d216765b86fce2928654d Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 22 Apr 2025 15:58:57 +0300 Subject: [PATCH 72/73] Add active lora scorer + remove loraAffinityThreshold filter --- pkg/epp/backend/metrics/metrics.go | 3 - pkg/epp/datastore/datastore.go | 13 ++- pkg/epp/scheduling/active_loras_scorer.go | 4 + pkg/epp/scheduling/filter.go | 61 ------------- pkg/epp/scheduling/filter_test.go | 104 ---------------------- pkg/epp/scheduling/scheduler.go | 15 +--- 6 files changed, 13 insertions(+), 187 deletions(-) diff --git a/pkg/epp/backend/metrics/metrics.go b/pkg/epp/backend/metrics/metrics.go index 647b07ee..f5e64090 100644 --- a/pkg/epp/backend/metrics/metrics.go +++ b/pkg/epp/backend/metrics/metrics.go @@ -26,7 +26,6 @@ import ( dto "github.com/prometheus/client_model/go" "github.com/prometheus/common/expfmt" "go.uber.org/multierr" - "sigs.k8s.io/controller-runtime/pkg/log" ) const ( @@ -105,7 +104,6 @@ func (p *PodMetricsClientImpl) promToPodMetrics( // Handle LoRA metrics (only if all LoRA MetricSpecs are present) if p.MetricMapping.LoraRequestInfo != nil { - logger := log.FromContext(context.TODO()) // 'vllm:lora_requests_info metrics contains list of different running loras permutations, // each metric's value is the reporting timestamp // we start from the most recent metric, if there are waiting loras - we are on the full capacity, no need to find less recent metric values @@ -161,7 +159,6 @@ func (p *PodMetricsClientImpl) promToPodMetrics( } } } - logger.Info(">>> In promToPodMetrics, updated loras", "active", updated.ActiveModels, "waiting", updated.WaitingModels) } return updated, errs diff --git a/pkg/epp/datastore/datastore.go b/pkg/epp/datastore/datastore.go index db37c06b..f84c0c13 100644 --- a/pkg/epp/datastore/datastore.go +++ b/pkg/epp/datastore/datastore.go @@ -85,7 +85,7 @@ func NewDatastore(parentCtx context.Context, pmf *backendmetrics.PodMetricsFacto pmf: pmf, } - go store.cleanupSessions(sessionKeepAliveCheckFrequency, sessionKeepAliveTime, parentCtx) + go store.cleanupSessions(sessionKeepAliveCheckFrequency, sessionKeepAliveTime) return store } @@ -308,10 +308,9 @@ type sessionInfo struct { lru time.Time } -// cleanup Cleans up the set of stored session information by removing information -// of old sessions. -func (ds *datastore) cleanupSessions(keepAliveCheckFrequency time.Duration, sessionKeepAlive time.Duration, ctx context.Context) { - logger := log.FromContext(ctx) +// cleanup Cleans up the set of stored session information by removing information of old sessions. +func (ds *datastore) cleanupSessions(keepAliveCheckFrequency time.Duration, sessionKeepAlive time.Duration) { + logger := log.FromContext(ds.parentCtx) logger.Info("Session-affinity cleanup started") ticker := time.NewTicker(keepAliveCheckFrequency) @@ -319,11 +318,11 @@ func (ds *datastore) cleanupSessions(keepAliveCheckFrequency time.Duration, sess for { select { - case <-ctx.Done(): + case <-ds.parentCtx.Done(): logger.Info("Session-affinity cleanup stopped:") return case now := <-ticker.C: - logger.Info("Session affinity checking") + logger.Info("Session affinity cleanup") ds.sessions.Range( func(sessionID any, rawSessionInfo any) bool { if sessionInfo, ok := rawSessionInfo.(*sessionInfo); ok { diff --git a/pkg/epp/scheduling/active_loras_scorer.go b/pkg/epp/scheduling/active_loras_scorer.go index 88a86252..670cf179 100644 --- a/pkg/epp/scheduling/active_loras_scorer.go +++ b/pkg/epp/scheduling/active_loras_scorer.go @@ -53,6 +53,10 @@ func (s ActiveLorasScorer) ScoreTargets(ctx *types.Context, pods []*types.PodMet // lora is running on this pod scoredPods[i].Score = s.weight logger.Info("Lora is running on a pod", "lora", ctx.Req.Model, "pod", pod.NamespacedName.String()) + } else if _, ok := pod.Metrics.WaitingModels[ctx.Req.Model]; ok { + // lora is waiting on this pod + scoredPods[i].Score = s.weight + logger.Info("Lora is waiting on a pod", "lora", ctx.Req.Model, "pod", pod.NamespacedName.String()) } scoredPods[i].Pod = pod } diff --git a/pkg/epp/scheduling/filter.go b/pkg/epp/scheduling/filter.go index 99044e97..ee602d0c 100644 --- a/pkg/epp/scheduling/filter.go +++ b/pkg/epp/scheduling/filter.go @@ -19,8 +19,6 @@ package scheduling import ( "errors" "math" - "math/rand" - "time" "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" logutil "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/util/logging" @@ -198,65 +196,6 @@ func leastKVCacheFilterFunc(ctx *types.Context, pods []*types.PodMetrics) ([]*ty return filtered, nil } -var loRAAffinityFilter = &basicFilter{ - name: "affinity LoRA", - filter: loRASoftAffinityFilterFunc, -} - -// loRASoftAffinityPredicate implements a pod selection strategy that prioritizes pods -// with existing LoRA model affinity while allowing for load balancing through randomization. -// -// The function works by: -// 1. Separating pods into two groups: those with target model affinity and those with available capacity -// 2. Using a probability threshold to sometimes select from non-affinity pods to enable load balancing -// 3. Falling back to whatever group has pods if one group is empty -// -// Parameters: -// - logger: Logger interface for diagnostic output -// - req: LLM request containing the resolved target model -// - pods: Slice of pod metrics to filter -// -// Returns: -// - Filtered slice of pod metrics based on affinity and availability -// - Error if any issues occur during filtering -func loRASoftAffinityFilterFunc(ctx *types.Context, pods []*types.PodMetrics) ([]*types.PodMetrics, error) { - - // Pre-allocate slices with estimated capacity - filtered_affinity := make([]*types.PodMetrics, 0, len(pods)) - filtered_available := make([]*types.PodMetrics, 0, len(pods)) - - // Categorize pods based on affinity and availability - for _, pod := range pods { - _, active := pod.ActiveModels[ctx.Req.ResolvedTargetModel] - _, waiting := pod.WaitingModels[ctx.Req.ResolvedTargetModel] - - if active || waiting { - filtered_affinity = append(filtered_affinity, pod) - } else if len(pod.ActiveModels)+len(pod.WaitingModels) < pod.MaxActiveModels { - filtered_available = append(filtered_available, pod) - } - } - - // Use crypto/rand for better randomization in production environments - randSource := rand.NewSource(time.Now().UnixNano()) - randGen := rand.New(randSource) - - // If both groups have pods, use probability to select which group to return - if len(filtered_affinity) > 0 && len(filtered_available) > 0 { - if randGen.Float64() < config.LoraAffinityThreshold { - return filtered_affinity, nil - } - return filtered_available, nil - } - - // Return whichever group has pods - if len(filtered_affinity) > 0 { - return filtered_affinity, nil - } - - return filtered_available, nil -} - // podPredicate is a filter function to check whether a pod is desired. type podPredicate func(req *types.LLMRequest, pod *types.PodMetrics) bool diff --git a/pkg/epp/scheduling/filter_test.go b/pkg/epp/scheduling/filter_test.go index 543826d0..8724ceb7 100644 --- a/pkg/epp/scheduling/filter_test.go +++ b/pkg/epp/scheduling/filter_test.go @@ -22,7 +22,6 @@ import ( "testing" "github.com/google/go-cmp/cmp" - k8stypes "k8s.io/apimachinery/pkg/types" backendmetrics "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/backend/metrics" "sigs.k8s.io/gateway-api-inference-extension/pkg/epp/scheduling/types" ) @@ -203,106 +202,3 @@ func TestFilterFunc(t *testing.T) { }) } } - -// TestLoRASoftAffinityDistribution tests that the loRASoftAffinityFilter function -// properly distributes requests according to the loraAffinityThreshold -func TestLoRASoftAffinityDistribution(t *testing.T) { - const ( - testModelName = "test-model" - testAffinityModel = "test-affinity-model" - numIterations = 10000 - tolerancePercent = 5.0 // Allow 5% tolerance from expected distribution - ) - - // Save original config value to restore later - originalThreshold := config.LoraAffinityThreshold - - // Set a specific test value for this test - testThreshold := 0.75 // 75% - config.LoraAffinityThreshold = testThreshold - - // Ensure we restore the original threshold when test completes - defer func() { - config.LoraAffinityThreshold = originalThreshold - }() - - // Create a test request and pods - req := &types.LLMRequest{ - Model: testAffinityModel, - ResolvedTargetModel: testAffinityModel, - } - - // Test setup: One affinity pod and one available pod - pods := []*types.PodMetrics{ - { - Pod: &backendmetrics.Pod{NamespacedName: k8stypes.NamespacedName{Name: "affinity-pod"}}, - Metrics: &backendmetrics.Metrics{ - MaxActiveModels: 2, - ActiveModels: map[string]int{ - testAffinityModel: 1, - }, - }, - }, - { - Pod: &backendmetrics.Pod{NamespacedName: k8stypes.NamespacedName{Name: "available-pod"}}, - Metrics: &backendmetrics.Metrics{ - MaxActiveModels: 2, - ActiveModels: map[string]int{}, - }, - }, - } - ctx := types.NewContext(context.Background(), req, pods) - - // Run the filter function multiple times and count the results - affinityCount := 0 - availableCount := 0 - - // Use the test threshold value - expectedAffinityPercent := config.LoraAffinityThreshold * 100 - expectedAvailabilityPercent := 100 - expectedAffinityPercent - - for i := 0; i < numIterations; i++ { - result, err := loRASoftAffinityFilterFunc(ctx, pods) - if err != nil { - t.Fatalf("Unexpected error: %v", err) - } - - // Check which type of pod was returned - if len(result) != 1 { - t.Fatalf("Expected exactly one pod in result, got %d", len(result)) - } - - // Identify if the returned pod is the affinity pod or available pod - if _, exists := result[0].GetMetrics().ActiveModels[testAffinityModel]; exists { - affinityCount++ - } else { - availableCount++ - } - } - - // Calculate the actual percentages - actualAffinityPercent := float64(affinityCount) / float64(numIterations) * 100 - actualAvailablePercent := float64(availableCount) / float64(numIterations) * 100 - - // Check if the distribution matches expected threshold within tolerance - affinityLowerBound := expectedAffinityPercent - tolerancePercent - affinityUpperBound := expectedAffinityPercent + tolerancePercent - - availableLowerBound := expectedAvailabilityPercent - tolerancePercent - availableUpperBound := expectedAvailabilityPercent + tolerancePercent - - t.Logf("Distribution results over %d iterations:", numIterations) - t.Logf("Expected affinity percent: %.2f%% (threshold: %.2f)", expectedAffinityPercent, config.LoraAffinityThreshold) - t.Logf("Expected availability percent: %.2f%% (threshold: %.2f)", expectedAvailabilityPercent, config.LoraAffinityThreshold) - t.Logf("Actual affinity percent: %.2f%% (%d out of %d)", actualAffinityPercent, affinityCount, numIterations) - t.Logf("Actual available percent: %.2f%% (%d out of %d)", actualAvailablePercent, availableCount, numIterations) - - if actualAffinityPercent < affinityLowerBound || actualAffinityPercent > affinityUpperBound { - t.Errorf("Affinity selection percent %.2f%% outside expected range %.2f%% to %.2f%%", - actualAffinityPercent, affinityLowerBound, affinityUpperBound) - } - if actualAvailablePercent < availableLowerBound || actualAvailablePercent > availableUpperBound { - t.Errorf("Availability selection percent %.2f%% outside expected range %.2f%% to %.2f%%", - actualAvailablePercent, availableLowerBound, availableUpperBound) - } -} diff --git a/pkg/epp/scheduling/scheduler.go b/pkg/epp/scheduling/scheduler.go index 8ec23547..aafe3074 100644 --- a/pkg/epp/scheduling/scheduler.go +++ b/pkg/epp/scheduling/scheduler.go @@ -34,7 +34,6 @@ type Config struct { KVCacheThreshold float64 QueueThresholdCritical int QueueingThresholdLoRA int - LoraAffinityThreshold float64 } const ( @@ -42,7 +41,6 @@ const ( defaultKVCacheThreshold = 0.8 defaultQueueThresholdCritical = 5 defaultQueueingThresholdLoRA = 128 - defaultLoraAffinityThreshold = 0.999 ) // LoadConfig loads configuration from environment variables @@ -54,7 +52,6 @@ func LoadConfig() Config { KVCacheThreshold: envutil.GetEnvFloat("KV_CACHE_THRESHOLD", defaultKVCacheThreshold, baseLogger), QueueThresholdCritical: envutil.GetEnvInt("QUEUE_THRESHOLD_CRITICAL", defaultQueueThresholdCritical, baseLogger), QueueingThresholdLoRA: envutil.GetEnvInt("QUEUING_THRESHOLD_LORA", defaultQueueingThresholdLoRA, baseLogger), - LoraAffinityThreshold: envutil.GetEnvFloat("LORA_AFFINITY_THRESHOLD", defaultLoraAffinityThreshold, baseLogger), } baseLogger.V(logutil.DEFAULT).Info("Scheduler configuration loaded", "config", config) @@ -68,21 +65,15 @@ var ( lowLatencyFilter = &decisionTreeFilter{ current: lowQueueFilter, nextOnSuccess: &decisionTreeFilter{ - current: loRAAffinityFilter, + current: leastQueueFilter, nextOnSuccessOrFailure: &decisionTreeFilter{ - current: leastQueueFilter, - nextOnSuccessOrFailure: &decisionTreeFilter{ - current: leastKVCacheFilter, - }, + current: leastKVCacheFilter, }, }, nextOnFailure: &decisionTreeFilter{ current: leastQueueFilter, nextOnSuccessOrFailure: &decisionTreeFilter{ - current: loRAAffinityFilter, - nextOnSuccessOrFailure: &decisionTreeFilter{ - current: leastKVCacheFilter, - }, + current: leastKVCacheFilter, }, }, } From bfb1d760bef381e39f2b6449d48b4fac6e61be1b Mon Sep 17 00:00:00 2001 From: Maya Barnea Date: Tue, 22 Apr 2025 17:59:54 +0300 Subject: [PATCH 73/73] fix lint problems --- pkg/epp/backend/metrics/metrics.go | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/pkg/epp/backend/metrics/metrics.go b/pkg/epp/backend/metrics/metrics.go index f5e64090..dbfaf102 100644 --- a/pkg/epp/backend/metrics/metrics.go +++ b/pkg/epp/backend/metrics/metrics.go @@ -18,6 +18,7 @@ package metrics import ( "context" + "errors" "fmt" "net/http" "strconv" @@ -108,12 +109,12 @@ func (p *PodMetricsClientImpl) promToPodMetrics( // each metric's value is the reporting timestamp // we start from the most recent metric, if there are waiting loras - we are on the full capacity, no need to find less recent metric values // if number of loras in running loras is less than max_lora value, go to next less recent metric and get running + waiting loras from it - // if number of loras achives max_loras - stop, otherwize continue the process untill we will have enough lora adapters + // if number of loras achives max_loras - stop, otherwize continue the process until we will have enough lora adapters latestLoraMetrics, latestTimestamp, err := p.getNextLatestLoraMetric(metricFamilies, 0.0) errs = multierr.Append(errs, err) - if latestLoraMetrics != nil && len(latestLoraMetrics) > 0 { + if len(latestLoraMetrics) > 0 { // first read max numbers of loras to use it while active loras reading maxLoras, err := p.getMaxLoras(latestLoraMetrics[0]) errs = multierr.Append(errs, err) @@ -203,7 +204,7 @@ func (p *PodMetricsClientImpl) getMaxLoras(metrics *dto.Metric) (int, error) { } } } - return 0, fmt.Errorf("Lora max is not defined") + return 0, errors.New("lora max is not defined") } // getLatestLoraMetric gets latest lora metric series in gauge metric family `vllm:lora_requests_info`