Creating Capsules

Capsules are user-defined workloads (jobs) that are a blend between lightweight containers generally used for applications and full servers traditionally provided by virtual or physical machines. Capsules let you leverage your investments in tooling and other resources without having to modify or rewrite them for cloud environments.

Overview

Capsules provide you with a bare container host that is only running an operating system (OS). You can SSH into capsules to install and configure software, and connect capsules to other jobs and services in your cluster.

You create capsules using a system-provided OS image, or from a package that you create or that is available to you. Capsule file system storage is ephemeral, but you can save the state of a capsule by creating a snapshot. Snapshots are saved as packages, which can be used as the basis for creating new capsules and full-fledged apps.

Using capsule commands

The apc capsule command lets you run capsules in your Apcera Platform cluster.

The capsule syntax is as follows:

apc capsule <subcommand> <required args> [optional args]
  • Run apc help capsule to view capsule syntax and commands.

  • Run apc help capsule <subcommand> to view required and optional arguments for any subcommand.

The following subcommands are available for capsules:

Subcommand Description
attract Establish a scheduling affinity between capsules
connect Connects to a capsule via SSH
create Creates a new capsule with the specified operating system
delete Shuts down and deletes an existing capsule
export Exports capsule(s) to a single package file
health View the health of a capsule
link Link one capsule to another
list Lists your existing capsules
logs Tail capsule logs
repel Remove a scheduling affinity from capsules
restart Restarts a capsule
show Shows information about a capsule
snapshot Creates a snapshot of a capsule, in order to persist changes
start Starts a capsule
stop Stops a capsule
stats Displays a capsule's resource stats
update Updates a capsule's individual properties

This tutorial explores the use of the most commonly used capsule subcommands.

Listing images for capsules

Apcera provides various Linux OS distributions for creating capsules, including Ubuntu version 14.04.

To obtain a list of the available base OS packages for creating capsules:

apc package list --type os --namespace /
Name Namespace Operating System State
ubuntu-14.04 /apcera/pkg/os linux, ubuntu, ubuntu-14.04 ready

In the Operating System column, note the tags that apply to each OS package: linux, ubuntu and ubuntu-14.04. Policy is used to resolve package dependencies for capsule image tags that are ambiguous.

When creating a capsule from your namespace, by default the system looks for the base image in namespace /apcera/pkg/os.

Creating capsules

To create a capsule use the following syntax:

apc capsule create <capsule-name> --image <image-name> [optional-args]

The capsule-name is a user-defined string. The image-name is an OS tag, such as linux or ubuntu or ubuntu-14.04.

For example, using the linux image:

apc capsule create test-capsule --image linux

Or, using the ubuntu image:

apc capsule create test-capsule --image ubuntu

Or, using a specific image version:

apc capsule create test-capsule -i ubuntu-14.04

The following sample output is presented by APC after running command apc capsule create test-capsule -i linux:

╭────────────────────────────────────────────────╮
│                 Capsule Settings               │
├─────────┬──────────────────────────────────────┤
│    FQN: │ job::/sandbox/username::test-capsule │
│  Image: │ linux                                │
│    CPU: │ 0ms/s (uncapped)                     │
│ Memory: │ 256MiB                               │
│   Disk: │ 1GiB                                 │
│ Netmin: │ 5Mbps                                │
│ Netmax: │ 0Mbps (uncapped)                     │
╰─────────┴──────────────────────────────────────╯

Is this correct? [Y/n]: y
Searching for operating system "linux"... done
Using package "Ubuntu_14.04"
Creating the capsule "test-capsule"... done
Waiting for the capsule to start...
Capsule should be accessible with:
  apc capsule connect test-capsule
Success!

To verify successful capsule creation:

apc capsule show test-capsule

You should see that the capsule is created.

Since a capsule is a job within the system, you can also run apc job show test-capsule to view the capsule details.

Allowing capsule egress

Capsules are jobs which run in containers that by default do not have outbound network access.

You can grant network egress to capsules in one of the following ways (subject to policy):

Option A. Bind the capsule to a service that provides external access, such as the system-provided /apcera::outside service:

apc service bind /apcera::outside --job test-capsule

Option B. Use the --allow-egress (-ae) optional argument when creating the capsule:

apc capsule create test-capsule --image linux --allow-egress

