Orchestration

Auto-Instrument OpenTelemetry in Kubernetes

June 18, 2026 Kubezilla Team 7 min read

In the dynamic landscape of modern cloud-native applications, understanding the behavior and performance of your services is paramount. As applications become increasingly distributed and complex, traditional monitoring approaches often fall short. This is where observability, specifically through distributed tracing, metrics, and logs, becomes indispensable. OpenTelemetry has emerged as the de facto standard for instrumenting applications, providing a vendor-agnostic way to generate, collect, and export telemetry data.

However, manually instrumenting every service in a microservices architecture can be a daunting, time-consuming, and error-prone task. This challenge is amplified in Kubernetes environments where applications are constantly scaling, deploying, and evolving. OpenTelemetry auto-instrumentation for Kubernetes offers a powerful solution, allowing you to automatically inject OpenTelemetry SDKs into your applications without modifying their source code. This guide will walk you through the process of setting up OpenTelemetry auto-instrumentation in your Kubernetes cluster, ensuring your applications are fully observable with minimal effort.

TL;DR: OpenTelemetry Auto-Instrumentation for Kubernetes

Automate OpenTelemetry instrumentation in your Kubernetes cluster using an Admission Controller and an OpenTelemetry Operator. This setup injects OpenTelemetry SDKs into your applications without code changes, enabling distributed tracing, metrics, and logs.

Key Commands:

# Install OpenTelemetry Operator (if not already present)
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update
helm upgrade --install opentelemetry-operator open-telemetry/opentelemetry-operator \
  --namespace opentelemetry-operator --create-namespace

# Deploy an OpenTelemetry Collector
kubectl apply -f collector.yaml

# Enable auto-instrumentation for a namespace
kubectl label namespace <your-namespace> opentelemetry-injection=enabled

# Deploy a sample application with auto-instrumentation
kubectl apply -f sample-app.yaml

# Verify traces (e.g., using Jaeger)
kubectl port-forward svc/jaeger-query 16686:16686 -n opentelemetry-collector

Prerequisites

Before diving into OpenTelemetry auto-instrumentation, ensure you have the following:

  • A running Kubernetes cluster (v1.20+ recommended). You can use Minikube, Kind, or any cloud provider’s managed Kubernetes service (EKS, GKE, AKS).
  • kubectl installed and configured to connect to your cluster. For installation instructions, refer to the official Kubernetes documentation.
  • helm installed (v3.0+). Helm is crucial for deploying the OpenTelemetry Operator and other components. Check the Helm installation guide if you don’t have it.
  • Basic understanding of Kubernetes concepts like Pods, Deployments, Services, and Namespaces.
  • Familiarity with observability concepts (metrics, traces, logs).

Step-by-Step Guide

1. Install the OpenTelemetry Operator

The OpenTelemetry Operator for Kubernetes provides a powerful way to manage OpenTelemetry components within your cluster. It includes an Admission Webhook that handles the auto-instrumentation injection. The operator watches for specific annotations or labels on Pods/Namespaces and automatically mutates Pod specifications to include the necessary OpenTelemetry SDKs and environment variables.

This operator simplifies the deployment and lifecycle management of OpenTelemetry Collectors, allowing you to define them as custom resources. It also streamlines the auto-instrumentation process by injecting sidecar containers or init containers, depending on the language and configuration. For instance, it can inject Java agents, Python auto-instrumentation libraries, or .NET profilers, ensuring your applications start sending telemetry data without requiring manual code changes or Dockerfile modifications.

# Add the OpenTelemetry Helm repository
helm repo add open-telemetry https://open-telemetry.github.io/opentelemetry-helm-charts
helm repo update

# Install the OpenTelemetry Operator
# We'll install it in its own namespace for better isolation.
helm upgrade --install opentelemetry-operator open-telemetry/opentelemetry-operator \
  --namespace opentelemetry-operator --create-namespace

Verify

Check if the operator’s Pods are running and the Custom Resource Definitions (CRDs) are installed. You should see a deployment for the operator and its webhook.

kubectl get pods -n opentelemetry-operator
kubectl get crd | grep opentelemetry

Expected Output:

NAME                                             READY   STATUS    RESTARTS   AGE
opentelemetry-operator-controller-manager-...   1/1     Running   0          2m

