Chapter 11. BOSH Releases

Chapter 10 introduced BOSH concepts on a high level. For operators who want a deeper understanding of BOSH releases, this chapter presents an overview of how releases are structured and packaged.

A BOSH release is your software, including all configuration and dependencies required to build and run your software in a reproducible way. Gaining an understanding of releases will help you to comprehend how individual components work. For example, understanding how a release is composed and deployed can help you to pinpoint where each release job runs. This ability to determine exactly which processes run and where they run is invaluable for debugging.

Release Overview

Releases are self-contained and provide very specific software solely relating to the purpose of that release. Here’s a simple example provided by bosh.io:

[A] Redis release might include startup and shutdown scripts for Redis-server, a tarball with Redis source code obtained from the Redis official website, and a few configuration properties allowing cluster operators to configure that Redis-server.

A release consists of versioned release jobs and packages. A release job describes a single component that can be run in isolation to do its work. A release package contains the required dependencies for a specific job. A release exists as a versioned collection of the following artifacts:

  • Configuration properties

  • Configuration templates

  • Scripts (including startup scripts and shutdown scripts) for the release jobs

  • Source code

  • Binary artifacts

  • Anything else required to build and deploy software in a reproducible way

By allowing the separation and layering of releases on top of stemcells, BOSH is able to version and roll out updated software to the entire cluster on a machine-by-machine basis. Releases ensure that the same compiled software version is used repeatedly for every deployment, as opposed to running a package installer such as apt-get, which can potentially install a different binary every time, depending on from where you pull binaries. All the required configuration options and scripts for software deployment are captured and all software dependencies are explicitly recorded with all changes tracked. Packing enables versioning, tracking, and self-containment of IaaS—agnostic software releases. This means that you can deploy a release version without internet access.

Cloud Foundry BOSH Release

Installing Cloud Foundry does not require you to create a new release; you can simply deploy a current Cloud Foundry release version. The current canonical Cloud Foundry deployment is cf-deployment. cf-deployment comprises several individual, self-contained component releases. This means that each Cloud Foundry component, such as the UAA, or Diego, or the GoRouter, resides in its own BOSH release. cf-deployment then draws these releases together via a canonical manifest for deploying Cloud Foundry. Chapter 12 discusses deployments, including how Cloud Foundry is deployed.

BOSH Director BOSH Release

The BOSH Director itself is a dedicated BOSH release. To install the BOSH Director, the $ BOSH create-env command will grab the BOSH Director BOSH release located on GitHub. This BOSH Director BOSH release has some subtle differences from typical BOSH releases. This chapter focuses on typical BOSH releases, such as Cloud Foundry.

Anatomy of a BOSH Release

A BOSH release has five release primitives, the most significant being jobs, packages, src, and blobs. These terms are discussed at length below. A typical release directory contains:

  • A jobs directory that contains job metadata

  • A package directory that contains package metadata

  • A config, blobs, and src directory

  • .dev_builds and .final_builds directories

  • Any Git subdirectories

To create a typical release directory with one job and one package, navigate to the workspace where you want the release to reside. Then, using the BOSH v2 CLI, run the following:

$ bosh init-release <release_name>
$ cd <release-name>
$ bosh generate-job <job-name>
$ bosh generate-package <package-name>

You can now view the skeleton release directory tree:

$ tree .
.
├── blobs
├── config
│   └── blobs.yml
├── jobs
│   └── job_name
│       ├── monit
│       ├── spec
│       └── templates
├── packages
│   └── package-name
│       └── packaging
└── src

Release Naming

By convention, BOSH uses a lowercase naming convention with dashes in the release name; for example, cf-deployment. For all other filenames in the release, BOSH uses underscores; for example, job_name.

Jobs

A release job (or simply job) conceptually describes a single component. You can run a release job in isolation and it will do its work. The release job can be comprised of several individual processes (e.g., a master process coupled with a separate worker process for tasks such as log rotation). A release job might depend on other jobs, and there may be several steps to instantiate a release job, but the end state should be a single component that you can start and stop by a single Monit script.

Release Jobs and Instance Groups

Release jobs are individual software components that can run in isolation. An instance group is the deployment unit. A single instance group represents one or more release jobs to be deployed to a single VM. An instance group can have several running instances (VMs) such as several Diego Cells or several GoRouters.

The BOSH releases for each core Cloud Foundry component (such as the Cloud Controller or GoRouter) are broken into one or more release jobs. Usually, we do not append “release” to the release name. Appending release is useful only for descriptive purposes such as a GitHub repository or when the release is distributed as a .tar file. You can view a list of the current jobs associated with the deployed instance groups by running the following command:

$ bosh -e <bosh_env> -d <deployment> instances --ps

Each job has its own directory containing a Monit file, a specification file, and a templates directory. A job needs to be able to start and stop its processes. BOSH currently achieves this by using a control script and Monit.

Control scripts

