Repository: kumahq/kuma
Pull request #1576 (2021-02-18 10:54:21)

fix(kuma-dp) remove the datplane of any completed Pod
### Summary

Since now we do support Jobs, we need to also make sure there are no offline dataplane proxies, as a result of completed jobs but still existing pods.
Delete the relevant resource and make sure it does not appear again while the containers in the pod are terminated.

### Documentation

- [ ] Not needed



Patch:
diff --git a/api/go.sum b/api/go.sum
index 33ce00af9..0314f935e 100644
--- a/api/go.sum
+++ b/api/go.sum
@@ -148,6 +148,7 @@ google.golang.org/protobuf v1.23.0/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2
 google.golang.org/protobuf v1.23.1-0.20200526195155-81db48ad09cc/go.mod h1:EGpADcykh3NcUnDUJcl1+ZksZNG86OlYog2l/sGQquU=
 google.golang.org/protobuf v1.25.0 h1:Ejskq+SyPohKW+1uil0JJMtmHCgJPJ/qWTxr8qp+R4c=
 google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlbajtzgsN7c=
+gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
 gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ=
diff --git a/api/mesh/v1alpha1/dataplane_helpers.go b/api/mesh/v1alpha1/dataplane_helpers.go
index d03a8db90..eb7ad25ff 100644
--- a/api/mesh/v1alpha1/dataplane_helpers.go
+++ b/api/mesh/v1alpha1/dataplane_helpers.go
@@ -139,6 +139,16 @@ func (n *Dataplane_Networking) ToInboundInterface(inbound *Dataplane_Networking_
 	return iface
 }
 
