Skip to content

Commit

Permalink
Integration du choix du conteneur par annotation
Browse files Browse the repository at this point in the history
  • Loading branch information
fscellos committed Feb 4, 2022
1 parent e8d6f8b commit db7ecc3
Show file tree
Hide file tree
Showing 12 changed files with 53 additions and 31 deletions.
8 changes: 8 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -215,6 +215,14 @@ The possible values for the annotation can be
* `"my-instrumentation"` - name of `Instrumentation` CR instance.
* `"false"` - do not inject

It as also possible in case of multiple-containers Pods (like Istio sidecars) to specify the name of the container in which you want to inject OTEL auto-instrumentation (by default the first container is choosen)

For this add this annotation to your Pod Specification with target container name :

```bash
instrumentation.opentelemetry.io/container-name: "name_of_your_target_container"
```

## Compatibility matrix

### OpenTelemetry Operator vs. OpenTelemetry Collector
Expand Down
1 change: 1 addition & 0 deletions apis/v1alpha1/zz_generated.deepcopy.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

7 changes: 4 additions & 3 deletions pkg/instrumentation/annotation.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,10 @@ import (
const (
// annotationInjectJava indicates whether java auto-instrumentation should be injected or not.
// Possible values are "true", "false" or "<Instrumentation>" name.
annotationInjectJava = "instrumentation.opentelemetry.io/inject-java"
annotationInjectNodeJS = "instrumentation.opentelemetry.io/inject-nodejs"
annotationInjectPython = "instrumentation.opentelemetry.io/inject-python"
annotationInjectJava = "instrumentation.opentelemetry.io/inject-java"
annotationInjectNodeJS = "instrumentation.opentelemetry.io/inject-nodejs"
annotationInjectPython = "instrumentation.opentelemetry.io/inject-python"
annotationInjectContainerName = "instrumentation.opentelemetry.io/container-name"
)

// annotationValue returns the effective annotationInjectJava value, based on the annotations from the pod and namespace.
Expand Down
4 changes: 2 additions & 2 deletions pkg/instrumentation/javaagent.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ const (
javaJVMArgument = " -javaagent:/otel-auto-instrumentation/javaagent.jar"
)

func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod) corev1.Pod {
func injectJavaagent(logger logr.Logger, javaSpec v1alpha1.Java, pod corev1.Pod, index int) corev1.Pod {
// caller checks if there is at least one container
container := &pod.Spec.Containers[0]
container := &pod.Spec.Containers[index]

// inject env vars
for _, env := range javaSpec.Env {
Expand Down
2 changes: 1 addition & 1 deletion pkg/instrumentation/javaagent_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func TestInjectJavaagent(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
pod := injectJavaagent(logr.Discard(), test.Java, test.pod)
pod := injectJavaagent(logr.Discard(), test.Java, test.pod, 0)
assert.Equal(t, test.expected, pod)
})
}
Expand Down
4 changes: 2 additions & 2 deletions pkg/instrumentation/nodejs.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,9 @@ const (
nodeRequireArgument = " --require /otel-auto-instrumentation/autoinstrumentation.js"
)

func injectNodeJSSDK(logger logr.Logger, nodeJSSpec v1alpha1.NodeJS, pod corev1.Pod) corev1.Pod {
func injectNodeJSSDK(logger logr.Logger, nodeJSSpec v1alpha1.NodeJS, pod corev1.Pod, index int) corev1.Pod {
// caller checks if there is at least one container
container := &pod.Spec.Containers[0]
container := &pod.Spec.Containers[index]

// inject env vars
for _, env := range nodeJSSpec.Env {
Expand Down
2 changes: 1 addition & 1 deletion pkg/instrumentation/nodejs_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ func TestInjectNodeJSSDK(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
pod := injectNodeJSSDK(logr.Discard(), test.NodeJS, test.pod)
pod := injectNodeJSSDK(logr.Discard(), test.NodeJS, test.pod, 0)
assert.Equal(t, test.expected, pod)
})
}
Expand Down
5 changes: 4 additions & 1 deletion pkg/instrumentation/podmutator.go
Original file line number Diff line number Diff line change
Expand Up @@ -94,9 +94,12 @@ func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod c
return pod, nil
}

// We retrieve the annotation for podname
var containerTarget = annotationValue(ns.ObjectMeta, pod.ObjectMeta, annotationInjectContainerName)

// once it's been determined that instrumentation is desired, none exists yet, and we know which instance it should talk to,
// we should inject the instrumentation.
return pm.sdkInjector.inject(ctx, insts, ns, pod), nil
return pm.sdkInjector.inject(ctx, insts, ns, pod, containerTarget), nil
}

