Service Specification Guide
  • 13 Apr 2023
  • 9 Minutes to read
  • Dark
    Light

Service Specification Guide

  • Dark
    Light

Article summary

1. Introduction

This document provides you the information to write your own custom service specification (also referred to as service spec and podspec).

All the examples represent the same podspec broken into sub-members of the parent structs, and it shows where each key and its value go into the podspec.

The podspec must be written in JSON format and is validated accordingly.

2. Service Specification Details

The service spec (podspec) is the high-level structure to define the attributes and lower-level member structures. Environment variables found in the service spec are auto-injected.

Podspec Example

{
    "name" : "customskyspark",
    "networks" : [
        {
            "network_id" : "n-7dff7fa36f7551e0",
            "ip_address" : "10.10.10.2",
            "is_default" : true
        }
    ],
    "kind" : "REPLICA",
    "cluster_id":"5e7f40e3-8959-4a11-9914-34bf03a83df3",
    "node_selector":
    {
       "_iotium.cluster.candidate":"true"
    },
    "services" : [
        {
            "name" : "customskyspark0",
            "image" : {
                "name" : "iotium/9aa679a9fe800f96",
                "version" : "3.0.20"
            },
            "docker" : {
                "environment_vars" : {
                    "HTTP_PORT" : "80",
                    "ADMIN_PASSWORD" : "sky"
                },
                "volume_mounts" : [
                    {
                        "name" : "newlicsky",
                        "mount_path" : "/skyspark/var/lic",
                        "read_only" : false
                    }
                ],
                "resources" : {
                    "limits" : {
                        "memory": 800
                    }
                }
            },
                "image_pull_policy":"IfNotPresent"
        }
    ],
    "volumes" : [
        {
            "name" : "newlicsky",
            "secret_volume" : {
                "secret" : "4e61cf01-b211-435a-b825-bfb1bfbc7934"
            }
        },
        {
            "name" : "proj_bk",
            "empty_dir" : {}
        },
        {
            "name" : "host_bk",
            "empty_dir" : {}
        }
                ],
    "dns" : [“8.8.8.8”, “4.4.4.4”],
    "dns_policy" : "Default",
    “restart_policy” : “Always”
    "termination_grace_period_in_seconds" : 60
    }
}

Podspec Elements

NameTypeRequiredDescription

name

string

True

Service name provided by the user

services

Service

True

List of containers belonging to the service. Containers cannot be added or removed.
At least one container is required in a service.
Cannot be updated.

volumes

Volume

True

List of volumes that can be mounted by containers belonging to the service.

restart_policy

String

False

Restart policy for all containers within the service. Possible values include:
Always — The container should be restarted whenever it exits, either a normal or an abnormal exit. This is the default.
OnFailure — The inode should restart the container only when an abnormal termination is seen.
Never — The container should never be restarted.
UnlessStopped — The container should be restarted in all cases, unless the Secure Edge Portal issued a Stop signal

networks

NetworkSetting

True

Networks that this service should connect to.

image_pull_secrets

[]String

True

ImagePullSecrets are references to names of Secret which are used for pulling any of the
images referenced by this PodSpec. This is an Array of strings.

dns_policy

String

False

DNS Policy index with four possible indices:
Default — The default inherits the name resolution configuration from the node. T
None — DNS settings are provided using the dns_config field in the service spec.

dns

[]String

False

DNS nameserver IP list as string.

kind

String

True (Cluster-only)

Kind/Type of Service deployment in a Cluster. Kind has 3 possible values:
Singleton : An instance of the service runs only on the master iNode.
Replica: An instance of the service runs on a specific subset of iNodes in the cluster. If an iNode label matches with a Replica
Service’s node selector label, that iNode will be part of the subset where that Replica Service runs.
Daemon: An instance of the service runs on all iNodes in the cluster.

node_selector

Labels

False

If an iNode label matches with a Replica Service’s node selector label, that iNode will be part of
the subset where that Replica Service runs.

cluster_id

String

True (Cluster-only)

Indicates the cluster where the service needs to be deployed.

termination_grace_period_in_seconds

