From f87a6a8beff91701348ff305a5215417ec62cde6 Mon Sep 17 00:00:00 2001 From: Kyle Schochenmaier Date: Thu, 18 Feb 2021 15:40:48 -0600 Subject: [PATCH] Split the init container into two init containers. One will cp the consul bin and the other will retain all of the existing behaviours Co-authored-by: Iryna Shustava --- connect-inject/container_init.go | 32 ++++++++++++++++++------- connect-inject/container_init_test.go | 34 +++++++++++---------------- connect-inject/handler.go | 7 ++++-- connect-inject/handler_test.go | 20 ++++++++++++++++ 4 files changed, 63 insertions(+), 30 deletions(-) diff --git a/connect-inject/container_init.go b/connect-inject/container_init.go index 044e92ff9c..3539c692eb 100644 --- a/connect-inject/container_init.go +++ b/connect-inject/container_init.go @@ -12,9 +12,10 @@ import ( ) const ( - InjectInitContainerName = "consul-connect-inject-init" - MetaKeyPodName = "pod-name" - MetaKeyKubeNS = "k8s-namespace" + InjectInitCopyContainerName = "copy-consul-bin" + InjectInitContainerName = "consul-connect-inject-init" + MetaKeyPodName = "pod-name" + MetaKeyKubeNS = "k8s-namespace" ) type initContainerCommandData struct { @@ -63,6 +64,25 @@ type initContainerCommandUpstreamData struct { Query string } +// containerInitCopyContainer returns the init container spec for the copy container which places +// the consul binary into the shared volume. +func (h *Handler) containerInitCopyContainer() corev1.Container { + // Copy the Consul binary from the image to the shared volume. + cmd := "cp /bin/consul /consul/connect-inject/consul" + return corev1.Container{ + Name: InjectInitCopyContainerName, + Image: h.ImageConsul, + Resources: h.InitContainerResources, + VolumeMounts: []corev1.VolumeMount{ + corev1.VolumeMount{ + Name: volumeName, + MountPath: "/consul/connect-inject", + }, + }, + Command: []string{"/bin/sh", "-ec", cmd}, + } +} + // containerInit returns the init container spec for registering the Consul // service, setting up the Envoy bootstrap, etc. func (h *Handler) containerInit(pod *corev1.Pod, k8sNamespace string) (corev1.Container, error) { @@ -452,8 +472,4 @@ chmod 444 /consul/connect-inject/acl-token {{- if .ConsulNamespace }} -namespace="{{ .ConsulNamespace }}" \ {{- end }} - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul -` + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml` diff --git a/connect-inject/container_init_test.go b/connect-inject/container_init_test.go index 08ebf40c59..97e45b09a0 100644 --- a/connect-inject/container_init_test.go +++ b/connect-inject/container_init_test.go @@ -105,10 +105,7 @@ EOF # Generate the envoy bootstrap code /bin/consul connect envoy \ -proxy-id="${PROXY_SERVICE_ID}" \ - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul`, + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml`, "", }, @@ -795,10 +792,7 @@ EOF /bin/consul connect envoy \ -proxy-id="${PROXY_SERVICE_ID}" \ -namespace="default" \ - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul`, + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml`, "", }, @@ -871,10 +865,7 @@ EOF /bin/consul connect envoy \ -proxy-id="${PROXY_SERVICE_ID}" \ -namespace="non-default" \ - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul`, + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml`, "", }, @@ -956,10 +947,7 @@ chmod 444 /consul/connect-inject/acl-token -proxy-id="${PROXY_SERVICE_ID}" \ -token-file="/consul/connect-inject/acl-token" \ -namespace="non-default" \ - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul`, + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml`, "", }, @@ -1042,10 +1030,7 @@ chmod 444 /consul/connect-inject/acl-token -proxy-id="${PROXY_SERVICE_ID}" \ -token-file="/consul/connect-inject/acl-token" \ -namespace="k8snamespace" \ - -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml - -# Copy the Consul binary -cp /bin/consul /consul/connect-inject/consul`, + -bootstrap > /consul/connect-inject/envoy-bootstrap.yaml`, "", }, @@ -1446,3 +1431,12 @@ func TestHandlerContainerInit_MeshGatewayModeErrors(t *testing.T) { } } + +// Test that the init copy container has the correct command. +func TestHandlerContainerInitCopyContainer(t *testing.T) { + require := require.New(t) + h := Handler{} + container := h.containerInitCopyContainer() + actual := strings.Join(container.Command, " ") + require.Contains(actual, `cp /bin/consul /consul/connect-inject/consul`) +} diff --git a/connect-inject/handler.go b/connect-inject/handler.go index e750914199..4c9f8280c5 100644 --- a/connect-inject/handler.go +++ b/connect-inject/handler.go @@ -348,9 +348,12 @@ func (h *Handler) Mutate(req *v1beta1.AdmissionRequest) *v1beta1.AdmissionRespon fmt.Sprintf("/spec/containers/%d/env", i))...) } + // Add the init container which copies the consul binary. + initCopyContainer := h.containerInitCopyContainer() + // Add the init container that registers the service and sets up // the Envoy configuration. - container, err := h.containerInit(&pod, req.Namespace) + initContainer, err := h.containerInit(&pod, req.Namespace) if err != nil { h.Log.Error("Error configuring injection init container", "err", err, "Request Name", req.Name) return &v1beta1.AdmissionResponse{ @@ -361,7 +364,7 @@ func (h *Handler) Mutate(req *v1beta1.AdmissionRequest) *v1beta1.AdmissionRespon } patches = append(patches, addContainer( pod.Spec.InitContainers, - []corev1.Container{container}, + []corev1.Container{initCopyContainer, initContainer}, "/spec/initContainers")...) // Add the Envoy and Consul sidecars. diff --git a/connect-inject/handler_test.go b/connect-inject/handler_test.go index e525fd0a17..a9143c70c3 100644 --- a/connect-inject/handler_test.go +++ b/connect-inject/handler_test.go @@ -97,6 +97,10 @@ func TestHandlerHandle(t *testing.T) { Operation: "add", Path: "/spec/initContainers", }, + { + Operation: "add", + Path: "/spec/initContainers/-", + }, { Operation: "add", Path: "/spec/containers/-", @@ -164,6 +168,10 @@ func TestHandlerHandle(t *testing.T) { Operation: "add", Path: "/spec/initContainers", }, + { + Operation: "add", + Path: "/spec/initContainers/-", + }, { Operation: "add", Path: "/spec/containers/-", @@ -237,6 +245,10 @@ func TestHandlerHandle(t *testing.T) { Operation: "add", Path: "/spec/initContainers", }, + { + Operation: "add", + Path: "/spec/initContainers/-", + }, { Operation: "add", Path: "/spec/containers/-", @@ -283,6 +295,10 @@ func TestHandlerHandle(t *testing.T) { Operation: "add", Path: "/spec/initContainers", }, + { + Operation: "add", + Path: "/spec/initContainers/-", + }, { Operation: "add", Path: "/spec/containers/-", @@ -334,6 +350,10 @@ func TestHandlerHandle(t *testing.T) { Operation: "add", Path: "/spec/initContainers", }, + { + Operation: "add", + Path: "/spec/initContainers/-", + }, { Operation: "add", Path: "/spec/containers/-",