NAME                                          CREATED AT
opentelemetrycollectors.opentelemetry.io      2023-10-27T10:00:00Z
instrumentations.opentelemetry.io             2023-10-27T10:00:00Z

2. Deploy an OpenTelemetry Collector

The OpenTelemetry Collector is a vendor-agnostic proxy that receives, processes, and exports telemetry data. It’s a critical component in any OpenTelemetry setup, acting as an intermediary between your instrumented applications and your telemetry backend (e.g., Jaeger, Prometheus, Loki, your cloud provider’s observability suite). The collector can be deployed as an agent (sidecar or DaemonSet) or a gateway (Deployment).

For auto-instrumentation, applications will typically send their telemetry data to a collector endpoint. This collector then performs tasks like batching, filtering, enriching, and ultimately exporting the data to your chosen backend. Deploying it as a Deployment with a Service allows all instrumented applications to easily discover and send data to it. The collector’s configuration defines its receivers (how it gets data), processors (how it manipulates data), and exporters (where it sends data). In this example, we’ll configure it to export to Jaeger for distributed tracing visualization.

# collector.yaml
apiVersion: opentelemetry.io/v1alpha1
kind: OpenTelemetryCollector
metadata:
  name: otel-collector
  namespace: opentelemetry-collector # Create this namespace if it doesn't exist
spec:
  mode: deployment
  image: otel/opentelemetry-collector-contrib:0.87.0 # Use a stable contrib image
  replicas: 1
  config: |
    receivers:
      otlp:
        protocols:
          grpc:
          http:

    processors:
      batch:
        send_batch_size: 100
        timeout: 10s

    exporters:
      jaeger:
        endpoint: jaeger-collector:14250
        tls:
          insecure: true
      logging:
        loglevel: debug # Useful for debugging

    service:
      pipelines:
        traces:
          receivers: [otlp]
          processors: [batch]
          exporters: [jaeger, logging]
        metrics:
          receivers: [otlp]
          processors: [batch]
          exporters: [logging] # For simplicity, not exporting metrics to Jaeger in this example
        logs:
          receivers: [otlp]
          processors: [batch]
          exporters: [logging] # For simplicity, not exporting logs in this example
---
apiVersion: v1
kind: Service
metadata:
  name: jaeger-collector
  namespace: opentelemetry-collector
spec:
  selector:
    app.kubernetes.io/component: collector
    app.kubernetes.io/instance: jaeger
    app.kubernetes.io/name: jaeger
  ports:
    - protocol: TCP
      name: grpc
      port: 14250
      targetPort: 14250
    - protocol: TCP
      name: http
      port: 14268
      targetPort: 14268
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: jaeger
  namespace: opentelemetry-collector
  labels:
    app.kubernetes.io/name: jaeger
    app.kubernetes.io/instance: jaeger
spec:
  selector:
    matchLabels:
      app.kubernetes.io/name: jaeger
      app.kubernetes.io/instance: jaeger
  replicas: 1
  template:
    metadata:
      labels:
        app.kubernetes.io/name: jaeger
        app.kubernetes.io/instance: jaeger
    spec:
      containers:
        - name: jaeger
          image: jaegertracing/all-in-one:1.49 # All-in-one for simplicity
          ports:
            - containerPort: 16686 # UI
              name: query
            - containerPort: 14250 # gRPC collector
              name: grpc
            - containerPort: 14268 # HTTP collector
              name: http
          env:
            - name: COLLECTOR_ZIPKIN_HOST_PORT
              value: ":9411"
---
apiVersion: v1
kind: Service
metadata:
  name: jaeger-query
  namespace: opentelemetry-collector
spec:
  selector:
    app.kubernetes.io/name: jaeger
    app.kubernetes.io/instance: jaeger
  ports:
    - protocol: TCP
      name: http
      port: 16686
      targetPort: 16686
  type: ClusterIP # Use LoadBalancer for external access in production
kubectl create namespace opentelemetry-collector
kubectl apply -f collector.yaml

Verify

Check if the collector and Jaeger Pods are running and their services are exposed.

kubectl get pods -n opentelemetry-collector
kubectl get svc -n opentelemetry-collector

Expected Output:

NAME                             READY   STATUS    RESTARTS   AGE
otel-collector-56...             1/1     Running   0          1m
jaeger-5c...                     1/1     Running   0          1m

NAME                   TYPE        CLUSTER-IP       EXTERNAL-IP   PORT(S)                               AGE
otel-collector         ClusterIP   10.96.10.10      <none>        4317/TCP,4318/TCP                     1m
jaeger-collector       ClusterIP   10.96.20.20      <none>        14250/TCP,14268/TCP                   1m
jaeger-query           ClusterIP   10.96.30.30      <none>        16686/TCP                             1m

3. Enable Auto-Instrumentation for a Namespace

The OpenTelemetry Operator’s Admission Webhook is the magic behind auto-instrumentation. By labeling a namespace, you instruct the webhook to intercept Pod creation requests within that namespace. When a new Pod is created, the webhook modifies its definition to inject the necessary OpenTelemetry SDKs, agents, or environment variables. This typically involves adding an initContainer or a sidecar container that sets up the instrumentation.

This approach is powerful because it’s completely transparent to your application code and deployment manifests. You don’t need to recompile, repackage, or even touch your application’s Dockerfile. The operator handles the language-specific injection (e.g., Java agent, Python wrapper, Node.js module) and ensures that the application is configured to export telemetry to the OpenTelemetry Collector endpoint. This significantly reduces the operational overhead of enabling observability across many services.

# Label the default namespace for auto-instrumentation
kubectl label namespace default opentelemetry-injection=enabled

Verify

Check if the label has been applied to the namespace.

kubectl get namespace default -o yaml | grep opentelemetry-injection

Expected Output:

    opentelemetry-injection: enabled

4. Deploy a Sample Application

Now, let’s deploy a simple application that will be automatically instrumented. We’ll use a basic Python Flask application. Notice that there are no OpenTelemetry specific libraries or configurations in the application’s manifest or code. The magic happens when the Pod is created in the labeled namespace.

When this application’s Pod starts, the OpenTelemetry Operator’s webhook will detect the opentelemetry-injection=enabled label on the namespace. It will then mutate the Pod definition to include an init container or sidecar that sets up the Python OpenTelemetry SDK. This typically involves mounting an auto-instrumentation library and setting environment variables like OTEL_SERVICE_NAME and OTEL_EXPORTER_OTLP_ENDPOINT. The application will then automatically generate traces for HTTP requests and send them to the OpenTelemetry Collector we deployed earlier.

# sample-app.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: python-sample-app
  labels:
    app: python-sample-app
spec:
  replicas: 1
  selector:
    matchLabels:
      app: python-sample-app
  template:
    metadata:
      labels:
        app: python-sample-app
      annotations:
        instrumentation.opentelemetry.io/inject-python: "true" # Specific annotation for Python injection
    spec:
      containers:
      - name: python-sample-app
        image: python:3.9-slim-buster
        command: ["/bin/bash", "-c"]
        args:
          - |
            pip install Flask opentelemetry-sdk opentelemetry-exporter-otlp opentelemetry-instrumentation-flask
            cat < app.py
            from flask import Flask, request
            from opentelemetry import trace
            from opentelemetry.sdk.resources import Resource
            from opentelemetry.sdk.resources import SERVICE_NAME
            from opentelemetry.sdk.trace import TracerProvider
            from opentelemetry.sdk.trace.export import BatchSpanProcessor
            from opentelemetry.exporter.otlp.proto.grpc.trace_exporter import OTLPSpanExporter
            from opentelemetry.instrumentation.flask import FlaskInstrumentor
            import os

            # This part is typically handled by auto-instrumentation
            # but is shown for context if manual setup were needed.
            # For auto-instrumentation, the operator injects these.
            resource = Resource.create({SERVICE_NAME: os.getenv("OTEL_SERVICE_NAME", "python-sample-app")})
            provider = TracerProvider(resource=resource)
            processor = BatchSpanProcessor(OTLPSpanExporter(endpoint=os.getenv("OTEL_EXPORTER_OTLP_ENDPOINT", "http://otel-collector.opentelemetry-collector:4317")))
            provider.add_span_processor(processor)
            trace.set_tracer_provider(provider)

            app = Flask(__name__)
            FlaskInstrumentor().instrument_app(app) # This is typically done by the auto-instrumentation agent

            @app.route("/")
            def hello():
                tracer = trace.get_tracer(__name__)
                with tracer.start_as_current_span("hello-request"):
                    return f"Hello from {os.getenv('OTEL_SERVICE_NAME', 'python-sample-app')}!"

            if __name__ == "__main__":
                app.run(host="0.0.0.0", port=5000)
            EOF
            python app.py
        ports:
        - containerPort: 5000