Integer

False

Termination grace period for service.

Service schema

The service schema describes the services and its attributes in the podspec that runs on the iNode.

Example of service schema:

"services" : [
    {
        "name" : "customskyspark0",
        "image" : {
            "name" : "iotium/9aa679a9fe800f96",
            "version" : "3.0.20"
        },
        "docker" : {
            "environment_vars" : {
                "HTTP_PORT" : "80",
                "ADMIN_PASSWORD" : "sky"
            },
           "volume_mounts" : [
                {
                    "name" : "newlicsky",
                    "mount_path" : "/skyspark/var/lic",
                    "read_only" : false
                },
                {
                    "name" : "proj_bk",
                    "mount_path" : "/skyspark/var/proj",
                    "read_only" : false
                }
            ],
            "resources" : {
                "limits" : {
                    "memory": 800
                }
            }
        },
        "image_pull_policy":"IfNotPresent"
     }
]
NameTypeRequiredDescription

name

String

True

A name for the service, to be used for display.

image

Image

True

Represents container image

docker

DockerContainer

True

Docker container parameters are put in the section, environment variables are auto-injected.

image_pull_policy

String

False

Image pull policy describes when an image should be pulled. Possible values include:
Always — The inode should always attempt to pull the latest image. The container fails if the pull fails. This is the default.
IfNotPresent — The inode pulls the image only if the image is not present on the disk. Container fails if the image is not present and the pull fails.
Never — The iNode never pulls an image, but uses only a local seeded image. The container fails if the image is missing.

Image Schema

The image schema indicates the container image name and the version of the container to be pulled from the registry to be executed on an iNode.

Example of image schema:

"services" : [
    {
        …
        "image" : {
            "name" : "iotium/9aa679a9fe800f96",
            "version" : "3.0.20"
        },
        …
        }
     },
     "image_pull_policy": "IfNotPresent"
]
NameTypeRequiredDescription

name

String

True

Docker image name.

version

String

True

Docker container version.

DockerContainer Schema

The DockerContainer schema, a subschema of the Services schema, indicates docker container parameters.

Example of DockerContainer schema:

"services" : [
    {
…
        "docker" : {
            "environment_vars" : {
                "HTTP_PORT" : "80",
                "ADMIN_PASSWORD" : "sky"
            },
            "cap_add":[
                "SYS_RAWIO"
           ],
           "volume_mounts" : [
                {
                    "name" : "newlicsky",
                    "mount_path" : "/skyspark/var/lic",
                    "read_only" : false
                },
                {
                    "name" : "proj_bk",
                    "mount_path" : "/skyspark/var/proj",
                    "read_only" : false
                }
            ],
            "resources" : {
                "limits" : {
                    "memory": 800
                }
            }
        },
…
     }
]
NameTypeRequiredDescription

environment_vars

String

False

A list of environment variables
key: variable name — in string
value: variable value — in string
Usually auto injected.

volume_mounts

[]VolumeMount

True

Lists attributes name:
name
path &
read_only

cap_add

[]String

False

An optional parameter that lists kernel capabilities to add to the container.
There is an exhaustive list of kernel capabilities that could be added to a container.

We don’t support some privileged capabilities like "SYS_ADMIN", "NET_ADMIN". but do support "SYSLOG", "SYS_RAWIO". Explanation of each capability is not in the scope of this document.

cap_drop

[]String

False

A list of kernel capabilities to drop from the container.

resources

Resources

False

Resource Management for the container.

VolumeMount Schema

The VolumeMount schema, a subschema of the DockerContainer schema, indicates the volume mount attributes of a docker container.

Example of VolumeMount schema:

"services" : [
    {
…
       "volume_mounts" : [
                {
                    "name" : "newlicsky",
                    "mount_path" : "/skyspark/var/lic",
                    "read_only" : false
                },
                {
                    "name" : "proj_bk",
                    "mount_path" : "/skyspark/var/proj",
                    "read_only" : false
                }
            ]
        },
…
     }
]
NameTypeRequiredDescription

name

String

True

This must match the name of a volume.

mount_path

string

