创建collector
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
name: otel
spec:
config: |
receivers:
otlp:
protocols:
grpc:
http:
processors:
exporters:
logging:
service:
pipelines:
traces:
receivers: [otlp]
processors: []
exporters: [logging]
会自动创建configmap,serviceaccount,service, deployment/daemonset/statefulset
service name为crd的name后面加-collector
创建Instrumentation
内容如下
apiVersion: opentelemetry.io/v1alpha1
kind: Instrumentation
metadata:
name: my-instrumentation
spec:
exporter:
endpoint: http://otel-collector:4317
propagators:
- tracecontext
- baggage
- b3
sampler:
type: parentbased_traceidratio
argument: "0.25"
java:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java:latest
nodejs:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-nodejs:latest
python:
image: ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:latest
创建deployment
apiVersion: apps/v1
kind: Deployment
metadata:
name: spring-petclinic
spec:
selector:
matchLabels:
app: spring-petclinic
replicas: 1
template:
metadata:
labels:
app: spring-petclinic
annotations:
sidecar.opentelemetry.io/inject: "true"
instrumentation.opentelemetry.io/inject-java: "true"
spec:
containers:
- name: app
image: ghcr.io/pavolloffay/spring-petclinic:latest
自动注入以下环境变量到pod的第一个容器中,用于sdk的相应配置
OTEL_SERVICE_NAME
OTEL_EXPORTER_OTLP_ENDPOINT
OTEL_RESOURCE_ATTRIBUTES
OTEL_PROPAGATORS,OTEL_TRACES_SAMPLER
OTEL_TRACES_SAMPLER_ARG
相关代码
代码仓库github.com/open-telemetry/opentelemetry-operator
main.go中
func main() {
...
mgr.GetWebhookServer().Register("/mutate-v1-pod", &webhook.Admission{
Handler: webhookhandler.NewWebhookHandler(cfg, ctrl.Log.WithName("pod-webhook"), mgr.GetClient(),
[]webhookhandler.PodMutator{
sidecar.NewMutator(logger, cfg, mgr.GetClient()),
instrumentation.NewMutator(logger, mgr.GetClient()),
}),
})
...
}
pkg/instrumentation/podmutator.go中
func NewMutator(logger logr.Logger, client client.Client) *instPodMutator {
return &instPodMutator{
Logger: logger,
Client: client,
sdkInjector: &sdkInjector{
logger: logger,
client: client,
},
}
}
func (pm *instPodMutator) Mutate(ctx context.Context, ns corev1.Namespace, pod corev1.Pod) (corev1.Pod, error) {
...
return pm.sdkInjector.inject(ctx, insts, ns, pod), nil
}
pkg/instrumentation/sdk.go中
func (i *sdkInjector) inject(ctx context.Context, insts languageInstrumentations, ns corev1.Namespace, pod corev1.Pod) corev1.Pod {
...
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 = i.injectCommonSDKConfig(ctx, otelinst, ns, pod)
pod = injectJavaagent(i.logger, otelinst.Spec.Java, 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]
resourceMap := i.createResourceMap(ctx, otelinst, ns, pod)
idx := getIndexOfEnv(container.Env, envOTELServiceName)
if idx == -1 {
container.Env = append(container.Env, corev1.EnvVar{
Name: envOTELServiceName,
Value: chooseServiceName(pod, resourceMap),
})
}
...
}
网友评论