---
apiVersion: v1
kind: Service
metadata:
  name: python-sample-app
spec:
  selector:
    app: python-sample-app
  ports:
    - protocol: TCP
      port: 80
      targetPort: 5000
  type: ClusterIP
kubectl apply -f sample-app.yaml

Verify

Observe the Pod events and check its description. You should see an initContainer related to OpenTelemetry injection. The application Pod should transition to a Running state.

kubectl get pods -l app=python-sample-app
kubectl describe pod -l app=python-sample-app | grep -A 5 "Init Containers"

Expected Output (snippet from describe pod):

Init Containers:
  opentelemetry-auto-instrumentation-python:
    Container ID:   containerd://...
    Image:          ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python:latest
    Image ID:       ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-python@sha256:...
    Port:           <none>
    Host Port:      <none>
    Command:
      cp
      -r
      /otel-python-agent
      /var/opentelemetry-instrumentation/

5. Generate Traffic and View Traces

Now that our application is running and auto-instrumented, let’s generate some traffic to ensure it produces traces. We’ll access the application through a simple port-forward.

After generating traffic, the auto-instrumented application will send its traces to the OpenTelemetry Collector, which in turn forwards them to Jaeger. Jaeger provides a user interface to visualize these distributed traces, allowing you to see the flow of requests across services, identify bottlenecks, and debug performance issues. This end-to-end visibility is crucial for understanding the behavior of complex microservices architectures.

# Port-forward the sample application service
kubectl port-forward svc/python-sample-app 8080:80 &

# Generate some requests
curl http://localhost:8080
curl http://localhost:8080/

# Port-forward Jaeger UI
kubectl port-forward svc/jaeger-query 16686:16686 -n opentelemetry-collector &

Verify

Open your web browser and navigate to http://localhost:16686. In the Jaeger UI, select “python-sample-app” from the “Service” dropdown and click “Find Traces.” You should see traces corresponding to your HTTP requests.

Expected Output: You should see traces in the Jaeger UI for the python-sample-app service, showing spans like GET / and hello-request.

Production Considerations

While auto-instrumentation simplifies observability, deploying it in a production Kubernetes environment requires careful planning:

  1. Resource Management: OpenTelemetry agents and collectors consume CPU and memory. Monitor their resource usage and scale collectors appropriately. Use Karpenter for cost optimization and intelligent node scaling to manage node resources efficiently, especially with fluctuating telemetry loads.
  2. High Availability: Deploy multiple replicas of the OpenTelemetry Collector and Jaeger components. Consider using a persistent storage backend for Jaeger (e.g., Elasticsearch, Cassandra) instead of all-in-one for production.
  3. Security:
    • TLS/mTLS: Secure communication between applications, collectors, and backends using TLS. The OpenTelemetry Collector supports TLS configuration.
    • Authentication: Implement authentication for exporters sending data to external systems.
    • Network Policies: Restrict network access to your OpenTelemetry Collector and observability backends using Kubernetes Network Policies. This prevents unauthorized data exfiltration or ingestion.
    • Image Security: Use trusted and scanned container images for OpenTelemetry components. Integrate with tools like Sigstore and Kyverno for supply chain security and policy enforcement.
  4. Scalability: For large clusters, consider deploying OpenTelemetry Collectors as a DaemonSet for agent-level collection and separate Deployments for gateway-level collection. This architecture scales horizontally.
  5. Configuration Management: Manage OpenTelemetry Collector configurations using GitOps principles. Use Helm charts with configurable values for different environments.
  6. Sampling: In high-throughput environments, sending every trace can be overwhelming. Implement intelligent sampling strategies (e.g., head-based, tail-based) within your OpenTelemetry Collector to reduce data volume while retaining critical traces.
  7. Data Retention: Plan your data retention policies for your observability backend (e.g., Jaeger, Prometheus, Loki) to manage storage costs and compliance.
  8. Monitoring and Alerting: Monitor the OpenTelemetry Collector itself for health, throughput, and error rates. Set up alerts for any issues that might impact telemetry data flow.
  9. Language-Specific Considerations: Be aware of the limitations and specific requirements for auto-instrumentation across different programming languages. Some languages might require specific environment variables or library versions.
  10. Integration with Service Mesh: If you’re using a service mesh like Istio (especially with Istio Ambient Mesh), understand how OpenTelemetry auto-instrumentation interacts with the mesh’s inherent observability features. You might choose to leverage the mesh’s tracing capabilities or augment them with OpenTelemetry.

