Use Init Containers

Note: This option applies to containers running in Kubernetes.

This option uses Kubernetes init containers to copy the Node.js Agent binaries into the application container when the application starts up. It assumes that the application image is built without any Node.js Agent binaries and that a second init container image is built which contains the Node.js Agent binaries. The deployment spec for the application is configured to copy and send the agent binaries to the running application container.

To copy the agent binaries with init containers:

  1. Build the Node.js Application Image
  2. Build the Node.js Agent Init Container Image
  3. Add the Init Container to the Deployment Spec
  4. Set the Node.js Agent Environment Variables
  5. Set the UNIQUE_HOST_ID Environment Variable
  6. (On-Premises Controller Only) Copy the Controller Certs to the Container
Note: These steps assume the application image is built using Node.js version 8 and later, which supports the NODE_OPTIONS environment variable. This environment variable is set in a ConfigMap. For Node.js versions 7 and earlier, refer to this example that uses a start script to include the appdynamics package.

Build the Node.js Application Image

Build the Node.js application image based on the application binaries and dependencies. Do not include the Node.js Agent binaries or settings in the application image.

Build the Node.js Agent Init Container Image

The agent init container image is built separately from the application image and can be reused across multiple Node.js application deployments.

Note: For Linux and Alpine environments, the Node.js Agent init container images are available on Dockerhub. For all other deployment environments, continue with the following instructions to build the init container image.

The Node.js and operating system versions of the init container image should match the Node.js and operating system versions of the application image to ensure that compatible Node.js Agent binaries are selected when running npm install. For more information, see Node.js Supported Environments.

The Node.js and operating system versions are determined by the FROM node:14.4-alpine statement in the Dockerfile:

FROM node:14.4-alpine
…

Follow these steps to build the init container image:

  1. Create a shim.js file that contains a require statement for appdynamics. Set the reuseNode property to true. Set reuseNodePrefix to the value of an environment variable that will be provided in a ConfigMap in a later step:

    require("appdynamics").profile({
    reuseNode: true,
    reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX
    });
  2. If the Node.js Agent should report Transaction Analytics data, add the analytics properties to the require statement and set the value to environment variables that will be provided in a ConfigMap in a later step. See Node.js Settings Reference.

    require("appdynamics").profile({
    reuseNode: true,
    reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
    analytics: {
    host: process.env.APPDYNAMICS_ANALYTICS_HOST_NAME,
    port: process.env.APPDYNAMICS_ANALYTICS_PORT,
    ssl: process.env.APPDYNAMICS_ANALYTICS_SSL_ENABLED
    }
    });
  3. If the Node.js Agent communicates with an on-premises Controller, add the certificateFile property and set it to the location where the cert file will be copied in a later step:

    require("appdynamics").profile({
    reuseNode: true,
    reuseNodePrefix: process.env.APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX,
    certificateFile: /opt/appdynamics/cacerts
    });
  4. In the Dockerfile, copy shim.js to the image:

    COPY ./shim.js /opt/appdynamics/shim.js
  5. Run the npm install command to resolve the appdynamics package:

    $ cd appdynamics
    $ npm install appdynamics@next
  6. In the Dockerfile, copy the contents of the folder containing the appdynamics package to the image:

    COPY appdynamics/ /opt/appdynamics/

For a complete example of building the Node.js Agent init container image using a multi-stage build, see this Dockerfile.

Add the Init Container to the Deployment Spec

Edit the deployment spec to add the sections required 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. It assumes the Node.js application image is published to myrepo/nodejs-app:v1 and the init container image is published to myrepo/appd-nodejs:latest. The shim.js file from the init container image is copied to /opt/appdynamics/shim.js in the application container.

kind: Deployment
spec:
containers:
- name: nodejs-app
image: myrepo/nodejs-app:v1
volumeMounts:
- mountPath: /opt/appdynamics
name: appd-agent-repo
initContainers:
- command:
- cp
- -r
- /opt/appdynamics/.
- /opt/temp
name: appd-agent
image: myrepo/appd-nodejs:latest
volumeMounts:
- mountPath: /opt/temp
name: appd-agent-repo
volumes:
- name: appd-agent-repo
emptyDir: {}

Set the Node.js Agent Environment Variables

To set all of the required Node.js Agent environment variables, try the following options depending on your use case:

See Best Practices to Configure Agents in Kubernetes for more information.

Use ConfigMaps to Configure the App Server Agent

  1. Use a ConfigMap to set the agent environment variables that are shared across Node.js applications in a namespace. For example, see this appd-nodejs-config.yaml snippet:

    apiVersion: v1
    data:
    APPDYNAMICS_AGENT_APPLICATION_NAME: eCommerce
    APPDYNAMICS_AGENT_ACCOUNT_NAME: <value>
    APPDYNAMICS_CONTROLLER_HOST_NAME: <value>
    APPDYNAMICS_CONTROLLER_PORT: <value>
    APPDYNAMICS_CONTROLLER_SSL_ENABLED: <value>
    APPDYNAMICS_AGENT_REUSE_NODE_NAME_PREFIX: <value>
    APPDYNAMICS_AGENT_NODE_NAME: <value> # not used in node name but required by Node.js agent
    APPDYNAMICS_LOGGER_OUTPUT_TYPE: console
    NODE_OPTIONS: '--require /opt/appdynamics/shim.js'
    # 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-nodejs-config

    The NODE_OPTIONS environment variable, supported in Node.js 8 and later, sets the --require option to the location of the shim.js file copied from the init container image. The analytics host, port and ssl settings depend on how the Analytics Agent is deployed. See Deploy Analytics in Kubernetes for options.

  2. Apply the ConfigMap to the namespace:

    $ kubectl -n ecommerce apply -f appd-nodejs-config.yaml
  3. Update the deployment spec to reference the ConfigMap:

    spec:
    containers:
    - name: nodejs-app
    envFrom:
    - configMapRef:
    name: appd-nodejs-config
    ...

Use Secrets for the Controller Access Key

  1. Create a Secret using kubectl:

    $ kubectl -n ecommerce create secret generic appd-agent-secret --from-literal=access-key=<access-key>
  2. Update the deployment spec to reference the Secret:

    spec:
    containers:
    - name: nodejs-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: nodejs-app
env:
- name: APPDYNAMICS_AGENT_TIER_NAME
value: nodejs-service

Set the UNIQUE_HOST_ID Environment Variable

Set the 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 with the values in Manually Configure App Agents to Correlate with the Cluster Agent.

For a Kubernetes environment with the Docker runtime, set the environment variable as shown in the following example:

spec:
containers:
command: ["/bin/sh"]
args: ["-c", "export UNIQUE_HOST_ID=$(sed -rn '1s#.*/##; 1s/(.{12}).*/\\1/p' /proc/self/cgroup) && node /nodejsapp/myapp.js"]

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

If on-premises Controller certs are required, define a ConfigMap to reference the cert file and use a volume mount in the deployment spec to mount the ConfigMap contents to the container.

$ kubectl create configmap appd-cert --from-file=cacerts

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: myrepo/nodejs-app:v1
volumeMounts:
- name: appd-cert
subPath: cacerts
mountPath: /opt/appdynamics/cacerts
volumes:
- name: appd-cert
configMap:
name: appd-cert

The mountPath value should match the certificateFile property in the shim.js file used when building the init container image.

Example Configuration for Using an Init Container

See this deployment spec for a complete example using an init container to copy the agent binaries.