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
.
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.
Encrypting capsule data volumes
When creating a capsule you can optionally specify that the data volume used to mount the capsule file system be encrypted using LUKS (Linux Unified Key Setup). When the application is started its data volume is encrypted using a random, one-time password.
To encrypt an capsule's data volume, pass the --encrypt
flag to the apc capsule create
command, as shown below:
apc capsule create my-encrypted-capsule --encrypt --image linux
Note that data volumes created for capsules are ephemeral and are destroyed when the application stops. To have persistent encrypted storage you can bind the capsule to an encrypted APCFS or encrypted SMB service.
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
andapc 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 containerroot
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.