Troubleshooting

  1. Issue: Pods are stuck in Pending or Init:0/1.

    Solution: This often indicates a problem with the init container injected by the OpenTelemetry Operator. Describe the Pod to check init container logs and events.

    kubectl describe pod <pod-name>
    kubectl logs <pod-name> -c opentelemetry-auto-instrumentation-python # Or other language agent

    Common causes include image pull failures, incorrect permissions, or issues with the injected agent’s startup script.

  2. Issue: Application Pods are running, but no traces appear in Jaeger.

    Solution:

    1. Check Namespace Label: Ensure the namespace has opentelemetry-injection=enabled.
    2. Check Pod Annotations: Verify the Pod has the correct language-specific annotation, e.g., instrumentation.opentelemetry.io/inject-python: "true".
    3. Collector Reachability: Ensure the application can reach the OpenTelemetry Collector. Check the OTEL_EXPORTER_OTLP_ENDPOINT environment variable in the application’s Pod.
    4. Collector Logs: Check the OpenTelemetry Collector logs for errors or dropped spans.
    5. kubectl logs -f otel-collector-... -n opentelemetry-collector
    6. Jaeger Collector Logs: Check if Jaeger’s collector is receiving data.
    7. kubectl logs -f jaeger-... -n opentelemetry-collector
  3. Issue: OpenTelemetry Operator Pod is not running.

    Solution: Check the operator’s logs and events for startup failures.

    kubectl get pods -n opentelemetry-operator
    kubectl describe pod opentelemetry-operator-controller-manager-... -n opentelemetry-operator
    kubectl logs opentelemetry-operator-controller-manager-... -n opentelemetry-operator

    Look for issues like RBAC permissions, misconfigured webhooks, or resource constraints.

  4. Issue: Auto-instrumentation is not working for a specific language/framework.

    Solution:

    1. Operator Version: Ensure you’re using a recent version of the OpenTelemetry Operator that supports the desired language’s auto-instrumentation.
    2. Agent Image: Verify the specific auto-instrumentation image for that language is correct and available (e.g., ghcr.io/open-telemetry/opentelemetry-operator/autoinstrumentation-java).
    3. Documentation: Refer to the OpenTelemetry documentation for language-specific auto-instrumentation requirements and known limitations.
  5. Issue: High resource consumption by auto-instrumented applications or the collector.

    Solution:

    1. Sampling: Implement head or tail-based sampling in your OpenTelemetry Collector configuration to reduce the volume of traces.
    2. Batching: Optimize batch processor settings in the collector (send_batch_size, timeout).
    3. Resource Limits: Set appropriate CPU and memory limits on your application containers and the collector Pods to prevent resource exhaustion.
    4. Collector Scaling: Scale up the number of OpenTelemetry Collector replicas if it’s a bottleneck. Consider a DaemonSet for agent-level collection on each node.
  6. Issue: Missing attributes or incorrect service names in traces.

    Solution:

    1. Environment Variables: Ensure OTEL_SERVICE_NAME and other relevant OTEL_RESOURCE_ATTRIBUTES environment variables are correctly set in the instrumented Pod. The operator usually injects these.
    2. Collector Processors: Use OpenTelemetry Collector processors like resourcedetection or attributes to enrich or modify span attributes if they are incorrect or missing.

