Using Docker for build and test pipelines you can benefit from:
- Isolate build activity from each other and from Jenkins server
- Build for different environments
- Using ephemeral containers for better resource utilization
Image by https://foxutech.com/author/motoskia/
Let's create a Docker container that will be used as a build agent for the Yolo5Build
and Yolo5Deploy
pipelines.
Take a look on the following Dockerfile:
FROM amazonlinux:2 as installer
RUN curl "https://awscli.amazonaws.com/awscli-exe-linux-x86_64.zip" -o "awscliv2.zip"
RUN yum update -y \
&& yum install -y unzip \
&& unzip awscliv2.zip \
&& ./aws/install --bin-dir /aws-cli-bin/
# this is an example demostrating how to install a tool on a some Docker image, then copy its artifacts to another image
RUN mkdir /snyk && cd /snyk \
&& curl https://static.snyk.io/cli/v1.666.0/snyk-linux -o snyk \
&& chmod +x ./snyk
FROM jenkins/agent
COPY --from=docker /usr/local/bin/docker /usr/local/bin/
COPY --from=installer /usr/local/aws-cli/ /usr/local/aws-cli/
COPY --from=installer /aws-cli-bin/ /usr/local/bin/
COPY --from=installer /snyk/ /usr/local/bin/
This dockerfile uses Multi-stage builds. Familiarize yourself with this technique.
The dockerfile starts with amazonlinux:2
as an installer
image in which we will install aws
cli and snyk
. After this image is built, we will copy the relevant artifacts to the other main image: jenkins/agent.
The jenkins/agent
is a base image suitable for running Jenkins activities.
In addition, we copy the docker
client only (as we want to build images as part of our pipeline) from docekr
, which is a Docker image containing docker
. Feel confused? read more....
- Build the image from a machine with an access to ECR.
- Push your image to a dedicated container registry in ECR.
- In your Jenkinsifles, replace
agent any
by (read more on Jenkins agent directive):
agent {
docker {
image '<image-url>'
args '--user root -v /var/run/docker.sock:/var/run/docker.sock'
}
}
The -v
mount the socket file that the docker client is using to talk with the docker daemon. In this case the docker client within the container will talk with the docker daemon on Jenkins machine.
The --user root
runs the container as root
user, which is necessary to access /var/run/docker.sock
.
- Test your pipeline on the Docker-based agent.
Jenkins EC2-plugin allows Jenkins to start agents on EC2 on demand, and kill them as they get unused. It'll start instances using the EC2 API and automatically connect them as Jenkins agents. When the load goes down, excess EC2 instances will be terminated.
- Install the
Amazon EC2
Jenkins plugin. - Once installed, navigate to the main Manage Jenkins > Nodes and Clouds page, and choose Configure Clouds.
- Add an Amazon EC2 cloud configured as follows:
- Give it a Name as your choice.
- Keep Amazon EC2 Credentials
none
. Instead, you should check Use EC2 instance profile to obtain credentials give appropriate permissions to Jenkins` server Role (full permissions JSON can be found in the plugin's page). - In EC2 Key Pair's Private Key choose your existed SSH key-pair credentials, or create one of you don't have yet.
- Under AMIs click Add and configure the AMI as the below steps.
- In AMI ID, search the ID of some
Amazon Linux
in the region you are operating from. - For Instance Type choose an appropriate
*.micro
type. - Choose an existed security group id for Security group names.
- Since the above AMI is based on Amazon Linux, Remote user is
ec2-user
and AMI Type inunix
. - Under Labels choose a label which will be used in your Jenkinsfile.
- Set the Idle termination time to
10
minutes. - Init script is the shell script to be run on the newly launched EC2 instance, before Jenkins starts launching an agent. Fill the script yourself such that pipelines could be run successfully.
- In the Advanced configurations, under Subnet IDs for VPC choose an existed subnet ID within your VPC.
- Set Instance Cap to
3
to restrict Jenkins from provisioning too many instances. - Under Host Key Verification Strategy choose
off
since we trust Jenkins agents by default. - Save you configurations
- In order to instruct Jenkins to run the pipeline on the configured nodes, put a
label
property in theagent{ docker {} }
setting, as follows:
agent {
docker {
label '<my-node-label>'
image '...'
args '...'
}
}
- Test your pipeline.