Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Instrumentations support select #2778

Open
wants to merge 21 commits into
base: main
Choose a base branch
from

Conversation

crossoverJie
Copy link
Contributor

Description:

apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
  name: my-instrumentation
spec:
  selector:
    app: appname
  propagators:
    - tracecontext
  java:
    image: image

Support select.

Link to tracking Issue(s): #2744

Testing:

Documentation:

@crossoverJie crossoverJie requested a review from a team as a code owner March 22, 2024 11:11
Copy link
Contributor

@swiatekm-sumo swiatekm-sumo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd also like to see a E2E test for this behaviour.

apis/v1alpha1/instrumentation_types.go Outdated Show resolved Hide resolved
@crossoverJie
Copy link
Contributor Author

I'd also like to see a E2E test for this behaviour.

I'll add it later.

Copy link
Contributor

@swiatekm-sumo swiatekm-sumo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM, minus some unnecessary changes from E2E tests.

Co-authored-by: Mikołaj Świątek <mail+sumo@mikolajswiatek.com>
Copy link
Contributor

@swiatekm-sumo swiatekm-sumo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I noticed that we're not following the standard semantics of v1.LabelSelector:

A label selector is a label query over a set of resources. The result of matchLabels and matchExpressions are ANDed. An empty label selector matches all objects. A null label selector matches no objects.

Whereas the way we have this implemented, null means "everything" and there's no way to select nothing. Could we switch to the standard semantics? I don't think there's a way to get kubebuilder to set this default for us, so we'd need to do it in the defaulting webhook, but we'd get to skip the conditional instructions in the Pod mutator. What do you think?

@crossoverJie
Copy link
Contributor Author

Could we switch to the standard semantics?

Good suggestion. I agree with you.

An empty label selector matches all objects. A null label selector matches no objects.

If we want to implement this semantics, the current test case will need to add empty selectors to pass the e2e test.

image

The implement code:
image

This will change the default behavior; is this necessary?

@swiatekm-sumo
Copy link
Contributor

Could we switch to the standard semantics?

Good suggestion. I agree with you.

An empty label selector matches all objects. A null label selector matches no objects.

If we want to implement this semantics, the current test case will need to add empty selectors to pass the e2e test.

image

The implement code: image

This will change the default behavior; is this necessary?

You can add the following annotation to the field: // +kubebuilder:default:={}, and it will work as intended. I also made the following change to your logic:

	for _, ins := range otelInsts.Items {
		labelSelector, err := v1.LabelSelectorAsSelector(ins.Spec.Selector)
		if err != nil {
			return nil, err
		}
		set := labels.Set(pod.GetLabels())
		if labelSelector.Matches(set) {
			availableInstrument = append(availableInstrument, ins)
		}
	}

and all the e2e tests passed.

The only potential problem here, is that this default value is only reflected in the CRD itself. So if a user were to upgrade the operator without upgrading their Instrumentation CRD, the field would be nil by default, and their Instrumentations would select nothing. So maybe it's better to keep your current logic and make this change when we promote Instrumentation to beta? @pavolloffay @jaronoff97 @TylerHelmuth WDYT?

@crossoverJie
Copy link
Contributor Author

Are there any new updates now?

@jaronoff97
Copy link
Contributor

@swiatekm-sumo i think it may be okay for the instrumentations to select none by default, given that's technically the current behavior right?

@swiatekm-sumo
Copy link
Contributor

@swiatekm-sumo i think it may be okay for the instrumentations to select none by default, given that's technically the current behavior right?

I don't think that's the case? Looking at the code being modified in this PR, it just picks the instrumentation defined in the namespace if the annotation isn't specific. Setting the default to nil would stop this from working.

Incidentally, we should document that this selector only applies to this situation. As is, if the selector doesn't fit the Pod, and the Pod asks for a specific Instrumentation via the annotation, it will still get it.

# Conflicts:
#	bundle/manifests/opentelemetry-operator.clusterserviceversion.yaml
@crossoverJie
Copy link
Contributor Author

So maybe it's better to keep your current logic and make this change when we promote Instrumentation to beta?

I prefer this approach; maybe we can finish the current issue first.

Copy link
Contributor

@swiatekm-sumo swiatekm-sumo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm ok keeping this as is, but we should document how we diverge from standard LabelSelector behavior.

