From 11e8400c434ea4a7bbed87e5386fb1817f33d602 Mon Sep 17 00:00:00 2001 From: Anton Bronnikov Date: Thu, 25 Apr 2024 12:02:23 +0300 Subject: [PATCH] feat: avoid container name collisions --- config/inject.go | 15 +++++++- deploy/deployment.yaml | 7 +++- deploy/dummy.yaml | 84 ++++++++++++++++++++++++++++++------------ server/k8s.go | 27 ++++++++++++-- 4 files changed, 103 insertions(+), 30 deletions(-) diff --git a/config/inject.go b/config/inject.go index 49eee5b..33d3ac0 100644 --- a/config/inject.go +++ b/config/inject.go @@ -7,7 +7,9 @@ import ( type Inject struct { LabelSelector *LabelSelector `yaml:"labelSelector,omitempty"` - Containers []Container `yaml:"containers,omitempty"` + + Annotations map[string]string `yaml:"annotations,omitempty"` + Containers []Container `yaml:"containers,omitempty"` } func (i Inject) Fingerprint() string { @@ -16,6 +18,17 @@ func (i Inject) Fingerprint() string { sum.Write([]byte("labelSelector:")) i.LabelSelector.hash(sum) + sum.Write([]byte("annotations:")) + for k, v := range i.Annotations { + sum.Write([]byte("key:")) + sum.Write([]byte(k)) + sum.Write([]byte{255}) + + sum.Write([]byte("value:")) + sum.Write([]byte(v)) + sum.Write([]byte{255}) + } + sum.Write([]byte("containers:")) for _, c := range i.Containers { c.hash(sum) diff --git a/deploy/deployment.yaml b/deploy/deployment.yaml index 7ae1dea..ea5241c 100644 --- a/deploy/deployment.yaml +++ b/deploy/deployment.yaml @@ -19,7 +19,7 @@ spec: serviceAccountName: kube-sidecar-injector containers: - name: kube-sidecar-injector - image: kube-sidecar-injector:0.0.2-dev + image: kube-sidecar-injector:0.0.2-2-g74221a4-dev ports: - name: https containerPort: 8443 @@ -44,7 +44,10 @@ metadata: data: config.yaml: |- inject: - - containers: + - annotations: + test: test + + containers: - name: node-exporter image: prom/node-exporter:v1.7.0 args: [ diff --git a/deploy/dummy.yaml b/deploy/dummy.yaml index e0fa396..31528c2 100644 --- a/deploy/dummy.yaml +++ b/deploy/dummy.yaml @@ -6,18 +6,18 @@ metadata: name: dummy spec: containers: - - name: dummy - image: ubuntu - command: - - /bin/bash - - -c - - |- - stop() { - touch stop - } - trap stop SIGTERM - trap stop SIGINT - while [[ ! -f stop ]]; do sleep 1; done + - name: dummy + image: ubuntu + command: + - /bin/bash + - -c + - |- + stop() { + touch stop + } + trap stop SIGTERM + trap stop SIGINT + while [[ ! -f stop ]]; do sleep 1; done --- @@ -30,15 +30,51 @@ metadata: spec: containers: - - name: dummy - image: ubuntu - command: - - /bin/bash - - -c - - |- - stop() { - touch stop - } - trap stop SIGTERM - trap stop SIGINT - while [[ ! -f stop ]]; do sleep 1; done + - name: dummy + image: ubuntu + command: + - /bin/bash + - -c + - |- + stop() { + touch stop + } + trap stop SIGTERM + trap stop SIGINT + while [[ ! -f stop ]]; do sleep 1; done + +--- + +kind: Pod +apiVersion: v1 +metadata: + name: dummy-collision + labels: + eks.amazonaws.com/fargate-profile: default + +spec: + containers: + - name: dummy + image: ubuntu + command: + - /bin/bash + - -c + - |- + stop() { + touch stop + } + trap stop SIGTERM + trap stop SIGINT + while [[ ! -f stop ]]; do sleep 1; done + - name: node-exporter + image: ubuntu + command: + - /bin/bash + - -c + - |- + stop() { + touch stop + } + trap stop SIGTERM + trap stop SIGINT + while [[ ! -f stop ]]; do sleep 1; done diff --git a/server/k8s.go b/server/k8s.go index e3e838a..a745f7d 100644 --- a/server/k8s.go +++ b/server/k8s.go @@ -5,6 +5,7 @@ import ( "encoding/json" "errors" "fmt" + "time" json_patch "github.com/evanphx/json-patch" "github.com/flashbots/kube-sidecar-injector/global" @@ -182,10 +183,26 @@ func (s *Server) mutatePod( // inject containers if len(inject.Containers) > 0 { + existing := make(map[string]struct{}, len(pod.Spec.Containers)) + for _, c := range pod.Spec.Containers { + existing[c.Name] = struct{}{} + } + containers := make([]core_v1.Container, 0, len(inject.Containers)) for _, c := range inject.Containers { + if _, collision := existing[c.Name]; collision { + l.Warn("Container with the same name already exists => skipping...", + zap.String("containerName", c.Name), + zap.String("namespace", pod.Namespace), + zap.String("pod", pod.Name), + ) + continue + } + l.Info("Injecting container", zap.String("containerName", c.Name), + zap.String("namespace", pod.Namespace), + zap.String("pod", pod.Name), ) container, err := c.Container() if err != nil { @@ -203,9 +220,13 @@ func (s *Server) mutatePod( // annotate if len(res) > 0 { - p, err := patch.UpdatePodAnnotations(pod, map[string]string{ - s.cfg.K8S.ServiceName + "." + global.OrgDomain + "/patched": "true", - }) + annotations := make(map[string]string, len(inject.Annotations)+1) + for k, v := range inject.Annotations { + annotations[k] = v + } + annotations[s.cfg.K8S.ServiceName+"."+global.OrgDomain+"/"+fingerprint] = time.Now().Format(time.RFC3339) + + p, err := patch.UpdatePodAnnotations(pod, annotations) if err != nil { return nil, err }