We use control scripts to configure and control job processes, including commands such as start and stop. The job’s control script is an embedded Ruby (ERB) template typically named <job_name>ctl.erb (arguably, it should just be called ctl.erb because it belongs to a specific job and so is already namespaced). It is stored in the job’s templates directory. By BOSH convention, control scripts should configure the job to store logs in /var/vcap/sys/log/<job_name>. If a release needs templates other than the control script, those templates should also reside in the templates directory.

ERB

ERB is a Ruby feature that provides a way to generate text from templates. The templates combine plain text with Ruby code for variable substitution and flow control.

When a release is deployed, BOSH transforms the control scripts into files, substituting the required variable values (properties), and then replicates these files onto the subsequent instance group VMs under /var/vcap/jobs/<job_name>.

The /var/vcap Directory Structure

By convention, the /var/vcap directory is used as the parent directory to the /sys and /jobs subdirectories.

Monit

In addition to the ctl.erb template script, a release also requires a controlling and monitoring process that can start (or restart), monitor, and stop the job processes. In Linux you do this by using a Monit file (with an equivalent for Windows1) for each release job. The Monit file has two key responsibilities:

  • Specifies the job’s process ID (PID) file

  • References all commands (e.g., start and stop) provided by the release job templates

The Monit file for a job typically contains the following:

check process <job_name>
  with pidfile /var/vcap/sys/run/<job_name>/pid
  start program "/var/vcap/jobs/<job_name>/bin/ctl start"
  stop program "/var/vcap/jobs/<job_name>/bin/ctl stop"
  group vcap

Note that the path to the ctl script is the path that will exist on the deployed instance group machine.

Specification Templates

Each job has a specification file that defines job metadata (including any additional templates) and any required job properties like db_password. Here is what the specification file lists:

name

The job name

packages

Includes both package dependencies and the packages created by this job

templates

An array of ERB template names and paths

properties

A list of properties required by the job

Job Descriptions

Often, specification files will contain a description used to describe the job. This is not part of BOSH. You can write whatever you want in the specification file; however, BOSH will consider only names, packages, templates, and properties.

The job specification file’s templates block contains a list of hashes. The template name is the key, and the path on the instance group machine’s filesystem is the hash value.

File paths are always relative to the /var/vcap/jobs/<job_name> directory on the instance group machine. By convention, these control scripts go in the bin directory. Therefore, on the instance group machine, bin/ctl becomes /var/vcap/jobs/<job_name>/bin/ctl.

Templates can be required for things like scripts that set up environment variables. Any such script is generated via a template, with properties injected in by the Director, which accesses properties set in the deployment manifest. Properties are discusssed further in “Properties”.

Packages

The packages directory contains the dependencies of a specific job. These dependencies are pulled in from the blobs and src directories. Packages provide BOSH with all of the information required to prepare the job binaries and job dependencies during the release-compile phase. A release can contain several jobs, each dependent on their specified packages.

  1. Packages provide source code and dependencies to jobs

  2. Src provides packages with the nonbinary files they need

  3. Blobs provide packages with the binaries they need (other than binaries that are checked in to a source code repository)

Figure 11-1 shows the dependency graph for a release job.

Jobs Dependency Graph
Figure 11-1. Job dependency graph

The packages directory also contains the packaging instructions so that BOSH can build each of the release job dependencies during the create-release compilation phase. A BOSH release has two kinds of dependencies: runtime dependencies and compile-time dependencies.

Runtime dependencies exist when a job depends on a package to run; for example, a Spring boot app depends on Java, or a Ruby app depends on Ruby. Compile-time dependencies occur when a package depends on another package at compile time; for example, Ruby depends on the YAML library to compile.

It is important to note that jobs are self-contained in that jobs can depend only on packages, not other jobs; however, packages can depend on other packages.

Src, Blobs, and Blobstores

As we just discussed in “Packages”, src and blobs directories contain the dependencies pulled in by the packages. The src contains source code that is explicitly part of the release. Job source code is either copied into the src directory or linked to it, using a mechanism such as a Git submodule or a Mercurial repository.

Most releases are highly dependent on a source code repository. However, releases often use blobs, such as .tar files or precompiled third-party libraries. Blob tarballs can contain both binaries or source code, and they usually contain all external dependencies. If the tarballs contain source code, the packaging script must define how to compile that code.

Typically, for components that are not your actual software (e.g., Ruby), you provide them via blobs. Components that you are responsible for releasing should be provided in the most generic form possible, namely source code.

Using Source over Binaries

You can compile dependencies from source as opposed to using prebuilt binaries. Binaries are usually tied to a specific OS architecture, so something that works on Ubuntu might not work on Centos. When you compile from source, you are creating binaries for the specific stemcell architecture defined in the deployment manifest.

