Deploying with Docker

Deploying Apama Applications with Docker

The recommended way to deploy Apama in production enviroments is using a containerized deployment using Docker, Kubernetes or other OCI-compatible systems. Information about deploying Apama in Kubernetes can be found in the About Deploying Apama Applications with Kubernetes section.

Introduction to Apama in Docker

Below is a brief overview of Docker; no familiarity with Docker commands is assumed in this part of the documentation. You need to install Docker before you can make use of the Apama images. See https://docs.docker.com/get-started/ for a more detailed overview of Docker and how to use it.

Images

Images are the base units of the Docker system, providing templates that are used to create the containers, which in turn form the running applications. Docker software runs on various operating systems and can run containers built from the Apama images.

Docker

Docker is a technology that allows an organization to remove the complexity of configuring and deploying software applications within the infrastructure it uses. The Docker platform achieves this by running the applications in what are called containers, which isolate the environment of an application from the deployment environment and provide tools for portability and scalability. As long as the organization infrastructure can run the Docker software, it can run the containers and consequently any applications contained in them. Use cases for Docker containers include modernization of legacy applications, migration to a cloud infrastructure, services, and continuous integration and deployment.

Apama and Cumulocity images

Cumulocity has a presence on the Amazon ECR Public Gallery image repository. Several images are available for Cumulocity products. The offering from Apama is an image which will run an instance of the correlator application. See https://gallery.ecr.aws/apama/ for the published images.

Alternatively, images for several products, including Apama, may be built from an installation using scripts included in the installation.

Published Apama container images

Cumulocity produces several different variations of the Apama product as Docker images, depending on your use case. Each Apama image has a corresponding builder image for use in multi-stage builds.

Image Use
public.ecr.aws/apama/apama-correlator Image for the correlator, including support for Cumulocity, Java, Python. This is the normal image to use for Cumulocity custom microservices.
public.ecr.aws/apama/apama-correlator-minimal Smallest image for the correlator, aimed at smaller use cases. Does not contain Cumulocity, Java or Python support.
public.ecr.aws/apama/apama-builder Project build and test tools for deploying and testing projects to be used with the apama-correlator and apama-minimal images in a multi-stage Docker build.

For more details of the content of each image, see the descriptions on the pages above. You must ensure that you select the appropriate image containing the components you require.

For information on how to use the builder images in a multi-stage build, see Building Apama projects during the Docker build.

Quick start to using an Apama image