Or, in short form:

apc capsule create test-capsule -i linux -ae

Option C. Update an existing capsule and allow egress:

apc capsule update test-capsule -ae

To verify network access:

apc job show test-capsule

The job is bound to service::/apcera::outside.

The service /apcera::outside is a system-provided service that uses a service gateway to connect to the external network. The --allow-egress option is a developer convenience or shortcut for the “service bind” command. Using -ae requires specific policy privileges and should not be used for production apps. When you snapshot a capsule, -ae is disabled.​

Binding capsules to services

You can easily bind a capsule to a service such as PostgreSQL DB.

For example:

apc ns /
Setting namespace to '/'... done
Success!
apc provider list
Working in "/"
╭───────────────────┬──────────┬───────────────────┬─────────────╮
│ Name              │ Type     │ Namespace         │ Description │
├───────────────────┼──────────┼───────────────────┼─────────────┤
│ apcfs             │ nfs      │ /apcera/providers │ NFSv4       │
│ mysql-provider    │ mysql    │ /apcera/providers │             │
│ postgres-provider │ postgres │ /apcera/providers │             │
╰───────────────────┴──────────┴───────────────────┴─────────────╯

As shown, this cluster has a registered PostgreSQL DB provider named postgres-provider. Note that the name of your provider may differ if you are using Enterprise Edition.

Using this provider we can easily create a service:

apc service create mydb --provider /apcera/providers::postgres-provider

Then, bind the capsule to the service:

apc service bind mydb --job test-capsule
Service Bind Settings
App Name:test-capsule
Service:mydb
Is this correct? [Y/n]: 
Binding service "mydb" to "test-capsule"...
Job must be stopped to bind to service. Do you want to stop it, apply the binding, and start it again?
Restart and proceed? [Y/n]: 
Stopping job... done
Creating binding... done
Starting job... done
Waiting for the job to start...
Binding Environment Variables
"BIND_MYDB_TEST_CAPSULE_URI"
"JDBC_POSTGRES_URI"
"MYDB_URI"
"POSTGRES_URI"
Success!

You can use the "Binding Environment Variables" to connect to the PostgreSQL DB service you created. This is demonstrated below.

Connecting to capsules

You can connect to capsules and install software on them.

By default capsules are started when you create them.

Use command apc capsule list to verify that the capsule (job) is started. If it is not, start it using apc job start test-capsule.

Since a capsule is a job, you could also use apc job list and apc job start test-capsule.

Once the capsule is running, you can use the following command to connect to it:

apc capsule connect test-capsule

This command connects to a bash shell on the capsule OS using the SSH protocol.

Successful connection is indicated by output similar to the following:

-bash-4.3#

From the resulting bash prompt, you can apt-get new packages, install software, and connect to service providers.

Using apt-get requires a binding to the outside network service or --allow-egress on the capsule.

For example, to update the container OS and install the PostgreSQL client onto it:

apt-get update
apt-get install postgresql-client-9.3

To log in to the PostgreSQL DB from the capsule job, use one of the Binding Environment Variables (a string with _URI as the suffix):

psql $POSTGRES_URI

Or, alternatively:

psql $MYDB_URI

Or, if you are using a JDBC Postgres client:

psql $JDBC_POSTGRES_URI

Each of which return the following, indicating you are logged in:

psql (9.3.7, server 9.4.8)
Type "help" for help.

Enter commands ​\dd​ and ​\dt​ to view the database schema and tables and verify successful connection to the Postgres DB. (These will be empty if the database table is not populated.)

Running a tool such as "top" or "free" inside a capsule (container) will report what the host has configured, not what is configured for the capsule (container). Note that the limitation of these tools in this regard is not specific to the Apcera container format. These tools use the proc file system to read memory values, but the proc file system is not containerized.

Exploring service bindings

To connect to the Postgres service from the capsule, all you had to do was use one of the Binding Environment Variables (POSTGRES_URI). You did not need to know the credentials to connect to the DB, nor the hostname or location of the DB.

A service binding is a URI that is stored as an environment variable. The URI encapsulates a metadata-decorated connection string in the form of scheme://username:password@hostname_or_IP:port/resource. The service binding is generated by the service gateway for the Postgres service that you created previously.

