Deploy .NET Core Agent Using Init Containers

An example illustrating how to deploy on Kubernetes a sample application with the .NET Core Agent using an init container (a.k.a. sidecar).

The init containers option, available in Kubernetes, is used to run additional containers at application startup. You can use this option to deploy your Seeker Agents without modifying your application images. This is achieved by downloading an Agent package using an init container, and loading it to the application container dynamically.

  1. Save the following code snippet in a file, for example, dotnet.yml:
    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dotnet
      namespace: apps
    spec:
      selector:
        matchLabels:
          app: dotnet
      template:
        metadata:
          labels:
            app: dotnet
        spec:      
          initContainers:
              # Download the .NET Core Agent package and extract it to the shared folder /seeker.
            - name: download-agent
              image: busybox:stable
              command:
                - /bin/sh
                - -c
                - |              
                  echo "Download Seeker Agent from: ${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/DOTNETCORE?osFamily=LINUX"
                  wget --no-check-certificate -O /tmp/seeker.zip "${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/DOTNETCORE?osFamily=LINUX"
                  unzip -d /seeker /tmp/seeker.zip              
                  rm -f /tmp/seeker.zip
    
              # Set the env variables below to point to your own server and project.
              env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "dotnet-k8s"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          containers:
            - name: dotnet
              image: mcr.microsoft.com/dotnet/samples:aspnetapp
              ports:
                - containerPort: 80          
               env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "dotnet-k8s"
                  # Instruct the CLR to load the .NET Core Agent on its start
                - name: CORECLR_PROFILER_PATH
                  value: "/seeker/x64/Agent.Profiler-Dnc.so"
                - name: CORECLR_ENABLE_PROFILING
                  value: "1"
                - name: CORECLR_PROFILER
                  value: "{C7AD49B3-093B-4AB1-A241-1E4365DD8901}"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          volumes:
            - name: seeker-agent
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: dotnet-service
      namespace: apps
    spec:
      type: NodePort
      selector:
        app: dotnet
      ports:
        - name: "http"
          protocol: TCP
          port: 80
          targetPort: 80
          nodePort: 31081

    If you are using an Alpine Linux-based Docker image, save the following snippet as dotnet-alpine.yml:

    apiVersion: apps/v1
    kind: Deployment
    metadata:
      name: dotnet-alpine
      namespace: apps
    spec:
      selector:
        matchLabels:
          app: dotnet-alpine
      template:
        metadata:
          labels:
            app: dotnet-alpine
        spec:      
          initContainers:
              # Download the .NET Core Agent package and extract it to the shared folder /seeker.
            - name: download-agent
              image: busybox:stable
              command:
                - /bin/sh
                - -c
                - |              
                  echo "Download Seeker Agent from: ${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/DOTNETCORE?osFamily=LINUX"
                  wget --no-check-certificate -O /tmp/seeker.zip "${SEEKER_SERVER_URL}/rest/api/latest/installers/agents/binaries/DOTNETCORE?osFamily=LINUX"
                  unzip -d /seeker /tmp/seeker.zip              
                  rm -f /tmp/seeker.zip
    
              # Set the env variables below to point to your own server and project.
              env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "dotnet-alpine-k8s"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          containers:
            - name: dotnet-alpine
              image: mcr.microsoft.com/dotnet/samples:aspnetapp
              ports:
                - containerPort: 80          
               env:
                - name: SEEKER_SERVER_URL
                  value: "https://seeker-server:8443"
                - name: SEEKER_PROJECT_KEY
                  value: "dotnet-alpine-k8s"
                  # Instruct the CLR to load the .NET Core Agent on its start
                - name: CORECLR_PROFILER_PATH
                  value: "/seeker/musl-x64/Agent.Profiler-Dnc.so"
                - name: CORECLR_ENABLE_PROFILING
                  value: "1"
                - name: CORECLR_PROFILER
                  value: "{C7AD49B3-093B-4AB1-A241-1E4365DD8901}"
                - name: LD_LIBRARY_PATH
                  value: ""$LD_LIBRARY_PATH:"/seeker/musl-x64/"
              volumeMounts:
                - name: seeker-agent
                  mountPath: "/seeker"
          volumes:
            - name: seeker-agent
              emptyDir: {}
    ---
    apiVersion: v1
    kind: Service
    metadata:
      name: dotnet-alpine-service
      namespace: apps
    spec:
      type: NodePort
      selector:
        app: dotnet-alpine
      ports:
        - name: "http"
          protocol: TCP
          port: 80
          targetPort: 80
          nodePort: 31081
  2. Deploy the application:
    kubectl apply -f dotnet.yml
    or
    kubectl apply -f dotnet-alpine.yml
    The application starts with the CORECLR_* variable that instructs the CLR to load the Agent on its start.