Repository: kumahq/kuma
Pull request #1602 (2021-02-23 12:18:39)

feat(kuma-cp) add versions endpoint
### Summary

Added `/versions` endpoint

The versions which are present in a json file, were taken from envoys included in every release starting from `1.0.0` by looking into Dockerfile of our image containing kuma-dp (i.e. https://github.com/kumahq/kuma/blob/1.0.0/tools/releases/dockerfiles/Dockerfile.kuma-dp#L2)

ref.
* Warnings using this endpoint in GUI: https://github.com/kumahq/kuma/pull/1563

### Documentation

- [ ] Link to the website [documentation PR](https://github.com/kumahq/kuma-website/pull/XXX)



Patch:
diff --git a/app/kumactl/cmd/install/install_transparent_proxy.go b/app/kumactl/cmd/install/install_transparent_proxy.go
index dd5cd67f8..d16ef4b9f 100644
--- a/app/kumactl/cmd/install/install_transparent_proxy.go
+++ b/app/kumactl/cmd/install/install_transparent_proxy.go
@@ -19,6 +19,7 @@ type transparenProxyArgs struct {
 	DryRun               bool
 	ModifyIptables       bool
 	RedirectPortOutBound string
+	RedirectInbound      bool
 	RedirectPortInBound  string
 	ExcludeInboundPorts  string
 	ExcludeOutboundPorts string
@@ -33,6 +34,7 @@ func newInstallTransparentProxy() *cobra.Command {
 		DryRun:               false,
 		ModifyIptables:       true,
 		RedirectPortOutBound: "15001",
+		RedirectInbound:      true,
 		RedirectPortInBound:  "15006",
 		ExcludeInboundPorts:  "",
 		ExcludeOutboundPorts: "",
@@ -129,6 +131,7 @@ runuser -u kuma-dp -- \
 	cmd.Flags().BoolVar(&args.DryRun, "dry-run", args.DryRun, "dry run")
 	cmd.Flags().BoolVar(&args.ModifyIptables, "modify-iptables", args.ModifyIptables, "modify the host iptables to redirect the traffic to Envoy")
 	cmd.Flags().StringVar(&args.RedirectPortOutBound, "redirect-outbound-port", args.RedirectPortOutBound, "outbound port redirected to Envoy, as specified in dataplane's `networking.transparentProxying.redirectPortOutbound`")
+	cmd.Flags().BoolVar(&args.RedirectInbound, "redirect-inbound", args.RedirectInbound, "redirect the inbound traffic to the Envoy. Should be disabled for Gateway data plane proxies.")
 	cmd.Flags().StringVar(&args.RedirectPortInBound, "redirect-inbound-port", args.RedirectPortInBound, "inbound port redirected to Envoy, as specified in dataplane's `networking.transparentProxying.redirectPortInbound`")
 	cmd.Flags().StringVar(&args.ExcludeInboundPorts, "exclude-inbound-ports", args.ExcludeInboundPorts, "a comma separated list of inbound ports to exclude from redirect to Envoy")
 	cmd.Flags().StringVar(&args.ExcludeOutboundPorts, "exclude-outbound-ports", args.ExcludeOutboundPorts, "a comma separated list of outbound ports to exclude from redirect to Envoy")
@@ -164,6 +167,7 @@ func modifyIpTables(cmd *cobra.Command, args *transparenProxyArgs) error {
 	output, err := tp.Setup(&config.TransparentProxyConfig{
 		DryRun:               args.DryRun,
 		RedirectPortOutBound: args.RedirectPortOutBound,
+		RedirectInBound:      args.RedirectInbound,
 		RedirectPortInBound:  args.RedirectPortInBound,
 		ExcludeInboundPorts:  args.ExcludeInboundPorts,
 		ExcludeOutboundPorts: args.ExcludeOutboundPorts,
diff --git a/pkg/api-server/server.go b/pkg/api-server/server.go
index 0cb81b2e5..c70aace62 100644
--- a/pkg/api-server/server.go
+++ b/pkg/api-server/server.go
@@ -113,6 +113,8 @@ func NewApiServer(resManager manager.ResourceManager, wsManager customization.AP
 	}
 	container.Add(configWs)
 
+	container.Add(versionsWs())
+
 	zonesWs := zonesWs(resManager)
 	container.Add(zonesWs)
 
diff --git a/pkg/api-server/versions_ws.go b/pkg/api-server/versions_ws.go
new file mode 100644
index 000000000..603550655
--- /dev/null
+++ b/pkg/api-server/versions_ws.go
@@ -0,0 +1,50 @@
+package api_server
+
+import (
+	"github.com/emicklei/go-restful"
+)
+
+var versions = []byte(`{
+  "kumaDp": {
+    "1.0.0": {
+      "envoy": "1.16.0"
+    },
+    "1.0.1": {
+      "envoy": "1.16.0"
+    },
+    "1.0.2": {
+      "envoy": "1.16.1"
+    },
+    "1.0.3": {
+      "envoy": "1.16.1"
+    },
+    "1.0.4": {
+      "envoy": "1.16.1"
+    },
+    "1.0.5": {
+      "envoy": "1.16.2"
+    },
+    "1.0.6": {
+      "envoy": "1.16.2"
+    },
+    "1.0.7": {
+      "envoy": "1.16.2"
+    },
+    "1.0.8": {
+      "envoy": "1.16.2"
+    }
+  }
+}`)
+
+func versionsWs() *restful.WebService {
+	ws := new(restful.WebService).Path("/versions")
+
+	ws.Route(ws.GET("").To(func(req *restful.Request, resp *restful.Response) {
+		resp.AddHeader("content-type", "application/json")
+		if _, err := resp.Write(versions); err != nil {
+			log.Error(err, "Could not write the index response")
+		}
+	}))
+
+	return ws
+}
diff --git a/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml b/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
index ddb1407be..0824970e5 100644
--- a/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
+++ b/pkg/config/app/kuma-cp/kuma-cp.defaults.yaml
@@ -100,6 +100,8 @@ xdsServer:
   dataplaneConfigurationRefreshInterval: 1s # ENV: KUMA_XDS_SERVER_DATAPLANE_CONFIGURATION_REFRESH_INTERVAL
   # Interval for flushing status of Dataplanes connected to the Control Plane
   dataplaneStatusFlushInterval: 10s # ENV: KUMA_XDS_SERVER_DATAPLANE_STATUS_FLUSH_INTERVAL
+  # Backoff that is executed when Control Plane is sending the response that was previously rejected by Dataplane
+  nackBackoff: 5s # ENV: KUMA_XDS_SERVER_NACK_BACKOFF
 
 # API Server configuration
 apiServer:
diff --git a/pkg/config/xds/config.go b/pkg/config/xds/config.go
index 01bb78dda..51f8a7df5 100644
--- a/pkg/config/xds/config.go
+++ b/pkg/config/xds/config.go
@@ -16,6 +16,8 @@ type XdsServerConfig struct {
 	DataplaneConfigurationRefreshInterval time.Duration `yaml:"dataplaneConfigurationRefreshInterval" envconfig:"kuma_xds_server_dataplane_configuration_refresh_interval"`
 	// Interval for flushing status of Dataplanes connected to the Control Plane
 	DataplaneStatusFlushInterval time.Duration `yaml:"dataplaneStatusFlushInterval" envconfig:"kuma_xds_server_dataplane_status_flush_interval"`
+	// Backoff that is executed when Control Plane is sending the response that was previously rejected by Dataplane
+	NACKBackoff time.Duration `yaml:"nackBackoff" envconfig:"kuma_xds_server_nack_backoff"`
 }
 
 func (x *XdsServerConfig) Sanitize() {
@@ -35,5 +37,6 @@ func DefaultXdsServerConfig() *XdsServerConfig {
 	return &XdsServerConfig{
 		DataplaneConfigurationRefreshInterval: 1 * time.Second,
 		DataplaneStatusFlushInterval:          10 * time.Second,
+		NACKBackoff:                           5 * time.Second,
 	}
 }
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/injector.go b/pkg/plugins/runtime/k8s/webhooks/injector/injector.go
index e69c9d27f..5b1cc33b1 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/injector.go
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/injector.go
@@ -382,13 +382,13 @@ func (i *KumaInjector) FindServiceAccountToken(pod *kube_core.Pod) *kube_core.Vo
 }
 
 func (i *KumaInjector) NewInitContainer(pod *kube_core.Pod) (kube_core.Container, error) {
-	inboundPortsToIntercept := "*"
+	redirectInbound := "true"
 	enabled, exist, err := metadata.Annotations(pod.Annotations).GetEnabled(metadata.KumaGatewayAnnotation)
 	if err != nil {
 		return kube_core.Container{}, err
 	}
 	if exist && enabled {
-		inboundPortsToIntercept = ""
+		redirectInbound = "false"
 	}
 	excludeInboundPorts, _ := metadata.Annotations(pod.Annotations).GetString(metadata.KumaTrafficExcludeInboundPorts)
 	excludeOutboundPorts, _ := metadata.Annotations(pod.Annotations).GetString(metadata.KumaTrafficExcludeOutboundPorts)
@@ -396,25 +396,20 @@ func (i *KumaInjector) NewInitContainer(pod *kube_core.Pod) (kube_core.Container
 		Name:            util.KumaInitContainerName,
 		Image:           i.cfg.InitContainer.Image,
 		ImagePullPolicy: kube_core.PullIfNotPresent,
+		Command:         []string{"/usr/bin/kumactl", "install", "transparent-proxy"},
 		Args: []string{
-			"-p",
+			"--redirect-outbound-port",
 			fmt.Sprintf("%d", i.cfg.SidecarContainer.RedirectPortOutbound),
-			"-z",
+			"--redirect-inbound=" + redirectInbound,
+			"--redirect-inbound-port",
 			fmt.Sprintf("%d", i.cfg.SidecarContainer.RedirectPortInbound),
-			"-u",
+			"--kuma-dp-uid",
 			fmt.Sprintf("%d", i.cfg.SidecarContainer.UID),
-			"-g",
-			fmt.Sprintf("%d", i.cfg.SidecarContainer.GID),
-			"-d",
+			"--exclude-inbound-ports",
 			excludeInboundPorts,
-			"-o",
+			"--exclude-outbound-ports",
 			excludeOutboundPorts,
-			"-m",
-			"REDIRECT",
-			"-i",
-			"*",
-			"-b",
-			inboundPortsToIntercept,
+			"--modify-resolv-conf=false",
 		},
 		SecurityContext: &kube_core.SecurityContext{
 			RunAsUser:  new(int64), // way to get pointer to int64(0)
diff --git a/pkg/transparentproxy/config/config.go b/pkg/transparentproxy/config/config.go
index 1b44df02b..cdf5832e1 100644
--- a/pkg/transparentproxy/config/config.go
+++ b/pkg/transparentproxy/config/config.go
@@ -3,6 +3,7 @@ package config
 type TransparentProxyConfig struct {
 	DryRun               bool
 	RedirectPortOutBound string
+	RedirectInBound      bool
 	RedirectPortInBound  string
 	ExcludeInboundPorts  string
 	ExcludeOutboundPorts string
diff --git a/pkg/transparentproxy/istio/istio.go b/pkg/transparentproxy/istio/istio.go
index f6a97afa5..fb5e947e6 100644
--- a/pkg/transparentproxy/istio/istio.go
+++ b/pkg/transparentproxy/istio/istio.go
@@ -29,7 +29,9 @@ func (tp *IstioTransparentProxy) Setup(cfg *config.TransparentProxyConfig) (stri
 	viper.Set(constants.ProxyUID, cfg.UID)
 	viper.Set(constants.ProxyGID, cfg.GID)
 	viper.Set(constants.InboundInterceptionMode, "REDIRECT")
-	viper.Set(constants.InboundPorts, "*")
+	if cfg.RedirectInBound {
+		viper.Set(constants.InboundPorts, "*")
+	}
 	viper.Set(constants.LocalExcludePorts, cfg.ExcludeInboundPorts)
 	viper.Set(constants.ServiceCidr, "*")
 	viper.Set(constants.LocalOutboundPortsExclude, cfg.ExcludeOutboundPorts)
diff --git a/pkg/util/xds/callbacks.go b/pkg/util/xds/callbacks.go
index e44b7d051..008b5de39 100644
--- a/pkg/util/xds/callbacks.go
+++ b/pkg/util/xds/callbacks.go
@@ -13,6 +13,7 @@ type DiscoveryRequest interface {
 	GetTypeUrl() string
 	GetResponseNonce() string
 	HasErrors() bool
+	ErrorMsg() string
 }
 
 // DiscoveryResponse defines interface over real Envoy's DiscoveryResponse.
diff --git a/pkg/util/xds/v2/callbacks.go b/pkg/util/xds/v2/callbacks.go
index b5df09349..8570ec138 100644
--- a/pkg/util/xds/v2/callbacks.go
+++ b/pkg/util/xds/v2/callbacks.go
@@ -64,6 +64,10 @@ func (d *discoveryRequest) HasErrors() bool {
 	return d.ErrorDetail != nil
 }
 
+func (d *discoveryRequest) ErrorMsg() string {
+	return d.GetErrorDetail().GetMessage()
+}
+
 func (d *discoveryRequest) Proto() proto.Message {
 	return d
 }
diff --git a/pkg/util/xds/v3/callbacks.go b/pkg/util/xds/v3/callbacks.go
index 98cf894e1..b1575d1a3 100644
--- a/pkg/util/xds/v3/callbacks.go
+++ b/pkg/util/xds/v3/callbacks.go
@@ -63,6 +63,10 @@ func (d *discoveryRequest) HasErrors() bool {
 	return d.ErrorDetail != nil
 }
 
+func (d *discoveryRequest) ErrorMsg() string {
+	return d.GetErrorDetail().GetMessage()
+}
+
 var _ xds.DiscoveryRequest = &discoveryRequest{}
 
 type discoveryResponse struct {
diff --git a/pkg/xds/server/callbacks/nack_backoff.go b/pkg/xds/server/callbacks/nack_backoff.go
new file mode 100644
index 000000000..b5236da81
--- /dev/null
+++ b/pkg/xds/server/callbacks/nack_backoff.go
@@ -0,0 +1,40 @@
+package callbacks
+
+import (
+	"time"
+
+	"github.com/kumahq/kuma/pkg/core"
+	util_xds "github.com/kumahq/kuma/pkg/util/xds"
+)
+
+var nackLog = core.Log.WithName("xds").WithName("nack-backoff")
+
+type nackBackoff struct {
+	backoff time.Duration
+	util_xds.NoopCallbacks
+}
+
+var _ util_xds.Callbacks = &nackBackoff{}
+
+func NewNackBackoff(backoff time.Duration) util_xds.Callbacks {
+	return &nackBackoff{
+		backoff: backoff,
+	}
+}
+
+func (n *nackBackoff) OnStreamResponse(_ int64, request util_xds.DiscoveryRequest, _ util_xds.DiscoveryResponse) {
+	if request.HasErrors() {
+		// When DiscoveryRequest contains errors, it means that Envoy rejected configuration generated by Control Plane
+		// It may happen for several reasons:
+		// 1) Eventual consistency - ex. listener consists reference to cluster which does not exist because listener was send before cluster (there is no ordering of responses)
+		// 2) Config is valid from CP side but invalid from Envoy side - ex. something already listening at this address:port
+		//
+		// Second case is especially dangerous because we will end up in a loop.
+		// CP is constantly trying to send a config and Envoy immediately rejects the config.
+		// Without this backoff, CP is under a lot of pressure from faulty Envoy.
+		//
+		// It is safe to sleep here because OnStreamResponse is executed in the goroutine of a single ADS stream
+		nackLog.Info("config was previously rejected by Envoy. Applying backoff before resending it", "backoff", n.backoff, "nodeID", request.NodeId(), "reason", request.ErrorMsg())
+		time.Sleep(n.backoff)
+	}
+}
diff --git a/pkg/xds/server/v2/components.go b/pkg/xds/server/v2/components.go
index 898cc8bf4..bab1af939 100644
--- a/pkg/xds/server/v2/components.go
+++ b/pkg/xds/server/v2/components.go
@@ -58,6 +58,7 @@ func RegisterXDS(
 		util_xds_v2.AdaptCallbacks(metadataTracker),
 		util_xds_v2.AdaptCallbacks(xds_callbacks.NewDataplaneLifecycle(rt.ResourceManager())),
 		util_xds_v2.AdaptCallbacks(DefaultDataplaneStatusTracker(rt)),
+		util_xds_v2.AdaptCallbacks(xds_callbacks.NewNackBackoff(rt.Config().XdsServer.NACKBackoff)),
 		newResourceWarmingForcer(xdsContext.Cache(), xdsContext.Hasher()),
 	}
 
diff --git a/pkg/xds/server/v3/components.go b/pkg/xds/server/v3/components.go
index 25293acfd..ee0795ef1 100644
--- a/pkg/xds/server/v3/components.go
+++ b/pkg/xds/server/v3/components.go
@@ -58,6 +58,7 @@ func RegisterXDS(
 		util_xds_v3.AdaptCallbacks(metadataTracker),
 		util_xds_v3.AdaptCallbacks(xds_callbacks.NewDataplaneLifecycle(rt.ResourceManager())),
 		util_xds_v3.AdaptCallbacks(DefaultDataplaneStatusTracker(rt)),
+		util_xds_v3.AdaptCallbacks(xds_callbacks.NewNackBackoff(rt.Config().XdsServer.NACKBackoff)),
 		newResourceWarmingForcer(xdsContext.Cache(), xdsContext.Hasher()),
 	}
 
diff --git a/tools/releases/dockerfiles/Dockerfile.kuma-init b/tools/releases/dockerfiles/Dockerfile.kuma-init
index 81449af5e..cd9639631 100644
--- a/tools/releases/dockerfiles/Dockerfile.kuma-init
+++ b/tools/releases/dockerfiles/Dockerfile.kuma-init
@@ -1,29 +1,16 @@
-FROM ubuntu:bionic as builder
+FROM ubuntu:focal
 
-ENV GOVERSION 1.15.6
-ENV GOROOT /opt/go
-ENV GOPATH /root/.go
+RUN apt-get update && \
+    apt-get -y install iptables && \
+    rm -rf /var/lib/apt/lists/*
 
-RUN apt-get update
-RUN apt-get -y install wget
-
-RUN cd /opt && wget https://storage.googleapis.com/golang/go${GOVERSION}.linux-amd64.tar.gz && \
-    tar zxf go${GOVERSION}.linux-amd64.tar.gz && rm go${GOVERSION}.linux-amd64.tar.gz && \
-    ln -s /opt/go/bin/go /usr/bin/ && \
-    mkdir $GOPATH
-
-RUN GO111MODULE=on go get istio.io/istio/tools/istio-iptables@1.7.6
-
-FROM ubuntu:bionic
-
-COPY --from=builder /root/.go/bin/istio-iptables ./kuma-iptables
-
-RUN apt-get update
-RUN apt-get -y install iptables
+ADD $KUMA_ROOT/build/artifacts-linux-amd64/kumactl/kumactl /usr/bin
 
 RUN mkdir /kuma
 COPY $KUMA_ROOT/tools/releases/templates/LICENSE /kuma
-COPY $KUMA_ROOT/tools/releases/templates/NOTICE-kuma-init /kuma/NOTICE
+COPY $KUMA_ROOT/tools/releases/templates/NOTICE-kumactl /kuma/NOTICE
 COPY $KUMA_ROOT/tools/releases/templates/README /kuma
 
-ENTRYPOINT ["./kuma-iptables"]
+RUN adduser --system --disabled-password --group kumactl --uid 5678
+
+ENTRYPOINT ["/usr/bin/kumactl", "install", "transparent-proxy"]
diff --git a/tools/releases/dockerfiles/Dockerfile.kuma-init.dockerignore b/tools/releases/dockerfiles/Dockerfile.kuma-init.dockerignore
index 5138cc66c..3292b6ace 100644
--- a/tools/releases/dockerfiles/Dockerfile.kuma-init.dockerignore
+++ b/tools/releases/dockerfiles/Dockerfile.kuma-init.dockerignore
@@ -1,4 +1,5 @@
 *
+!build/artifacts-linux-amd64/kumactl/kumactl
 !tools/releases/templates/LICENSE
-!tools/releases/templates/NOTICE-kuma-init
+!tools/releases/templates/NOTICE-kumactl
 !tools/releases/templates/README
diff --git a/tools/releases/dockerfiles/Dockerfile.kumactl b/tools/releases/dockerfiles/Dockerfile.kumactl
index a86938738..820aa6da8 100644
--- a/tools/releases/dockerfiles/Dockerfile.kumactl
+++ b/tools/releases/dockerfiles/Dockerfile.kumactl
@@ -6,7 +6,7 @@ ADD $KUMA_ROOT/build/artifacts-linux-amd64/kumactl/kumactl /usr/bin
 
 RUN mkdir /kuma
 COPY $KUMA_ROOT/tools/releases/templates/LICENSE /kuma
-COPY $KUMA_ROOT/tools/releases/templates/NOTICE /kuma
+COPY $KUMA_ROOT/tools/releases/templates/NOTICE-kumactl /kuma/NOTICE
 COPY $KUMA_ROOT/tools/releases/templates/README /kuma
 
 RUN addgroup -S -g 6789 kumactl \
diff --git a/tools/releases/dockerfiles/Dockerfile.kumactl.dockerignore b/tools/releases/dockerfiles/Dockerfile.kumactl.dockerignore
index a99efe164..c1ffc8fa2 100644
--- a/tools/releases/dockerfiles/Dockerfile.kumactl.dockerignore
+++ b/tools/releases/dockerfiles/Dockerfile.kumactl.dockerignore
@@ -1,6 +1,6 @@
 *
 !build/artifacts-linux-amd64/kumactl/kumactl
 !tools/releases/templates/LICENSE
-!tools/releases/templates/NOTICE
+!tools/releases/templates/NOTICE-kumactl
 !tools/releases/templates/README
 !tools/releases/templates/install_missing_crds.sh
diff --git a/tools/releases/templates/NOTICE b/tools/releases/templates/NOTICE
index 102565087..653637ff2 100644
--- a/tools/releases/templates/NOTICE
+++ b/tools/releases/templates/NOTICE
@@ -1,4 +1,4 @@
 Kuma
-Copyright 2019 Kong Inc.
+Copyright 2019-2021 Kong Inc.
 
-This product includes software developed at Kong Inc (https://konghq.com/).
\ No newline at end of file
+This product includes software developed at Kong Inc (https://konghq.com/).
diff --git a/tools/releases/templates/NOTICE-kuma-init b/tools/releases/templates/NOTICE-kumactl
similarity index 79%
rename from tools/releases/templates/NOTICE-kuma-init
rename to tools/releases/templates/NOTICE-kumactl
index f6cd16edf..8ef17a376 100644
--- a/tools/releases/templates/NOTICE-kuma-init
+++ b/tools/releases/templates/NOTICE-kumactl
@@ -1,5 +1,5 @@
 Kuma
-Copyright 2019 Kong Inc.
+Copyright 2019-2021 Kong Inc.
 
 This product includes software developed at Kong Inc (https://konghq.com/).
-This product includes software developed by Istio (https://istio.io/).
\ No newline at end of file
+This product includes software developed by Istio (https://istio.io/).


Test patch:
diff --git a/app/kumactl/cmd/completion/testdata/bash.golden b/app/kumactl/cmd/completion/testdata/bash.golden
index 728a48d67..73c1c6d6f 100644
--- a/app/kumactl/cmd/completion/testdata/bash.golden
+++ b/app/kumactl/cmd/completion/testdata/bash.golden
@@ -2334,6 +2334,8 @@ _kumactl_install_transparent-proxy()
     local_nonpersistent_flags+=("--modify-iptables")
     flags+=("--modify-resolv-conf")
     local_nonpersistent_flags+=("--modify-resolv-conf")
+    flags+=("--redirect-inbound")
+    local_nonpersistent_flags+=("--redirect-inbound")
     flags+=("--redirect-inbound-port=")
     two_word_flags+=("--redirect-inbound-port")
     local_nonpersistent_flags+=("--redirect-inbound-port=")
diff --git a/app/kumactl/cmd/completion/testdata/zsh.golden b/app/kumactl/cmd/completion/testdata/zsh.golden
index 5becf85e4..87f7da2d9 100644
--- a/app/kumactl/cmd/completion/testdata/zsh.golden
+++ b/app/kumactl/cmd/completion/testdata/zsh.golden
@@ -951,6 +951,7 @@ function _kumactl_install_transparent-proxy {
     '--kuma-dp-user[the user that will run kuma-dp]:' \
     '--modify-iptables[modify the host iptables to redirect the traffic to Envoy]' \
     '--modify-resolv-conf[modify the host `/etc/resolv.conf` to allow `.mesh` resolution through kuma-cp]' \
+    '--redirect-inbound[redirect the inbound traffic to the Envoy. Should be disabled for Gateway data plane proxies.]' \
     '--redirect-inbound-port[inbound port redirected to Envoy, as specified in dataplane'\''s `networking.transparentProxying.redirectPortInbound`]:' \
     '--redirect-outbound-port[outbound port redirected to Envoy, as specified in dataplane'\''s `networking.transparentProxying.redirectPortOutbound`]:' \
     '--config-file[path to the configuration file to use]:' \
diff --git a/pkg/api-server/config_ws_test.go b/pkg/api-server/config_ws_test.go
index f71e41740..43d93b530 100644
--- a/pkg/api-server/config_ws_test.go
+++ b/pkg/api-server/config_ws_test.go
@@ -267,7 +267,8 @@ var _ = Describe("Config WS", func() {
           },
           "xdsServer": {
             "dataplaneConfigurationRefreshInterval": "1s",
-            "dataplaneStatusFlushInterval": "10s"
+            "dataplaneStatusFlushInterval": "10s",
+            "nackBackoff": "5s"
           },
           "diagnostics": {
             "serverPort": 5680,
diff --git a/pkg/api-server/versions_ws_test.go b/pkg/api-server/versions_ws_test.go
new file mode 100644
index 000000000..9450c2bc9
--- /dev/null
+++ b/pkg/api-server/versions_ws_test.go
@@ -0,0 +1,104 @@
+package api_server_test
+
+import (
+	"encoding/json"
+	"fmt"
+	"net/http"
+
+	. "github.com/onsi/ginkgo"
+	. "github.com/onsi/gomega"
+
+	config "github.com/kumahq/kuma/pkg/config/api-server"
+	"github.com/kumahq/kuma/pkg/metrics"
+	"github.com/kumahq/kuma/pkg/plugins/resources/memory"
+)
+
+var _ = Describe("Versions WS", func() {
+	It("should return the supported versions", func() {
+		// setup
+		resourceStore := memory.NewStore()
+		metrics, err := metrics.NewMetrics("Standalone")
+		Expect(err).ToNot(HaveOccurred())
+		apiServer := createTestApiServer(resourceStore, config.DefaultApiServerConfig(), true, metrics)
+
+		stop := make(chan struct{})
+		go func() {
+			defer GinkgoRecover()
+			err := apiServer.Start(stop)
+			Expect(err).ToNot(HaveOccurred())
+		}()
+
+		// wait for the server
+		Eventually(func() error {
+			_, err := http.Get(fmt.Sprintf("http://%s/versions", apiServer.Address()))
+			return err
+		}, "3s").ShouldNot(HaveOccurred())
+
+		// when
+		resp, err := http.Get(fmt.Sprintf("http://%s/versions", apiServer.Address()))
+		Expect(err).ToNot(HaveOccurred())
+
+		// then
+		var data struct {
+			KumaDp map[string]struct {
+				Envoy string
+			}
+		}
+
+		Expect(json.NewDecoder(resp.Body).Decode(&data)).ToNot(HaveOccurred())
+
+		// 1.0.0
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.0"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.0"].Envoy).To(Equal("1.16.0"))
+
+		// 1.0.1
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.1"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.1"].Envoy).To(Equal("1.16.0"))
+
+		// 1.0.2
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.2"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.2"].Envoy).To(Equal("1.16.1"))
+
+		// 1.0.3
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.3"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.3"].Envoy).To(Equal("1.16.1"))
+
+		// 1.0.4
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.4"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.4"].Envoy).To(Equal("1.16.1"))
+
+		// 1.0.5
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.5"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.5"].Envoy).To(Equal("1.16.2"))
+
+		// 1.0.6
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.6"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.6"].Envoy).To(Equal("1.16.2"))
+
+		// 1.0.7
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.7"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.7"].Envoy).To(Equal("1.16.2"))
+
+		// 1.0.8
+		Expect(data).ToNot(BeNil())
+		Expect(data.KumaDp).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.8"]).ToNot(BeNil())
+		Expect(data.KumaDp["1.0.8"].Envoy).To(Equal("1.16.2"))
+	})
+})
diff --git a/pkg/config/loader_test.go b/pkg/config/loader_test.go
index 883a300e3..bd90588dc 100644
--- a/pkg/config/loader_test.go
+++ b/pkg/config/loader_test.go
@@ -205,6 +205,7 @@ var _ = Describe("Config loader", func() {
 
 			Expect(cfg.XdsServer.DataplaneStatusFlushInterval).To(Equal(7 * time.Second))
 			Expect(cfg.XdsServer.DataplaneConfigurationRefreshInterval).To(Equal(21 * time.Second))
+			Expect(cfg.XdsServer.NACKBackoff).To(Equal(10 * time.Second))
 
 			Expect(cfg.Metrics.Zone.Enabled).To(BeFalse())
 			Expect(cfg.Metrics.Zone.SubscriptionLimit).To(Equal(23))
@@ -383,6 +384,7 @@ diagnostics:
 xdsServer:
   dataplaneConfigurationRefreshInterval: 21s
   dataplaneStatusFlushInterval: 7s
+  nackBackoff: 10s
 metrics:
   zone:
     enabled: false
@@ -516,6 +518,7 @@ sdsServer:
 				"KUMA_DIAGNOSTICS_DEBUG_ENDPOINTS":                                                         "true",
 				"KUMA_XDS_SERVER_DATAPLANE_STATUS_FLUSH_INTERVAL":                                          "7s",
 				"KUMA_XDS_SERVER_DATAPLANE_CONFIGURATION_REFRESH_INTERVAL":                                 "21s",
+				"KUMA_XDS_SERVER_NACK_BACKOFF":                                                             "10s",
 				"KUMA_METRICS_ZONE_ENABLED":                                                                "false",
 				"KUMA_METRICS_ZONE_SUBSCRIPTION_LIMIT":                                                     "23",
 				"KUMA_METRICS_MESH_MAX_RESYNC_TIMEOUT":                                                     "27s",
diff --git a/pkg/config/xds/config_test.go b/pkg/config/xds/config_test.go
index 3fbc49ea4..1acc1cb22 100644
--- a/pkg/config/xds/config_test.go
+++ b/pkg/config/xds/config_test.go
@@ -1,7 +1,6 @@
 package xds_test
 
 import (
-	"io/ioutil"
 	"os"
 	"path/filepath"
 	"strings"
@@ -12,6 +11,7 @@ import (
 
 	"github.com/kumahq/kuma/pkg/config"
 	kuma_xds "github.com/kumahq/kuma/pkg/config/xds"
+	. "github.com/kumahq/kuma/pkg/test/matchers"
 )
 
 var _ = Describe("XdsServerConfig", func() {
@@ -77,15 +77,10 @@ var _ = Describe("XdsServerConfig", func() {
 
 		// when
 		actual, err := config.ToYAML(cfg)
-		// then
-		Expect(err).ToNot(HaveOccurred())
 
-		// when
-		expected, err := ioutil.ReadFile(filepath.Join("testdata", "default-config.golden.yaml"))
 		// then
 		Expect(err).ToNot(HaveOccurred())
-		// and
-		Expect(actual).To(MatchYAML(expected))
+		Expect(actual).To(MatchGoldenYAML(filepath.Join("testdata", "default-config.golden.yaml")))
 	})
 
 	It("should have validators", func() {
diff --git a/pkg/config/xds/testdata/default-config.golden.yaml b/pkg/config/xds/testdata/default-config.golden.yaml
index e298a3ca5..1b15fc9ad 100644
--- a/pkg/config/xds/testdata/default-config.golden.yaml
+++ b/pkg/config/xds/testdata/default-config.golden.yaml
@@ -1,2 +1,3 @@
 dataplaneConfigurationRefreshInterval: 1s
 dataplaneStatusFlushInterval: 10s
+nackBackoff: 5s
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.01.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.01.golden.yaml
index f3e293a3d..e5ee29edc 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.01.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.01.golden.yaml
@@ -111,24 +111,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.02.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.02.golden.yaml
index b19fad120..d833b0a15 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.02.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.02.golden.yaml
@@ -119,24 +119,22 @@ spec:
     name: init
     resources: {}
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.03.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.03.golden.yaml
index ad44291ac..b8c9feae1 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.03.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.03.golden.yaml
@@ -173,24 +173,22 @@ spec:
   enableServiceLinks: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.04.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.04.golden.yaml
index bcc2f4504..69177af52 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.04.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.04.golden.yaml
@@ -111,24 +111,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.05.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.05.golden.yaml
index efa35e8dd..cd2f60553 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.05.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.05.golden.yaml
@@ -104,24 +104,22 @@ spec:
       runAsUser: 5678
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.06.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.06.golden.yaml
index 85bf44f7f..25af3bd26 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.06.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.06.golden.yaml
@@ -112,24 +112,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=false
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
-    - ""
-    - -o
+    - --exclude-inbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
+    - --exclude-outbound-ports
     - ""
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.07.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.07.golden.yaml
index f3e293a3d..e5ee29edc 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.07.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.07.golden.yaml
@@ -111,24 +111,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.08.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.08.golden.yaml
index f199a5408..12fd7deb7 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.08.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.08.golden.yaml
@@ -114,24 +114,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.09.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.09.golden.yaml
index 54b41fc7c..fa19a11ef 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.09.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.09.golden.yaml
@@ -113,24 +113,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.11.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.11.golden.yaml
index 060794ffb..2ee79fc08 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.11.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.11.golden.yaml
@@ -112,24 +112,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.12.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.12.golden.yaml
index daecf689e..facaf6175 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.12.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.12.golden.yaml
@@ -111,24 +111,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.13.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.13.golden.yaml
index 34ef1b5d5..240de1648 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.13.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.13.golden.yaml
@@ -111,24 +111,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.14.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.14.golden.yaml
index a8936b581..a62283e3c 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.14.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.14.golden.yaml
@@ -123,24 +123,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.15.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.15.golden.yaml
index 79e4491fa..75b808ac6 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.15.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.15.golden.yaml
@@ -123,24 +123,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.16.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.16.golden.yaml
index f379a86f2..d27a12929 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.16.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.16.golden.yaml
@@ -123,24 +123,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.17.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.17.golden.yaml
index ce6640331..9644fd1be 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.17.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.17.golden.yaml
@@ -120,24 +120,22 @@ spec:
     name: init
     resources: {}
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - 1234,1235
-    - -o
+    - --exclude-outbound-ports
     - "1236"
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.18.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.18.golden.yaml
index c605e87d1..cceba40a9 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.18.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.18.golden.yaml
@@ -120,24 +120,22 @@ spec:
     name: init
     resources: {}
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - 1234,5678
-    - -o
+    - --exclude-outbound-ports
     - 4321,7654
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.19.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.19.golden.yaml
index 96c4158a3..d0d229ba6 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.19.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.19.golden.yaml
@@ -120,24 +120,22 @@ spec:
     name: init
     resources: {}
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.21.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.21.golden.yaml
index f379a86f2..d27a12929 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.21.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.21.golden.yaml
@@ -123,24 +123,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.22.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.22.golden.yaml
index a8936b581..a62283e3c 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.22.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.22.golden.yaml
@@ -123,24 +123,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.23.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.23.golden.yaml
index 5d2510938..74f4882df 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.23.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.23.golden.yaml
@@ -128,24 +128,22 @@ spec:
       readOnly: true
   initContainers:
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.24.golden.yaml b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.24.golden.yaml
index 248577f39..0c189cdff 100644
--- a/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.24.golden.yaml
+++ b/pkg/plugins/runtime/k8s/webhooks/injector/testdata/inject.24.golden.yaml
@@ -124,24 +124,22 @@ spec:
     name: init
     resources: {}
   - args:
-    - -p
+    - --redirect-outbound-port
     - "15001"
-    - -z
+    - --redirect-inbound=true
+    - --redirect-inbound-port
     - "15006"
-    - -u
+    - --kuma-dp-uid
     - "5678"
-    - -g
-    - "5678"
-    - -d
+    - --exclude-inbound-ports
     - ""
-    - -o
+    - --exclude-outbound-ports
     - ""
-    - -m
-    - REDIRECT
-    - -i
-    - '*'
-    - -b
-    - '*'
+    - --modify-resolv-conf=false
+    command:
+    - /usr/bin/kumactl
+    - install
+    - transparent-proxy
     image: kuma/kuma-init:latest
     imagePullPolicy: IfNotPresent
     name: kuma-init
diff --git a/test/dockerfiles/Dockerfile.universal b/test/dockerfiles/Dockerfile.universal
index 3982df3e5..707e83ed9 100644
--- a/test/dockerfiles/Dockerfile.universal
+++ b/test/dockerfiles/Dockerfile.universal
@@ -1,7 +1,7 @@
 # using Envoy's base to copy the Envoy binary
 FROM envoyproxy/envoy-alpine:v1.17.0 as envoy
 
-FROM ubuntu:bionic as builder
+FROM ubuntu:focal as builder
 
 ENV GOVERSION 1.15.6
 ENV GOROOT /opt/go