apis/v1alpha1/instrumentation_types.go Outdated Show resolved Hide resolved
crossoverJie and others added 2 commits April 2, 2024 17:14
Co-authored-by: Mikołaj Świątek <mail+sumo@mikolajswiatek.com>
pkg/instrumentation/podmutator.go Outdated Show resolved Hide resolved
// Unlike standard label selectors, `nil` means `everything`, and this is also the default.
// This may change in a future CRD version.
// +optional
Selector *metav1.LabelSelector `json:"selector,omitempty"`
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are all pods from all namespaces matched?

What is the precedence order when annotation instrumentation.opentelemetry.io/ is also present on the pod/namespace?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this feature only comes into play when the annotation is not set and we try to pick an Instrumentation from the namespace the Pod is in. The annotation has precedence. But we should document this behaviour somewhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I believe this feature only comes into play when the annotation is not set and we try to pick an Instrumentation from the namespace the Pod is in

func (pm *instPodMutator) getInstrumentationInstance(ctx context.Context, ns corev1.Namespace, pod corev1.Pod, instAnnotation string) (*v1alpha1.Instrumentation, error) {
instValue := annotationValue(ns.ObjectMeta, pod.ObjectMeta, instAnnotation)
if len(instValue) == 0 || strings.EqualFold(instValue, "false") {
return nil, nil
}
if strings.EqualFold(instValue, "true") {
return pm.selectInstrumentationInstanceFromNamespace(ctx, ns)
}

Did I understand it wrong? I think the premise for this feature to take effect is that the instrumentation.opentelemetry.io/inject-xx is equal to true.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What I meant to say was that this mechanism only applies if the annotation doesn't specify which instrumentation should be used. Apologies for the confusion.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks; I understand that the documentation has been supplemented.

@crossoverJie
Copy link
Contributor Author

crossoverJie commented Apr 9, 2024

@swiatekm-sumo The E2E test failed, but I can pass it locally, any suggestions?

@swiatekm-sumo
Copy link
Contributor

@swiatekm-sumo The E2E test failed, but I can pass it locally, any suggestions?

Can you try recreating the test cluster locally to see if tests still pass? It's possible you're using an older docker image in tests.

@crossoverJie
Copy link
Contributor Author

Can you try recreating the test cluster locally to see if tests still pass? It's possible you're using an older docker image in tests.

Thanks; I have changed the e2e test.

@swiatekm-sumo
Copy link
Contributor

@crossoverJie I think you're running into trouble merging changes in generated manifests. I suggest running make precommit and including the output in the merge commit.

@crossoverJie
Copy link
Contributor Author

@crossoverJie I think you're running into trouble merging changes in generated manifests. I suggest running make precommit and including the output in the merge commit.

Thanks, done.

@swiatekm-sumo swiatekm-sumo self-requested a review May 8, 2024 14:25
Copy link

linux-foundation-easycla bot commented May 17, 2024

CLA Signed

The committers listed above are authorized under a signed CLA.

@swiatekm-sumo
Copy link
Contributor

@crossoverJie can you rebase on main? That should get rid of the EasyCLA complaint.

@crossoverJie
Copy link
Contributor Author

@crossoverJie can you rebase on main? That should get rid of the EasyCLA complaint.

Thanks for your reminder, done.

@swiatekm-sumo
Copy link
Contributor

I don't get why EasyCLA complains about my email address. Feel free to just drop the Co-authored-by: Mikołaj Świątek <mail+sumo@mikolajswiatek.com> messages from the commits it complains about. I don't want this to block this PR.

kind: Pod
metadata:
annotations:
instrumentation.opentelemetry.io/inject-java: "true"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand the use-case to have the Selector in the CR while the inject annotation is still needed.

What is the use-case this feature solves? Why do we need to maintain two approaches to solve the same use-case?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This test case is to test that when there are multiple Instrumentation (they all use Selector), the Selector feature can still work as expected.

@swiatekm-sumo
Copy link
Contributor

swiatekm-sumo commented May 22, 2024

/easycla

Edit: FYI, the problem was communitybridge/easycla#4329.

@swiatekm-sumo swiatekm-sumo added the discuss-at-sig This issue or PR should be discussed at the next SIG meeting label May 23, 2024
@jaronoff97 jaronoff97 removed the discuss-at-sig This issue or PR should be discussed at the next SIG meeting label May 23, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Instrumentation support selector
5 participants