To view what comprises a service binding URI, while still connected via SSH to the capsule OS, grep your Postgres credentials from the output of the env command:

env | grep POSTGRES

POSTGRES_URI=postgres://{username}:{password}@{hostname}:5432/{database}

For example (formatted for readability):

-bash-4.3# env | grep postgres

POSTGRES_URI=postgres://ml8hfekyshjluh0k:5OUz7VYOJ4amtXKG@169.254.131.241:20000/cfe629e745054ce69bbebe73a1216c7c

D587DC79C49A47AA947C391A7F43DC11_URI=postgres://ml8hfekyshjluh0k:5OUz7VYOJ4amtXKG@169.254.131.241:20000/cfe629e745054ce69bbebe73a1216c7c

JDBC_POSTGRES_URI=jdbc:postgresql://169.254.131.241:20000/cfe629e745054ce69bbebe73a1216c7c?user=ml8hfekyshjluh0k&password=5OUz7VYOJ4amtXKG

MYDB_URI=postgres://ml8hfekyshjluh0k:5OUz7VYOJ4amtXKG@169.254.131.241:20000/cfe629e745054ce69bbebe73a1216c7c

The result is the contents of the service binding. In this case, because a semantic pipeline is being used, the credentials provided are ephemeral: they are not the actual credentials to connect to the DB, just the credentials to connect to the semantic pipeline. Further, these credentials can only be used by this particular client.

Issue command ​\q​ to quit the PostgreSQL client.

Use command exit to exit the SSH session and disconnect from the container OS.

Taking capsule snapshots

A snapshot is a package that captures the state of a capsule. You can create new capsules from snapshots, and move snapshots between environments. You can add environment variables to the snapshot packages using the apc package update command. In addition, you can create apps from a package created as a result of a capsule snapshot.

To snapshot a capsule and create a package:

apc capsule snapshot test-capsule

The capsule snapshot is saved as a package to the current namespace using a default name that includes the UUID for the package, such as:

package::/sandbox/<user-name>::snapshot-test-capsule-1433632461

You can use the --name flag to name the snapshot package differently.

The --directory flag lets you specify a directory within the capsule to snapshot.

Snapshots only include the changes made to the capsule, not the entire capsule itself. In other words, a capsule snapshot is not a full blown OS image. Since snapshots only contain the changes subsequent to capsule creation, snapshotting capsules created from snapshots do not work as you might expect.

Creating apps from packages

The snapshot of a capsule is saved as a package.

You can create an app from a package snapshot using the following syntax:

apc app from package <app-name> -p <pkg-name> [optional-args]

For example:

apc app from package mysql-app -p snapshot-mysql-cap-142670904 -dr --start-cmd 'sudo /bin/sh /usr/bin/mysqld_safe'

Where snapshot-mysql-cap-142670904 is the package name of the capsule snapshot, the -dr option disables routes, and 'sudo /bin/sh /usr/bin/mysqld_safe' is the start command.

When creating an app from the snapshot of a capsule, the start command will be issued from the root user. It should be noted that this container root user is not root on the host, due to the implementation of user namespaces. When defining your app's start command, keep this in mind as it pertains to permissions in the container environment.

Refer to Working with Providers for more information on using app from package.

Resolving package dependencies

When you create a capsule you specify the OS image type. For example:

apc capsule create test-capsule --image linux

The value for the --image argument can be linux, ubuntu, or the full version, such as ubuntu-14.04.

Per policy the default OS for a linux capsule image is Ubunutu 14.04:

job::/
  if (dependency equals os.linux)
    { package.default "package::/apcera/pkg/os::ubuntu-14.04" }

Likewise, the default OS for an ubuntu capsule image is Ubuntu 14.04:

job::/
  if (dependency equals os.ubuntu)
    { package.default "package::/apcera/pkg/os::ubuntu-14.04" }

Thus, if you wanted to create a capsule using Ubuntu 14.10, you would have to use this explicit command:

apc capsule create test-capsule --image ubuntu-14.10

Alternatively, you can use policy to set the package resolution for jobs in your namespace having the os.ubuntu dependency:

job::/sandbox/your_username
  if (dependency equals os.ubuntu)
    { package.default "package::/apcera/pkg/os::ubuntu-14.10" }

Refer to How Apcera Platform resolves package dependencies for more information on package resolution.