Jenkins Continuous Integration Cookbook PDF
Jenkins Continuous Integration Cookbook PDF
Jenkins Continuous Integration Cookbook PDF
1
1.1. Introduction .................................................................................................... 1
1.2. Choosing the right hardware for masters ....................................................... 1
1.2.1. Memory requirements for the master .................................................. 1
1.3. Choosing the right slave machines ................................................................ 2
1.3.1. Requirements for a machine to be a slave .......................................... 2
1.4. Sample use cases published on-line ............................................................... 2
1.4.1. Netflix .................................................................................................. 3
1.4.2. Yahoo .................................................................................................. 5
2. Architecting for Scale ............................................................................................... 7
2.1. Introduction .................................................................................................... 7
2.2. Distributed Builds Architecture ..................................................................... 8
2.2.1. Master/slave communication protocols ............................................. 10
2.3. Creating fungible slaves ............................................................................... 12
2.3.1. Configuring tools location on slaves ................................................ 12
2.3.2. Define a policy to share slave machines ........................................... 13
2.3.3. Setting up cloud slaves ..................................................................... 13
2.4. Right-sizing Jenkins masters ........................................................................ 14
2.4.1. Master division strategies .................................................................. 14
2.4.2. Calculating how many jobs, masters, and executors are needed ....... 15
2.4.3. Scalable storage for masters ............................................................. 16
2.5. Setting up a backup policy .......................................................................... 17
2.5.1. Finding your $JENKINS_HOME ..................................................... 17
2.5.2. Anatomy of a $JENKINS_HOME .................................................... 18
2.5.3. Choosing a backup strategy .............................................................. 19
2.5.4. Define a Jenkins instance to rollback to ........................................... 21
2.6. Resilient Jenkins Architecture ..................................................................... 21
3. Architecting for Manageability ............................................................................... 23
3.1. Introduction .................................................................................................. 23
3.2. Test Instances ............................................................................................... 23
3.2.1. Setting up a test instance .................................................................. 23
4. Continuous Delivery with Jenkins Workflow ........................................................ 30
4.1. Introduction .................................................................................................. 30
4.2. Prerequisites ................................................................................................. 30
4.3. Concepts ....................................................................................................... 31
4.4. Artifact traceability with fingerprinting ....................................................... 34
4.5. Workflow DSL Keywords ........................................................................... 35
4.5.1. node: Allocate node .......................................................................... 35
4.5.2. stage: Stage ...................................................................................... 36
4.5.3. input: Input ....................................................................................... 36
4.5.4. parallel: Execute sub-workflows in parallel .................................. 36
4.5.5. bat: Windows Batch Script .............................................................. 37
ii
Jenkins Cookbook
iii
Jenkins Cookbook
iv
Chapter 1. Hardware Recommendations
1.1. Introduction
Sizing a Jenkins environment depends on a number of factors, which makes it a very
inexact science. Achieving an optimal configuration requires some experience and
experimentation, but it is possible to make a smart approximation to start, especially
when designing with Jenkins best practices in mind.
The following chapter will outline these factors and how you can account for them
when sizing your configuration. It will also share some sample configurations and
the hardwares behind some of the largest Jenkins installations presented in a Jenkins
Scalability Summit.
1
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/
_right_sizing_jenkins_masters.html#_calculating_how_many_jobs_masters_and_executors_are_needed
1
Hardware Recommendations
downtime. Instead, it is advisable to set up slaves that the Jenkins master can delegate
build jobs to, keeping the bulk of the work off of the master itself.
2
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/
_architecting_for_scale.html#_distributed_builds_architecture
3
http://www.slideshare.net/andrewbayer/seven-habits-of-highly-effective-jenkins-users-2014-edition
4
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/_architecting_for_scale.html
2
Hardware Recommendations
In the Jenkins community, such examples can be found by presenters at the Jenkins
User Conferences, scalability summits, and other such community events.
Here are a few case studies from the 2013 Jenkins Scalability Summit:
1.4.1. Netflix
1 master
Elastic slaves with Amazon EC2 + 40 ad-hoc slaves in Netflixs data center
1,600 jobs
2 TB of builds
Hardware Configuration
26G memory
3
Hardware Recommendations
By 2013, Netflix split their monolithic master and significantly increased their number
of jobs and builds:
6 masters
100 slaves
3,200 jobs
3 TB of builds
4
Hardware Recommendations
would also monitor slave connections for errors and would remove the offending
slaves. Removed slaves were then de-provisioned.
1.4.2. Yahoo
Mujibur Wahab of Yahoo also presented Yahoos massive installation to the 2013
Scalability Summit. Their installation was:
1 primary master
3 backup masters
400+ executors
13,000 jobs
8,000 builds/day
Hardware Configuration
96G memory
1.2TB disk
5
Hardware Recommendations
6
Chapter 2. Architecting for Scale
2.1. Introduction
As an organization matures from a continuous delivery standpoint, its Jenkins
requirements will similarly grow. This growth is often reflected in the Jenkins masters
architecture, whether that be "vertical" or "horizontal" growth.
Vertical growth is when a masters load is increased by having more configured
jobs or orchestrating more frequent builds. This may also mean that more teams are
depending on that one master.
Horizontal growth is the creation of additional masters within an organization to
accommodate new teams or projects, rather than adding these things to an existing
single master.
There are potential pitfalls associated with each approach to scaling Jenkins, but with
careful planning, many of them can be avoided or managed. Here are some things to
consider when choosing a strategy for scaling your organizations Jenkins instances:
Do you have the resources to maintain multiple masters? Jenkins masters will
require regular plugin updates, semi-monthly core upgrades, and regular backups
of configurations and build histories. Security settings and roles will have to be
manually configured for each master. Downed masters will require manual restart
of the Jenkins master and any jobs that were killed by the outage.
How mission critical are each teams projects? Consider segregating the most
vital projects to separate masters to minimize the impact of a single downed
master. Also consider converting any mission-critical project pipelines to
Workflow jobs, which have the ability to survive a master-slave connection
interruptions.
How important is a fast start-up time for your Jenkins instance? The more
jobs a master has configured, the longer it takes to load Jenkins after an upgrade
or a crash. The use of folders and views to organize jobs can limit the number of
that need to be rendered on start up.
7
Architecting for Scale
8
Architecting for Scale
Note
An architecture with 1 Jenkins master connected to 1 slave over a TCP/
IP socket. Slave has 4 execution slots and is building 3 of the masters
configured jobs.
A slave is a machine set up to offload build projects from the master. The method
for scheduling builds depends on the configuration given to a specific project: some
9
Architecting for Scale
projects may be configured to only use a specific slave while others can freely pick up
slaves among the pool of slaves assigned to the master.
In a distributed builds environment, the Jenkins master will use its resources to only
handle HTTP requests and manage the build environment. Actual execution of builds
will be delegated to the slaves. With this configuration it is possible to horizontally
scale an architecture, which allows a single Jenkins installation to host a large number
of projects and build environments.
The SSH connector: Configuring a slave to use the SSH connector is the
preferred and the most stable way to establish master-slave communication.
Jenkins has a built-in SSH client implementation. This means that the Jenkins
master can easily communicate with any machine with a SSHD server installed.
The only requirements is that the public key of the master is part of the set of the
authorized-keys of the slaves. Once defined the host and the ssh key to be used (in
the Manage Node # Add New Node configuration page), Jenkins will manage the
communication automatically by installing the binaries of the agent program and
starting/stopping the slave program as needed.
10
Architecting for Scale
Java Web Start program has to be launched in the slave machine in 2 different
ways:
<serviceKey> is the name of the registry key to define this slave service and <service
display name> is the label that will identify the service in the Service Manager
interface.
To ensure that restarts are automated, you will need to download a slave jar newer than
v 2.37 and copy it to a permanent location on the slave machine. The slave.jar can be
found in:
http://<your-jenkins-host>/jnlpJars/slave.jar
If running a version of Jenkins newer than 1.559, the slave.jar will be kept up to date
each time it connects to the master.
11
Architecting for Scale
1
http://wiki.jenkins-ci.org/display/JENKINS/SSH+slaves+and+Cygwin
2
http://wiki.jenkins-ci.org/display/JENKINS/Windows+Slaves+Plugin
3
http://wiki.jenkins-ci.org/display/JENKINS/Installing+Jenkins+as+a+Windows+service
12
Architecting for Scale
One best practice to avoid this failure is to configure a job with the assumption that
the target slave does not have the necessary tools installed, and to include the tools
installation as part of the build process.
The EC2 Plugin4 let Jenkins use AWS EC2 instances as cloud build resources
when it runs out of on-premise slaves. The EC2 slaves will be dynamically
created inside an AWS network and de-provisioned when they are not needed.
The JCloud plugin5 creates the possibility of executing the jobs on any cloud
provider supported by JCloud libraries
4
https://wiki.jenkins-ci.org/display/JENKINS/Amazon+EC2+Plugin
5
https://wiki.jenkins-ci.org/display/JENKINS/JClouds+Plugin
13
Architecting for Scale
1. By environment (QA, DEV, etc) - With this strategy, Jenkins masters are
populated by jobs based on what environment they are deploying to.
Pros
Can easily restrict access to an environment to only users who will be using
that environment
Cons
2. By org chart - This strategy is when masters are assigned to divisions within an
organization.
Pros
Can easily restrict access to a divisions projects to only users who are
within that division
Cons
6
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Cloud+Connector+Plugin
14
Architecting for Scale
Pros
Entire flows can be visualized because all steps are on one master
Reduces the impact of one masters downtime on only affects a small subset
of products
Cons
A strategy for restricting permissions must be devised to keep all users from
having access to all items on a master.
When evaluating these strategies, it is important to weigh them against the vertical and
horizontal scaling pitfalls discussed in the introduction.
Another note is that a smaller number of jobs translates to faster recovery from failures
and more importantly a higher mean time between failures.
2.4.2. Calculating how many jobs, masters, and executors are needed
Having the best possible estimate of necessary configurations for a Jenkins installation
allows an organization to get started on the right foot with Jenkins and reduces the
number of configuration iterations needed to achieve an optimal installation. The
challenge for Jenkins architects is that true limit of vertical scaling on a Jenkins master
is constrained by whatever hardware is in place for the master, as well as harder to
quantify pieces like the types of builds and tests that will be run on the build nodes.
There is a way to estimate roughly how many masters, jobs and executors will be
needed based on build needs and number of developers served. These equations
assume that the Jenkins master will have 5 cores with one core per 100 jobs (500 total
jobs/master) and that teams will be divided into groups of 40.
If you have information on the actual number of available cores on your planned
master, you can make adjustments to the number of masters equations accordingly.
The equation for estimating the number of masters and executors needed when the
number of configured jobs is known is as follows:
15
Architecting for Scale
The equation for estimating the maximum number of jobs, masters, and executors
needed for an organization based on the number of developers is as follows:
These numbers will provide a good starting point for a Jenkins installation, but
adjustments to actual installation size may be needed based on the types of builds and
tests that an installation runs.
Logical Volume Manager for Linux - LVM manages disk drives and allows
logical volumes to be resized on the fly. Many distributions of Linux use LVM
when they are installed, but Jenkins should have its our LVM setup.
ZFS for Solaris - ZFS is even more flexible than LVM and spanned volumes and
just requires that the $JENKINS_HOME be on its own filesystem. This makes it
easier to create snapshots, backups, etc.
Symbolic Links - For systems with existing Jenkins installations and who cannot
use any of the above-mentioned methods, symbolic links (symlinks) may be
used instead to store job folders on separate volumes with symlinks to those
directories.
Additionally, to easily prevent a $JENKINS_HOME folder from becoming bloated,
make it mandatory for jobs to discard build records after a specific time period has
passed and/or after a specific number of builds have been run. This policy can be set
on a jobs configuration page.
16
Architecting for Scale
7
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/_backing_up_with_cloudbees_backup_plugin.html
17
Architecting for Scale
The default location for your $JENKINS_HOME will be set to /var/lib/jenkins and
the $JENKINS_WAR home will be in /usr/lib/jenkins.
FreeBSD
If installing Jenkins using a port, the $JENKINS_HOME will be located in whichever
directory you run the make command in. It is recommended to create a /usr/ports/
devel/jenkins folder and compile Jenkins in that directory.
You will be able to edit the $JENKINS_HOME by editing the /usr/local/etc/jenkins.
OpenBSD
If installing Jenkins using a package,the $JENKINS_HOME is set by default to /var/
jenkins.
If installing Jenkins using a port, the $JENKINS_HOME will be located in whichever
directory you run the make command in. It is recommended to create a /usr/ports/
devel/jenkins folder and compile Jenkins in that directory.
You will be able to edit the $JENKINS_HOME by editing the /usr/local/etc/jenkins
file.
Solaris/OpenIndiana
The Jenkins project voted on September 17, 2014 to discontinue Solaris packages.
18
Architecting for Scale
These folders will automatically be recreated the next time a build runs or Jenkins is
launched.
Jobs and Folders. Your job or folder configurations, build histories, archived
artifacts, and workspace will exist entirely within the jobs folder.
The jobs directory, whether nested within a folder or at the root level is as follows:
If you only need to backup your job configurations, you can opt to only backup the
config.xml for each job. Generally build records and workspaces do not need to be
backed up, as workspaces will be re-created when a job is run and build records are
only as important as your organizations deems them.
System configurations. Your instances system configurations exist in the root
level of the $JENKINS_HOME folder:
19
Architecting for Scale
The config.xml is the root configuration file for your Jenkins. It includes configurations
for the paths of installed tools, workspace directory, and slave agent port.
Any .xml other than that config.xml in the root Jenkins folder is a global configuration
file for an installed tool or plugin (i.e. Maven, Git, Ant, etc). This includes the
credentials.xml if the Credentials plugin is installed.
If you only want to backup your core Jenkins configuration, you only need to back up
the config.xml.
Plugins. Your instances plugin files (.hpi and .jpi) and any of their dependent
resources (help files, pom.xml files, etc) will exist in the plugins folder in
$JENKINS_HOME.
The identity.key is an RSA key pair that identifies and authenticates the current Jenkins
instance.
The secret.key is used to encrypt plugin and other Jenkins data, and to establish a
secure connection between a master and slave.
The secret.key.not-so-secret file is used to validate when the $JENKINS_HOME was
created. It is also meant to be a flag that the secret.key file is a deprecated way of
encrypting information.
The files in the secrets folder are used by Jenkins to encrypt and decrypt your
instances stored credentials, if any exist. Loss of these files will prevent recovery of
any stored credentials. hudson.util.Secret is used for encrypting some Jenkins data like
20
Architecting for Scale
the credentials.xml, while the master.key is used for encrypting the hudson.util.Secret
key. Finally, the InstanceIdentity.KEY is used to identity this instance and for
producing digital signatures.
2. Restoring from a backup - A plan must be put in place on whether the backup
should be restored manually or with scripts when the primary goes down.
8
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/
_setting_up_high_availability_with_cloudbees_high_availability_plugin.html
21
Architecting for Scale
A proxy (typically HAProxy or F5) then fronts the primary master. The proxys job
is to continuously monitor the primary master and route requests to the backup if the
primary goes down. To make the infrastructure more resilient, you can have multiple
backup masters configured.
Step 2: Enable security. Set up an authentication realm that Jenkins will use for its
user database. If using CloudBees Jenkins Enterprise, enable the Role-based Access
Control plugin that comes bundled with it.
Tip
If you are trying to set up a proof-of-concept, it is recommended to use the
Mock Security Realm plugin9 for authentication.
Step 3: Add build nodes (slaves) to master. Add build servers to your master to
ensure you are conducting actual build execution off of the master, which is meant to
be an orchestration hub, and onto a dumb machine with sufficient memory and I/O
for a given job or test.
Step 4: Setup a test instance10. A test instance is typically used to test new plugin
updates. When a plugin is ready to be used, it should be installed into the main
production update center. :imagesdir: ../resources/
9
https://wiki.jenkins-ci.org/display/JENKINS/Mock+Security+Realm+Plugin
10
http://jenkins-cookbook.apps.cloudbees.com/docs/jenkins-cookbook/_test_instances.html
22
Chapter 3. Architecting for Manageability
3.1. Introduction
With over 1,000 plugins and countless versions of said plugins in the open-source
community, testing for all possible conflicts before upgrading one or more production
Jenkins instances is simply not feasible. While Jenkins itself will warn of potential
incompatibility if it detects that a plugin requires a newer version of the Jenkins core,
there is no automatic way to detect conflicts between plugins or to automatically
quantifying the impact of upgrading a plugin before doing the upgrade.
Instead, Jenkins administrators should be made responsible for manually testing
their own instances plugin and core version updates before performing them on the
production instance. This kind of testing requires a copy or test instance of the
production server to act as the sandbox for such tests and can prevent production
master downtime.
23
Architecting for Manageability
It is ideal to first ensure sure the master is idle (no running or queued jobs) before
attempting to create a test master.
If you are running CloudBees Jenkins Enterprise, there are also a few files specific to
CJE which you should not copy over into your alternate installation:
identity.key should not be copied to the test master, as this identifies the
installation generally. For the new installation you will need a distinct test license.
The jgroups subdirectory should not be copied. Otherwise the new installation
may attempt to join an HA cluster with the old installation.
24
Architecting for Manageability
.owner
.ri
.rvm
.ssh
.viminfo
.vnc
bin/
tools/
**/.owner
**/queue.xml
**/fingerprints/
**/shelvedProjects/
**/updates/
**/jobs/*/workspace/
**/war/
/tools/
**/custom_deps/
**/slave/workspace/
**/slave-slave.log.*
cache/
fingerprints/
**/wars/jenkins*.war
*.log
*.zip
*.rrd
*.gz
Once you have a good .gitignore file, you can run the follow git commands to commit
your $JENKINS_HOME to a git repository like GitHub:
git add -all
git commit -m first commit
git push
Now you can install Jenkins to a fresh instance and git clone this $JENKINS_HOME
from the git repository to your new instance. You will need to replace the files in the
new instance with your version-controlled files to complete the migration, whether
through scripts or through a drag-and-drop process.
Once this is done, you will need to restart the new test masters Jenkins service
or reload its configuration from the Jenkins UI (Manage Jenkins >> Reload
Configuration).
With GitHub + Docker (Linux-only)
When it comes to version controlling your $JENKINS_HOME, just follow the
instructions in the previous section.
The next step will be to create a Docker image with identical configurations to your
production instances - operating system (Linux-only), installed libraries/tools, and
open ports. This can be accomplished through Dockerfiles.
25
Architecting for Manageability
You will then just need to create mounted storage on your Docker server with a clone
of your version-controlled $JENKINS_HOME home and a simple image to clone the
$JENKINS_HOME into.
For example, we can create a Docker image called jenkins-storage and version control
our $JENKINS_HOME in a Github repository known as demo-joc. The jenkins-
storage Docker image can be built from a Dockerfile similar to this:
FROM debian:jessie
RUN apt-get update && apt-get -y upgrade
RUN apt-get install -y --no-install-recommends \
openjdk-7-jdk \
openssh-server \
curl \
ntp \
ntpdate \
git \
maven \
less \
vim
RUN printf "AddressFamily inet" >> /etc/ssh/ssh_config
ENV MAVEN_HOME /usr/bin/mvn
ENV GIT_HOME /usr/bin/git
# Install Docker client
RUN curl https://get.docker.io/builds/Linux/x86_64/docker-latest -o /usr/local/bin/d
RUN chmod +x /usr/local/bin/docker
RUN groupadd docker
# Create Jenkins user
RUN useradd jenkins -d /home/jenkins
RUN echo "jenkins:jenkins" | chpasswd
RUN usermod -a -G docker jenkins
# Make directories for [masters] JENKINS_HOME, jenkins.war lib and [slaves] remote F
RUN mkdir /usr/lib/jenkins /var/lib/jenkins /home/jenkins /var/run/sshd
# Set permissions
RUN chown -R jenkins:jenkins /usr/lib/jenkins /var/lib/jenkins /home/jenkins
#create data folder for cloning
RUN ["mkdir", "/data"]
RUN ["chown", "-R", "jenkins:jenkins", "/data"]
USER jenkins
VOLUME ["/data"]
WORKDIR /data
# USER jenkins
CMD ["git", "clone", "https://github.com/[your-github-id]/docker-jenkins-storage.git
Creating mounted storage for containers would just require something similar to the
following command:
docker run --name storage [your-dockerhub-id]/jenkins-storage git clone https://gith
And Jenkins images that rely on the mounted storage for their $JENKNIS_HOME will
then need to point to the mounted volume:
26
Architecting for Manageability
Note that Docker only supports one mounted volume at a time, so if you are planning
on running multiple test instances on Docker, all of their _$JENKINS_HOME_s will
need to be version controlled in the same GitHub repo.
With Jenkins Operations Center
CloudBees Jenkins Operations Center can push plugins, core Jenkins versions, and
security configurations to any Jenkins master that is managed by it. This makes it
possible to attach a test server instance (whether that be a Docker container, EC2
instance, vSphere VM, etc) and CJOC will automatically push to the master those pre-
configured settings once a connection is established.
To keep both masters in sync plugin/core-wise, 3 Custom Update Centers would need
to be set up using the Custom Update Center plugin by CloudBees. The update center
would need to be hosted on CloudBees Jenkins Operations Center and maintained by
the Jenkins administrator.
Update centers can take several different upstream resources:
27
Architecting for Manageability
- Like the previous experimental update centers, this UC contains the most
cutting edge versions of the CloudBees Jenkins Operations Center products
feature set.
With this in mind, here is how a test instance could be set up with a combination of the
above update centers:
Main update center - This custom update center would only take the OSS
plugins as its upstream plugins. The administrator would need to select which
plugins to store and which versions to push to any downstream update center.
This update center should be configured to automatically promote the latest
plugin.
Production update center - This custom update center would need to take the
main update center as its upstream and be configured to not automatically take
the latest version. This allows the administrator more control over what plugins
will be available to the downstream master, in this case the production master.
This will in turn prevent users of the downstream master from being able to
upgrade beyond an approved version of a plugin of the Jenkins core.
Test update center - This customer update center would need to take the main
update center as its upstream and be configured to automatically take the latest
version of its plugins. This allows the test environment to always have access to
the latest plugins to be tested against your environment. The test master will be
the downstream master for this update center.
The only further configuration that would need to be duplicated would be the jobs,
which can be accomplished by copy/pasting the jobs folder from the production master
to the target test master or by a script that is run by a Cluster Operation on CJOC. Such
a custom script can be configured to run after certain triggers or at certain intervals.
Test master slaves. Test masters can be connected to test slaves, but this will
require further configurations. Depending on your implementation of a test instance,
you will either need to create a Jenkins Docker slave image or a slave VM. Of course,
open-source plugins like the EC2 plugin also the option of spinning up new slaves on-
demand.
If you are not using CloudBees Jenkins Operations Center, the slave connection
information will then need to be edited in the config.xml located in your test masters
$JENKINS_HOME.
If using Jenkins Operations Center, no further configuration is required so long as the
test master has been added as a client master to CJOC.
Rolling back plugins that cause failures. If you discover that a plugin update is
causing conflict within the test master, you can rollback in several ways:
28
Architecting for Manageability
For bad plugins, you can rollback the plugin from the UI by going to the plugin
manager (Manage Jenkins >> Manage Plugins) and going to the Available
tab. Jenkins will show a downgrade button next to any plugins that can be
downgraded.
1
http://updates.jenkins-ci.org/download/plugins
29
Chapter 4. Continuous Delivery with
Jenkins Workflow
4.1. Introduction
Continuous delivery allows organizations to deliver software with lower risk. The path
to continuous delivery starts by modeling the software delivery pipeline used within
the organization and then focusing on the automation of it all. Early, directed feedback,
enabled by pipeline automation enables software delivery more quickly over traditional
methods of delivery.
Jenkins is the Swiss army knife in the software delivery toolchain. Developers and
operations (DevOps) personnel have different mindsets and use different tools to get
their respective jobs done. Since Jenkins integrates with a huge variety of toolsets, it
serves as the intersection point between development and operations teams.
Many organizations have been orchestrating pipelines with existing Jenkins plugins
for several years. As their automation sophistication and their own Jenkins experience
increases, organizations inevitably want to move beyond simple pipelines and create
complex flows specific to their delivery process.
These Jenkins users require a feature that treats complex pipelines as a first-class
object, and so CloudBees engineers developed and contributed the new Jenkins
Workflow feature1 to the Jenkins open source project. This Workflow plugin was built
with the communitys requirements for a flexible, extensible, and script-based pipeline
in mind.
4.2. Prerequisites
Continuous delivery is a process - rather than a tool - and requires a mindset and
culture that must percolate from the top-down within an organization. Once the
organization has bought into the philosophy, the next and most difficult part is
mapping the flow of software as it makes its way from development to production.
The root of such a pipeline will always be an orchestration tool like a Jenkins, but there
are some key requirements that such an integral part of the pipeline must satisfy before
it can be tasked with enterprise-critical processes:
1
https://wiki.jenkins-ci.org/display/JENKINS/Workflow+Plugin
30
Continuous Delivery with Jenkins Workflow
failure on day six of a seven-day pipeline has serious consequences for on-time
delivery of a product.
Audit runs and debug ability: Build managers like to see the exact execution
flow through the pipeline, so they can easily debug issues.
To ensure a tool can scale with an organization and suitably automate existing delivery
pipelines without changing them, the tool should also support:
The Workflow plugin allows users to create such a pipeline through a new job type
called Workflow. The flow definition is captured in a Groovy script, thus adding
control flow capabilities such as loops, forks and retries. Workflow allows for stages
with the option to set concurrencies, preventing multiple builds of the same workflow
from trying to access the same resource at the same time.
4.3. Concepts
Workflow Job Type. There is just one job to capture the entire software delivery
pipeline in an organization. Of course, you can still connect two workflow job
types together if you want. A Workflow job type uses a Groovy-based DSL for job
definitions. The DSL affords the advantage of defining jobs programmatically:
node(linux){
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def mvnHome = tool 'M3'
env.PATH = "${mvnHome}/bin:${env.PATH}"
sh 'mvn -B clean verify'
}
31
Continuous Delivery with Jenkins Workflow
Consider a simple pipeline with three stages. A naive implementation of this pipeline
can sequentially trigger each stage on every commit. Thus, the deployment step is
triggered immediately after the Selenium test steps are complete. However, this would
mean that the deployment from commit two overrides the last deployment in motion
from commit one. The right approach is for commits two and three to wait for the
deployment from commit one to complete, consolidate all the changes that have
happened since commit one and trigger the deployment. If there is an issue, developers
can easily figure out if the issue was introduced in commit two or commit three.
Jenkins Workflow provides this functionality by enhancing the stage primitive. For
example, a stage can have a concurrency level of one defined to indicate that at any
point only one thread should be running through the stage. This achieves the desired
state of running a deployment as fast as it should run.
32
Continuous Delivery with Jenkins Workflow
deployment of a particular stack to a data center. Teams can also write their own
extensions to hook into the Workflow job type and make the deployment easier.
Meanwhile, job creators can write a plain old Groovy function to define any custom
steps that can deploy (or undeploy) artifacts from production.
node {
sh './build-and-test'
}
checkpoint 'Completed tests'
node {
sh './deploy'
}
Workflow Stage View. When you have complex builds pipelines, it is useful to see
the progress of each stage and to see where build failures are occurring in the pipeline.
This can enable users to debug which tests are failing at which stage or if there are
other problems in their pipeline. Many organization also want to make their pipelines
user-friendly for non-developers without having to develop a homegrown UI, which
can prove to be a lengthy and ongoing development effort.
The Workflow Stage View feature offers extended visualization of workflow build
history on the index page of a flow project. This visualization also includes helpful
metrics like average run time by stage and by build, and a user-friendly interface for
interacting with input steps.
33
Continuous Delivery with Jenkins Workflow
The only prerequisite for this plugin is a workflow with defined stages in the flow.
There can be as many stages as you desired and they can be in a linear sequence, and
the stage names will be displayed as columns in the Stage View UI. This feature is part
of the CloudBees Jenkins Enterprise product.
will archive any WAR artifacts created in the Workflow and fingerprint them for
traceability. This trace log of this artifact and a list of all fingerprinted artifacts in a
build will then be available in the left-hand menu of Jenkins:
34
Continuous Delivery with Jenkins Workflow
To find where an artifact is used and deployed to, simply follow the more details link
through the artifacts name and view the entires for the artifact in its Usage list.
For more information, visit the Jenkins communitys wiki2 on how fingerprints work
and their usage.
2
https://wiki.jenkins-ci.org/display/JENKINS/Fingerprint
35
Continuous Delivery with Jenkins Workflow
Params:
Nested block
node('master') {}
Params:
Params:
message : String, default "Workflow has paused and needs your input before
proceeding"
id: Optional ID that uniquely identifies this input from all others.
parameters: List<ParameterDefinition>
input hello world
36
Continuous Delivery with Jenkins Workflow
parallel branches
Params:
Params:
More information on the Workflow DSL can be found in the Workflow tutorial3.
node(linux){
git url: 'https://github.com/jglick/simple-maven-project-with-tests.git'
def mvnHome = tool 'M3'
env.PATH = "${mvnHome}/bin:${env.PATH}"
sh 'mvn -B clean verify'
}
Where node is the step that schedules the tasks in the following block on whatever
node with the label specified in its argument. In this case, the blocks tasks will only
be run on a node with the label linux. The node block is required to tell Jenkins what
system to run the commands.
git is the step that specifies what source code repository code should be checked from
and does the checkout at this point.
The tool step makes sure a tool with the given name, in this case, a specific version of
the Maven build tool, is installed on the current node. Merely running this step does
3
https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md
37
Continuous Delivery with Jenkins Workflow
not do much good; the script needs to know where it was installed, so the tool can be
run later. For this, we need a variable.
The def keyword in Groovy is the quickest way to define a new variable, hence the
def mvnHome. The return value of the tool M3 check is assigned to the mvnHome
variable.
Workflow also allows for the creation of very complex pipelines, with parallel stages,
conditional logic gates, and for definitions to be loaded from version control and
shared between workflows. This allows for workflows and certain standardized scripts
to be shared between teams and changes to these scripts to be protected and reviewed
by an administrator.
Here is an example script for such a scenario, where the bulk of the script is version
controlled in GitHub:
def flow
node('master') {
git branch: 'master', changelog: false, poll: true, url: 'https://github.com/lav
flow = load 'flow.groovy'
flow.devQAStaging()
}
flow.production()
def devQAStaging() {
env.PATH="${tool 'Maven 3.x'}/bin:${env.PATH}"
stage 'Dev'
sh 'mvn clean install package'
archive 'target/x.war'
try {
checkpoint('Archived war')
} catch (NoSuchMethodError _) {
echo 'Checkpoint feature available in Jenkins Enterprise by CloudBees.'
}
stage 'QA'
parallel(longerTests: {
runWithServer {url ->
sh "mvn -f sometests/pom.xml test -Durl=${url} -Dduration=30"
}
}, quickerTests: {
runWithServer {url ->
sh "mvn -f sometests/pom.xml test -Durl=${url} -Dduration=20"
}
})
stage name: 'Staging', concurrency: 1
deploy 'target/x.war', 'staging'
}
def production() {
input message: "Does http://localhost:8888/staging/ look good?"
38
Continuous Delivery with Jenkins Workflow
try {
checkpoint('Before production')
} catch (NoSuchMethodError _) {
echo 'Checkpoint feature available in Jenkins Enterprise by CloudBees.'
}
stage name: 'Production', concurrency: 1
node {
unarchive mapping: ['target/x.war' : 'x.war']
deploy 'target/x.war', 'production'
echo 'Deployed to http://localhost:8888/production/'
}
}
def deploy(war, id) {
sh "cp ${war} /tmp/webapps/${id}.war"
}
def undeploy(id) {
sh "rm /tmp/webapps/${id}.war"
}
return this;
Fingerprinter (core)
4
http://jenkins-enterprise.cloudbees.com/docs/user-guide-docs/workflow.html
5
https://github.com/jenkinsci/workflow-plugin/blob/master/TUTORIAL.md
39
Continuous Delivery with Jenkins Workflow
JUnitResultArchiver (junit)
JavadocArchiver (javadoc)
Mailer (mailer)
4.7.4. Clouds
docker: supported as of 0.8
4.7.5. Miscellaneous
rebuild: JENKINS-260248
build-token-root: JENKINS-266939
6
https://issues.jenkins-ci.org/browse/JENKINS-24887
7
https://issues.jenkins-ci.org/browse/JENKINS-24673
8
https://issues.jenkins-ci.org/browse/JENKINS-26024
9
https://issues.jenkins-ci.org/browse/JENKINS-26693
10
https://issues.jenkins-ci.org/browse/JENKINS-26104
40
Continuous Delivery with Jenkins Workflow
There are some plugins which have not yet incorporated support for workflow. Guides
on how to add this support, as well as their relevant Jenkins JIRA tickets can be found
in the Workflow Plugin GitHub documentation11. :imagesdir: ../resources/
11
https://github.com/jenkinsci/workflow-plugin/blob/master/COMPATIBILITY.md
41
Chapter 5. Virtualization
In general, bare-metal servers tend to perform faster than virtualized servers, which
suffer from a reported 1-5% of CPU overhead and 5-10% of memory overhead on
older hardware and 2-3% on newer hardware. This overhead can be accounted for
when architecting an installation, but even with such overhead, virtualization still
makes sense if scalability trumps performance or virtualization is being used for only
certain components of a Jenkins installation.
5.1. Masters
In general, it is not recommended to virtualize the Jenkins master. Reasons include
the fact that the number of jobs tend to increase over time, while the master itself
is the orchestrator of these jobs builds. At the same time, the number of executors
connecting to the master similarly increases. This ever increasing load, combined
with the loads of other VMs on the same machine invites performance problems on a
virtualized Jenkins master. When the Jenkins masters are throttled, slaves connections
will be dropped, killing all in-flight builds. To prevent this, masters that are set up on
VMs will need to be regularly resized as the installation grows organically.
An exception to the general recommendation is when certain features exclusive
to VMs are being leveraged, like VMwares live migration for vSphere. Such live
migration allows for VMs to be copied between physical servers without downtime,
which confers obvious and VM-exclusive benefits.
5.2. Slaves
In general, slaves are simply dumb machines that only need enough memory to run a
few builds. This makes them suitable for being virtualized and even being ephemeral if
utilizing a VM cloud, like VMwares vSphere.
Various open source plugins exist to provide integrations between various VM
providers CloudBees in particular offers a vSphere plugin which allows for a true
cloud integration with vSphere. In this case, you can simply install a separate agent on
a VM box and the CloudBees vSphere plugin to Jenkins, which is covered in Chapter
7.
It must be noted however, that running builds on virtualized slaves versus bare metal
slaves may suffer from slower build times. Whether or not this hit will happen is based
on many factors, but Grid Dynamics Kirill Evstigneev had the following configuration
and saw the average build time increase 25% when switching to virtualized slaves:
42
Virtualization
RAM: 8 GB RAM
Processor: i7
Note
Metrics from soldering-iron.blogspot.com
However, there are many cases where any possible performance hit is dwarfed by
a larger increase in productivity due to the elasticity and scalability of a virtualized
environment.
43
Virtualization
Docker and other containerization technologies do not suffer from these performance
hits due to an elimination of hardware virtualization layers and direct execution on the
metal. scaledwidth=90%:imagesdir: ../resources/
44
Chapter 6. Containers
Containerization is an alternative approach to virtualization, such that the elimination
of hardware virtualization layers and direct execution on the metal allow containers
to be light-weight and not suffer from some of the performance issues of traditional
VMs.
6.1. Docker
Docker is an open-source project that provides a platform for building and shipping
applications using containers. This platform enables developers to easily create
standardized environments that ensure that a testing environment is the same as the
production environment, as well as providing a lightweight solution for virtualizing
applications. Docker has inspired a wave of microservice architectures and is
supported by tech giants like Google, Microsoft, IBM and Amazon.
The versatility and usability of Docker has made it a popular choice among DevOps-
driven organizations. It has also made Docker an ideal choice for creating the
standardized and repeatable environments.
45
Containers
This testing and validation is possible with end-to-end CD, where the environments
captured by Docker containers are also subject to a pipeline of builds and tests,
as well as human-approved pushes back to an image repository like Docker hub.
This approach to continuously managing containers quality ensures that testing
and production environments are always stable and adaptable to changes in an
organizations needs. To further enhance this end-to-end pipeline, Docker images can
also be tracked, allowing individual images to be tied to any deployed containers and
for easy rollbacks should a change in one image break another.
46
Containers
Because Docker offers the ability to quickly create multiple environments from
one definition, Docker containers are also ideal for serving as standardized build
environments for an organization.
The Jenkins open source community has plugins which enable all of these use cases
for Docker and Jenkins, allowing Docker to be leveraged for continuous delivery and
creating a Docker-based Jenkins architecture. The recommended open-source plugins
for these use cases are:
Custom Build Environments for Jenkins with the CloudBees Docker Custom
Builds Environment Plugin1 (formerly the Oki Docki plugin)
Triggering Jenkins pipelines with Docker Hub with the CloudBees Docker Hub
Notification Plugin3
Building and publishing Docker images with the CloudBees Docker Build and
Publish Plugin4
Orchestrating Workflows with Jenkins and Docker with the CloudBees Workflow
Docker Plugin5
CloudBees also offers a way for sharing Docker slave configurations using Docker
Swarm and the CloudBees Jenkins Operations Center product6, which is part of the
CloudBees Jenkins Platform.
6.1.3. Prerequisites
Most all plugins focused on Docker also require the installation of Docker to any
slaves that will use the Docker CLI, like the CloudBees Docker Build and Publish
Plugin.
Docker is an open source project and supports installation to a wide range of operating
systems and platforms7. Though non-Linux operating systems will also require the
installation of another open source project known as Boot2Docker. Boot2Docker
allows non-Linux operating systems to run the Docker host in a VirtualBox
environment.
1
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Custom+Build+Environment+Plugin
2
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Traceability
3
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Hub+Notification
4
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Build+and+Publish+plugin
5
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Workflow+Plugin
6
http://operations-center.cloudbees.com/docs
7
https://docs.docker.com/installation
47
Containers
Builds often require that credentials or tooling be available to the slave node which
runs it. For a small installation with few specialized jobs, this may be manageable
using generic slaves, but when these requirements are multiplied by the thousands of
jobs that many organizations running per day, managing and standardizing these slave
environments becomes more challenging.
Docker has established itself as a popular and convenient way to bootstrap isolated
and reproducible environments, which allows Docker containers serve as the easiest to
maintain slave environments. Docker containers tooling and other configurations can
be version controlled in an environment definition a Dockerfile, and multiple identical
containers can be created quickly using this definition.
The CloudBees Custom Builds Environment Plugin allows Docker images and files to
serve as template for Jenkins slaves, reducing the administrative overhead of a slave
installation to only updating a few lines in a handful of environment definitions for
potentially thousands of slaves.
Prerequisites. Machines which will host the Docker containers must have Docker
both installed and running. It is highly recommended that such slaves be labeled
docker. Also note that Docker only supports Linux runtimes, so .NET, OS X, and
other OS-dependent builds will not run in a Dockerized Linux environment.
The Docker build environment can be used to build any type of Jenkins job.
Configuration. This plugin adds the option Build inside a Docker container
in the build environment configuration of a job. To enable it, simply scroll to the
Build Environment section of any Jenkins job and select the Build inside a Docker
container option. You will then be able to specify whether a slave container should be
created from a Dockerfile checked into the workspace (e.g. the file was in the root of
the project to be built) or whether to pull an explicit image from a Docker registry to
use as the slave container.
8
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Custom+Build+Environment+Plugin
48
Containers
For the latter option, you can leverage the most popular Docker slave image in Docker
Hub called evarga/jenkins-slave9 or create a new image with a custom Dockerfile. To
create a new Dockerfile, you can fork the evarga/jenkins-slave or edit the below
copy of it using the Dockerfile guidelines10 and reference11:
FROM ubuntu:trusty
MAINTAINER Ervin Varga <[email protected]>
RUN apt-get update
RUN apt-get -y upgrade
RUN apt-get install -y openssh-server
RUN sed -i 's|session required pam_loginuid.so|session optional pam_lo
RUN mkdir -p /var/run/sshd
RUN apt-get install -y openjdk-7-jdk
RUN adduser --quiet jenkins
RUN echo "jenkins:jenkins" | chpasswd
EXPOSE 22
CMD ["/usr/sbin/sshd", "-D"]
Builds which are built within a Docker container will display a Docker icon in a jobs
build history:
9
https://registry.hub.docker.com/u/evarga/jenkins-slave/dockerfile
10
https://docs.docker.com/articles/dockerfile_best-practices
11
https://docs.docker.com/reference/builder
49
Containers
This section will allow a user to optionally create a link in the left-hand menu to an
overall view of all tracked Docker images (http://jenkins-url/docker-traceability),
though the direct link to this overall view will always be available.
12
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Traceability
50
Containers
The other configuration option allows fingerprints to be created for docker images
that have been created outside of Jenkins (e.g. with the Docker CLI). By default, the
CloudBees Docker Traceability plugin will only collect traceability reports for images
created within Jenkins and with plugins that utilize the Docker Commons Plugin.
Security. It is highly recommended to only use this plugin on a master with
security enabled. This is because the JSON stored by this plugin may contain sensitive
information. In light of this, this plugin also adds an extra set of security permissions
that are compatible with the CloudBees Role-Based Access Control plugin:
6.1.6. Triggering Jenkins pipelines with Docker Hub with the CloudBees
Docker Hub Notification Plugin13
Any organization using Docker will also need to leverage a Docker registry to store
any images they create for re-use in other images or for deployment, and Docker Hub
is a Docker image registry which is offered by Docker Inc. as both a hosted service
and a software for on-premise installations. Docker Hub allows images to be shared
13
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Hub+Notification
51
Containers
and pulled for use as containers or as dependencies for other Docker images. Docker
containers can also be committed to Docker Hub as images to save them in their
current state. Docker Hub is to Docker images what GitHub has become for many
developers code an essential tool for version and access control.
To allow Docker Hub to play as pivotal a role in continuous delivery as any source
code repository, the CloudBees Docker Hub Notification plugin gives Docker Hub
the ability to trigger application and slave environment builds, as well as application
packaging, application releases via images, and application deployments via Docker
containers.
Prerequisites. This plugin requires configuring a webhook in Docker Hub that
points to the target Jenkins instances Docker Hub endpoint (http://jenkins-url/
dockerhub-webhook/notify):
This is a generic hook for all Docker Hub repos that allows them to be linked to
all downstream jobs in a master. You can configure up to 15 different jobs on the
same webhook, and all jobs with this repository configured will be triggered once a
notification is received.
Configuration. This plugin adds new a build trigger to both standard Jenkins
jobs and Jenkins Workflows. This trigger is called Monitor Docker Hub for image
changes and allows Jenkins to track when a given Docker image is rebuilt, whether
that image is simply referenced by the job or is in a given repository.
Once a job has been triggered, the builds log will state what the trigger was (e.g.
triggered by push to <Docker Hub repo name>). Triggers can be set by two
52
Containers
parameters that have have been created by the plugin - the Docker Hub repository
name and Docker Hub host.
Docker Hub pipelines. Docker Hub itself supports webhook chains, which you can
read more about in Dockers webhook documentation14. If you have added several
webhooks for different operations, the callback that each service is doing is done in a
chain. If one hook fails higher up in the chain, then any following webhooks will not
be run. This can be useful if using the downstream Jenkins job as a QA check before
performing any other operations based on the pushed image.
<jenkins-url>/jenkins/dockerhub-webhook/details will list all events triggered by all
hook events, and you will be linked directly to the build, while Docker Hubs webhook
will link back to the Jenkins instance. You can also push tags to the Docker Hub
repository, but build status is not pulled by default. The Docker Hub webhook will
show result of builds in the history of the image on Docker Hub.
Other operations
This plugin also adds a build step for pulling images from Docker Hub. This is a
simple build step that does a docker pull using the specified ID, credentials, and
registry URL.
14
https://docs.docker.com/docker-hub/builds/#webhooks
15
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Build+and+Publish+plugin
53
Containers
standardized and repeatable environments that an organization needs for both creating
identical testing and production environments as well as for packaging portable
applications.
If an application is packaged in a Docker image, testing and deploying is a matter of
creating a container from that image and running tests against the application inside. If
the application passes the tests, then they should be stored in a registry and eventually
deployed to production.
Automating the release. According to Forrester Research, the top pain of release
management is a lack of visibility into the release management process and their
process lack of automation.
However, the testing, deploying, and releasing stages of a release pipeline can be
orchestrated by Jenkins using the CloudBees Docker Build and Publish plugin. This
plugin creates a new build step for building and packaging applications into Docker
containers, as well as publishing them a images to both private and public Docker
registries like Docker Hub.
Testing and QA. Applications packaged in Docker images can be tested by running
them as a container. Docker allows containers to be linked, granting the linked
container shell access and allowing it to run scripts against the applications container.
This link can also be made between the Docker application container and another
container which is packaging a service the application needs to run against for a true
integration test, such as a test database.
Promotion and Release. Jenkins supports the concept of promotion, where tested
and approved artifacts are promoted to the next stage in a pipeline. Promotion is
compatible with both traditional Jenkins jobs and the new Jenkins Workflow, and
promotions can be set to only trigger if manually approved by particular users or team
members.
Once an artifact is promoted, it can be manually or automatically moved to the next
stage of its pipeline, whether that is a pre-production staging area or a registry like
54
Containers
Docker Hub for later use as a dependency for another artifacts build. The promotion
can also trigger any other number of pre-release actions, such as notifications and
sending data about the artifact to a company dashboard.
Prerequisites. Unlike the CloudBees Docker Hub Notifications plugin, this plugin
is only running the build of Docker images and pushing them to a specified Docker
registry - no Docker registry webhook setup is required.
To use this plugin, the Docker CLI must be available on the slave machine that will be
running the build.
Credentials for the Docker server will also need to be configured to push to a registry,
and this can either be configured in a .dockercfg16 file or within the Jenkins job. The
target Docker servers URI can also be configured in this file or in the Jenkins job.
Configuration. To use this plugin, users will need to point Jenkins to where the
Dockerfile for the target application is located. This can be a Dockerfile that is been
checked into the slaves workspace or within the root folder of a project.
This plugin provides the following configuration options for the build/publish build
step:
Tag - Whatever tag the build should take. This field supports using environment
variables, such as the ${BUILD_NUMBER}, to tag the image. Docker server
URI - If left blank, this plugin will rely on the installed Docker servers the
environment variables. The credentials for the Docker server will be stored in
16
https://coreos.com/docs/launching-containers/building/customizing-docker
55
Containers
Figure 6.12. Configuring credentials for the Docker Build and Publish plugin
Skip push - Opt to just build, not push to specified Docker registry. A use case
for this is to build an image locally for testing purposes before pushing it.
No cache - An option to discard the old cache for this image completely during
the build and do the build from scratch.
Force Pull - An option to pull all dependent images, even if they are cached
locally.
Skip Decorate - An option to not show the repository name and tag in the Jenkins
build history.
Figure 6.13. Image build decorations with the Docker Build and Publish plugin
Skip tag as latest - By default, every time an image is built, it gets the default
latest tag.
Tips and Tricks. Explicit v. Default Docker Configurations
If you have multiple slaves and each have Docker installed, you should not set
credentials for each job, but would instead leave the configuration options blank so
56
Containers
that the jobs builds rely on the Docker CLI to be correctly configured on each slave
machine. One set of credentials would not work for all of the build/publish jobs steps
unless explicitly configured.
OSX/Windows Docker Compatibility
If a server or registry is not configured, it will use the default of the Docker command
line. This means that the Docker command line must be installed to the machine that
will run this build.
This plugin can support boot2docker on OSX/Windows as long as Boot2Docker
is up and the Docker Server URI for the OSX/Windows machine points to some
Docker server or the Linux container running Docker. The Docker Server Certificate
Authentication needs to be configured as a credential in Jenkins, and for boot2docker
these keys/certificates are generated by boot2docker itself.
This variable allows access to Docker-related functions for use in the Workflow
script.
Params:
Global variable
17
https://wiki.jenkins-ci.org/display/JENKINS/CloudBees+Docker+Workflow+Plugin
18
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/_continuous_delivery_with_jenkins_workflow.html
57
Containers
docker.node() {}
This step schedules the tasks in its nested block on whatever Docker
container was defined in the image that this command is being run from (e.g.
maven32.inside(){} means that all commands in the curly brace will be run
inside the maven32 container).
Params:
Nested block
docker.image(maven:3.3.3-jdk-8).inside {}
This step publishes to a registry whatever Docker image this command is being
run from (e.g. newApp.push() will publish newApps image to a registry).
docker.image(maven:3.3.3-jdk-8).push()
This step selects a Docker registry which all tasks in the nested block will run
against.
Params:
credentials: String -
Nested block
docker.withRegistry(https://docker.mycorp.com/', docker-login) { }
More information on syntax and advanced usages can be found in the CloudBees
Docker Workflow documentation19. A Docker-based demonstration environment can
also be found here20.
scaledwidth=90%:imagesdir: ../resources/
19
http://jenkins-enterprise.cloudbees.com/docs/user-guide-docs/docker-workflow.html
20
https://github.com/jenkinsci/docker-workflow-plugin/blob/master/demo/README.md
58
Chapter 7. CloudBees Services
CloudBees is a company which offers a Jenkins-as-a-service, proprietary
enhancements, and support for Jenkins and open-source plugins. These enhancements
are in the form of plugins and a separate, Jenkins-based software for managing Jenkins
masters.
59
CloudBees Services
60
CloudBees Services
61
CloudBees Services
The alternate approach to use CloudBees DEV@cloud slaves is to use them as offload
capacity when your slaves are busy. Jenkins will transparently offload to DEV@cloud
slaves if all your local slaves are busy as long as the label restriction is compatible.
62
CloudBees Services
When such a build has completed, the acquired machine(s) are released back to the
pool for use by the same or other jobs. When a machine is acquired it may be powered
on, and when a machine is released it may be powered off.
63
CloudBees Services
You can then enter the connection details of the vCenter and verify them clicking on
"Test Connection"
You can now define pools of virtual machines that will be used during Jenkins builds
as slaves or as ephemeral servers used by builds.
Static Pool
A static pool is a pool of virtual machines enumerated one by one.
Click on "Add a new Machine Pool" then select "Static Machine Pool".
64
CloudBees Services
You can now enumerate all the machines of your pool. The "Machine Name" must
match the name of a virtual machine defined in vCenter.
For each declared virtual machine, you can define environment variables than can help
to describe the capabilities of the VM.
"Behaviour on power-on" and "Behaviour on power-off" will be described later in this
chapter.
Folder Pool
A "Folder Pool" is more flexible than a "Static Pool" as it allows you to specify a
vCenter folder path or a vApp name and Jenkins will use all the VMs of the folder /
vApp.
Click on "Add a new Machine Pool" then select "Folder Machine Pool".
65
CloudBees Services
You can now enter the name of the folder of the vCenter Data Center or the name of
the vApp.
You can decide to recurse in the sub folders selecting the "Recurse" checkbox.
Revert to the last snapshot and power up: revert the state of the VM to the last
snapshot and power-on the VM.
Take a snapshot after power off: take a snapshot of the state of the VM after
powered off.
66
CloudBees Services
Take a snapshot after suspend: take a snapshot of the state of the VM after
suspended.
Power-on Wait Conditions. Wait conditions allows to ensure that the slave is
properly started before triggering builds on it.
Wait for VMWare Tools to come up. Wait for the VMWare Tools service
installed on the guest to be started. You can optionally wait for the VMWare Tools to
report the IP address of the guest.
Wait for a TCP port to start listening. Wait for the guest to start listening on a
given TCP port such as the SSH port or the listen port of a database server (e.g. 3306
with MySQL).
67
CloudBees Services
Once the pool(s) of vSphere virtual machines are declared, you can add a new cloud of
slaves in Jenkins configuration.
Go to "Manage Jenkins / Configure System" then in the "Cloud" section at the bottom
of the page, add a cloud of type "Pooled VMWare Virtual Machines".
The configuration of the slaves of a cloud is very similar to the configuration of
"Dumb Slaves" (labels, remote FS root, connector, etc).
VMWare vSphere slaves are similar to standard to other slaves, you can use them
restricting a job to a label that is specific to this pool of slaves or using the usage
strategy "use this node as much as possible".
68
CloudBees Services
69
CloudBees Services
The status screen list the virtual machines indicating their status and their vSphere
UUID:
Click on the desired Virtual Machine and you can take if off-line:
70
CloudBees Services
You can monitor the pools of VMWare virtual machines. On the left menu, select
"Pooled Virtual Machines":
71
CloudBees Services
The status screen list the virtual machines indicating their status and their vSphere
UUID.
72
CloudBees Services
If only one ephemeral virtual machine is allocated, then its IP address is injected
in build steps with the environment variable VMIP. If more than one ephemeral
virtual machines are allocated, then their IP address is injected in build steps with the
environment variables VMIP_1, VMIP_2
73
CloudBees Services
folders. Despite this special classification, a shared slave is like any traditional
Jenkins slave machine. This means that to make a machine a shared slave, it is required
to:
Additionally:
Jenkins should have the appropriate permissions over the slaves filesystem
The administrator should also know how many execution slots the slave should
have (general 1 or 2 per CPU core)
Figure 7.34. Scalable architecture for Jenkins using CJOC and CJE
To create a new shared slave, you will have to create it as a new dashboard-level object
of the type shared slave.
74
CloudBees Services
You will then be taken to the shared slave configuration screen. This screen is almost
identical to a traditional slaves configuration screen, so many of the options will be
familiar to an experienced Jenkins administrator.
Shared slaves can be connected to CJOC using the same connection methods as typical
Jenkins slaves:
SSH
As a Windows service
They can also be configured to have availability policies:
75
CloudBees Services
parenthesis
!expr
negation
expr&&expr
and
expr||expr
or
a -> b
76
CloudBees Services
a <-> b
"if and only if" operator. Equivalent to a&&b || !a&&!b. For example,
windows<#sfbay could be thought of as "if run on a Windows slave, that slave
must be in the SF bay area, but if not on Windows, it must not be in the bay area."
All operators are left-associative (i.e., a#b#c <# (a#b)#c ), and an expression can
contain whitespace for better readability, as white spaces will be ignored.
Label names or slave names can be quoted if they contain unsafe characters. For
example, "jenkins-solaris (Solaris)" || "Windows 2008"
Job configurations
System configurations - this option also allows you to specify whether youd like
to exclude the master.key file or any other files in your $JENKINS_HOME.
This plugin also offers the option for configuring where the backup will be stored
(locally, remote SFTP or WebDAV server), as well as the retention policy and format
of the backup (tar.gz or zip).
Like other jobs, back up jobs can be configured to have certain triggers - whether
that be other jobs, a remote trigger, periodic builds, or some change to an SCM.
This plugin allows users to create backup tasks as jobs. In this way, users can use
the familiar interface for scheduling execution of backup and monitor any failure in
backup activities.
1
http://jenkins-cookbook.cloudbees.com/docs/jenkins-cookbook/_setting_up_a_backup_policy.html
77
CloudBees Services
For example, you might have a daily job that only backs up the system configuration
and job configuration, as they are small but more important, then use another job to
take the full backup of the system once a week.
78
CloudBees Services
Where a load balancer is placed in front of the Jenkins masters and all masters use
a NAS for their $JENKINS_HOME. The load balancer then pings all nodes in the
cluster via a health check URL and uses their return codes to determine which node is
the primary/active master.
The actual details of implementation are highly dependent on what set up is viable
within your actual environment.
79
CloudBees Services
80
CloudBees Services
Tutorial. In this tutorial, we will describe the simplest HA Jenkins setup, which
creates a baseline when for later discussions on other modes of deployment. Here, we
deploy Jenkins in the following configuration for high availability:
Two linux systems that form a Jenkins HA cluster, by running one JVM each
(well call them alpha and bravo). In this tutorial, those two machines need to be
on the same local network.
One floating IP address (well call this 1.2.3.4). Alpha and bravo take this IP
address while each is acting as the primary, thereby ensuring that users can
always access Jenkins through the DNS name thats associated with this IP
address.
First, install CloudBees Jenkins Enterprise packages to alpha and bravo. You need to
install both the Jenkins package for the CloudBees Jenkins Enterprise master itself and
the jenkins-ha-monitor package, which is the Jenkins Enterprise by CloudBees HA
monitor tool.
Tip
81
CloudBees Services
To make this mount automatically happen, update your /etc/fstab by adding the
following entry:
sierra:/jenkins nfs rw,hard,intr 0 2
Repeat this mount setup on bravo, and ensure that both alpha and bravo see the same
data. (For example, touch a from alpha, and make sure ls from bravo will see it. Make
sure the uid and the gid appear the same on alpha and bravo.)
Boot Jenkins on alpha and bravo by issuing /etc/init.d/jenkins start. Now Jenkins
Enterprise boots up in a two-node HA cluster. Access http://alpha:8080/ and http://
bravo:8080/. One will serve the familiar Jenkins UI, and the other will tell you that its
acting as a stand-by node. In the Jenkins UI, go to "Manage Jenkins" then click "High
Availability Status" and make sure two nodes are listed as members. You can kill the
primary JVM (for example by kill -9 PID) while watching the log file via tail -f /var/
log/jenkins/jenkins.log, and you will see the stand-by node take over the primary role.
Finally, we set up a monitoring service to ensure that the floating IP address gets
assigned to the system thats hosting the primary. To do this, log on to alpha and install
the jenkins-ha-monitor package.
This monitoring program watches Jenkins as root, and when the role transition occurs,
it will execute the promotion script or the demotion script. In this tutorial, we will
make these scripts assign/release the floating IP address.
In /etc/jenkins-ha-monitor/promotion.sh, write the following script:
#!/bin/sh
# assign the floating IP address 1.2.3.4 as an alias of eth1
ifconfig eth1:100 1.2.3.4
eth1:100 needs to be your network interface name followed by an unique alias ID (see
"Linux IP aliasing" for more details.) Now that the configuration file is updated, restart
the JA monitoring service by running /etc/init.d/jenkins-ha-monitor restart. Access the
"High Availability Status" in the "Manage Jenkins" section from the web UI to verify
that the monitoring service is recognized as a part of the cluster. Run ifconfig to verify
that the virtual IP address is assigned to the system thats hosting the primary JVM.
Once you have completed these steps successfully, you will have a highly-available
Jenkins instance!
Using HAproxy as a reverse proxy
Lets expand on this setup further by introducing an external load balancer / reverse
proxy that receives traffic from users, then direct them to the active primary JVM.
82
CloudBees Services
Compared to IP aliasing, this is more complex, but it allows two nodes that arent in
the same subnet to form a cluster, and you can set this up without having a root access.
HAproxy can be installed on most Linux systems via native packages, such as apt-get
install haproxy or yum install haproxy. For Jenkins Enterprise HA, the configuration
file (normally /etc/haproxy/haproxy.cfg) should look like the following:
global
log 127.0.0.1 local0
log 127.0.0.1 local1 notice
maxconn 4096
user haproxy
group haproxy
defaults
log global
# The following log settings are useful for debugging
# Tune these for production use
option logasap
option http-server-close
option redispatch
option abortonclose
option log-health-checks
mode http
option dontlognull
retries 3
maxconn 2000
timeout http-request 10s
timeout queue 1m
timeout connect 10s
timeout client 1m
timeout server 1m
timeout http-keep-alive 10s
timeout check 500
default-server inter 5s downinter 500 rise 1 fall 1
listen application 0.0.0.0:80
balance roundrobin
reqadd X-Forwarded-Proto:\ http
option forwardfor except 127.0.0.0/8
option httplog
option httpchk HEAD /ha/health-check
server alpha alpha:8080 check
server bravo bravo:8080 check
listen jnlp 0.0.0.0:10001
mode tcp
option tcplog
timeout server 15m
timeout client 15m
# Jenkins by default runs a ping every 10 minutes and waits 4
# minutes for a timeout before killing the connection, thus we
# need to keep these TCP raw sockets open for at least that
# long.
option httpchk HEAD /ha/health-check
83
CloudBees Services
The global section is stock settings. defaults has been modified to include additional
logging for debugging. It is advisable to review and tune the log settings before
production use. defaults has also been configured with typical timeout settings.
Again, these should be tuned before production use.
The part that you will need to add and configure specifically for your environment is
the listen blocks for application, JNLP and ssh. These tell HAproxy to forward traffic
to two servers alpha and bravo, and periodically check their health by sending a GET
request to /ha/health-check. Stand-by nodes do not respond positively to this health
check, while the active and primary Jenkins master will. This is how HAproxy will
know which of the two machines to send the traffic to.
Note the specific timeout overrides for the JNLP service based on Jenkins internal
behavior.
For the JNLP and ssh services HAproxy is configured to forward tcp requests. For
these services we have specifically configured HAproxy to use the same health check
on the application port (8080). This ensures that all services fail over together when the
health check fails.
The second listen status section allows you to monitor HAproxy by accessing port
8081. This is handy when you want to understand how HAproxy is behaving.
84