+func (n *Dataplane_Networking) GetHealthyInbounds() (inbounds []*Dataplane_Networking_Inbound) {
+	for _, inbound := range n.GetInbound() {
+		if inbound.Health != nil && !inbound.Health.Ready {
+			continue
+		}
+		inbounds = append(inbounds, inbound)
+	}
+	return
+}
+
 // Matches is simply an alias for MatchTags to make source code more aesthetic.
 func (d *Dataplane) Matches(selector TagSelector) bool {
 	if d != nil {
diff --git a/api/mesh/v1alpha1/health_check.pb.go b/api/mesh/v1alpha1/health_check.pb.go
index a516ef9ae..32f10cdb0 100644
--- a/api/mesh/v1alpha1/health_check.pb.go
+++ b/api/mesh/v1alpha1/health_check.pb.go
@@ -111,6 +111,14 @@ type HealthCheck_Conf struct {
 	UnhealthyThreshold uint32 `protobuf:"varint,3,opt,name=unhealthy_threshold,json=unhealthyThreshold,proto3" json:"unhealthy_threshold,omitempty"`
 	// Number of consecutive healthy checks before considering a host healthy.
 	HealthyThreshold uint32 `protobuf:"varint,4,opt,name=healthy_threshold,json=healthyThreshold,proto3" json:"healthy_threshold,omitempty"`
+	// If specified, Envoy will start health checking after for a random time in ms between 0 and initial_jitter.
+	// This only applies to the first health check.
+	InitialJitter *duration.Duration `protobuf:"bytes,7,opt,name=initial_jitter,json=initialJitter,proto3" json:"initial_jitter,omitempty"`
+	// If specified, during every interval Envoy will add interval_jitter to the wait time.
+	IntervalJitter *duration.Duration `protobuf:"bytes,8,opt,name=interval_jitter,json=intervalJitter,proto3" json:"interval_jitter,omitempty"`
+	// If specified, during every interval Envoy will add interval_ms * interval_jitter_percent / 100 to the wait time.
+	// If interval_jitter_ms and interval_jitter_percent are both set, both of them will be used to increase the wait time.
+	IntervalJitterPercent uint32 `protobuf:"varint,9,opt,name=interval_jitter_percent,json=intervalJitterPercent,proto3" json:"interval_jitter_percent,omitempty"`
 	// Types that are assignable to Protocol:
 	//	*HealthCheck_Conf_Tcp_
 	//	*HealthCheck_Conf_Http_
@@ -177,6 +185,27 @@ func (x *HealthCheck_Conf) GetHealthyThreshold() uint32 {
 	return 0
 }
 
+func (x *HealthCheck_Conf) GetInitialJitter() *duration.Duration {
+	if x != nil {
+		return x.InitialJitter
+	}
+	return nil
+}
+
+func (x *HealthCheck_Conf) GetIntervalJitter() *duration.Duration {
+	if x != nil {
+		return x.IntervalJitter
+	}
+	return nil
+}
+
+func (x *HealthCheck_Conf) GetIntervalJitterPercent() uint32 {
+	if x != nil {
+		return x.IntervalJitterPercent
+	}
+	return 0
+}
+
 func (m *HealthCheck_Conf) GetProtocol() isHealthCheck_Conf_Protocol {
 	if m != nil {
 		return m.Protocol
@@ -482,7 +511,7 @@ var file_mesh_v1alpha1_health_check_proto_rawDesc = []byte{
 	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f,
 	0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70,
 	0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x17, 0x76, 0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2f, 0x76,
-	0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0x82, 0x09,
+	0x61, 0x6c, 0x69, 0x64, 0x61, 0x74, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x22, 0xc0, 0x0a,
 	0x0a, 0x0b, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x12, 0x40, 0x0a,
 	0x07, 0x73, 0x6f, 0x75, 0x72, 0x63, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c,
 	0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
@@ -496,7 +525,7 @@ var file_mesh_v1alpha1_health_check_proto_rawDesc = []byte{
 	0x6f, 0x6e, 0x66, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x24, 0x2e, 0x6b, 0x75, 0x6d, 0x61,
 	0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48,
 	0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x52,
-	0x04, 0x63, 0x6f, 0x6e, 0x66, 0x1a, 0xaa, 0x07, 0x0a, 0x04, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x41,
+	0x04, 0x63, 0x6f, 0x6e, 0x66, 0x1a, 0xe8, 0x08, 0x0a, 0x04, 0x43, 0x6f, 0x6e, 0x66, 0x12, 0x41,
 	0x0a, 0x08, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b,
 	0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
 	0x75, 0x66, 0x2e, 0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x42, 0x0a, 0xfa, 0x42, 0x07,
@@ -512,53 +541,65 @@ var file_mesh_v1alpha1_health_check_proto_rawDesc = []byte{
 	0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x5f, 0x74, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f, 0x6c,
 	0x64, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0d, 0x42, 0x07, 0xfa, 0x42, 0x04, 0x2a, 0x02, 0x20, 0x00,
 	0x52, 0x10, 0x68, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x79, 0x54, 0x68, 0x72, 0x65, 0x73, 0x68, 0x6f,
-	0x6c, 0x64, 0x12, 0x3c, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32,
-	0x28, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c,
-	0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b,
-	0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70,
-	0x12, 0x3f, 0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29,
-	0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70,
-	0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e,
-	0x43, 0x6f, 0x6e, 0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74,
-	0x70, 0x1a, 0x6d, 0x0a, 0x03, 0x54, 0x63, 0x70, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x64,
-	0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61,
-	0x6c, 0x75, 0x65, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x64, 0x12, 0x35, 0x0a, 0x07, 0x72, 0x65, 0x63,
-	0x65, 0x69, 0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74,
-	0x65, 0x73, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65,
-	0x1a, 0xb3, 0x03, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74,
-	0x68, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x70, 0x0a,
-	0x16, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73,
-	0x5f, 0x74, 0x6f, 0x5f, 0x61, 0x64, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e,
+	0x6c, 0x64, 0x12, 0x40, 0x0a, 0x0e, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x5f, 0x6a, 0x69,
+	0x74, 0x74, 0x65, 0x72, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x67, 0x6f, 0x6f,
+	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x44, 0x75, 0x72,
+	0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0d, 0x69, 0x6e, 0x69, 0x74, 0x69, 0x61, 0x6c, 0x4a, 0x69,
+	0x74, 0x74, 0x65, 0x72, 0x12, 0x42, 0x0a, 0x0f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76, 0x61, 0x6c,
+	0x5f, 0x6a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e,
+	0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e,
+	0x44, 0x75, 0x72, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x76,
+	0x61, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x12, 0x36, 0x0a, 0x17, 0x69, 0x6e, 0x74, 0x65,
+	0x72, 0x76, 0x61, 0x6c, 0x5f, 0x6a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x5f, 0x70, 0x65, 0x72, 0x63,
+	0x65, 0x6e, 0x74, 0x18, 0x09, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x15, 0x69, 0x6e, 0x74, 0x65, 0x72,
+	0x76, 0x61, 0x6c, 0x4a, 0x69, 0x74, 0x74, 0x65, 0x72, 0x50, 0x65, 0x72, 0x63, 0x65, 0x6e, 0x74,
+	0x12, 0x3c, 0x0a, 0x03, 0x74, 0x63, 0x70, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x28, 0x2e,
 	0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68,
 	0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43,
-	0x6f, 0x6e, 0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56,
-	0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75,
-	0x65, 0x73, 0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x12,
-	0x55, 0x0a, 0x11, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74,
-	0x75, 0x73, 0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f,
-	0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e,
-	0x74, 0x33, 0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x10,
-	0xd8, 0x04, 0x28, 0x64, 0x52, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x74,
-	0x61, 0x74, 0x75, 0x73, 0x65, 0x73, 0x1a, 0x35, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72,
-	0x56, 0x61, 0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01,
-	0x28, 0x09, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65,
-	0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x96, 0x01,
-	0x0a, 0x11, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74,
-	0x69, 0x6f, 0x6e, 0x12, 0x4d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20,
-	0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e,
-	0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43,
-	0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x2e, 0x48,
-	0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64,
-	0x65, 0x72, 0x12, 0x32, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01,
-	0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74,
-	0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06,
-	0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63,
-	0x6f, 0x6c, 0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d,
-	0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x2f, 0x61, 0x70, 0x69,
-	0x2f, 0x6d, 0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06,
-	0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33,
+	0x6f, 0x6e, 0x66, 0x2e, 0x54, 0x63, 0x70, 0x48, 0x00, 0x52, 0x03, 0x74, 0x63, 0x70, 0x12, 0x3f,
+	0x0a, 0x04, 0x68, 0x74, 0x74, 0x70, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x29, 0x2e, 0x6b,
+	0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61,
+	0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43, 0x6f,
+	0x6e, 0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x48, 0x00, 0x52, 0x04, 0x68, 0x74, 0x74, 0x70, 0x1a,
+	0x6d, 0x0a, 0x03, 0x54, 0x63, 0x70, 0x12, 0x2f, 0x0a, 0x04, 0x73, 0x65, 0x6e, 0x64, 0x18, 0x01,
+	0x20, 0x01, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x56, 0x61, 0x6c, 0x75,
+	0x65, 0x52, 0x04, 0x73, 0x65, 0x6e, 0x64, 0x12, 0x35, 0x0a, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69,
+	0x76, 0x65, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1b, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x42, 0x79, 0x74, 0x65, 0x73,
+	0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x07, 0x72, 0x65, 0x63, 0x65, 0x69, 0x76, 0x65, 0x1a, 0xb3,
+	0x03, 0x0a, 0x04, 0x48, 0x74, 0x74, 0x70, 0x12, 0x12, 0x0a, 0x04, 0x70, 0x61, 0x74, 0x68, 0x18,
+	0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x04, 0x70, 0x61, 0x74, 0x68, 0x12, 0x70, 0x0a, 0x16, 0x72,
+	0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x5f, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x5f, 0x74,
+	0x6f, 0x5f, 0x61, 0x64, 0x64, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3b, 0x2e, 0x6b, 0x75,
+	0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31,
+	0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65, 0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6e,
+	0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x2e, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c,
+	0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f, 0x6e, 0x52, 0x13, 0x72, 0x65, 0x71, 0x75, 0x65, 0x73,
+	0x74, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x73, 0x54, 0x6f, 0x41, 0x64, 0x64, 0x12, 0x55, 0x0a,
+	0x11, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x5f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73,
+	0x65, 0x73, 0x18, 0x03, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c,
+	0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x55, 0x49, 0x6e, 0x74, 0x33,
+	0x32, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x42, 0x0a, 0xfa, 0x42, 0x07, 0x2a, 0x05, 0x10, 0xd8, 0x04,
+	0x28, 0x64, 0x52, 0x10, 0x65, 0x78, 0x70, 0x65, 0x63, 0x74, 0x65, 0x64, 0x53, 0x74, 0x61, 0x74,
+	0x75, 0x73, 0x65, 0x73, 0x1a, 0x35, 0x0a, 0x0b, 0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61,
+	0x6c, 0x75, 0x65, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09,
+	0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, 0x14, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02,
+	0x20, 0x01, 0x28, 0x09, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x1a, 0x96, 0x01, 0x0a, 0x11,
+	0x48, 0x65, 0x61, 0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x4f, 0x70, 0x74, 0x69, 0x6f,
+	0x6e, 0x12, 0x4d, 0x0a, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28,
+	0x0b, 0x32, 0x35, 0x2e, 0x6b, 0x75, 0x6d, 0x61, 0x2e, 0x6d, 0x65, 0x73, 0x68, 0x2e, 0x76, 0x31,
+	0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x2e, 0x48, 0x65, 0x61, 0x6c, 0x74, 0x68, 0x43, 0x68, 0x65,
+	0x63, 0x6b, 0x2e, 0x43, 0x6f, 0x6e, 0x66, 0x2e, 0x48, 0x74, 0x74, 0x70, 0x2e, 0x48, 0x65, 0x61,
+	0x64, 0x65, 0x72, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x68, 0x65, 0x61, 0x64, 0x65, 0x72,
+	0x12, 0x32, 0x0a, 0x06, 0x61, 0x70, 0x70, 0x65, 0x6e, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b,
+	0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62,
+	0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x61, 0x70,
+	0x70, 0x65, 0x6e, 0x64, 0x42, 0x0a, 0x0a, 0x08, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c,
+	0x42, 0x2a, 0x5a, 0x28, 0x67, 0x69, 0x74, 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x6b,
+	0x75, 0x6d, 0x61, 0x68, 0x71, 0x2f, 0x6b, 0x75, 0x6d, 0x61, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x6d,
+	0x65, 0x73, 0x68, 0x2f, 0x76, 0x31, 0x61, 0x6c, 0x70, 0x68, 0x61, 0x31, 0x62, 0x06, 0x70, 0x72,
+	0x6f, 0x74, 0x6f, 0x33,
 }
 
 var (
@@ -593,19 +634,21 @@ var file_mesh_v1alpha1_health_check_proto_depIdxs = []int32{
 	1,  // 2: kuma.mesh.v1alpha1.HealthCheck.conf:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf
 	7,  // 3: kuma.mesh.v1alpha1.HealthCheck.Conf.interval:type_name -> google.protobuf.Duration
 	7,  // 4: kuma.mesh.v1alpha1.HealthCheck.Conf.timeout:type_name -> google.protobuf.Duration
-	2,  // 5: kuma.mesh.v1alpha1.HealthCheck.Conf.tcp:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp
-	3,  // 6: kuma.mesh.v1alpha1.HealthCheck.Conf.http:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http
-	8,  // 7: kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp.send:type_name -> google.protobuf.BytesValue
-	8,  // 8: kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp.receive:type_name -> google.protobuf.BytesValue
-	5,  // 9: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.request_headers_to_add:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption
-	9,  // 10: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.expected_statuses:type_name -> google.protobuf.UInt32Value
-	4,  // 11: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption.header:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValue
-	10, // 12: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption.append:type_name -> google.protobuf.BoolValue
-	13, // [13:13] is the sub-list for method output_type
-	13, // [13:13] is the sub-list for method input_type
-	13, // [13:13] is the sub-list for extension type_name
-	13, // [13:13] is the sub-list for extension extendee
-	0,  // [0:13] is the sub-list for field type_name
+	7,  // 5: kuma.mesh.v1alpha1.HealthCheck.Conf.initial_jitter:type_name -> google.protobuf.Duration
+	7,  // 6: kuma.mesh.v1alpha1.HealthCheck.Conf.interval_jitter:type_name -> google.protobuf.Duration
+	2,  // 7: kuma.mesh.v1alpha1.HealthCheck.Conf.tcp:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp
+	3,  // 8: kuma.mesh.v1alpha1.HealthCheck.Conf.http:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http
+	8,  // 9: kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp.send:type_name -> google.protobuf.BytesValue
+	8,  // 10: kuma.mesh.v1alpha1.HealthCheck.Conf.Tcp.receive:type_name -> google.protobuf.BytesValue
+	5,  // 11: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.request_headers_to_add:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption
+	9,  // 12: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.expected_statuses:type_name -> google.protobuf.UInt32Value
+	4,  // 13: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption.header:type_name -> kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValue
+	10, // 14: kuma.mesh.v1alpha1.HealthCheck.Conf.Http.HeaderValueOption.append:type_name -> google.protobuf.BoolValue
+	15, // [15:15] is the sub-list for method output_type
+	15, // [15:15] is the sub-list for method input_type
+	15, // [15:15] is the sub-list for extension type_name
+	15, // [15:15] is the sub-list for extension extendee
+	0,  // [0:15] is the sub-list for field type_name
 }
 
 func init() { file_mesh_v1alpha1_health_check_proto_init() }
diff --git a/api/mesh/v1alpha1/health_check.proto b/api/mesh/v1alpha1/health_check.proto
index 056e7d1a0..a5a52ff68 100644
--- a/api/mesh/v1alpha1/health_check.proto
+++ b/api/mesh/v1alpha1/health_check.proto
@@ -41,6 +41,21 @@ message HealthCheck {
     // Number of consecutive healthy checks before considering a host healthy.
     uint32 healthy_threshold = 4 [ (validate.rules).uint32 = {gt : 0} ];
 
+    // If specified, Envoy will start health checking after for a random time in
+    // ms between 0 and initial_jitter. This only applies to the first health
+    // check.
+    google.protobuf.Duration initial_jitter = 7;
+
+    // If specified, during every interval Envoy will add interval_jitter to the
+    // wait time.
+    google.protobuf.Duration interval_jitter = 8;
+
+    // If specified, during every interval Envoy will add interval_ms *
+    // interval_jitter_percent / 100 to the wait time. If interval_jitter_ms and
+    // interval_jitter_percent are both set, both of them will be used to
+    // increase the wait time.
+    uint32 interval_jitter_percent = 9;
+
     // Tcp defines optional configuration for specifying bytes to send and
     // expected response during the health check
     message Tcp {
diff --git a/app/kuma-dp/pkg/dataplane/accesslogs/server.go b/app/kuma-dp/pkg/dataplane/accesslogs/server.go
index 4ce9c613c..26ef0e735 100644
--- a/app/kuma-dp/pkg/dataplane/accesslogs/server.go
+++ b/app/kuma-dp/pkg/dataplane/accesslogs/server.go
@@ -3,6 +3,9 @@ package accesslogs
 import (
 	"fmt"
 	"net"
+	"os"
+
+	"github.com/pkg/errors"
 
 	v2 "github.com/kumahq/kuma/app/kuma-dp/pkg/dataplane/accesslogs/v2"
 	v3 "github.com/kumahq/kuma/app/kuma-dp/pkg/dataplane/accesslogs/v3"
@@ -40,10 +43,29 @@ func (s *accessLogServer) Start(stop <-chan struct{}) error {
 	v2.RegisterAccessLogServer(s.server)
 	v3.RegisterAccessLogServer(s.server)
 
+	_, err := os.Stat(s.address)
+	if err == nil {
+		// File is accessible try to rename it to verify it is not open
+		newName := s.address + ".bak"
+		err := os.Rename(s.address, newName)
+		if err != nil {
+			return errors.Errorf("file %s exists and probably opened by another kuam-dp instance", s.address)
+		}
+		err = os.Remove(newName)
+		if err != nil {
+			return errors.Errorf("not able the delete the backup file %s", newName)
+		}
+	}
+
 	lis, err := net.Listen("unix", s.address)
 	if err != nil {
 		return err
 	}
+
+	defer func() {
+		lis.Close()
+	}()
+
 	logger.Info("starting Access Log Server", "address", fmt.Sprintf("unix://%s", s.address))
 	errCh := make(chan error, 1)
 	go func() {
diff --git a/go.sum b/go.sum
index a561a1ed1..fcaa24e59 100644
--- a/go.sum
+++ b/go.sum
@@ -50,6 +50,7 @@ github.com/Azure/azure-sdk-for-go v35.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9mo
 github.com/Azure/azure-sdk-for-go v38.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v44.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
 github.com/Azure/azure-sdk-for-go v46.0.0+incompatible/go.mod h1:9XXNKU+eRnpl9moKnB4QOLf1HestfXbmab5FXxiDBjc=
+github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78 h1:w+iIsaOQNcT7OZ575w+acHgRric5iCyQh+xv+KJ4HB8=
 github.com/Azure/go-ansiterm v0.0.0-20170929234023-d6e3b3328b78/go.mod h1:LmzpDX56iTiv29bbRTIsUNlaFfuhWRQBWjQdVyAevI8=
 github.com/Azure/go-autorest v10.8.1+incompatible/go.mod h1:r+4oMnoxhatjLLJ6zxSWATqVooLgysK6ZNox3g/xq24=
 github.com/Azure/go-autorest v14.2.0+incompatible h1:V5VMDjClD3GiElqLWO7mz2MxNAK/vTfRHdAubSIPRgs=
@@ -107,8 +108,10 @@ github.com/InVisionApp/go-health v2.1.0+incompatible/go.mod h1:/+Gv1o8JUsrjC6pi6
 github.com/InVisionApp/go-logger v1.0.1/go.mod h1:+cGTDSn+P8105aZkeOfIhdd7vFO5X1afUHcjvanY0L8=
 github.com/Knetic/govaluate v3.0.1-0.20171022003610-9aa49832a739+incompatible/go.mod h1:r7JcOSlj0wfOMncg0iLm8Leh48TZaKVeNIfJntJ2wa0=
 github.com/MakeNowJust/heredoc v0.0.0-20170808103936-bb23615498cd/go.mod h1:64YHyfSL2R96J44Nlwm39UHepQbyR5q10x7iYa1ks2E=
+github.com/Masterminds/goutils v1.1.0 h1:zukEsf/1JZwCMgHiK3GZftabmxiCw4apj3a28RPBiVg=
 github.com/Masterminds/goutils v1.1.0/go.mod h1:8cTjp+g8YejhMuvIA5y2vz3BpJxksy863GQaJW2MFNU=
 github.com/Masterminds/semver v1.4.2/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
+github.com/Masterminds/semver v1.5.0 h1:H65muMkzWKEuNDnfl9d70GUjFniHKHRbFPGBuZ3QEww=
 github.com/Masterminds/semver v1.5.0/go.mod h1:MB6lktGJrhw8PrUyiEoblNEGEQ+RzHPF078ddwwvV3Y=
 github.com/Masterminds/semver/v3 v3.1.0 h1:Y2lUDsFKVRSYGojLJ1yLxSXdMmMYTYls0rCvoqmMUQk=
 github.com/Masterminds/semver/v3 v3.1.0/go.mod h1:VPu/7SZ7ePZ3QOrcuXROw5FAcLl4a0cBrbBpGY/8hQs=
@@ -149,6 +152,7 @@ github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRF
 github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho=
 github.com/alicebob/gopher-json v0.0.0-20180125190556-5a6b3ba71ee6/go.mod h1:SGnFV6hVsYE877CKEZ6tDNTjaSXYUk6QqoIK6PrAtcc=
 github.com/alicebob/miniredis v2.5.0+incompatible/go.mod h1:8HZjEj4yU0dwhYHky+DxYx+6BMjkBbe5ONFIF1MXffk=
+github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129 h1:MzBOUgng9orim59UnfUTLRjMpd09C5uEVQ6RPGeCaVI=
 github.com/andres-erbsen/clock v0.0.0-20160526145045-9e14626cd129/go.mod h1:rFgpPQZYZ8vdbc+48xibu8ALc3yeyd64IhHS+PU6Yyg=
 github.com/andreyvit/diff v0.0.0-20170406064948-c7f18ee00883/go.mod h1:rCTlJbsFo29Kk6CurOXKm700vrz8f0KW0JNfpkRJY/8=
 github.com/antlr/antlr4 v0.0.0-20190819145818-b43a4c3a8015/go.mod h1:T7PbCXFs94rrTttyxjbyT5+/1V8T2TYDejxUfHJjw1Y=
@@ -293,6 +297,7 @@ github.com/docker/cli v0.0.0-20191017083524-a8ff7f821017/go.mod h1:JLrzqnKDaYBop
 github.com/docker/cli v0.0.0-20200109221225-a4f60165b7a3/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/cli v0.0.0-20200130152716-5d0cf8839492/go.mod h1:JLrzqnKDaYBop7H2jaqPtU4hHvMKP+vjCwu2uszcLI8=
 github.com/docker/distribution v0.0.0-20191216044856-a8371794149d/go.mod h1:0+TTO4EOBfRPhZXAeF1Vu+W3hHZ8eLp8PgKVZlcvtFY=
+github.com/docker/distribution v2.7.1+incompatible h1:a5mlkVzth6W5A4fOsS3D2EO5BUmsJpcB+cRlLU7cSug=
 github.com/docker/distribution v2.7.1+incompatible/go.mod h1:J2gT2udsDAN96Uj4KfcMRqY0/ypR+oyYUYmja8H+y+w=
 github.com/docker/docker v0.7.3-0.20190327010347-be7ac8be2ae0/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker v1.4.2-0.20190924003213-a8608b5b67c7/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
@@ -302,9 +307,11 @@ github.com/docker/docker v1.13.1/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsv
 github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible h1:iWPIG7pWIsCwT6ZtHnTUpoVMnete7O/pzd9HFE3+tn8=
 github.com/docker/docker v17.12.0-ce-rc1.0.20200618181300-9dc6525e6118+incompatible/go.mod h1:eEKB0N0r5NX/I1kEveEz05bcu8tLC/8azJZsviup8Sk=
 github.com/docker/docker-credential-helpers v0.6.3/go.mod h1:WRaJzqw3CTB9bk10avuGsjVBZsD05qeibJ1/TYlvc0Y=
+github.com/docker/go-connections v0.4.0 h1:El9xVISelRB7BuFusrZozjnkIM5YnzCViNKohAFqRJQ=
 github.com/docker/go-connections v0.4.0/go.mod h1:Gbd7IOopHjR8Iph03tsViu4nIes5XhDvyHbTtUxmeec=
 github.com/docker/go-metrics v0.0.0-20180209012529-399ea8c73916/go.mod h1:/u0gXw0Gay3ceNrsHubL3BtdOL2fHf93USgMTe0W5dI=
 github.com/docker/go-units v0.3.3/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
+github.com/docker/go-units v0.4.0 h1:3uh0PgVws3nIA0Q+MwDC8yjEPf9zjRfZZWXZYDct3Tw=
 github.com/docker/go-units v0.4.0/go.mod h1:fgPhTUdO+D/Jk86RDLlptpiXQzgHJF7gydDDbaIK4Dk=
 github.com/docker/libtrust v0.0.0-20150114040149-fa567046d9b1/go.mod h1:cyGadeNEkKy96OOhEzfZl+yxihPEzKnqJwvfuSUqbZE=
 github.com/docker/spdystream v0.0.0-20160310174837-449fdfce4d96/go.mod h1:Qh8CwZgvJUkLughtfhJv5dyTYa91l1fOUCrgjqmcifM=
@@ -452,6 +459,7 @@ github.com/go-sql-driver/mysql v1.4.0/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG
 github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w=
 github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
 github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
+github.com/go-stack/stack v1.8.0 h1:5SgMzNM5HxrEjV0ww2lTmX6E2Izsfxas4+YHWRs3Lsk=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
 github.com/go-test/deep v1.0.2-0.20181118220953-042da051cf31/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA=
 github.com/gobuffalo/envy v1.7.0/go.mod h1:n7DRkBerg/aorDM8kbduw5dN3oXGswK5liaSCx4T5NI=
@@ -481,6 +489,7 @@ github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69
 github.com/golang-migrate/migrate/v4 v4.14.1 h1:qmRd/rNGjM1r3Ve5gHd5ZplytrD02UcItYNxJ3iUHHE=
 github.com/golang-migrate/migrate/v4 v4.14.1/go.mod h1:l7Ks0Au6fYHuUIxUhQ0rcVX1uLlJg54C/VvW7tvxSz0=
 github.com/golang-sql/civil v0.0.0-20190719163853-cb61b32ac6fe/go.mod h1:8vg3r2VgvsThLBIFL93Qb5yWzgyZWhEmBwUJWevAkK0=
+github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekfRL6a582T4P37/31XEstQ5p58=
 github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
 github.com/golang/groupcache v0.0.0-20160516000752-02826c3e7903/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
 github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
@@ -650,6 +659,7 @@ github.com/hashicorp/vault/sdk v0.1.13/go.mod h1:B+hVj7TpuQY1Y/GPbCpffmgd+tSEwvh
 github.com/hashicorp/yamux v0.0.0-20180604194846-3520598351bb/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
 github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d h1:kJCB4vdITiW1eC1vq2e6IsrXKrZit1bv/TDYFGMp4BQ=
 github.com/hashicorp/yamux v0.0.0-20181012175058-2f1d1f20f75d/go.mod h1:+NfK9FKeTrX5uv1uIXGdwYDTeHna2qgaIlx54MXqjAM=
+github.com/hoisie/mustache v0.0.0-20160804235033-6375acf62c69 h1:umaj0TCQ9lWUUKy2DxAhEzPbwd0jnxiw1EI2z3FiILM=
 github.com/hoisie/mustache v0.0.0-20160804235033-6375acf62c69/go.mod h1:zdLK9ilQRSMjSeLKoZ4BqUfBT7jswTGF8zRlKEsiRXA=
 github.com/howeyc/fsnotify v0.9.0/go.mod h1:41HzSPxBGeFRQKEEwgh49TRw/nKBsYZ2cF1OzPjSJsA=
 github.com/hpcloud/tail v1.0.0/go.mod h1:ab1qPbhIpdTxEkNHXyeSf5vhxWSCs/tWer42PpOxQnU=
@@ -665,6 +675,7 @@ github.com/imdario/mergo v0.3.8/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJ
 github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
 github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imkira/go-observer v1.0.3/go.mod h1:zLzElv2cGTHufQG17IEILJMPDg32TD85fFgKyFv00wU=
+github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/influxdata/influxdb1-client v0.0.0-20191209144304-8bf82d3c094d/go.mod h1:qj24IKcXYK6Iy9ceXlo3Tc+vtHo9lIhSX5JddghvEPo=
 github.com/jackc/chunkreader v1.0.0/go.mod h1:RT6O25fNZIuasFJRyZ4R/Y2BbhasbmZXF9QQ7T3kePo=
@@ -737,10 +748,12 @@ github.com/konsorten/go-windows-terminal-sequences v1.0.2/go.mod h1:T0+1ngSBFLxv
 github.com/konsorten/go-windows-terminal-sequences v1.0.3/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
 github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/ktrysmt/go-bitbucket v0.6.4/go.mod h1:9u0v3hsd2rqCHRIpbir1oP7F58uo5dq19sBYvuMoyQ4=
 github.com/kylelemons/godebug v1.1.0/go.mod h1:9/0rRGxNHcop5bhtWyNeEfOS8JIWk580+fNqagV/RAw=
@@ -837,6 +850,7 @@ github.com/modern-go/reflect2 v0.0.0-20180320133207-05fbef0ca5da/go.mod h1:bx2lN
 github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
 github.com/modern-go/reflect2 v1.0.1 h1:9f412s+6RmYXLWZSEzVVgPGK7C2PphHj5RJrvfx9AWI=
 github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0=
+github.com/morikuni/aec v1.0.0 h1:nP9CBfwrvYnBRgY6qfDQkygYDmYwOilePFkwzv4dU8A=
 github.com/morikuni/aec v1.0.0/go.mod h1:BbKIizmSmc5MMPqRYbxO4ZU0S0+P200+tUnFx7PXmsc=
 github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
 github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ=
@@ -897,6 +911,7 @@ github.com/opencontainers/go-digest v1.0.0-rc1/go.mod h1:cMLVZDEM3+U2I4VmLI6N8jQ
 github.com/opencontainers/go-digest v1.0.0 h1:apOUWs51W5PlhuyGyz9FCeeBIOUDA/6nW8Oi/yOhh5U=
 github.com/opencontainers/go-digest v1.0.0/go.mod h1:0JzlMkj0TRzQZfJkVvzbP0HBR3IKzErnv2BNG4W4MAM=
 github.com/opencontainers/image-spec v1.0.0/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
+github.com/opencontainers/image-spec v1.0.1 h1:JMemWkRwHx4Zj+fVxWoMCFm/8sYGGrUVojFA6h/TRcI=
 github.com/opencontainers/image-spec v1.0.1/go.mod h1:BtxoFyWECRxE4U/7sNtV5W15zMzWCbyJoFRP3s7yZA0=
 github.com/opencontainers/runc v0.0.0-20190115041553-12f6a991201f/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
 github.com/opencontainers/runc v0.1.1/go.mod h1:qT5XzbpPznkRYVz/mWwUaVBUv2rmF59PVA73FjuZG0U=
@@ -916,6 +931,7 @@ github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnh
 github.com/oracle/oci-go-sdk v7.1.0+incompatible/go.mod h1:VQb79nF8Z2cwLkLS35ukwStZIg5F66tcBccjip/j888=
 github.com/pact-foundation/pact-go v1.0.4/go.mod h1:uExwJY4kCzNPcHRj+hCR/HBbOOIwwtUjcrb0b5/5kLM=
 github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
+github.com/pascaldekloe/goe v0.1.0 h1:cBOtyMzM9HTpWjXfbbunk26uA6nG3a8n06Wieeh0MwY=
 github.com/pascaldekloe/goe v0.1.0/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc=
 github.com/patrickmn/go-cache v2.1.0+incompatible h1:HRMgzkcYKYpi3C8ajMPV8OFXaaRUnok+kx1WdO15EQc=
 github.com/patrickmn/go-cache v2.1.0+incompatible/go.mod h1:3Qf8kWWT7OJRJbdiICTKqZju1ZixQ/KpMGzzAfe6+WQ=
@@ -940,6 +956,7 @@ github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pkg/profile v1.2.1/go.mod h1:hJw3o1OdXxsrSjjVksARp5W95eeEaEfptyVZyv6JUPA=
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
 github.com/pmezard/go-difflib v0.0.0-20151028094244-d8ed2627bdf0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI=
 github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
@@ -1089,6 +1106,7 @@ github.com/streadway/amqp v0.0.0-20190827072141-edfb9018d271/go.mod h1:AZpEONHx3
 github.com/streadway/handy v0.0.0-20190108123426-d5acb3125c2a/go.mod h1:qNTQ5P5JnDBl6z3cMAg/SywNDC5ABu5ApDIw6lUbRmI=
 github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
 github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME=
+github.com/stretchr/objx v0.2.0 h1:Hbg2NidpLE8veEBkEZTL3CvlkUIVzuU9jDplZO54c48=
 github.com/stretchr/objx v0.2.0/go.mod h1:qt09Ya8vawLte6SNmTgCsAVtYtaKzEcn8ATUoHMkEqE=
 github.com/stretchr/testify v0.0.0-20151208002404-e3a8ff8ce365/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
 github.com/stretchr/testify v1.2.0/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs=
@@ -1531,6 +1549,7 @@ google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7
 google.golang.org/appengine v1.6.1/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.2/go.mod h1:i06prIuMbXzDqacNJfV5OdTW448YApPu5ww/cMBSeb0=
 google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
+google.golang.org/appengine v1.6.6 h1:lMO5rYAqUxkmaj76jAkRUvt5JZgFymx/+Q5Mzfivuhc=
 google.golang.org/appengine v1.6.6/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=
 google.golang.org/cloud v0.0.0-20151119220103-975617b05ea8/go.mod h1:0H1ncTHf11KCFhTc/+EFRbzSCOZx+VUbRMk55Yv5MYk=
 google.golang.org/genproto v0.0.0-20170818010345-ee236bd376b0/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
@@ -1621,6 +1640,7 @@ gopkg.in/asn1-ber.v1 v1.0.0-20181015200546-f715ec2f112d/go.mod h1:cuepJuh7vyXfUy
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20141024133853-64131543e789/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/d4l3k/messagediff.v1 v1.2.1/go.mod h1:EUzikiKadqXWcD1AzJLagx0j/BeeWGtn++04Xniyg44=
@@ -1660,6 +1680,7 @@ gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
 gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
+gotest.tools v2.2.0+incompatible h1:VsBPFP1AI068pPrMxtb/S8Zkgf9xEmTLJjfM+P5UIEo=
 gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 helm.sh/helm/v3 v3.2.4/go.mod h1:ZaXz/vzktgwjyGGFbUWtIQkscfE7WYoRGP2szqAFHR0=
 helm.sh/helm/v3 v3.3.4 h1:tbad6WQVMxEw1HlVBvI2rQqOblmI5lgXOrWAMwJ198M=
diff --git a/pkg/core/resources/apis/mesh/healthcheck_validator.go b/pkg/core/resources/apis/mesh/healthcheck_validator.go
index 8a9952778..4e602c535 100644
--- a/pkg/core/resources/apis/mesh/healthcheck_validator.go
+++ b/pkg/core/resources/apis/mesh/healthcheck_validator.go
@@ -97,6 +97,12 @@ func (d *HealthCheckResource) validateConf() (err validators.ValidationError) {
 	err.Add(ValidateDuration(path.Field("timeout"), d.Spec.Conf.Timeout))
 	err.Add(ValidateThreshold(path.Field("unhealthyThreshold"), d.Spec.Conf.UnhealthyThreshold))
 	err.Add(ValidateThreshold(path.Field("healthyThreshold"), d.Spec.Conf.HealthyThreshold))
+	if d.Spec.Conf.InitialJitter != nil {
+		err.Add(ValidateDuration(path.Field("initialJitter"), d.Spec.Conf.InitialJitter))
+	}
+	if d.Spec.Conf.IntervalJitter != nil {
+		err.Add(ValidateDuration(path.Field("intervalJitter"), d.Spec.Conf.IntervalJitter))
+	}
 	if d.Spec.Conf.GetHttp() != nil {
 		err.Add(d.validateConfHttp(path.Field("http")))
 	}
diff --git a/pkg/plugins/resources/k8s/native/go.mod b/pkg/plugins/resources/k8s/native/go.mod
index 2ad5ebb2d..6f3227327 100644
--- a/pkg/plugins/resources/k8s/native/go.mod
+++ b/pkg/plugins/resources/k8s/native/go.mod
@@ -13,7 +13,6 @@ require (
 	k8s.io/apimachinery v0.18.14
 	k8s.io/client-go v0.18.14
 	sigs.k8s.io/controller-runtime v0.6.4
-	sigs.k8s.io/controller-tools v0.3.0 // indirect
 )
 
 replace github.com/kumahq/kuma/api => ../../../../../api
diff --git a/pkg/plugins/resources/k8s/native/go.sum b/pkg/plugins/resources/k8s/native/go.sum
index d5d6e2f33..7c2ce3762 100644
--- a/pkg/plugins/resources/k8s/native/go.sum
+++ b/pkg/plugins/resources/k8s/native/go.sum
@@ -29,6 +29,7 @@ github.com/beorn7/perks v1.0.0 h1:HWo1m869IqiPhD389kmkxeTalrjNbbJTC8LXupb+sl0=
 github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
 github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs=
 github.com/blang/semver v3.5.0+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk=
+github.com/census-instrumentation/opencensus-proto v0.2.1 h1:glEXhBS5PSLLv4IXzLA5yPRVX4bilULVyxxbrfOtDAk=
 github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
 github.com/client9/misspell v0.3.4/go.mod h1:qj6jICC3Q7zFZvVWo7KLAzC3yx5G7kyvSDkc90ppPyw=
 github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk=
@@ -72,12 +73,12 @@ github.com/evanphx/json-patch v4.2.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLi
 github.com/evanphx/json-patch v4.5.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
 github.com/evanphx/json-patch v4.9.0+incompatible h1:kLcOMZeuLAJvL2BPWLMIj5oaZQobrkAqrL+WFZwQses=
 github.com/evanphx/json-patch v4.9.0+incompatible/go.mod h1:50XU6AFN0ol/bzJsmQLiYLvXMP4fmwYFNcr97nuDLSk=
-github.com/fatih/color v1.7.0 h1:DkWD4oS2D8LGGgTQ6IvwJJXSL5Vp2ffcQg58nFV38Ys=
 github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4=
 github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
 github.com/fsnotify/fsnotify v1.4.9 h1:hsms1Qyu0jgnwNXIxa+/V/PDsU6CfLf6CNO8H7IWoS4=
 github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4IgpuI1SZQ=
 github.com/ghodss/yaml v0.0.0-20150909031657-73d445a93680/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
+github.com/ghodss/yaml v1.0.0 h1:wQHKEahhL6wmXdzwWG11gIVCkOv05bNOh+Rxn0yngAk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/globalsign/mgo v0.0.0-20180905125535-1ca0a4f7cbcb/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
 github.com/globalsign/mgo v0.0.0-20181015135952-eeefdecb41b8/go.mod h1:xkRDCp4j0OGD1HRkm4kmhM+pmpv3AKq5SU7GMg4oO/Q=
@@ -131,8 +132,6 @@ github.com/go-openapi/validate v0.18.0/go.mod h1:Uh4HdOzKt19xGIGm1qHf/ofbX1YQ4Y+
 github.com/go-openapi/validate v0.19.2/go.mod h1:1tRCw7m3jtI8eNWEEliiAqUIcBztB2KDnRCRMUi7GTA=
 github.com/go-openapi/validate v0.19.5/go.mod h1:8DJv2CVJQ6kGNpFW6eV9N3JviE1C85nY1c2z52x1Gk4=
 github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY=
-github.com/gobuffalo/flect v0.2.0 h1:EWCvMGGxOjsgwlWaP+f4+Hh6yrrte7JeFL2S6b+0hdM=
-github.com/gobuffalo/flect v0.2.0/go.mod h1:W3K3X9ksuZfir8f/LrfVtWmCDQFfayuylOJ7sz/Fj80=
 github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ=
 github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4=
 github.com/gogo/protobuf v1.3.1 h1:DqDEcV5aeaTmdFBePNpYsp3FlcVH/2ISVVM9Qf8PSls=
@@ -195,7 +194,6 @@ github.com/iancoleman/strcase v0.0.0-20180726023541-3605ed457bf7/go.mod h1:SK73t
 github.com/imdario/mergo v0.3.5/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
 github.com/imdario/mergo v0.3.9 h1:UauaLniWCFHWd+Jp9oCEkTBj8VO/9DKg3PV3VCNMDIg=
 github.com/imdario/mergo v0.3.9/go.mod h1:2EnlNZ0deacrJVfApfmtdGgDfMuh/nq6Ok1EcJh5FfA=
-github.com/inconshreveable/mousetrap v1.0.0 h1:Z8tu5sraLXCXIcARxBp/8cbvlwVa7Z1NHg9XEKhtSvM=
 github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
 github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
 github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
@@ -211,9 +209,11 @@ github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+o
 github.com/konsorten/go-windows-terminal-sequences v1.0.1/go.mod h1:T0+1ngSBFLxvqU3pZ+m/2kptfBszLMUkC4ZK/EgS/cQ=
 github.com/kr/fs v0.1.0/go.mod h1:FFnZGqtBN9Gxj7eW1uZ42v5BccTP0vu6NEaFoC2HwRg=
 github.com/kr/logfmt v0.0.0-20140226030751-b84e30acd515/go.mod h1:+0opPa2QZZtGFBFZlji/RkVcI2GknAs/DXo4wKdlNEc=
+github.com/kr/pretty v0.1.0 h1:L/CwN0zerZDmRFUapSPitk6f+Q3+0za1rQkzVuMiMFI=
 github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORNo=
 github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
 github.com/kr/pty v1.1.5/go.mod h1:9r2w37qlBe7rQ6e1fg1S/9xpWHSnaqNdHD3WcMdbPDA=
+github.com/kr/text v0.1.0 h1:45sCR5RtlFHMR4UwH9sdQ5TC8v0qDQCHnXt+kaKSTVE=
 github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
 github.com/lyft/protoc-gen-star v0.5.1/go.mod h1:9toiA3cC7z5uVbODF7kEQ91Xn7XNFkVUl+SrEe+ZORU=
 github.com/magiconair/properties v1.8.0/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ=
@@ -224,11 +224,7 @@ github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN
 github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc=
 github.com/mailru/easyjson v0.7.0/go.mod h1:KAzv3t3aY1NaHWoQz1+4F1ccyAH66Jk7yos7ldAVICs=
 github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU=
-github.com/mattn/go-colorable v0.1.2 h1:/bC9yWikZXAL9uJdulbSfyVNIR3n3trXl+v8+1sx8mU=
-github.com/mattn/go-colorable v0.1.2/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE=
 github.com/mattn/go-isatty v0.0.4/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4=
-github.com/mattn/go-isatty v0.0.8 h1:HLtExJ+uU2HOZ+wI0Tt5DtUDrx8yhUqDcp7fYERX4CE=
-github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s=
 github.com/mattn/go-runewidth v0.0.2/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1 h1:4hp9jkHxhMHkqkrB3Ix0jegS5sx/RkqARlsWZ6pIwiU=
 github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0=
@@ -256,7 +252,6 @@ github.com/onsi/ginkgo v1.15.0/go.mod h1:hF8qUzuuC8DJGygJH3726JnCZX4MYbRB8yFfISq
 github.com/onsi/gomega v0.0.0-20170829124025-dcabb60a477c/go.mod h1:C1qb7wdrVGGVU+Z6iS04AVkA3Q65CEZX59MT0QO5uiA=
 github.com/onsi/gomega v1.7.0/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY=
 github.com/onsi/gomega v1.7.1/go.mod h1:XdKZgCCFLUoM/7CFJVPcG8C1xQ1AJ0vpAezJrB7JYyY=
-github.com/onsi/gomega v1.8.1/go.mod h1:Ho0h+IUsWyvy1OpqCwxlQ/21gkhVunqlU8fDGcoTdcA=
 github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1ybHNo=
 github.com/onsi/gomega v1.10.5 h1:7n6FEkpFmfCoo2t+YYqXH0evK+a9ICQz0xcAy9dYcaQ=
 github.com/onsi/gomega v1.10.5/go.mod h1:gza4q3jKQJijlu05nKWRCW/GavJumGt8aNRxWg7mt48=
@@ -268,6 +263,7 @@ github.com/pkg/errors v0.8.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINE
 github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
 github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZI=
+github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA=
 github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw=
@@ -296,7 +292,6 @@ github.com/spf13/afero v1.3.3/go.mod h1:5KUK8ByomD5Ti5Artl0RtHeI5pTF7MIDuXL3yY52
 github.com/spf13/afero v1.3.4/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I=
 github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE=
 github.com/spf13/cobra v0.0.3/go.mod h1:1l0Ry5zgKvJasoi3XT1TypsSe7PqH0Sj9dhYf7v3XqQ=
-github.com/spf13/cobra v0.0.5 h1:f0B+LkLX6DtmRH1isoNA9VTtNUK9K8xYd28JNNfOv/s=
 github.com/spf13/cobra v0.0.5/go.mod h1:3K3wKZymM7VvHMDS9+Akkh4K60UwM26emMESw8tLCHU=
 github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo=
 github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4=
@@ -356,7 +351,6 @@ golang.org/x/lint v0.0.0-20190313153728-d0100b6bd8b3/go.mod h1:6SW0HCj/g11FgYtHl
 golang.org/x/lint v0.0.0-20200302205851-738671d3881b/go.mod h1:3xt1FjdF8hUf6vQPIChWIBhFzV8gjjsPE/fR3IyQdNY=
 golang.org/x/mod v0.1.1-0.20191105210325-c90efee705ee/go.mod h1:QqPTAvyqsEbceGzBzNggFXnrqF1CaUcvgkdR5Ot7KZg=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20170114055629-f2499483f923/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
 golang.org/x/net v0.0.0-20180724234803-3673e40ba225/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
@@ -400,7 +394,6 @@ golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5h
 golang.org/x/sys v0.0.0-20181205085412-a5c9d58dba9a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190209173611-3b5209105503/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190222072716-a9d3bda3a223/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190321052220-f7bb7a8bee54/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/sys v0.0.0-20190422165155-953cdadca894/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -441,7 +434,6 @@ golang.org/x/tools v0.0.0-20190920225731-5eefd052ad72/go.mod h1:b+2E5dAYhXwXZwtn
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200130002326-2f3ba24bd6e7/go.mod h1:TB2adYChydJhpapKDTa4BR/hXlZSLoq2Wpct/0txZ28=
 golang.org/x/tools v0.0.0-20200522201501-cb1345f3a375/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e h1:4nW4NLDYnU28ojHaHO8OVxFHk/aQ33U01a9cjED+pzE=
 golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
@@ -453,6 +445,7 @@ gomodules.xyz/jsonpatch/v2 v2.0.1/go.mod h1:IhYNNY4jnS53ZnfE4PAmpKtDpTCj1JFXc+3m
 google.golang.org/api v0.4.0/go.mod h1:8k5glujaEP+g9n7WNsDg8QP6cUVNI86fCNMcbazEtwE=
 google.golang.org/appengine v1.1.0/go.mod h1:EbEs0AVv82hx2wNQdGPgUI5lhzA/G0D9YwlJXL52JkM=
 google.golang.org/appengine v1.4.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
+google.golang.org/appengine v1.5.0 h1:KxkO13IPW4Lslp2bz+KHP2E3gtFlrIGNThxkZQ3g+4c=
 google.golang.org/appengine v1.5.0/go.mod h1:xpcJRLb0r/rnEns0DIKYYv+WjYCduHsrkT7/EB5XEv4=
 google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoALGmiZfu7CAH4rXhgtRTLTxftemlI0sWmxmc=
 google.golang.org/genproto v0.0.0-20190307195333-5fe7a883aa19/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
@@ -481,6 +474,7 @@ google.golang.org/protobuf v1.25.0/go.mod h1:9JNX74DMeImyA3h4bdi1ymwjUzf21/xIlba
 gopkg.in/alecthomas/kingpin.v2 v2.2.6/go.mod h1:FMv+mEhP44yOT+4EoQTLFTRgOQ1FBLkstjWtayDeSgw=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
+gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo=
 gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
 gopkg.in/cheggaaa/pb.v1 v1.0.25/go.mod h1:V/YB90LKu/1FcN3WVnfiiE5oMCibMjukxqG/qStrOgw=
 gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys=
@@ -498,33 +492,25 @@ gopkg.in/yaml.v2 v2.2.4/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.2.8/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v2 v2.3.0 h1:clyUAQHOM3G0M3f5vQj7LuJrETvjVot3Z5el9nffUtU=
 gopkg.in/yaml.v2 v2.3.0/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
-gopkg.in/yaml.v3 v3.0.0-20190905181640-827449938966/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gotest.tools v2.2.0+incompatible/go.mod h1:DsYFclhRJ6vuDpmuTbkuFWG+y2sxOXAzmJt81HFBacw=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190523083050-ea95bdfd59fc/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
-k8s.io/api v0.18.2/go.mod h1:SJCWI7OLzhZSvbY7U8zwNl9UA4o1fizoug34OV/2r78=
 k8s.io/api v0.18.6/go.mod h1:eeyxr+cwCjMdLAmr2W3RyDI0VvTawSg/3RFFBEnmZGI=
 k8s.io/api v0.18.14 h1:tKRYsRhfL7Hfs60rFm8sNdhWydDuk7vnBqnt8uy+i/Q=
 k8s.io/api v0.18.14/go.mod h1:rMEP0KbqUY9Bm/nbQBXtUizL9r7XvD7IV1XhnGSHsy4=
-k8s.io/apiextensions-apiserver v0.18.2/go.mod h1:q3faSnRGmYimiocj6cHQ1I3WpLqmDgJFlKL37fC4ZvY=
 k8s.io/apiextensions-apiserver v0.18.6 h1:vDlk7cyFsDyfwn2rNAO2DbmUbvXy5yT5GE3rrqOzaMo=
 k8s.io/apiextensions-apiserver v0.18.6/go.mod h1:lv89S7fUysXjLZO7ke783xOwVTm6lKizADfvUM/SS/M=
-k8s.io/apimachinery v0.18.2/go.mod h1:9SnR/e11v5IbyPCGbvJViimtJ0SwHG4nfZFjU77ftcA=
 k8s.io/apimachinery v0.18.6/go.mod h1:OaXp26zu/5J7p0f92ASynJa1pZo06YlV9fG7BoWbCko=
 k8s.io/apimachinery v0.18.14 h1:wH0doJJajeG0qIuQD1/yo5JrBDAsZ3olqlNXZBiauVw=
 k8s.io/apimachinery v0.18.14/go.mod h1:PF5taHbXgTEJLU+xMypMmYTXTWPJ5LaW8bfsisxnEXk=
-k8s.io/apiserver v0.18.2/go.mod h1:Xbh066NqrZO8cbsoenCwyDJ1OSi8Ag8I2lezeHxzwzw=
 k8s.io/apiserver v0.18.6/go.mod h1:Zt2XvTHuaZjBz6EFYzpp+X4hTmgWGy8AthNVnTdm3Wg=
-k8s.io/client-go v0.18.2/go.mod h1:Xcm5wVGXX9HAA2JJ2sSBUn3tCJ+4SVlCbl2MNNv+CIU=
 k8s.io/client-go v0.18.6/go.mod h1:/fwtGLjYMS1MaM5oi+eXhKwG+1UHidUEXRh6cNsdO0Q=
 k8s.io/client-go v0.18.14 h1:9dWb5D0dBsuc2umLPuWVE07rPDmBNsggW3vvctDyJII=
 k8s.io/client-go v0.18.14/go.mod h1:fpZHBter1MB6bs+GISolsmIRsGlBEJyd0mllE0H9f2Y=
-k8s.io/code-generator v0.18.2/go.mod h1:+UHX5rSbxmR8kzS+FAv7um6dtYrZokQvjHpDSYRVkTc=
 k8s.io/code-generator v0.18.6/go.mod h1:TgNEVx9hCyPGpdtCWA34olQYLkh3ok9ar7XfSsr8b6c=
-k8s.io/component-base v0.18.2/go.mod h1:kqLlMuhJNHQ9lz8Z7V5bxUUtjFZnrypArGl58gmDfUM=
 k8s.io/component-base v0.18.6/go.mod h1:knSVsibPR5K6EW2XOjEHik6sdU5nCvKMrzMt2D4In14=
 k8s.io/gengo v0.0.0-20190128074634-0689ccc1d7d6/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
 k8s.io/gengo v0.0.0-20200114144118-36b2048a9120/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0=
@@ -534,7 +520,6 @@ k8s.io/klog v1.0.0 h1:Pt+yjF5aB1xDSVbau4VsWe+dQNzA0qv1LlXdC2dF6Q8=
 k8s.io/klog v1.0.0/go.mod h1:4Bi6QPql/J/LkTDqv7R/cd3hPo4k2DG6Ptcz060Ez5I=
 k8s.io/klog/v2 v2.0.0 h1:Foj74zO6RbjjP4hBEKjnYtjjAhGg4jNynUdYF6fJrok=
 k8s.io/klog/v2 v2.0.0/go.mod h1:PBfzABfn139FHAV07az/IF9Wp1bkk3vpT2XSJ76fSDE=
-k8s.io/kube-openapi v0.0.0-20200121204235-bf4fb3bd569c/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6 h1:Oh3Mzx5pJ+yIumsAD0MOECPVeXsVot0UkiaCGVyfGQY=
 k8s.io/kube-openapi v0.0.0-20200410145947-61e04a5be9a6/go.mod h1:GRQhZsXIAJ1xR0C9bd8UpWHZ5plfAS9fzPjJuQ6JL3E=
 k8s.io/utils v0.0.0-20200324210504-a9aa75ae1b89/go.mod h1:sZAwmy6armz5eXlNoLmJcl4F1QuKu7sr+mFQ0byX7Ew=
@@ -543,8 +528,6 @@ k8s.io/utils v0.0.0-20200603063816-c1c6865ac451/go.mod h1:jPW/WVKK9YHAvNhRxK0md/
 sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.7/go.mod h1:PHgbrJT7lCHcxMU+mDHEm+nx46H4zuuHZkDP6icnhu0=
 sigs.k8s.io/controller-runtime v0.6.4 h1:4013CKsBs5bEqo+LevzDett+LLxag/FjQWG94nVZ/9g=
 sigs.k8s.io/controller-runtime v0.6.4/go.mod h1:WlZNXcM0++oyaQt4B7C2lEE5JYRs8vJUzRP4N4JpdAY=
-sigs.k8s.io/controller-tools v0.3.0 h1:y3YD99XOyWaXkiF1kd41uRvfp/64teWcrEZFuHxPhJ4=
-sigs.k8s.io/controller-tools v0.3.0/go.mod h1:enhtKGfxZD1GFEoMgP8Fdbu+uKQ/cq1/WGJhdVChfvI=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0-20200116222232-67a7b8c61874/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0 h1:dOmIZBMfhcHS09XZkMyUgkq5trg3/jRyJYFZUiaOp8E=
 sigs.k8s.io/structured-merge-diff/v3 v3.0.0/go.mod h1:PlARxl6Hbt/+BC80dRLi1qAmnMqwqDg62YvvVkZjemw=
diff --git a/pkg/plugins/runtime/k8s/controllers/pod_controller.go b/pkg/plugins/runtime/k8s/controllers/pod_controller.go
index a482f9b7a..200f1f66d 100644
--- a/pkg/plugins/runtime/k8s/controllers/pod_controller.go
+++ b/pkg/plugins/runtime/k8s/controllers/pod_controller.go
@@ -75,6 +75,11 @@ func (r *PodReconciler) Reconcile(req kube_ctrl.Request) (kube_ctrl.Result, erro
 		return kube_ctrl.Result{}, nil
 	}
 
+	// skip a Pod if is complete/terminated (most probably a completed job)
+	if r.isPodComplete(pod) {
+		return kube_ctrl.Result{}, nil
+	}
+
 	// for Pods marked with ingress annotation special type of Dataplane will be injected
 	enabled, exist, err := metadata.Annotations(pod.Annotations).GetEnabled(metadata.KumaIngressAnnotation)
 	if err != nil {
@@ -288,6 +293,20 @@ func (r *PodReconciler) SetupWithManager(mgr kube_ctrl.Manager) error {
 		Complete(r)
 }
 
+func (r *PodReconciler) isPodComplete(pod *kube_core.Pod) bool {
+	for _, cs := range pod.Status.ContainerStatuses {
+		// the sidecar amy or may not be terminated yet
+		if cs.Name == util_k8s.KumaSidecarContainerName {
+			continue
+		}
+		if cs.State.Terminated == nil {
+			// at least one container not terminated, therefore pod is still active
+			return false
+		}
+	}
+	return true
+}
+
 type ServiceToPodsMapper struct {
 	kube_client.Client
 	Log logr.Logger
diff --git a/pkg/plugins/runtime/k8s/controllers/pod_status_controller.go b/pkg/plugins/runtime/k8s/controllers/pod_status_controller.go
index 2023e5375..083389b1d 100644
--- a/pkg/plugins/runtime/k8s/controllers/pod_status_controller.go
+++ b/pkg/plugins/runtime/k8s/controllers/pod_status_controller.go
@@ -3,6 +3,8 @@ package controllers
 import (
 	"context"
 
+	"go.uber.org/multierr"
+
 	"github.com/pkg/errors"
 
 	core_mesh "github.com/kumahq/kuma/pkg/core/resources/apis/mesh"
@@ -97,10 +99,18 @@ func (r *PodStatusReconciler) Reconcile(req kube_ctrl.Request) (kube_ctrl.Result
 			return kube_ctrl.Result{}, err
 		}
 
+		var errs error
 		err := r.EnvoyAdminClient.PostQuit(dp)
 		if err != nil {
-			return kube_ctrl.Result{}, errors.Wrapf(err, "envoy admin client failed. Most probably the pod is already going down.")
+			errs = multierr.Append(errs, errors.Wrapf(err, "envoy admin client failed. Most probably the pod is already going down."))
 		}
+
+		err = r.Client.Delete(ctx, dataplane)
+		if err != nil {
+			errs = multierr.Append(errs, errors.Wrapf(err, "trying to delete the job's dataplane"))
+		}
+
+		return kube_ctrl.Result{}, errs
 	}
 
 	return kube_ctrl.Result{}, nil
diff --git a/pkg/xds/envoy/clusters/v2/health_check_configurer.go b/pkg/xds/envoy/clusters/v2/health_check_configurer.go
index 6f5b0bee8..4c6e53880 100644
--- a/pkg/xds/envoy/clusters/v2/health_check_configurer.go
+++ b/pkg/xds/envoy/clusters/v2/health_check_configurer.go
@@ -103,10 +103,13 @@ func (e *HealthCheckConfigurer) Configure(cluster *envoy_api.Cluster) error {
 		HealthChecker: &envoy_core.HealthCheck_TcpHealthCheck_{
 			TcpHealthCheck: &envoy_core.HealthCheck_TcpHealthCheck{},
 		},
-		Interval:           activeChecks.Interval,
-		Timeout:            activeChecks.Timeout,
-		UnhealthyThreshold: &wrappers.UInt32Value{Value: activeChecks.UnhealthyThreshold},
-		HealthyThreshold:   &wrappers.UInt32Value{Value: activeChecks.HealthyThreshold},
+		Interval:              activeChecks.Interval,
+		Timeout:               activeChecks.Timeout,
+		UnhealthyThreshold:    &wrappers.UInt32Value{Value: activeChecks.UnhealthyThreshold},
+		HealthyThreshold:      &wrappers.UInt32Value{Value: activeChecks.HealthyThreshold},
+		InitialJitter:         activeChecks.InitialJitter,
+		IntervalJitter:        activeChecks.IntervalJitter,
+		IntervalJitterPercent: activeChecks.IntervalJitterPercent,
 	}
 
 	if tcp := activeChecks.GetTcp(); tcp != nil {
diff --git a/pkg/xds/envoy/clusters/v3/health_check_configurer.go b/pkg/xds/envoy/clusters/v3/health_check_configurer.go
index eaff1d251..613666433 100644
--- a/pkg/xds/envoy/clusters/v3/health_check_configurer.go
+++ b/pkg/xds/envoy/clusters/v3/health_check_configurer.go
@@ -103,10 +103,13 @@ func (e *HealthCheckConfigurer) Configure(cluster *envoy_cluster.Cluster) error
 		HealthChecker: &envoy_core.HealthCheck_TcpHealthCheck_{
 			TcpHealthCheck: &envoy_core.HealthCheck_TcpHealthCheck{},
 		},
-		Interval:           activeChecks.Interval,
-		Timeout:            activeChecks.Timeout,
-		UnhealthyThreshold: &wrappers.UInt32Value{Value: activeChecks.UnhealthyThreshold},
-		HealthyThreshold:   &wrappers.UInt32Value{Value: activeChecks.HealthyThreshold},
+		Interval:              activeChecks.Interval,
+		Timeout:               activeChecks.Timeout,
+		UnhealthyThreshold:    &wrappers.UInt32Value{Value: activeChecks.UnhealthyThreshold},
+		HealthyThreshold:      &wrappers.UInt32Value{Value: activeChecks.HealthyThreshold},
+		InitialJitter:         activeChecks.InitialJitter,
+		IntervalJitter:        activeChecks.IntervalJitter,
+		IntervalJitterPercent: activeChecks.IntervalJitterPercent,
 	}
 
 	if tcp := activeChecks.GetTcp(); tcp != nil {
diff --git a/pkg/xds/ingress/dataplane.go b/pkg/xds/ingress/dataplane.go
index fabb3fd6c..4d30d4afd 100644
--- a/pkg/xds/ingress/dataplane.go
+++ b/pkg/xds/ingress/dataplane.go
@@ -86,7 +86,7 @@ func GetIngressAvailableServices(others []*core_mesh.DataplaneResource) []*mesh_
 		if dp.Spec.IsIngress() {
 			continue
 		}
-		for _, dpInbound := range dp.Spec.GetNetworking().GetInbound() {
+		for _, dpInbound := range dp.Spec.GetNetworking().GetHealthyInbounds() {
 			tagSets.addInstanceOfTags(dp.GetMeta().GetMesh(), dpInbound.Tags)
 		}
 	}
diff --git a/pkg/xds/ingress/outbound.go b/pkg/xds/ingress/outbound.go
index 0f2f50325..a75d0c52b 100644
--- a/pkg/xds/ingress/outbound.go
+++ b/pkg/xds/ingress/outbound.go
@@ -16,7 +16,7 @@ func BuildEndpointMap(destinations core_xds.DestinationMap, dataplanes []*mesh_c
 		if dataplane.Spec.IsIngress() {
 			continue
 		}
-		for _, inbound := range dataplane.Spec.Networking.GetInbound() {
+		for _, inbound := range dataplane.Spec.GetNetworking().GetHealthyInbounds() {
 			service := inbound.Tags[mesh_proto.ServiceTag]
 			selectors, ok := destinations[service]
 			if !ok {
diff --git a/pkg/xds/topology/outbound.go b/pkg/xds/topology/outbound.go
index 4865776b2..d666941b4 100644
--- a/pkg/xds/topology/outbound.go
+++ b/pkg/xds/topology/outbound.go
@@ -66,17 +66,11 @@ func fillDataplaneOutbounds(outbound core_xds.EndpointMap, dataplanes []*mesh_co
 		if dataplane.Spec.IsIngress() {
 			continue
 		}
-		for _, inbound := range dataplane.Spec.Networking.GetInbound() {
+		for _, inbound := range dataplane.Spec.GetNetworking().GetHealthyInbounds() {
 			service := inbound.Tags[mesh_proto.ServiceTag]
 			iface := dataplane.Spec.Networking.ToInboundInterface(inbound)
 			// TODO(yskopets): do we need to dedup?
 			// TODO(yskopets): sort ?
-
-			// if inbound.Health == nil we consider Dataplane as healthy in order to be compatible with Universal
-			// where we Kuma doesn't fill inbound.Health automatically
-			if inbound.Health != nil && !inbound.Health.Ready {
-				continue
-			}
 			outbound[service] = append(outbound[service], core_xds.Endpoint{
 				Target:   iface.DataplaneIP,
 				Port:     iface.DataplanePort,


Test patch:
diff --git a/api/mesh/v1alpha1/dataplane_helpers_test.go b/api/mesh/v1alpha1/dataplane_helpers_test.go
index 1728dc402..e13a60680 100644
--- a/api/mesh/v1alpha1/dataplane_helpers_test.go
+++ b/api/mesh/v1alpha1/dataplane_helpers_test.go
@@ -128,6 +128,44 @@ var _ = Describe("Dataplane_Networking", func() {
 			)
 		})
 	})
+
+	Describe("GetHealthyInbounds()", func() {
+
+		It("should return only healty inbounds", func() {
+			networking := &Dataplane_Networking{
+				Inbound: []*Dataplane_Networking_Inbound{
+					{
+						Health:      nil,
+						Port:        8080,
+						ServicePort: 80,
+					},
+					{
+						Health:      &Dataplane_Networking_Inbound_Health{Ready: true},
+						Port:        9090,
+						ServicePort: 90,
+					},
+					{
+						Health:      &Dataplane_Networking_Inbound_Health{Ready: false},
+						Port:        7070,
+						ServicePort: 70,
+					},
+				},
+			}
+
+			actual := networking.GetHealthyInbounds()
+			Expect(actual).To(HaveLen(2))
+			Expect(actual).To(ConsistOf(
+				&Dataplane_Networking_Inbound{
+					Health:      &Dataplane_Networking_Inbound_Health{Ready: true},
+					Port:        9090,
+					ServicePort: 90,
+				},
+				&Dataplane_Networking_Inbound{
+					Port:        8080,
+					ServicePort: 80,
+				}))
+		})
+	})
 })
 
 var _ = Describe("Dataplane_Networking_Outbound", func() {
diff --git a/pkg/core/resources/apis/mesh/healthcheck_validator_test.go b/pkg/core/resources/apis/mesh/healthcheck_validator_test.go
index 20e848159..a2949e8ac 100644
--- a/pkg/core/resources/apis/mesh/healthcheck_validator_test.go
+++ b/pkg/core/resources/apis/mesh/healthcheck_validator_test.go
@@ -111,6 +111,8 @@ var _ = Describe("HealthCheck", func() {
                   timeout: 0s
                   unhealthyThreshold: 0
                   healthyThreshold: 0
+                  initialJitter: 0s
+                  intervalJitter: 0s
                   http:
                     path: ""
                     requestHeadersToAdd:
@@ -131,6 +133,10 @@ var _ = Describe("HealthCheck", func() {
                   message: must have a positive value
                 - field: conf.healthyThreshold
                   message: must have a positive value
+                - field: conf.initialJitter
+                  message: must have a positive value
+                - field: conf.intervalJitter
+                  message: must have a positive value
                 - field: conf.http.path
                   message: has to be defined and cannot be empty
                 - field: conf.http.expectedStatuses[0]
diff --git a/pkg/plugins/runtime/k8s/controllers/pod_controller_test.go b/pkg/plugins/runtime/k8s/controllers/pod_controller_test.go
index 3b9043795..dad188091 100644
--- a/pkg/plugins/runtime/k8s/controllers/pod_controller_test.go
+++ b/pkg/plugins/runtime/k8s/controllers/pod_controller_test.go
@@ -87,6 +87,11 @@ var _ = Describe("PodReconciler", func() {
 				},
 				Status: kube_core.PodStatus{
 					PodIP: "192.168.0.1",
+					ContainerStatuses: []kube_core.ContainerStatus{
+						{
+							State: kube_core.ContainerState{},
+						},
+					},
 				},
 			},
 			&kube_core.Pod{
@@ -103,6 +108,11 @@ var _ = Describe("PodReconciler", func() {
 				},
 				Status: kube_core.PodStatus{
 					PodIP: "192.168.0.1",
+					ContainerStatuses: []kube_core.ContainerStatus{
+						{
+							State: kube_core.ContainerState{},
+						},
+					},
 				},
 			},
 			&kube_core.Pod{
@@ -119,6 +129,11 @@ var _ = Describe("PodReconciler", func() {
 				},
 				Status: kube_core.PodStatus{
 					PodIP: "192.168.0.1",
+					ContainerStatuses: []kube_core.ContainerStatus{
+						{
+							State: kube_core.ContainerState{},
+						},
+					},
 				},
 			},
 			&kube_core.Service{
@@ -348,12 +363,14 @@ var _ = Describe("PodReconciler", func() {
           networking:
             address: 192.168.0.1
             inbound:
-            - port: 8080
+            - health: {} 
+              port: 8080
               tags:
                 app: sample
                 kuma.io/protocol: http
                 kuma.io/service: example_demo_svc_80
-            - port: 6060
+            - health: {} 
+              port: 6060
               tags:
                 app: sample
                 kuma.io/service: example_demo_svc_6061
@@ -420,12 +437,14 @@ var _ = Describe("PodReconciler", func() {
           networking:
             address: 192.168.0.1
             inbound:
-            - port: 8080
+            - health: {} 
+              port: 8080
               tags:
                 app: sample
                 kuma.io/protocol: http
                 kuma.io/service: example_demo_svc_80
-            - port: 6060
+            - health: {} 
+              port: 6060
               tags:
                 app: sample
                 kuma.io/service: example_demo_svc_6061
diff --git a/pkg/xds/envoy/clusters/v2/health_check_configurer_test.go b/pkg/xds/envoy/clusters/v2/health_check_configurer_test.go
index 5e67de59a..3ffebaa66 100644
--- a/pkg/xds/envoy/clusters/v2/health_check_configurer_test.go
+++ b/pkg/xds/envoy/clusters/v2/health_check_configurer_test.go
@@ -233,6 +233,44 @@ var _ = Describe("HealthCheckConfigurer", func() {
               timeout: 4s
               unhealthyThreshold: 3
             name: testCluster
+            type: EDS`,
+		}),
+		Entry("HealthCheck with jitter", testCase{
+			clusterName: "testCluster",
+			healthCheck: &mesh_core.HealthCheckResource{
+				Spec: &mesh_proto.HealthCheck{
+					Sources: []*mesh_proto.Selector{
+						{Match: mesh_proto.TagSelector{"kuma.io/service": "backend"}},
+					},
+					Destinations: []*mesh_proto.Selector{
+						{Match: mesh_proto.TagSelector{"kuma.io/service": "redis"}},
+					},
+					Conf: &mesh_proto.HealthCheck_Conf{
+						Interval:              ptypes.DurationProto(5 * time.Second),
+						Timeout:               ptypes.DurationProto(4 * time.Second),
+						UnhealthyThreshold:    3,
+						HealthyThreshold:      2,
+						InitialJitter:         ptypes.DurationProto(6 * time.Second),
+						IntervalJitter:        ptypes.DurationProto(7 * time.Second),
+						IntervalJitterPercent: 50,
+					},
+				},
+			},
+			expected: `
+            connectTimeout: 5s
+            edsClusterConfig:
+              edsConfig:
+                ads: {}
+            healthChecks:
+            - healthyThreshold: 2
+              interval: 5s
+              tcpHealthCheck: {}
+              timeout: 4s
+              unhealthyThreshold: 3
+              initialJitter: 6s
+              intervalJitter: 7s
+              intervalJitterPercent: 50
+            name: testCluster
             type: EDS`,
 		}),
 	)
diff --git a/pkg/xds/envoy/clusters/v3/health_check_configurer_test.go b/pkg/xds/envoy/clusters/v3/health_check_configurer_test.go
index 55e5ee489..1b01001a8 100644
--- a/pkg/xds/envoy/clusters/v3/health_check_configurer_test.go
+++ b/pkg/xds/envoy/clusters/v3/health_check_configurer_test.go
@@ -238,6 +238,45 @@ var _ = Describe("HealthCheckConfigurer", func() {
               timeout: 4s
               unhealthyThreshold: 3
             name: testCluster
+            type: EDS`,
+		}),
+		Entry("HealthCheck with jitter", testCase{
+			clusterName: "testCluster",
+			healthCheck: &mesh_core.HealthCheckResource{
+				Spec: &mesh_proto.HealthCheck{
+					Sources: []*mesh_proto.Selector{
+						{Match: mesh_proto.TagSelector{"kuma.io/service": "backend"}},
+					},
+					Destinations: []*mesh_proto.Selector{
+						{Match: mesh_proto.TagSelector{"kuma.io/service": "redis"}},
+					},
+					Conf: &mesh_proto.HealthCheck_Conf{
+						Interval:              ptypes.DurationProto(5 * time.Second),
+						Timeout:               ptypes.DurationProto(4 * time.Second),
+						UnhealthyThreshold:    3,
+						HealthyThreshold:      2,
+						InitialJitter:         ptypes.DurationProto(6 * time.Second),
+						IntervalJitter:        ptypes.DurationProto(7 * time.Second),
+						IntervalJitterPercent: 50,
+					},
+				},
+			},
+			expected: `
+            connectTimeout: 5s
+            edsClusterConfig:
+              edsConfig:
+                ads: {}
+                resourceApiVersion: V3
+            healthChecks:
+            - healthyThreshold: 2
+              interval: 5s
+              tcpHealthCheck: {}
+              timeout: 4s
+              unhealthyThreshold: 3
+              initialJitter: 6s
+              intervalJitter: 7s
+              intervalJitterPercent: 50
+            name: testCluster
             type: EDS`,
 		}),
 	)
diff --git a/test/e2e/deploy/kuma_deploy_hybrid_kube_global_test.go b/test/e2e/deploy/kuma_deploy_hybrid_kube_global_test.go
index b0f54bda5..c2f4c0a27 100644
--- a/test/e2e/deploy/kuma_deploy_hybrid_kube_global_test.go
+++ b/test/e2e/deploy/kuma_deploy_hybrid_kube_global_test.go
@@ -55,8 +55,8 @@ var _ = Describe("Test Kubernetes/Universal deployment when Global is on K8S", f
 
 		err = NewClusterSetup().
 			Install(Kuma(core.Remote, optsRemote...)).
-			Install(EchoServerUniversal("universal", "default", echoServerToken)).
-			Install(DemoClientUniversal("default", demoClientToken)).
+			Install(EchoServerUniversal(AppModeEchoServer, "default", "universal", echoServerToken)).
+			Install(DemoClientUniversal(AppModeDemoClient, "default", demoClientToken)).
 			Install(IngressUniversal("default", ingressToken)).
 			Setup(remoteCluster)
 		Expect(err).ToNot(HaveOccurred())
diff --git a/test/e2e/deploy/kuma_deploy_hybrid_test.go b/test/e2e/deploy/kuma_deploy_hybrid_test.go
index 4e57cf027..3febed9db 100644
--- a/test/e2e/deploy/kuma_deploy_hybrid_test.go
+++ b/test/e2e/deploy/kuma_deploy_hybrid_test.go
@@ -136,8 +136,8 @@ metadata:
 
 		err = NewClusterSetup().
 			Install(Kuma(core.Remote, optsRemote3...)).
-			Install(EchoServerUniversal("universal", nonDefaultMesh, echoServerToken, WithTransparentProxy(true))).
-			Install(DemoClientUniversal(nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
+			Install(EchoServerUniversal(AppModeEchoServer, nonDefaultMesh, "universal", echoServerToken, WithTransparentProxy(true))).
+			Install(DemoClientUniversal(AppModeDemoClient, nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
 			Install(IngressUniversal(defaultMesh, ingressToken)).
 			Setup(remote_3)
 		Expect(err).ToNot(HaveOccurred())
@@ -152,7 +152,7 @@ metadata:
 
 		err = NewClusterSetup().
 			Install(Kuma(core.Remote, optsRemote4...)).
-			Install(DemoClientUniversal(nonDefaultMesh, demoClientToken)).
+			Install(DemoClientUniversal(AppModeDemoClient, nonDefaultMesh, demoClientToken)).
 			Install(IngressUniversal(defaultMesh, ingressToken)).
 			Setup(remote_4)
 		Expect(err).ToNot(HaveOccurred())
diff --git a/test/e2e/deploy/kuma_deploy_universal_test.go b/test/e2e/deploy/kuma_deploy_universal_test.go
index 99e6487ce..a0adf2097 100644
--- a/test/e2e/deploy/kuma_deploy_universal_test.go
+++ b/test/e2e/deploy/kuma_deploy_universal_test.go
@@ -84,8 +84,8 @@ name: %s
 
 		err = NewClusterSetup().
 			Install(Kuma(core.Remote, optsRemote1...)).
-			Install(EchoServerUniversal("universal1", nonDefaultMesh, echoServerToken, WithTransparentProxy(true))).
-			Install(DemoClientUniversal(nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
+			Install(EchoServerUniversal(AppModeEchoServer, nonDefaultMesh, "universal1", echoServerToken, WithTransparentProxy(true))).
+			Install(DemoClientUniversal(AppModeDemoClient, nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
 			Install(IngressUniversal(defaultMesh, ingressToken)).
 			Setup(remote_1)
 		Expect(err).ToNot(HaveOccurred())
@@ -101,8 +101,8 @@ name: %s
 
 		err = NewClusterSetup().
 			Install(Kuma(core.Remote, optsRemote2...)).
-			Install(EchoServerUniversal("universal2", nonDefaultMesh, echoServerToken, WithTransparentProxy(true))).
-			Install(DemoClientUniversal(nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
+			Install(EchoServerUniversal(AppModeEchoServer, nonDefaultMesh, "universal2", echoServerToken, WithTransparentProxy(true))).
+			Install(DemoClientUniversal(AppModeDemoClient, nonDefaultMesh, demoClientToken, WithTransparentProxy(true))).
 			Install(IngressUniversal(defaultMesh, ingressToken)).
 			Setup(remote_2)
 		Expect(err).ToNot(HaveOccurred())
diff --git a/test/e2e/deploy/kuma_deploy_universal_transparent_proxy_test.go b/test/e2e/deploy/kuma_deploy_universal_transparent_proxy_test.go
index d3546a6e6..3a0f1f3d2 100644
--- a/test/e2e/deploy/kuma_deploy_universal_transparent_proxy_test.go
+++ b/test/e2e/deploy/kuma_deploy_universal_transparent_proxy_test.go
@@ -35,9 +35,9 @@ var _ = Describe("Test Universal Transparent Proxy deployment", func() {
 		demoClientToken, err := cluster.GetKuma().GenerateDpToken("default", "demo-client")
 		Expect(err).ToNot(HaveOccurred())
 
-		err = EchoServerUniversal("universal", "default", echoServerToken, WithTransparentProxy(true))(cluster)
+		err = EchoServerUniversal(AppModeEchoServer, "default", "universal", echoServerToken, WithTransparentProxy(true))(cluster)
 		Expect(err).ToNot(HaveOccurred())
-		err = DemoClientUniversal("default", demoClientToken, WithTransparentProxy(true))(cluster)
+		err = DemoClientUniversal(AppModeDemoClient, "default", demoClientToken, WithTransparentProxy(true))(cluster)
 		Expect(err).ToNot(HaveOccurred())
 	})
 
diff --git a/test/e2e/externalservices/externalservices_universal_test.go b/test/e2e/externalservices/externalservices_universal_test.go
index ff6263da2..85795dfbb 100644
--- a/test/e2e/externalservices/externalservices_universal_test.go
+++ b/test/e2e/externalservices/externalservices_universal_test.go
@@ -87,7 +87,7 @@ networking:
 		err = NewClusterSetup().
 			Install(externalservice.Install(externalservice.HttpServer, externalservice.UniversalAppEchoServer)).
 			Install(externalservice.Install(externalservice.HttpsServer, externalservice.UniversalAppHttpsEchoServer)).
-			Install(DemoClientUniversal("default", demoClientToken)).
+			Install(DemoClientUniversal(AppModeDemoClient, "default", demoClientToken)).
 			Setup(cluster)
 		Expect(err).ToNot(HaveOccurred())
 
diff --git a/test/e2e/healthcheck/healthcheck_hybrid_test.go b/test/e2e/healthcheck/healthcheck_hybrid_test.go
new file mode 100644
index 000000000..719174d8d
--- /dev/null
+++ b/test/e2e/healthcheck/healthcheck_hybrid_test.go
@@ -0,0 +1,166 @@
+package healthcheck_test
+
+import (
+	"fmt"
+	"strings"
+
+	"github.com/gruntwork-io/terratest/modules/k8s"
+	"github.com/gruntwork-io/terratest/modules/retry"
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+	"github.com/pkg/errors"
+	metav1 "k8s.io/apimachinery/pkg/apis/meta/v1"
+
+	"github.com/kumahq/kuma/pkg/config/core"
+	. "github.com/kumahq/kuma/test/framework"
+)
+
+var _ = Describe("Test application HealthCheck on Kubernetes/Universal", func() {
+	meshMTLSOn := func(mesh string) string {
+		return fmt.Sprintf(`
+apiVersion: kuma.io/v1alpha1
+kind: Mesh
+metadata:
+  name: %s
+spec:
+  mtls:
+    enabledBackend: ca-1
+    backends:
+    - name: ca-1
+      type: builtin
+`, mesh)
+	}
+
+	namespaceWithSidecarInjection := func(namespace string) string {
+		return fmt.Sprintf(`
+apiVersion: v1
+kind: Namespace
+metadata:
+  name: %s
+  annotations:
+    kuma.io/sidecar-injection: "enabled"
+`, namespace)
+	}
+
+	var global, remoteK8s, remoteUniversal Cluster
+	var optsRemoteK8s, optsRemoteUniversal []DeployOptionsFunc
+
+	BeforeEach(func() {
+		k8sClusters, err := NewK8sClusters([]string{Kuma1, Kuma2}, Silent)
+		Expect(err).ToNot(HaveOccurred())
+
+		universalClusters, err := NewUniversalClusters([]string{Kuma3}, Silent)
+		Expect(err).ToNot(HaveOccurred())
+
+		global = k8sClusters.GetCluster(Kuma1)
+		err = NewClusterSetup().
+			Install(Kuma(core.Global)).
+			Install(YamlK8s(meshMTLSOn("default"))).
+			Setup(global)
+		Expect(err).ToNot(HaveOccurred())
+
+		optsRemoteK8s = []DeployOptionsFunc{
+			WithIngress(),
+			WithGlobalAddress(global.GetKuma().GetKDSServerAddress()),
+		}
+		remoteK8s = k8sClusters.GetCluster(Kuma2)
+		err = NewClusterSetup().
+			Install(Kuma(core.Remote, optsRemoteK8s...)).
+			Install(KumaDNS()).
+			Install(YamlK8s(namespaceWithSidecarInjection(TestNamespace))).
+			Install(DemoClientK8s("default")).
+			Setup(remoteK8s)
+		Expect(err).ToNot(HaveOccurred())
+
+		echoServerToken, err := global.GetKuma().GenerateDpToken("default", "echo-server_kuma-test_svc_8080")
+		Expect(err).ToNot(HaveOccurred())
+		ingressToken, err := global.GetKuma().GenerateDpToken("default", "ingress")
+		Expect(err).ToNot(HaveOccurred())
+
+		optsRemoteUniversal = []DeployOptionsFunc{
+			WithGlobalAddress(global.GetKuma().GetKDSServerAddress()),
+		}
+		remoteUniversal = universalClusters.GetCluster(Kuma3)
+		err = NewClusterSetup().
+			Install(Kuma(core.Remote, optsRemoteUniversal...)).
+			Install(EchoServerUniversal("dp-echo-1", "default", "echo-universal-1", echoServerToken, WithProtocol("tcp"))).
+			Install(EchoServerUniversal("dp-echo-2", "default", "echo-universal-2", echoServerToken, WithProtocol("tcp"), ProxyOnly(), ServiceProbe())).
+			Install(EchoServerUniversal("dp-echo-3", "default", "echo-universal-3", echoServerToken, WithProtocol("tcp"))).
+			Install(IngressUniversal("default", ingressToken)).
+			Setup(remoteUniversal)
+		Expect(err).ToNot(HaveOccurred())
+		err = remoteUniversal.VerifyKuma()
+		Expect(err).ToNot(HaveOccurred())
+	})
+
+	AfterEach(func() {
+		if ShouldSkipCleanup() {
+			return
+		}
+
+		_ = k8s.KubectlDeleteFromStringE(remoteK8s.GetTesting(), remoteK8s.GetKubectlOptions(), namespaceWithSidecarInjection(TestNamespace))
+		err := remoteK8s.DeleteKuma(optsRemoteK8s...)
+		Expect(err).ToNot(HaveOccurred())
+
+		err = remoteUniversal.DeleteKuma(optsRemoteUniversal...)
+		Expect(err).ToNot(HaveOccurred())
+
+		err = global.DeleteKuma()
+		Expect(err).ToNot(HaveOccurred())
+
+		err = remoteUniversal.DismissCluster()
+		Expect(err).ToNot(HaveOccurred())
+	})
+
+	It("should not load balance requests to unhealthy instance", func() {
+		pods, err := k8s.ListPodsE(remoteK8s.GetTesting(), remoteK8s.GetKubectlOptions(TestNamespace), metav1.ListOptions{
+			LabelSelector: fmt.Sprintf("app=%s", "demo-client"),
+		})
+		Expect(err).ToNot(HaveOccurred())
+		Expect(pods).To(HaveLen(1))
+
+		cmd := []string{"curl", "-v", "-m", "3", "--fail", "echo-server_kuma-test_svc_8080.mesh"}
+
+		checkInstance := func(instance string) {
+			_, err = retry.DoWithRetryE(remoteK8s.GetTesting(), fmt.Sprintf("kubectl exec -- %s", strings.Join(cmd, " ")),
+				DefaultRetries, DefaultTimeout, func() (string, error) {
+					stdout, _, err := remoteK8s.Exec(TestNamespace, pods[0].GetName(), "demo-client", cmd...)
+					if err != nil {
+						return "", err
+					}
+					if !strings.Contains(stdout, instance) {
+						return "", errors.New("wrong instance")
+					}
+					return "", nil
+				},
+			)
+		}
+
+		checkInstance("echo-universal-1")
+		checkInstance("echo-universal-2")
+
+		var counter1, counter2, counter3 int
+		const numOfRequest = 100
+
+		for i := 0; i < numOfRequest; i++ {
+			var stdout string
+
+			stdout, _, err = remoteK8s.Exec(TestNamespace, pods[0].GetName(), "demo-client", cmd...)
+			Expect(err).ToNot(HaveOccurred())
+
+			switch {
+			case strings.Contains(stdout, "Echo echo-universal-1"):
+				counter1++
+			case strings.Contains(stdout, "Echo echo-universal-2"):
+				counter2++
+			case strings.Contains(stdout, "Echo echo-universal-3"):
+				counter3++
+			}
+		}
+
+		Expect(counter2).To(Equal(0))
+		Expect(counter1 > 0).To(BeTrue())
+		Expect(counter3 > 0).To(BeTrue())
+		Expect(counter1 + counter3).To(Equal(numOfRequest))
+	})
+})
diff --git a/test/e2e/healthcheck/healthcheck_universal_test.go b/test/e2e/healthcheck/healthcheck_universal_test.go
index 048999b1a..de5b5adf4 100644
--- a/test/e2e/healthcheck/healthcheck_universal_test.go
+++ b/test/e2e/healthcheck/healthcheck_universal_test.go
@@ -29,9 +29,9 @@ var _ = Describe("Test application HealthCheck on Universal", func() {
 		demoClientToken, err := cluster.GetKuma().GenerateDpToken("default", "demo-client")
 		Expect(err).ToNot(HaveOccurred())
 
-		err = EchoServerUniversal("universal", "default", echoServerToken, ProxyOnly(), ServiceProbe())(cluster)
+		err = EchoServerUniversal("dp-echo-server", "default", "universal", echoServerToken, ProxyOnly(), ServiceProbe())(cluster)
 		Expect(err).ToNot(HaveOccurred())
-		err = DemoClientUniversal("default", demoClientToken, ServiceProbe())(cluster)
+		err = DemoClientUniversal("dp-demo-client", "default", demoClientToken, ServiceProbe())(cluster)
 		Expect(err).ToNot(HaveOccurred())
 	})
 
diff --git a/test/e2e/tracing/tracing_universal_test.go b/test/e2e/tracing/tracing_universal_test.go
index b9c5ddfbf..8223a2502 100644
--- a/test/e2e/tracing/tracing_universal_test.go
+++ b/test/e2e/tracing/tracing_universal_test.go
@@ -59,9 +59,9 @@ selectors:
 		demoClientToken, err := cluster.GetKuma().GenerateDpToken("default", "demo-client")
 		Expect(err).ToNot(HaveOccurred())
 
-		err = EchoServerUniversal("universal", "default", echoServerToken)(cluster)
+		err = EchoServerUniversal(AppModeEchoServer, "default", "universal", echoServerToken)(cluster)
 		Expect(err).ToNot(HaveOccurred())
-		err = DemoClientUniversal("default", demoClientToken)(cluster)
+		err = DemoClientUniversal(AppModeDemoClient, "default", demoClientToken)(cluster)
 		Expect(err).ToNot(HaveOccurred())
 	})
 
diff --git a/test/framework/interface.go b/test/framework/interface.go
index 9ae7e9b17..349eb0a25 100644
--- a/test/framework/interface.go
+++ b/test/framework/interface.go
@@ -39,14 +39,35 @@ type deployOptions struct {
 	// app specific
 	namespace   string
 	appname     string
-	id          string
+	name        string
+	appYaml     string
+	appArgs     []string
 	token       string
 	transparent bool
+	protocol    string
 	mesh        string
 }
 
 type DeployOptionsFunc func(*deployOptions)
 
+func WithYaml(appYaml string) DeployOptionsFunc {
+	return func(o *deployOptions) {
+		o.appYaml = appYaml
+	}
+}
+
+func WithProtocol(protocol string) DeployOptionsFunc {
+	return func(o *deployOptions) {
+		o.protocol = protocol
+	}
+}
+
+func WithArgs(appArgs []string) DeployOptionsFunc {
+	return func(o *deployOptions) {
+		o.appArgs = appArgs
+	}
+}
+
 func ProxyOnly() DeployOptionsFunc {
 	return func(o *deployOptions) {
 		o.proxyOnly = true
@@ -163,9 +184,9 @@ func WithAppname(appname string) DeployOptionsFunc {
 	}
 }
 
-func WithId(id string) DeployOptionsFunc {
+func WithName(name string) DeployOptionsFunc {
 	return func(o *deployOptions) {
-		o.id = id
+		o.name = name
 	}
 }
 
diff --git a/test/framework/setup.go b/test/framework/setup.go
index a55b4eb71..4b44b7cec 100644
--- a/test/framework/setup.go
+++ b/test/framework/setup.go
@@ -245,9 +245,23 @@ spec:
 	)
 }
 
-func EchoServerUniversal(id, mesh, token string, fs ...DeployOptionsFunc) InstallFunc {
+func EchoServerUniversal(name, mesh, echo, token string, fs ...DeployOptionsFunc) InstallFunc {
 	return func(cluster Cluster) error {
-		fs = append(fs, WithMesh(mesh), WithAppname(AppModeEchoServer), WithId(id), WithToken(token))
+		opts := newDeployOpt(fs...)
+		args := []string{"ncat", "-lk", "-p", "80", "--sh-exec", "'echo \"HTTP/1.1 200 OK\n\n Echo " + echo + "\n\"'"}
+		appYaml := ""
+		if opts.protocol == "" {
+			opts.protocol = "http"
+		}
+		switch {
+		case opts.transparent:
+			appYaml = fmt.Sprintf(EchoServerDataplaneTransparentProxy, mesh, "8080", "80", "8080", redirectPortInbound, redirectPortOutbound)
+		case opts.serviceProbe:
+			appYaml = fmt.Sprintf(EchoServerDataplaneWithServiceProbe, mesh, "8080", "80", "8080", opts.protocol)
+		default:
+			appYaml = fmt.Sprintf(EchoServerDataplane, mesh, "8080", "80", "8080", opts.protocol)
+		}
+		fs = append(fs, WithName(name), WithMesh(mesh), WithAppname(AppModeEchoServer), WithToken(token), WithArgs(args), WithYaml(appYaml))
 		return cluster.DeployApp(fs...)
 	}
 }
@@ -255,7 +269,7 @@ func EchoServerUniversal(id, mesh, token string, fs ...DeployOptionsFunc) Instal
 func IngressUniversal(mesh, token string) InstallFunc {
 	return func(cluster Cluster) error {
 		uniCluster := cluster.(*UniversalCluster)
-		app, err := NewUniversalApp(cluster.GetTesting(), uniCluster.name, AppIngress, true, []string{})
+		app, err := NewUniversalApp(cluster.GetTesting(), uniCluster.name, AppIngress, AppIngress, true, []string{})
 		if err != nil {
 			return err
 		}
@@ -360,9 +374,21 @@ spec:
 	)
 }
 
-func DemoClientUniversal(mesh, token string, fs ...DeployOptionsFunc) InstallFunc {
+func DemoClientUniversal(name, mesh, token string, fs ...DeployOptionsFunc) InstallFunc {
 	return func(cluster Cluster) error {
-		fs = append(fs, WithMesh(mesh), WithAppname(AppModeDemoClient), WithToken(token))
+		opts := newDeployOpt(fs...)
+		args := []string{"ncat", "-lvk", "-p", "3000"}
+		appYaml := ""
+		if opts.transparent {
+			appYaml = fmt.Sprintf(DemoClientDataplaneTransparentProxy, mesh, "3000", redirectPortInbound, redirectPortOutbound)
+		} else {
+			if opts.serviceProbe {
+				appYaml = fmt.Sprintf(DemoClientDataplaneWithServiceProbe, mesh, "13000", "3000", "80", "8080")
+			} else {
+				appYaml = fmt.Sprintf(DemoClientDataplane, mesh, "13000", "3000", "80", "8080")
+			}
+		}
+		fs = append(fs, WithName(name), WithMesh(mesh), WithAppname(AppModeDemoClient), WithToken(token), WithArgs(args), WithYaml(appYaml))
 		return cluster.DeployApp(fs...)
 	}
 }
diff --git a/test/framework/universal_app.go b/test/framework/universal_app.go
index d2f0eb845..47b9c8568 100644
--- a/test/framework/universal_app.go
+++ b/test/framework/universal_app.go
@@ -53,7 +53,7 @@ networking:
     servicePort: %s
     tags:
       kuma.io/service: echo-server_kuma-test_svc_%s
-      kuma.io/protocol: http
+      kuma.io/protocol: %s
 `
 
 	EchoServerDataplaneWithServiceProbe = `
@@ -69,7 +69,7 @@ networking:
       tcp: {}
     tags:
       kuma.io/service: echo-server_kuma-test_svc_%s
-      kuma.io/protocol: http
+      kuma.io/protocol: %s
 `
 
 	EchoServerDataplaneTransparentProxy = `
@@ -183,7 +183,7 @@ type UniversalApp struct {
 	verbose      bool
 }
 
-func NewUniversalApp(t testing.TestingT, clusterName string, mode AppMode, verbose bool, caps []string) (*UniversalApp, error) {
+func NewUniversalApp(t testing.TestingT, clusterName, dpName string, mode AppMode, verbose bool, caps []string) (*UniversalApp, error) {
 	app := &UniversalApp{
 		t:            t,
 		ports:        map[string]string{},
@@ -198,7 +198,7 @@ func NewUniversalApp(t testing.TestingT, clusterName string, mode AppMode, verbo
 	}
 
 	opts := defaultDockerOptions
-	opts.OtherOptions = append(opts.OtherOptions, "--name", clusterName+"_"+string(mode))
+	opts.OtherOptions = append(opts.OtherOptions, "--name", clusterName+"_"+dpName)
 	for _, cap := range caps {
 		opts.OtherOptions = append(opts.OtherOptions, "--cap-add", cap)
 	}
@@ -302,7 +302,7 @@ func (s *UniversalApp) CreateDP(token, cpAddress, appname, ip, dpyaml string) {
 		"--cp-address=" + cpAddress,
 		"--dataplane-token-file=/kuma/token-" + appname,
 		"--dataplane-file=/kuma/dpyaml-" + appname,
-		"--dataplane-var", "name=dp-" + appname,
+		"--dataplane-var", "name=" + appname,
 		"--dataplane-var", "address=" + ip,
 		"--binary-path", "/usr/local/bin/envoy",
 	})
diff --git a/test/framework/universal_cluster.go b/test/framework/universal_cluster.go
index 9e6777418..3e9ee58a3 100644
--- a/test/framework/universal_cluster.go
+++ b/test/framework/universal_cluster.go
@@ -85,7 +85,7 @@ func (c *UniversalCluster) DeployKuma(mode string, fs ...DeployOptionsFunc) erro
 		cmd = append(cmd, "--config-file", confPath)
 	}
 
-	app, err := NewUniversalApp(c.t, c.name, AppModeCP, true, caps)
+	app, err := NewUniversalApp(c.t, c.name, AppModeCP, AppModeCP, true, caps)
 	if err != nil {
 		return err
 	}
@@ -155,29 +155,20 @@ func (c *UniversalCluster) DeployApp(fs ...DeployOptionsFunc) error {
 	opts := newDeployOpt(fs...)
 	appname := opts.appname
 	token := opts.token
-	id := opts.id
 	transparent := opts.transparent
+	dpyaml := opts.appYaml
+	args := opts.appArgs
 
 	if opts.mesh == "" {
 		opts.mesh = "default"
 	}
 
-	var args []string
-	switch appname {
-	case AppModeEchoServer:
-		args = []string{"ncat", "-lk", "-p", "80", "--sh-exec", "'echo \"HTTP/1.1 200 OK\n\n Echo " + id + "\n\"'"}
-	case AppModeDemoClient:
-		args = []string{"ncat", "-lvk", "-p", "3000"}
-	default:
-		return errors.Errorf("not supported app type %s", appname)
-	}
-
 	caps := []string{}
 	if transparent {
 		caps = append(caps, "NET_ADMIN", "NET_RAW")
 	}
 
-	app, err := NewUniversalApp(c.t, c.name, AppMode(appname), c.verbose, caps)
+	app, err := NewUniversalApp(c.t, c.name, opts.name, AppMode(appname), c.verbose, caps)
 	if err != nil {
 		return err
 	}
@@ -188,31 +179,7 @@ func (c *UniversalCluster) DeployApp(fs ...DeployOptionsFunc) error {
 
 	ip := app.ip
 
-	dpyaml := ""
-	switch appname {
-	case AppModeEchoServer:
-		if transparent {
-			dpyaml = fmt.Sprintf(EchoServerDataplaneTransparentProxy, opts.mesh, "8080", "80", "8080", redirectPortInbound, redirectPortOutbound)
-		} else {
-			if opts.serviceProbe {
-				dpyaml = fmt.Sprintf(EchoServerDataplaneWithServiceProbe, opts.mesh, "8080", "80", "8080")
-			} else {
-				dpyaml = fmt.Sprintf(EchoServerDataplane, opts.mesh, "8080", "80", "8080")
-			}
-		}
-	case AppModeDemoClient:
-		if transparent {
-			dpyaml = fmt.Sprintf(DemoClientDataplaneTransparentProxy, opts.mesh, "3000", redirectPortInbound, redirectPortOutbound)
-		} else {
-			if opts.serviceProbe {
-				dpyaml = fmt.Sprintf(DemoClientDataplaneWithServiceProbe, opts.mesh, "13000", "3000", "80", "8080")
-			} else {
-				dpyaml = fmt.Sprintf(DemoClientDataplane, opts.mesh, "13000", "3000", "80", "8080")
-			}
-		}
-	}
-
-	err = c.CreateDP(app, appname, ip, dpyaml, token)
+	err = c.CreateDP(app, opts.name, ip, dpyaml, token)
 	if err != nil {
 		return err
 	}
@@ -225,7 +192,7 @@ func (c *UniversalCluster) DeployApp(fs ...DeployOptionsFunc) error {
 		}
 	}
 
-	c.apps[appname] = app
+	c.apps[opts.name] = app
 
 	return nil
 }