FAQ Section

  1. What is OpenTelemetry auto-instrumentation?

    OpenTelemetry auto-instrumentation is a technique that allows you to automatically instrument your applications to collect telemetry data (traces, metrics, logs) without modifying their source code. In Kubernetes, this is typically achieved using an OpenTelemetry Operator that injects language-specific agents or libraries into your application Pods at runtime.

  2. Which programming languages are supported for auto-instrumentation?

    The OpenTelemetry Operator supports auto-instrumentation for several popular languages, including Java, Python, Node.js, .NET, and PHP. Support for other languages is continuously evolving. Always refer to the official OpenTelemetry documentation for the most up-to-date list and specific requirements.

  3. What’s the difference between auto-instrumentation and manual instrumentation?

    Manual instrumentation involves adding OpenTelemetry SDK code directly into your application’s source code. This gives you fine-grained control over what data is collected and how. Auto-instrumentation uses agents or bytecode manipulation to automatically capture common operations (like HTTP requests, database calls) without touching your code. Auto-instrumentation is quicker to deploy for basic observability, while manual instrumentation is better for capturing custom business logic or specific performance bottlenecks.

  4. Can I combine auto-instrumentation with manual instrumentation?

    Yes, absolutely! This is a common and recommended practice. Auto-instrumentation provides a baseline of observability for common framework operations. You can then use manual instrumentation to add custom spans, attributes, or metrics for specific business transactions or critical code paths that the auto-instrumentation might miss. The two approaches complement each other, providing comprehensive visibility.

  5. How does auto-instrumentation impact application performance?

    OpenTelemetry auto-instrumentation agents are designed to have a minimal performance overhead. However, like any additional process or library, they will consume some CPU and memory resources. The impact varies depending on the language, the agent’s implementation, and the volume of telemetry data generated. It’s crucial to perform load testing and monitor resource usage in a staging environment to understand the specific impact on your applications.

Cleanup Commands

To remove all resources created during this tutorial:

# Delete the sample application
kubectl delete -f sample-app.yaml

# Remove the namespace label
kubectl label namespace default opentelemetry-injection-

# Delete the OpenTelemetry Collector and Jaeger
kubectl delete -f collector.yaml
kubectl delete namespace opentelemetry-collector

# Uninstall the OpenTelemetry Operator
helm uninstall opentelemetry-operator -n opentelemetry-operator
kubectl delete namespace opentelemetry-operator

# Remove Helm repo (optional)
helm repo remove open-telemetry

Next Steps / Further Reading

You’ve successfully set up OpenTelemetry auto-instrumentation! Here are some next steps to deepen your understanding and enhance your observability setup:

  • Explore OpenTelemetry Collector Processors: Learn about various OpenTelemetry Collector processors for data enrichment, filtering, batching, and sampling.
  • Integrate with Other Backends: Configure your OpenTelemetry Collector to export to other observability backends like Prometheus for metrics, Loki for logs, or cloud-specific services like AWS X-Ray, Google Cloud Trace, or Azure Monitor.
  • Advanced Sampling Strategies: Dive deeper into OpenTelemetry sampling to manage data volume in high-traffic scenarios.
  • Custom Instrumentation: Learn how to add manual instrumentation for critical business logic in your applications.
  • eBPF Observability: Explore how eBPF can provide even deeper insights into your Kubernetes workloads, especially for network and system-level observability. Check out our guide on eBPF Observability with Hubble.
  • Service Mesh Integration: If you’re using a service mesh, understand how to integrate OpenTelemetry with tools like Istio Ambient Mesh for enhanced traffic management and observability.
  • Security and Policy: Strengthen your cluster’s security posture by implementing Kubernetes Network Policies and integrating with tools like Sigstore and Kyverno for supply chain security.

Conclusion

OpenTelemetry auto-instrumentation for Kubernetes is a game-changer for achieving comprehensive observability in cloud-native environments. By leveraging the OpenTelemetry Operator, you can effortlessly inject tracing, metrics, and logging capabilities into your applications without modifying their source code. This not only accelerates your journey to full observability but also reduces the maintenance burden associated with manual instrumentation.

As your Kubernetes clusters grow in complexity, the ability to automatically gain insights into your services becomes invaluable. Coupled with robust collectors and powerful visualization tools like Jaeger, OpenTelemetry provides the foundation for understanding application behavior, diagnosing performance issues, and ensuring the health of your distributed systems. Embrace auto-instrumentation to unlock the full potential of observability in your Kubernetes deployments.

Leave a comment