Use Init Containers

Note: Init container installation requires a Kubernetes environment.

You can use Kubernetes init containers to instrument the .NET Agent. In this method, the init container copies the agent binaries into the application container at runtime. The deployment spec used by the application references two containers:

  • Application container based on an image that does not contain any .NET Agent binaries
  • Second init container based on an image that only contains the .NET Agent binaries.

The deployment spec is updated to reference these two containers and copy the agent binaries from the init container to the application container at deployment time. Once the copy is performed, the init container terminates.

To use init containers to copy the .NET Agent for Linux binaries, perform these steps:

  1. Build the .NET Core Application Image
  2. Build the .NET Agent for Linux Init Container Image
  3. Add the Init Container to the Deployment Spec
  4. Set the .NET Agent for Linux Environment Variables
  5. Set the APPDYNAMICS_AGENT_UNIQUE_HOST_ID Environment Variable
  6. Copy the AppDynamicsConfig.json File to the Container
  7. (On-Premises Controller Only) Copy the Controller Certs to the Container
  8. Example Configuration for Using an Init Container

Build the .NET Core Application Image

Build a .NET Core application image. Do not include the .NET Agent for Linux binaries.

Build the .NET Agent for Linux Init Container Image

Build the .NET Agent for Linux image separately from the application image. You can reuse this image across multiple .NET Core application deployments.

Alternatively, the init container can reference a pre-built image from Splunk AppDynamics on Docker Hub.

Add the Init Container to the Deployment Spec

Edit the deployment spec to add the required sections that allow you to copy the agent binaries from the init container to the application image.

The following snippet from a deployment spec shows the required volumes, volumeMounts, and initContainer definitions. The code example assumes the .NET Core application image is published to dotnet-samples:aspnetapp and the init container image uses the pre-built image docker.io/appdynamics/dotnet-core-agent:<version> (where <version> is the .NET Agent version; for example, 21.5.0):

kind: Deployment
spec:
containers:
- name: dotnet-app
image: microsoft/dotnet-samples:aspnetapp
volumeMounts:
- mountPath: /opt/appdynamics
name: appd-agent-repo
initContainers:
- name: appd-agent
image: docker.io/appdynamics/dotnet-core-agent:<version>
volumeMounts:
- mountPath: /appdynamics
name: appd-agent-repo
volumes:
- name: appd-agent-repo
emptyDir: {}

Use ConfigMaps to Configure the App Server Agent

  1. Use a ConfigMap to set the .NET Agent for Linux environment variables that are shared across applications in a namespace:
    apiVersion: v1
    data:
    CORECLR_PROFILER: "{57e1aa68-2229-41aa-9931-a6e93bbc64d8}"
    CORECLR_ENABLE_PROFILING: "1"
    CORECLR_PROFILER_PATH: "/opt/appdynamics/libappdprofiler.so"
    APPDYNAMICS_AGENT_APPLICATION_NAME: "<value>"
    APPDYNAMICS_AGENT_ACCOUNT_NAME: "<value>"
    APPDYNAMICS_CONTROLLER_HOST_NAME: "<value>"
    APPDYNAMICS_CONTROLLER_PORT: "<value>"
    APPDYNAMICS_CONTROLLER_SSL_ENABLED: "<value>"
    APPDYNAMICS_AGENT_REUSE_NODE_NAME: "true"
    APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX: "<value>"
    # variables required to send transaction analytics data
    APPDYNAMICS_ANALYTICS_HOST_NAME: "<value>"
    APPDYNAMICS_ANALYTICS_PORT: "<value>"
    APPDYNAMICS_ANALYTICS_SSL_ENABLED: "<value>"
    kind: ConfigMap
    metadata:
    name: appd-dotnet-config
    Note that the analytics host, port and ssl settings depend on how the Analytics Agent is deployed. See Deploy Analytics in Kubernetes for options.
  2. (Optional) If you are running your .NET Core application in an Alpine Linux container, set LD_LIBRARY_PATH in the ConfigMap:
    apiVersion: v1
    data:
    CORECLR_PROFILER: "{57e1aa68-2229-41aa-9931-a6e93bbc64d8}"
    CORECLR_ENABLE_PROFILING: "1"
    CORECLR_PROFILER_PATH: "/opt/appdynamics/libappdprofiler.so"
    LD_LIBRARY_PATH: "/opt/appdynamics"
    ...
    kind: ConfigMap
    metadata:
    name: appd-dotnet-config
  3. Apply the ConfigMap to the namespace:
    kubectl -n dotnetapp apply -f appd-dotnet-config.yaml
  4. Update the deployment spec to reference the ConfigMap:
    spec:
    containers:
    - name: dotnet-app
    envFrom:
    - configMapRef:
    name: appd-dotnet-config
    ...