A lot of source code repositories, for example GitHub, are not suitable for checking in large blobs. BOSH avoids the requirement to check blobs into a repository in two ways:

  • For a dev release, BOSH uses local copies of blobs.

  • For a final release, BOSH uploads blobs to a release blobstore.

For the latter, to deploy a release, the BOSH CLI needs to obtain the required blobs and then upload those blobs to the Director. Keep in mind that there are two unrelated blobstores in play here: a Director blobstore that the Director uses, and a release blobstore that is used only for managing a specific release.

The Director blobstore can reside anywhere the Director can reach it. A release blobstore is release-specific; for example, final UAA release saves the final artifacts in a UAA-specific blobstore.

The CLI has a number of ways to upload the release into the Director blobstore. The CLI can read the release blobstore location from a GitHub repo and then send the blobs over to the Director. This method means that the CLI must have access to both the Director blobstore as well as the release blobstore.

However, the BOSH Director does not require access to a release blobstore, which means that the Director does not require internet access. An operator can simply bring a release tarball that has been previously composed from the required blobs from the release blobstore and then upload that tarball to the Director. This method means that the tarball has no reference to the original release blobstore, and, as such, the Director and CLI do not require any access to the release blobstore.

Theoretically, a release can also be constructed from scratch if you can obtain all dependent blobs, or the release author places blobs in the blobs directory, but it is a better experience for your release consumers if you package a release for consumption, as discussed further in “Packaging a Release”.

All of the information about the release blobstore is recorded via the config directory. Two files reside in this directory:

final.yml

This file names the blobstore and specifies its type. Type is either local to the BOSH Director VM or one of several other types that specify blobstore providers, such as a local NFS, or public blobstores such as Amazon S3.

private.yml

This file specifies the blobstore path and secret key for accessing the blobstore. As such, for security reasons, it should not be checked into a repository.

The config directory also contains an automatically generated blobs.yml file.

Although a local blobstore is convenient for getting started, the resulting releases are held only locally and cannot be shared beyond the immediate BOSH deployment.

Packaging a Release

BOSH provides two main ways by which you can distribute a release version:

  • Package the release in its entirety as a tarball and then store it somewhere.

  • Use a Git repo and the releases/<release-name>/release.yml file that points to the release blobstore.

To upload a release, run the following:

$ bosh -e <env> upload-release <your-release>

This upload-release command accepts different URL schemes. Typically you can provide an HTTPS URL for the entire tarball, or you can clone the release’s Git repo into a local directory and then provide, for example, the releases/cf/cf-x.yml. This <release>.yml file tells the CLI with the information on what the publisher published for that release version. Specifically, it contains pointers to blobstore objects (packages and jobs) that are required for a given release version. These blobs usually reside either locally (for a development release) or in the release blobstore (for a final release). From that YAML file, the BOSH CLI is able to create a release tarball that can be uploaded from the release blobstore to the Director blobstore.2

These blobs are resolved within the .final_builds file, which references the release blobstore for final jobs and packages (each referenced by one or more releases). For storing final releases, the config provides the URLs and access credentials to the release blobstore. Any Git subdirectories provide local Git hooks to pull those subdirectories in.

You might want to create a BOSH release for additional custom Cloud Foundry services. It is important to note that you do not need to create a new release version for installing Cloud Foundry, because you can use the existing release version. For example, you can simply clone and use a Git URL by invoking $ bosh -c <env> upload-release releases/cf-x.yml. This has the same behavior as accessing a release directly from bosh.io. Using bosh.io is completely optional.

Compilation VMs

Some releases might still require further compilation (from source code to binary, based on the appropriate stemcell). BOSH uses compilation VMs to achieve this. Compilation brings up the machine or VM, takes the source package, runs a packaging script, and then produces a compiled package. BOSH then saves these compiled packages and will then use the compiled packages to deploy the instance group machines. Compilation VMs were discussed earlier in “Compilation VMs”.

Summary

A BOSH release does the following:

  • Encapsulates all your software in a self-contained way

  • Includes all configuration and dependencies required to build and run your software in a reproducible way

  • Has five release primitives, the most significant being jobs, packages, src, and blobs

  • Can be versioned, packaged, and distributed

BOSH deploys software to the defined IaaS layer using a deployment manifest, one or more stemcells, and one or more releases. A BOSH deployment consists of a collection of one or more machines or VMs, built from stemcells and then layered and configured with specified release jobs obtained from software releases.

What you choose to actually deploy is not dictated by releases; you have the freedom to select which release jobs you would like to deploy and on which instance groups those jobs should reside. This choice is defined in the deployment manifest. Chapter 12 looks more closely at BOSH deployments and deployment manifests.

1 The concept is the same for Windows support; however, Windows uses a custom job supervisor with Windows services instead of Monit, and JSON in place of a ctl script.

2 The new BOSH v2.0 CLI has a Git syntax that can clone a Git repository in the background for you by using the command $ git clone, and then use the specified version of the YAML file to upload the release tarball.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
3.17.81.201