True

Path within the container at which the volume should be mounted.
MUST NOT CONTAIN ':'

read_only

Boolean

True

Mounted read-only if true, read-write otherwise.

Volume Schema

The Volume schema provides a list of volumes that are used by a service. It contains a name and the volume source schema in each of elements.

NameTypeRequiredDescription

name

String

True

The volume name must be unique within the service.

volumeSource

VolumeSource

True

VolumeSource represents the location and type of the mounted volume. If not specified, the volume is implied to be an EmptyDir.

VolumeSource Schema

The VolumeSource schema identifies the type of volume. Empty_volume loads temporary directories, which could be used by the service as long as they are running. Secret_volume holds critical files like license files and keys, SSH keys, and other forms of secure data.

Example of VolumeSource schema:

 "volumes" : [
        {
            "name" : "newlicsky",
            "secret_volume" : {
              "secret" : "4e61cf01-b211-435a-b825-bfb1bfbc7934"
            }
        },
        {
            "name" : "proj_bk",
            "empty_volume" : {}
        },
        {
            "name" : "host_bk",
            "empty_volume" : {}
        }
    ]
NameTypeRequiredDescription

emptyDir

EmptyDirVolumeSource

True

emptyDir represents a temporary directory that shares a service’s lifetime.

secret

SecretVolumeSource

True

SecretVolume represents a secret that should populate this volume.

SecretVolumeSource Schema

SecretVolumeSource is one type of volume source. It indicates the service secret mappings.

Example of SecretVolumeSource schema:

"volumes" : [
    …
        {
            "name" : "newlicsky",
            "secret_volume" : {
               "secret" : "4e61cf01-b211-435a-b825-bfb1bfbc7934"
            }
        }
    …
    ]
NameTypeRequiredDescription

secret

String

True

Indicates the secret volume id which needs to be used in the service.

NetworkSetting Schema

Network Settings indicator for the service infra container - networkId, ip addresses and other networking related params.

Example of NetworkSetting schema:

    "networks" : [
        {
            "network_id" : "n-7dff7fa36f7551e0",
            "ip_address" : "10.10.10.2",
            "is_default" : "True"
        },
    …
    ]
NameTypeRequiredDescription

network_id

String

True

Network namespace identifier

ip_address

String

True

IP Address of the service infra interface

mac_address

String

False

MAC address of the primary associated interface in the infra

is_default

Boolean

False

Is this the Default network for the Service's outbound traffic? "True" or "False". Defaults to True.

ImagePullSecret Schema

ImagePullSecret schema indicates one instance of image pull secrets required to download the docker images.

NameTypeRequiredDescription

name

String

True

Generic named reference to an object within a specific context

Resources Schema

The Resources schema, a subschema of the DockerContainer schema, specifies the resources that the docker container can use.

Example of Resources schema:

"services" : [
    {
…
            "resources" : {
                "limits" : {
                    "memory": 800
                }
            }
…
     }
]
NameTypeRequiredDescription

limits

ResourceLimit

True

Resource limits for the contianer.

ResourceLimit Schema

The ResourceLimit schema, a subschema of the Resources schema, specifies the resources that the docker container can use.

Example of ResourceLimit schema:

"services" : [
    {
…
            "resources" : {
                "limits" : {
                    "memory": 800
                }
            }
…
     }
]
NameTypeRequiredDescription

memory

integer

True

Limit for the system memory (RAM) in MBytes that the container can use.

When the container memory usage exceeds this limit, one or more processes running in the container will be OOM killed. If the killed process is an entry point process for the container, then the container itself is terminated.

3. Custom Service Spec Example

The following is an example of a custom service specification.

