diff --git a/docs/gitbook/how-it-works.md b/docs/gitbook/how-it-works.md index 0a07d68b..03378a7a 100644 --- a/docs/gitbook/how-it-works.md +++ b/docs/gitbook/how-it-works.md @@ -33,6 +33,8 @@ spec: service: # container port port: 9898 + # service port name (optional, will default to "http") + portName: http-podinfo # Istio gateways (optional) gateways: - public-gateway.istio-system.svc.cluster.local @@ -115,6 +117,8 @@ spec: service: # container port port: 9898 + # service port name (optional, will default to "http") + portName: http-frontend # Istio gateways (optional) gateways: - public-gateway.istio-system.svc.cluster.local @@ -484,6 +488,37 @@ The above configuration validates the canary by checking if the HTTP 404 req/sec percentage is below 5 percent of the total traffic. If the 404s rate reaches the 5% threshold, then the canary fails. +```yaml + canaryAnalysis: + threshold: 1 + maxWeight: 50 + stepWeight: 5 + metrics: + - name: "rpc error rate" + threshold: 5 + query: | + 100 - (sum + rate( + grpc_server_handled_total{ + grpc_service="my.TestService", + grpc_code!="OK" + }[1m] + ) + ) + / + sum( + rate( + grpc_server_started_total{ + grpc_service="my.TestService" + }[1m] + ) + ) * 100 +``` + +The above configuration validates the canary by checking if the percentage of +non-OK GRPC req/sec is below 5 percent of the total requests. If the non-OK +rate reaches the 5% threshold, then the canary fails. + When specifying a query, Flagger will run the promql query and convert the result to float64. Then it compares the query result value with the metric threshold value. diff --git a/pkg/apis/flagger/v1alpha3/types.go b/pkg/apis/flagger/v1alpha3/types.go index d0650524..92bc5516 100755 --- a/pkg/apis/flagger/v1alpha3/types.go +++ b/pkg/apis/flagger/v1alpha3/types.go @@ -17,10 +17,11 @@ limitations under the License. package v1alpha3 import ( + "time" + istiov1alpha3 "github.com/weaveworks/flagger/pkg/apis/istio/v1alpha3" hpav1 "k8s.io/api/autoscaling/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" - "time" ) const ( @@ -111,6 +112,7 @@ type CanaryStatus struct { // and Istio Virtual Service type CanaryService struct { Port int32 `json:"port"` + PortName string `json:"portName,omitempty"` Match []istiov1alpha3.HTTPMatchRequest `json:"match,omitempty"` Rewrite *istiov1alpha3.HTTPRewrite `json:"rewrite,omitempty"` Timeout string `json:"timeout,omitempty"` diff --git a/pkg/router/kubernetes.go b/pkg/router/kubernetes.go index f42819d6..f0158513 100644 --- a/pkg/router/kubernetes.go +++ b/pkg/router/kubernetes.go @@ -2,6 +2,7 @@ package router import ( "fmt" + flaggerv1 "github.com/weaveworks/flagger/pkg/apis/flagger/v1alpha3" clientset "github.com/weaveworks/flagger/pkg/client/clientset/versioned" "go.uber.org/zap" @@ -24,6 +25,11 @@ type KubernetesRouter struct { func (c *KubernetesRouter) Sync(cd *flaggerv1.Canary) error { targetName := cd.Spec.TargetRef.Name primaryName := fmt.Sprintf("%s-primary", targetName) + portName := cd.Spec.Service.PortName + if portName == "" { + portName = "http" + } + canaryService, err := c.kubeClient.CoreV1().Services(cd.Namespace).Get(targetName, metav1.GetOptions{}) if errors.IsNotFound(err) { canaryService = &corev1.Service{ @@ -43,7 +49,7 @@ func (c *KubernetesRouter) Sync(cd *flaggerv1.Canary) error { Selector: map[string]string{"app": primaryName}, Ports: []corev1.ServicePort{ { - Name: "http", + Name: portName, Protocol: corev1.ProtocolTCP, Port: cd.Spec.Service.Port, TargetPort: intstr.IntOrString{ @@ -82,7 +88,7 @@ func (c *KubernetesRouter) Sync(cd *flaggerv1.Canary) error { Selector: map[string]string{"app": targetName}, Ports: []corev1.ServicePort{ { - Name: "http", + Name: portName, Protocol: corev1.ProtocolTCP, Port: cd.Spec.Service.Port, TargetPort: intstr.IntOrString{ @@ -120,7 +126,7 @@ func (c *KubernetesRouter) Sync(cd *flaggerv1.Canary) error { Selector: map[string]string{"app": primaryName}, Ports: []corev1.ServicePort{ { - Name: "http", + Name: portName, Protocol: corev1.ProtocolTCP, Port: cd.Spec.Service.Port, TargetPort: intstr.IntOrString{