The Apama image that we are using here is available on Amazon ECR Public Gallery (https://gallery.ecr.aws/apama/apama-correlator/).

  1. Log in to Amazon ECR Public Gallery using your credentials:

    docker login
    
  2. Obtain the image from the repository so that it will be available to use:

    docker pull public.ecr.aws/apama/apama-correlator:version
    

    where version is the current Apama version number.

    Note:

    If you logged in successfully but get an error during the docker pull command, it is likely that there is a spelling mistake or that the image you specified is missing.

  3. List the images available to you:

    docker images
    

    You should see the image that you pulled in the output of the above command (keep in mind there may be many images if you are using a shared machine).

  4. Create a container using the image and run it in Docker:

    docker run -d --name container --rm public.ecr.aws/apama/apama-correlator:version
    

    The above command will “detach” after running the container. You can see it running using the following command:

    docker ps
    

    You can interact with the running image in many ways (see the Docker documentation for the appropriate commands), but we will now retrieve the logs from the running container and then stop the container.

  5. To examine the log of the running container, enter the following command using the name that was set with the --name container argument of the docker run command.

    docker logs container
    

    When the above command is executed, the container identifier or the name which you can find in the output of the docker ps command is taken as a parameter.

  6. You can now stop the container:

    docker stop container
    

    This also removes the container since it was started with the --rm option.

Running as the apama user within a container

Cumulocity images are configured not to run processes as root by default within containers. This is standard container practice. All images create a user apama with the user identifier and group identifier of 1724. By default, all processes run in the container, and all RUN commands in Dockerfiles using these images as a base run with that user identifier.

COPY commands may need to specify writing as the apama user via the --chown argument. It is recommended to continue using this user for all of your commands within Docker.

If you need to run as another user, you need to add USER statements to your Dockerfile or the appropriate options to your docker run command.

Deploying an Apama application in Docker

The examples below reference the image in Amazon ECR Public Gallery.

The base image simply provides an empty running correlator, with the management port exposed. Usually, you will create your own image derived from the base image which adds your application and uses correlator command line arguments to configure the correlator to initialize itself with your application. You can also use the command line tools described in Command line tools to manage the correlator if needed.

  1. Typically, the first step is to create the Dockerfile that references the required image of the Apama correlator. The following is an example Dockerfile:

    # Reference the Apama image at public.ecr.aws/apama/apama-correlator:<TAG>.
    # The tag refers to the version number of the Apama correlator.
    FROM public.ecr.aws/apama/apama-correlator:version
    
    # Copy files from the local app directory to /app in the resulting image.
    COPY --chown=apama:apama app/* /app/
    
    # This is the command we run - it references the internal directory.
    CMD ["correlator","--config","/app"]
    

    The above example file produces an image that contains a root level directory called /app that has copies of local files in it. These files will be owned by the user the correlator runs as, called apama.

  2. When the correlator image runs, it is directed to read the configuration file init.yaml that is present within the directory. An example of this from the Simple sample application is shown below. It can be found in the applications/Simple directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository, along with the HelloWorld.mon file that it references.

    Example init.yaml:

    correlator:
        initialization:
            list:
                - ${PARENT_DIR}/HelloWorld.mon
    

    At correlator startup, the above configuration file injects the monitor file HelloWorld.mon from the same directory. The image build process will copy the HelloWorld.mon and init.yaml files into the image. Thus, the application image can run without outside dependencies.

  3. You build the image using the docker build command. The following example assumes that the command is run from the directory containing the Dockerfile. See the Docker documentation for details on the available options.

    docker build --tag organization/application.
    
  4. Once the image is built, it is stored locally. You can view it using the docker images command. Note that the image is not running at this point.

    docker images | grep application
    
  5. To run the image as a container, enter the following command:

    docker run -d --rm --name container organization/application
    

    The options -d and --rm are used to detach and remove the container after shutdown.

  6. To examine the running process, enter the following command:

    docker ps
    
  7. To examine the logs, enter the following command:

    docker logs container
    
  8. To stop the container, enter the following command:

    docker stop container
    

    Now the docker ps command should no longer show your container.

  9. To remove the image, enter the following command:

    docker rmi organization/application
    

    This untags and deletes the image.

Note that the application is included in the image you create. The files copied into the image will not change and any output will not persist outside the container. The management port is exposed, and therefore the correlator can be manipulated remotely through the Management interface (see also Using the Management interface). However, you can interact with the running container in many ways, including starting a shell, examining logs, and running commands in the container. See the Docker documentation for details on the available options.

Developing an Apama application using the Docker image

The Dockerfile that you created in Deploying an Apama application in Docker includes the app directory and its contents. Thus, you would have to recreate the image every time the configuration file or the EPL files change, which is inconvenient during the development phase of the application where the EPL changes frequently. You can address that by mapping in a local directory when running the container and use that to hold your application. For example:

docker run -d --rm --name container -v /local/path:/app public.ecr.aws/apama/apama-correlator:version correlator --config /app

Keep in mind that you are using the official image and not creating your own. Because you are mounting in a local directory containing the application, there is no need to build a custom image. It will be read from the /local/path which is mounted in instead.

Now you can make changes to the EPL or init.yaml file and simply restart the container to pick up the changes. When you have completed your changes and want to deploy, you can add a Dockerfile to bake the files into the image again. It is possible to define and map multiple volumes, allowing flexible usage of the image.

Building Apama projects during the Docker build

Some Apama applications require additional build steps when creating a Docker image, such as building custom plug-ins, or running the engine_deploy tool (see also Deploying a correlator). A second builder image can be used for project build steps, to keep the runtime image as small as possible. The builder image can be used as part of a Docker multi-stage build.

A typical multi-stage Dockerfile looks like this:

FROM buildbase as builder

COPY source /source
RUN buildstep

FROM runtimebase

COPY --from=builder /buildoutput /buildoutput

CMD ["/buildoutput"]

For a typical Apama project, the Dockerfile looks something like this:

ARG APAMA_VERSION=version
ARG APAMA_BUILDER=public.ecr.aws/apama/apama-builder:${APAMA_VERSION}
ARG APAMA_IMAGE=public.ecr.aws/apama/apama-correlator:${APAMA_VERSION}
FROM ${APAMA_BUILDER} as builder

COPY --chown=apama:apama MyProject ${APAMA_WORK}/MyProject
RUN engine_deploy --outputDeployDir ${APAMA_WORK}/MyProject_deployed \
${APAMA_WORK}/MyProject

FROM ${APAMA_IMAGE}

COPY --from=builder --chown=apama:apama ${APAMA_WORK}/MyProject_deployed \
${APAMA_WORK}/MyProject_deployed

WORKDIR ${APAMA_WORK}

CMD ["correlator", "--config", "MyProject_deployed"]

A project with Docker support can be built into an image using the following command:

docker build MyProject

For most projects, the provided Dockerfile will be sufficient. If you have additional build steps (such as building custom plug-ins), you can add them to the Dockerfile in your project. A default Dockerfile with the name Dockerfile.project is provided in the etc directory of your Apama installation. You can copy this file manually into the root of any project which can be deployed using the engine_deploy tool.

Also, note the use of build arguments in the Dockerfile. This allows you to use --build-arg to specify the name of an alternative builder or runtime image. If needed you can change the version of Apama that is used from Amazon ECR Public Gallery:

docker build -t appimage --build-arg APAMA_VERSION=version

Note: Each time you import an Apama project from a previous version into the current version, you have to update the version in the Dockerfile, or you have to run docker build with the appropriate build arguments to override the version.

For more details of the images available, see Published Apama container images. For exact details of the contents of each image, see the corresponding pages on Amazon ECR Public Gallery. However, in general, the builder images contain the following additional tools:

The image also contains a Java compiler. It does not by default contain a C++ compiler. If you want to compile C++ code, then you need to install a C++ compiler as part of your build step using a multi-stage build. This is only included while you are building, not in the final image, as long as you do it in the build part of a multi-stage build.

ARG APAMA_BUILDER=public.ecr.aws/apama/apama-builder:version
ARG APAMA_IMAGE=public.ecr.aws/apama/apama-correlator:version
FROM ${APAMA_BUILDER} as builder

COPY --chown=apama:apama MyProject ${APAMA_WORK}/MyProject
RUN engine_deploy --outputDeployDir ${APAMA_WORK}/MyProject_deployed \
${APAMA_WORK}/MyProject
RUN apt install -y clang-19 make && make -C MyProject

FROM ${APAMA_IMAGE}

COPY --chown=apama:apama --from=builder \
${APAMA_WORK}/MyProject_deployed ${APAMA_WORK}/MyProject_deployed
COPY --chown=apama:apama --from=builder \
${APAMA_WORK}/MyProject/libMyLib.so ${APAMA_WORK}/lib/libMyLib.so

WORKDIR ${APAMA_WORK}

CMD ["correlator", "--config", "MyProject_deployed"]

Apama samples for Docker

There are a number of samples that can be found in the applications directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository. The Simple sample contains a “Hello world” application. The other samples in the above directory cover more complex use cases. These samples build upon the base image and demonstrate how to use a dockerized Apama correlator to build your own application or service.

The README.md files that are provided in the applications directory and in each of the individual sample subdirectories guide you through the process of building and running. The samples demonstrate various ways in which Docker can be used to deploy Apama.

Weather

This sample deploys Apama’s Weather demo. It demonstrates that various Apama components can be run in distinct containers.

MemoryStore

Earlier samples showed how to use Dockerfiles to create derived images that give Apama components from the base image access to configuration and EPL code. However, this approach only suffices for static data that can be reproduced by copying in files from a canonical source. For containers to share dynamic data, they need a live view on that data. This is provided by a Docker feature called “volumes”, which allows containers to share parts of their file system with each other.

This sample contains a toy application MemoryStoreCounter.mon that makes use of the MemoryStore to lay down persistent state on disk in the form of a number that increments each time the monitor is loaded. While the correlator container is the one reading and writing to the MemoryStore, the persistent file is on a Docker volume which is persisted between container restarts.

You can view the created volume using the following command:

docker volume ls

Docker volumes give you the ability to manage data that has a different lifecycle to the container that uses it. In an application like this, you can replace the other containers with equivalents that are based on a newer version of Apama. After bringing them up again, the correlator will still have access to the MemoryStore data that it wrote in a previous iteration, as this data is owned by the volume.

Secrets

This sample demonstrates how to use Docker secrets to set variables in correlator configuration files. These can then be loaded at runtime into a correlator.

Deploying Apama Applications with Kubernetes

Introduction to Apama in Kubernetes

Kubernetes is an open-source system that provides an alternative for orchestrating containers. The Apama images as described in Deploying Apama applications with Docker can be used within Kubernetes, allowing an alternative to deploying and controlling a user application. See https://kubernetes.io/ for a more detailed overview of Kubernetes and how to use it.

Images

Much like Docker, images form the basis of the containers that are run and controlled by Kubernetes. Creating and obtaining images is identical to Docker. You can get the Apama image from Amazon ECR Public Gallery as described in Quick start to using an Apama image.

The images are templates that are used to create the containers. Kubernetes software runs on various operating systems and can run containers built from the Apama images.

Kubernetes

Kubernetes uses a different command line application and terminology from Docker. For example, the simplest unit is a pod. A pod corresponds to a running process on the cluster, but can be more than one container. The command line interface is kubectl and should be used instead of docker. See the Kubernetes documentation for more details on the various command-line options.

Quick start to using Apama in Kubernetes

For this quick start, you have to build the image from the Simple sample that can be found in the applications/Simple directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository. See the README.md file in the applications directory for detailed instructions.

Once you have built the image, proceed as described below.

  1. Define a deployment YAML file which references the image you wish to run as a container. An example of this is the kubernetes.yml file which can be found in the applications/Simple directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository.

    This example YAML file creates a pod. However, Kubernetes can be used to define much more complex objects and behaviors; see the Kubernetes documentation for details of the possible configurations.

  2. Use the Kubernetes command line tool (kubectl) to create the container and run it (for example, using the above example YAML file):

    kubectl create -f kubernetes.yml
    

    The create command starts the container under Kubernetes control. You can now use the kubectl command line to interrogate the pod that has been created, see below.

  3. To return the name of the pod that corresponds to running your Apama container:

    kubectl get pods
    
  4. To examine the logs from the container in the pod:

    kubectl logs podname
    
  5. Once you are finished, you can shut down everything and remove the containers. To do so, you use the same YAML file that has been used to start the process:

    kubectl delete -f kubernetes.yml
    

The power of Kubernetes comes with more complex setups involving multiple containers and hosts. Some of these features are covered in more complex samples; see Apama samples for Kubernetes for further information.

Deploying an Apama application using Kubernetes

You will either need to create an image or you will already have images for the application you wish to deploy using Kubernetes.

  1. To create images use docker build and docker push.

    To use Kubernetes, you must publish the images in a registry and not just in a local Docker server. You must also include these tags in the Kubernetes configuration file that is used to create the objects.

  2. Once you have determined which images you want to use, and know their location and tag name, you can create the YAML configuration file for Kubernetes. This configuration file defines the state that you want from a running system, indicating the runtime characteristics you want Kubernetes to adhere to. This file makes no mention of where things run on a cluster, but it can be used to determine behavior like restarting, replica containers, load balancing and resource restrictions.

    Apama provides the example configuration file kubernetes.yml which can be found in the applications/Secrets directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository. Detailed descriptions of the possible contents of a Kubernetes configuration file can be found on the Kubernetes website (https://kubernetes.io/).

  3. To create the Kubernetes objects (pods and service):

    kubectl create -f kubernetes.yml
    

    After you have created the objects defined in the kubernetes.yml file, you can list the pods and the service, and you can examine the details of the running objects, see below.

  4. To list the pods:

    kubectl get pods
    
  5. To list the service:

    kubectl get services
    
  6. To examine the details of the running objects (image, container, volumes, and status events):

    kubectl describe pod PODNAME
    
  7. To examine logs use a command such as:

    kubectl logs PODNAME
    
  8. You can run commands in the pod. For example, to run a single command:

    kubectl exec PODNAME 'ls'
    

    Or to open a shell on the running container:

    kubectl exec -it PODNAME bash
    
  9. To shut down the application, you use the same YAML file that has been used to start the process:

    kubectl delete -f kubernetes.yml
    

For more samples of Kubernetes configurations applied to Apama images and applications, see Apama samples for Kubernetes.

Apama samples for Kubernetes

There are a number of samples that can be found in the applications directory of the https://github.com/Cumulocity-IoT/apama-streaming-analytics-docker-samples repository. The Simple sample has already been referenced in Quick start to using Apama in Kubernetes. The other samples in the above directory cover more complex use cases. These samples build upon the base image and demonstrate how to use an Apama correlator in a Kubernetes environment to build your own applications.

The README.md files that are provided in the applications directory and in each of the individual sample subdirectories guide you through the process of building and running. The samples demonstrate various ways in which Kubernetes can be used to deploy Apama.

MemoryStore

For containers to share dynamic data, they need a live view on that data. This is provided by a Kubernetes feature called “volumes”, which allows containers to share parts of their file system with each other. We use the Kubernetes PersistentVolume, PersistantVolumeClaim and Deployment objects to implement the sample.

This sample contains a toy application MemoryStoreCounter.mon that makes use of the MemoryStore to lay down persistent state on disk in the form of a number that increments each time the monitor is loaded. While the correlator container is the one reading and writing to the MemoryStore, the persistent file is on a volume which is persisted between container restarts.

Kubernetes volumes give you the ability to manage data that has a different lifecycle to the container that uses it. In an application like this, you can replace the other containers with equivalents that are based on a newer version of Apama. After bringing them up again, the correlator will still have access to the MemoryStore data that it wrote in a previous iteration, as this data is owned by the volume.

Secrets

This sample demonstrates how to use Kubernetes secrets to set variables in correlator configuration files. These can then be loaded at runtime into a correlator.