{
  "name":"Custom-Pod-Example",
  "services":[
    {
      "image":{
        "name":"iotium/customcontainer",
        "version":"1.1.4"
      },
      "docker":{
        "volume_mounts":[
          {
              "name":"data.txt",
              "mount_path":"/opt/iotium/"
          },
          {
              "name":"/var/host",
              "mount_path":"/var/host"
          }
        ],
        "resources" : {
            "limits" : {
                "memory": 1024
            }
        },
        "environment_vars":{
          "ADMIN_PASSWORD":"custompod",
          "HTTP_PORT":"80",
          "_JAVA_OPTIONS":"-Xmx1024M"
        },
        "cap_add":[
          "SYS_RAWIO"
        ],
        "devices":[
          {
            "onHost":"/dev/mem",
            "inService":"/dev/mem",
            "permissions":"rw"
          },
          {
            "onHost":"/dev/ttyS0",
            "inService":"/dev/ttyS1",
            "permissions":"rw"
          }
        ]
      }
    }
  ]
}

4. Built-in Environment Variables

IOTIUM_NODE_SERIAL_ID

The value of this variable is the base64-encoded form of an iNode serial number in clear.

IOTIUM_NODE_ROLE

This is an optional built-in environment variable, that gets set to Master/Slave in a Cluster environment, when a service spec has the label "_iotium_master_elect : subscribed" in it. The purpose of this variable is to enable the application service ( running as replica / daemon) to have capability to find whether they are running on Master node or backup nodes. Application services can leverage on this environment variable if they need to distinguish between the master and the backup nodes

For example:

To run the postgres database with one master and multiple slaves in cluster of nodes , we always want the master postgres to run in the master node while all other instances run as backup.The following podspec with the label ""_iotium_master_elect : subscribed" helps us achieve this. The node manager sets the env IOTIUM_NODE_ROLE as MASTER in the master node and SLAVE in the other nodes. The postgres service starts as master instance or slave instance depending on this env variable.

{
	"name": "Postgres",
	"labels": {
		"io_iotium_template": "postgres",
		"io_iotium_fileName": "",
		"_iotium_master_elect": "subscribed",
		"_iotium_master_elect_ip": "20.4.0.130",
		"_iotium_master_elect_ip_prefixlen": "16"
	},
	"networks": [{
		"network_id": "n-bcdcb51f302aa9d1"
	}],
	"services": [{
		"image": {
			"name": "iotium/postgres",
			"version": "v12.3.0-aaeeb216-amd64"
		},
		"docker": {
			"environment_vars": {
				"POSTGRESQL_PASSWORD": "password",
				"DHCP_DB_NAME": "dhcp",
				"DHCP_DB_USER": "dhcp4",
				"DHCP_DB_PASSWORD": "password",
				"DNS_DB_NAME": "pdns",
				"DNS_DB_USER": "pdns",
				"DNS_DB_PASSWORD": "password",
				"POSTGRESQL_MASTER_HOST": "20.4.0.130"
			},
			"volume_mounts": [{
				"name": "datadir",
				"mount_path": "/bitnami/postgresql"
			}]
		},
		"liveness_probe": {
			"exec": {
				"command": ["/healthcheck.sh"]
			},
			"initial_delay_seconds": 10,
			"timeout_seconds": 5,
			"period_seconds": 30,
			"success_threshold": 1,
			"failure_threshold": 3
		},
		"image_pull_policy": "IfNotPresent"
	}],
	"volumes": [{
		"name": "datadir",
		"emptyDir": {}
	}],
	"termination_grace_period_in_seconds": 60,
	"kind": "REPLICA",
	"cluster_id": "5e7f40e3-8959-4a11-9914-34bf03a83df3",
	"node_selector": {
		"_iotium.cluster.candidate": true
	}
}

5. Cluster Specific Labels

NameTypeRequiredDescription

_iotium_master_elect

string

False

If Value of this label is "subscribed", will set the env variable IOTIUM_NODE_ROLE as master/ slave based on node role in a cluster. This env can be used by application services that need to differentiate between the service instance running in cluster master or slave.

_iotium_master_elect_ip/_iotium_master_elect_ip_prefixlen

string

False

If set, the _iotium_master_elect_ip and _iotium_master_elect_ip_prefixlen will be set as the IPAddress/PrefixLen of the Application service instance running on the Master (the iNode with IOTIUM_NODE_ROLE equal to Master). Prerequisite for this to take effect is, _iotium_master_elect needs to be subscribed to.


Was this article helpful?