Use Secrets for the Controller Access Key

  1. Create a Secret using kubectl:
    kubectl -n dotnetapp create secret generic appd-agent-secret --from-literal=access-key=<access-key>
  2. Update the deployment spec to reference the Secret:
    spec:
    containers:
    - name: dotnet-app
    env:
    - name: APPDYNAMICS_AGENT_ACCOUNT_ACCESS_KEY
    valueFrom:
    secretKeyRef:
    name: appd-agent-secret
    key: access-key
    ...

Set Application-Specific Configuration in the Deployment Spec

Set the application-specific tier name environment variable APPDYNAMICS_AGENT_TIER_NAME in the deployment spec:
spec:
containers:
- name: dotnet-app
env:
- name: APPDYNAMICS_AGENT_TIER_NAME
value: dotnet-service

Set the APPDYNAMICS_AGENT_UNIQUE_HOST_ID Environment Variable

Note: The APPDYNAMICS_AGENT_UNIQUE_HOST_ID environment variable is supported in version 20.7.0+ of the .NET Agent for Linux. For earlier versions, a property must be set in AppDynamicsConfig.json based on a runtime value. See this example deployment spec.

Set the APPDYNAMICS_AGENT_UNIQUE_HOST_ID environment variable to enable APM correlation with the Cluster Agent. Since the value depends on a runtime value, set this environment variable in the container startup command using the values documented in Manually Configure App Agents to Correlate with the Cluster Agent. For example, for a Kubernetes environment with the Docker runtime, set the environment variable as shown (export is required):

kind: Deployment
spec:
containers:
image: microsoft/dotnet-samples:aspnetapp
command: ["/bin/sh"]
args: ["-c", "export APPDYNAMICS_AGENT_UNIQUE_HOST_ID=$(sed -rn '1s#.*/##; 1s/(.{12}).*/\\1/p' /proc/self/cgroup) && dotnet aspnetapp.dll"]
...

Copy the AppDynamicsConfig.json File to the Container

Some .NET Agent for Linux options must be set in the AppDynamicsConfig.json file. This includes setting the outputtype to console, which facilitates sending the agent logs to log aggregation tools and viewing the logs using kubectl logs.

  1. Create a ConfigMap based on the contents of AppDynamicsConfig.json:
    $ kubectl -n dotnetapp create configmap appd-config --from-file=AppDynamicsConfig.json
  2. Update the deployment spec to add the AppDynamicsConfig.json file to the container file system. Use volumes and volumeMounts that reference the ConfigMap contents:
    kind: Deployment
    spec:
    containers:
    image: microsoft/dotnet-samples:aspnetapp
    command: ["/bin/sh"]
    args: ["-c", "export APPDYNAMICS_AGENT_UNIQUE_HOST_ID=$(sed -rn '1s#.*/##; 1s/(.{12}).*/\\1/p' /proc/self/cgroup) && dotnet aspnetapp.dll"]
    volumeMounts:
    - name: appd-config
    subPath: AppDynamicsConfig.json
    mountPath: /opt/appdynamics/AppDynamicsConfig.json
    volumes:
    - name: appd-config
    configMap:
    name: appd-config

(On-Premises Controller Only) Copy the Controller Certs to the Container

If the .NET Agent for Linux communicates with an on-premises Controller, the Controller certs must be copied to the container. See Enable SSL for the .NET Agent.

  1. Define a ConfigMap to reference the cert file. Use a volume mount in the deployment spec to mount the ConfigMap contents to the container:
    $ kubectl create configmap appd-cert --from-file=cacerts
  2. Add the cert file to the container file system using volumes and volumeMounts as shown in the deployment spec snippet:
    kind: Deployment
    spec:
    containers:
    image: microsoft/dotnet-samples:aspnetapp
    volumeMounts:
    - name: appd-cert
    subPath: cacerts
    mountPath: /opt/appdynamics/cacerts
    volumes:
    - name: appd-cert
    configMap:
    name: appd-cert
  3. Set the APPDYNAMICS_CONTROLLER_SSL_ENABLED and APPDYNAMICS_CONTROLLER_SSL_CERTFILE environment variables in the ConfigMap. See .NET Agent for Linux Environment Variables.
    apiVersion: v1
    data:
    CORECLR_PROFILER: "{57e1aa68-2229-41aa-9931-a6e93bbc64d8}"
    CORECLR_ENABLE_PROFILING: "1"
    CORECLR_PROFILER_PATH: "/opt/appdynamics/libappdprofiler.so"
    APPDYNAMICS_CONTROLLER_SSL_ENABLED: true
    APPDYNAMICS_CONTROLLER_SSL_CERTFILE: /opt/appdynamics/cacerts
    ...
    kind: ConfigMap
    metadata:
    name: appd-dotnet-config

Example Configuration for Using an Init Container

This Dockerfile is an example of building the .NET Agent for Linux init container image using a multi-stage build. A complete example of a deployment spec that uses an init container to copy the agent binaries can be found on Github: dotnet-app.yaml.