Services

Creating Services

You can create a new Service by adding it to an application. You can also create services, or applications with a single service from an existing Docker image, for example from the DockerHub.

Add a Service to an Application

To add a Service to an Application, click on the Application name to go to Application details and select the + icon.

_images/create-service-wizard-2.png

The Wizard will guide you through the following steps:

Service

Specify the service name and select a Container Type:

Field Required? Description
Name required a unique name for the Service
Type required the Container Type to use for the Service
Depends on optional other services that this Service depends on at runtime. Also see: Service Dependency Injection.

Image

Select or enter an image path, and optionally the version, for the Service:

Field Required? Description
Image Registry optional the Docker Registry to pull the image from
Image Repository required the full image path, including the registry URL
Tag optional the image tag. The ‘latest’ tag is used if not specified

Run Settings (Optional)

Here, you can manage the runtime command line, host name, and environment details for your container:

Field Required? Description
Run Command optional the command line to invoke in the container
Hostname optional the host name to use for the container
Environment Variables optional environment variables to set in the container. See Service Dependency Injection.

Networking

On this page, you can choose how your Service will communicate with other services. You can enable the Nirmata Service Networking, which provides seamless Service Naming, Registration and Discovery, Service Load Balancing, and Customizable Service Routing, or you choose to manage your own networking.

Field Required? Description
Service Networking required enable, or disable, Nirmata Service Networking. See Service Naming, Registration and Discovery, Dynamic Load Balancing, Service Gateway and Service Gateway for more information on Nirmata’s Service Networking features.
Service Ports optional configure which ports are exposed on the container and host. Also see Service Port Management
Network Mode optional Select the Docker Network mode.
DNS optional Configure one or more DNS servers for the container

Routes (Optional)

Field Required? Description
Routes optional Configure URL or DNS routes, if your service is reachable via the Nirmata Gateway Service. See Service Gateway

Health Check (Optional)

Field Required? Description
Type required Type of health check: TCP, HTTP, HTTPS or NONE (No health check)
Endpoint required Endpoint/port for the health check.
Path optional Path/URL to query for the health check.
Start Delay required Time in seconds after which health check should be started.
Interval required Time in seconds between health checks.
Timeout required Health check timeout when the service doesn’t respond
Failure threshold required Number of health check attempts after which a service should be marked DOWN
Success threshold required Number of health check attempts after which a service should be marked UP

Volumes (Optional)

If your Service requires shared or persistent storage, you can map a host file system volumes to the container.

Field Required? Description
Volumes optional configure the Host volume paths to map to the Service container

Advanced (Optional)

If your Service requires shared or persistent storage, you can map a volume to the container.

Field Required Description
Privileged Mode optional select if your Service needs access to host devices. Warning: enabling this mode is not a security best practice.

Environment Variables Injection

Several environment variables are injected by default into every container. These environment variables provide information regarding the context in which the container is running. You can retrieve the value of these environment variables from your code if necessary.

Environment Variable Description
NIRMATA_APPLICATION_NAME The name you gave to your application
NIRMATA_APPLICATION_ID A unique ID generated by Nirmata identifying your application. This ID is used in the Nirmata REST APIs.
NIRMATA_ENVIRONMENT_NAME The environment name where the application is being deployed
NIRMATA_ENVIRONMENT_ID A unique ID generated by Nirmata identifying your environment. This ID is used in the Nirmata REST APIs.
NIRMATA_ENVIRONMENT_TYPE_NAME The name of the environment type use to deploy the environment.
NIRMATA_CONTAINER_TYPE_NAME Name of the container type associated to this service instance.
NIRMATA_CLOUD_PROVIDER_NAME The name
NIRMATA_CLOUD_PROVIDER_ID Unique ID identifying the Cloud Provider used to start the container
NIRMATA_HOST_GROUP_NAME Name of the Host Group selected to start the container
NIRMATA_HOST_GROUP_ID Unique ID of the Host Group selected to start the container
NIRMATA_HOST_ADDRESS IP address of the host selected to run the container
NIRMATA_HOST_NAME Name of the host selected to run the container
NIRMATA_HOST_ID Unique ID identifying the host selected to run the container
NIRMATA_SERVICE_INSTANCE_ID Unique ID identifying the service instance associated to the container
NIRMATA_SERVICE_NAME The name of the service being instantiated
NIRMATA_SERVICE_ID Unique ID identifying the service being instantiated
NIRMATA_SERVICE_VERSION docker tag of the service being instantiated
NIRMATA_SERVICE_PORTS List of ports exposed by this containers. The syntax is: <port-type>:<host-port1>:<container-port1>, ... , <port-type>:<host-portN>:<container-portN> where port type is either TCP or UDP. Example: “TCP:8081:80,TCP:8082:80