func (pm *instPodMutator) getInstrumentationInstance(ctx context.Context, ns corev1.Namespace, pod corev1.Pod, instAnnotation string) (*v1alpha1.Instrumentation, error) {
Expand Down
4 changes: 2 additions & 2 deletions pkg/instrumentation/python.go
Original file line number Diff line number Diff line change
Expand Up @@ -30,9 +30,9 @@ const (
pythonPathSuffix = "/otel-auto-instrumentation"
)

func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1.Pod) corev1.Pod {
func injectPythonSDK(logger logr.Logger, pythonSpec v1alpha1.Python, pod corev1.Pod, index int) corev1.Pod {
// caller checks if there is at least one container
container := &pod.Spec.Containers[0]
container := &pod.Spec.Containers[index]

// inject env vars
for _, env := range pythonSpec.Env {
Expand Down
2 changes: 1 addition & 1 deletion pkg/instrumentation/python_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ func TestInjectPythonSDK(t *testing.T) {

for _, test := range tests {
t.Run(test.name, func(t *testing.T) {
pod := injectPythonSDK(logr.Discard(), test.Python, test.pod)
pod := injectPythonSDK(logr.Discard(), test.Python, test.pod, 0)
assert.Equal(t, test.expected, pod)
})
}
Expand Down
37 changes: 23 additions & 14 deletions pkg/instrumentation/sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,39 +56,48 @@ type sdkInjector struct {
client client.Client
}

func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations, ns corev1.Namespace, pod corev1.Pod) corev1.Pod {
func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations, ns corev1.Namespace, pod corev1.Pod, containerName string) corev1.Pod {
if len(pod.Spec.Containers) < 1 {
return pod
}

// We search for specific container to inject variables and if no one is found
// We fallback to first container
var index = 0
for idx, ctnair := range pod.Spec.Containers {
if ctnair.Name == containerName {
index = idx
}
}

// inject only to the first container for now
// in the future we can define an annotation to configure this
if insts.Java != nil {
otelinst := *insts.Java
i.logger.V(1).Info("injecting java instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name)
pod = injectJavaagent(i.logger, otelinst.Spec.Java, pod)
pod = i.injectCommonEnvVar(otelinst, pod)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod)
pod = injectJavaagent(i.logger, otelinst.Spec.Java, pod, index)
pod = i.injectCommonEnvVar(otelinst, pod, index)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index)
}
if insts.NodeJS != nil {
otelinst := *insts.NodeJS
i.logger.V(1).Info("injecting nodejs instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name)
pod = injectNodeJSSDK(i.logger, otelinst.Spec.NodeJS, pod)
pod = i.injectCommonEnvVar(otelinst, pod)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod)
pod = injectNodeJSSDK(i.logger, otelinst.Spec.NodeJS, pod, index)
pod = i.injectCommonEnvVar(otelinst, pod, index)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index)
}
if insts.Python != nil {
otelinst := *insts.Python
i.logger.V(1).Info("injecting python instrumentation into pod", "otelinst-namespace", otelinst.Namespace, "otelinst-name", otelinst.Name)
pod = injectPythonSDK(i.logger, otelinst.Spec.Python, pod)
pod = i.injectCommonEnvVar(otelinst, pod)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod)
pod = injectPythonSDK(i.logger, otelinst.Spec.Python, pod, index)
pod = i.injectCommonEnvVar(otelinst, pod, index)
pod = i.injectCommonSDKConfig(ctx, otelinst, ns, pod, index)
}
return pod
}

func (i *sdkInjector) injectCommonEnvVar(otelinst v1alpha1.Instrumentation, pod corev1.Pod) corev1.Pod {
container := &pod.Spec.Containers[0]
func (i *sdkInjector) injectCommonEnvVar(otelinst v1alpha1.Instrumentation, pod corev1.Pod, index int) corev1.Pod {
container := &pod.Spec.Containers[index]
for _, env := range otelinst.Spec.Env {
idx := getIndexOfEnv(container.Env, env.Name)
if idx == -1 {
Expand All @@ -98,8 +107,8 @@ func (i *sdkInjector) injectCommonEnvVar(otelinst v1alpha1.Instrumentation, pod
return pod
}

func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alpha1.Instrumentation, ns corev1.Namespace, pod corev1.Pod) corev1.Pod {
container := &pod.Spec.Containers[0]
func (i *sdkInjector) injectCommonSDKConfig(ctx context.Context, otelinst v1alpha1.Instrumentation, ns corev1.Namespace, pod corev1.Pod, index int) corev1.Pod {
container := &pod.Spec.Containers[index]
resourceMap := i.createResourceMap(ctx, otelinst, ns, pod)
idx := getIndexOfEnv(container.Env, envOTELServiceName)
if idx == -1 {
Expand Down
8 changes: 4 additions & 4 deletions pkg/instrumentation/sdk_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -364,7 +364,7 @@ func TestSDKInjection(t *testing.T) {
inj := sdkInjector{
client: k8sClient,
}
pod := inj.injectCommonSDKConfig(context.Background(), test.inst, corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: test.pod.Namespace}}, test.pod)
pod := inj.injectCommonSDKConfig(context.Background(), test.inst, corev1.Namespace{ObjectMeta: metav1.ObjectMeta{Name: test.pod.Namespace}}, test.pod, 0)
_, err = json.MarshalIndent(pod, "", " ")
assert.NoError(t, err)
assert.Equal(t, test.expected, pod)
Expand Down Expand Up @@ -399,7 +399,7 @@ func TestInjectJava(t *testing.T) {
},
},
},
})
}, "")
assert.Equal(t, corev1.Pod{
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -497,7 +497,7 @@ func TestInjectNodeJS(t *testing.T) {
},
},
},
})
}, "")
assert.Equal(t, corev1.Pod{
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
Expand Down Expand Up @@ -596,7 +596,7 @@ func TestInjectPython(t *testing.T) {
},
},
},
})
}, "")
assert.Equal(t, corev1.Pod{
Spec: corev1.PodSpec{
Volumes: []corev1.Volume{
Expand Down

0 comments on commit db7ecc3

Please sign in to comment.