Service Dependency Injection

You may need services to know information about other services. This can be achieved using the Nirmata REST API with the Service, or by configuring a dependency across the services, and then injecting service properties such as hostname, IP addresses and port values.

Service Dependency injection is supported within the following fields:

  • Run Command
  • Environment Variables
  • Volume Mappings

There are three syntaxes supported

Syntax 1: {property}

The list of properties supported with syntax 1 are:

  • NIRMATA_APPLICATION_NAME
  • NIRMATA_APPLICATION_ID
  • NIRMATA_ENVIRONMENT_NAME
  • NIRMATA_ENVIRONMENT_ID
  • NIRMATA_ENVIRONMENT_TYPE_NAME
  • NIRMATA_CONTAINER_TYPE_NAME
  • NIRMATA_SERVICE_NAME
  • NIRMATA_SERVICE_ID
  • NIRMATA_SERVICE_INSTANCE_ID
  • NIRMATA_SERVICE_INSTANCE_VERSION
  • NIRMATA_CONTAINER_NAME
  • NIRMATA_HOST_ADDRESS
  • NIRMATA_HOST_PUBLIC_ADDRESS
  • NIRMATA_HOST_PRIVATE_ADDRESS
  • NIRMATA_HOST_NAME
  • NIRMATA_HOST_DNS_NAME
  • NIRMATA_HOST_PUBLIC_DNS_NAME
  • NIRMATA_HOST_PRIVATE_DNS_NAME

This form of dependency injection is used to inject parameters related to the environment (both logical and physical) where the service is going to run.

Example

_images/dependency-injection-form-1.png

Syntax 2: {<service-name>.property}

Where <service-name> is the name of a service required by the service being instantiated. When defining the blueprint of your service you must add <service-name> to the list of required services (“Depends On” field).

The list of properties supported with syntax 2 are:

  • NIRMATA_SERVICE_HOST_NAME
  • NIRMATA_SERVICE_HOST_DNS_NAME
  • NIRMATA_SERVICE_HOST_PUBLIC_DNS_NAME
  • NIRMATA_SERVICE_HOST_PRIVATE_DNS_NAME
  • NIRMATA_SERVICE_ADDRESS
  • NIRMATA_SERVICE_PUBLIC_ADDRESS
  • NIRMATA_SERVICE_PRIVATE_ADDRESS

This form of dependency injection is used to inject runtime parameters from one service into another.

Example

_images/dependency-injection-form-2.png

Syntax 3: {<service-name>.NIRMATA_SERVICE_PORT.<port-name>}

This form of dependency injection is used to inject a port value from one service into another. <service-name> must defined as a required service and <port-name> must be defined in the blueprint of <service-name>.

Example

First we define a management port in the catalog service. In this particular case, the host port is set to 0 to indicate that the port must be allocated dynamically.

_images/dependency-injection-form-3-1.png

Then we can define that the order service depends on the catalog service and we inject the value of catalog management port into the order service.

_images/dependency-injection-form-3-2.png

Service Port Management

The host port can be left blank. In this case, the host port is allocated dynamically within the custom port range (49152-65535).

Ports exposed by a service can have an optional name that is used to identify the port, if this port must be injected into another service.

Service Health Checks

You can optionally configure Service Health Checks for a Service. Nirmata supports TCP, HTTP, and HTTPS health checks. The health check is performed after the application container is running, and after a configurable delay.

_images/service-health.png
Field Description
Type The type of check (TCP, HTTP, or HTTPS) to perform.
Endpoint The Service port to perform the check against
Path The URL to use (required for HTTP and HTTPS checks.) A HTTP 2xx code is considered successful.
Start Delay The number of seconds to wait after the container is started, before performing health checks.
Interval The number of seconds between health checks.
Timeout The TCP connection timeout.
Failure Threshold The number of allowed failures, before a service is set to ‘Failed’
Success Threshold The number of required successes, before a service is set to ‘Running’.

When Service Health checks are enabled, the service’s health state is used to determine if a Service Instance should be marked as running or not. This can impact overall deployment times, especially when Service dependencies are configured.

Cluster Services

When defining Service you can check the “Enable Cluster” flag to specify that this service operates as a cluster.

_images/cluster-service-flag.png

A Cluster Service differ from a regular Service in several ways:

  • Additional environment variables are injected in each container being part of the cluster. These environment variables provide details about the other members in the cluster.
  • When an member is restarted, it is always restarted on the same host. This is done to make sure environment variables injected in other members remain valid.
  • When a Service depends on a Cluster Service, then its service instances are only started once all the members in the cluster are up and running.
  • Scaling up and scaling down a cluster may require a manual restart of the cluster node in order to re-generate the right configuration files.

Cluster Environment Variables

There are 3 additional environment variables injected into containers being part of a cluster.

Variable Description
NIRMATA_CLUSTER_NODE_COUNT Indicates the number of nodes in the cluster
NIRMATA_CLUSTER_NODE_ID ID assigned to this node. Numbering starts from 1.
NIRMATA_CLUSTER_INFO JSON formatted string. It provides details about the IP and ports of all the nodes in the cluster.

The syntax for the NIRMATA_CLUSTER_INFO environment variable is:

[
        {
                "nodeId" : <integer>,
                "ipAddress":<string>,
                "ports": [
                                { "portName":<string>, portType: <"TCP"|"UDP"|"HTTP"|"HTTPS">, "hostPort":<integer>, "containerPort":<integer>}
                ]
        }
]

These environment variables can be used to generate the configuration files of your cluster service.

When a service depends on a cluster service then a specific environment variable is injected in the dependent service’s container. If your service depends on multiple clusters then there will be one environment variable injected per required cluster. The name of the environment variable is formatted using the name of the cluster service:

NIRMATA_CLUSTER_INFO_<cluster-service-name>

The value of the environment variable is a JSON formatted string. Its format is identical to the format of the NIRMATA_CLUSTER_INFO. The dependent service instances will only be started once all the required cluster members are fully deployed.

Scaling Up a Cluster

To add a node to a deployed cluster, you just need to edit the scaling rule of the cluster service and specify the total number of members you need.

If your cluster service uses static host ports, you must make sure that you have enough hosts available in your host group to avoid port conflicts. It is possible to deploy cluster services on fewer hosts than what you have specified in the scaling rule. In this case, you must use dynamic host ports in the service blueprint.

The procedure used to scale up a cluster varies based on the type of cluster you are deploying. Some clusters like older versions of Zookeeper require changing the configuration of existing nodes when a new node is added. Other clusters such as MongoDB do no not require restarting the nodes to expend the cluster.

You can use the restart action in the service instance pull-down menu to restart a node. A cluster service instance is always restarted on the same host. The environment variables injected into the new container reflect the new configuration and size of the cluster.

Scaling Down a Cluster

To scale down a cluster, just edit the scaling rule of the cluster service and decrease the number of service instance required.

Depending on the type of cluster you are operating, you may have to restart the remaining nodes of the cluster.