practical jenkins
- 1. Practical Jenkins for Production Deployments
- 2. The Development Stages
- 3. What is Continuous Integration?
- 4. What is Continous Delivery?
- 5. What is Continous Deployment?
- 6. Setting up git, code repositories, and dependencies for Jenkins
- 7. High-availability, monitoring, and management of jenkins deployments
Practical Jenkins for Production Deployments
- Installation, configuration, and automation of Jenkins and its dependencies
- Attention to high-availability, monitoring, management, and security
- Utilizing distributed architectures and ability to work with diverse infrastructure platforms
- Understanding and implementing pipeline as code with special attention to multi-branch pipeline
- Being able to deploy code continously
- Integration with extenal services for optimal workflow desgin
The Development Stages
- Feature branch forked from devlop branch
- Code added/modified and then build/test is executed against it
- On success, the node is merged to the develop branch
- More builds/tests are executed against the develop branch including integration tests
- On success, the code is merged to the master branch
- A tag is created and (optionally) a package is prepared for deployment
- Next setps:
- The package is deployed to target systems by Jenkins
- Jenkins triggers an event in another deployment tool
- Acceptance testing is performed on the target systems (optional)
What is Continuous Integration?
- It is a development practice
- A new feature is added by forking an integration branch
- The new feature branch is tested before merging the code to the integration branch
- Errors and problems are detected early
- Testing and merging happens automatically without manual intervention
- New code is added, modified, and merged regularly to the integration branch
What is Continous Delivery?
- It is the practice of getting code into a deployable state
- This is achieved irrespective of the size of the application or number of developers making commits
- Includes new features, changes, bug fixes, etc
- Makes sure that all changes are ready to be deployed at any time
- Makes releases low risk and of higher quality
- Depends on Continous Integration
What is Continous Deployment?
- It is the process of automatic releases to production
- It is the next step to Continous Delivery
- The level of testing decides how good the release will be
- Release happends in small batches and continuously
- Gradual product improvement and increase in quality
- The processes of Continous Integration and Continuous Delivery need to be perfect to ensure that releases are without issues
- Relieves developers and administrators from the periodic taks of releasing
Setting up git, code repositories, and dependencies for Jenkins
Storage for Jenkins Data
- Setting up a dedicated storage
- Run on physical hardware-rate configuration with multiple disks
- Run on virtualized cloud platform-dedicated elastic volumes
- Home directory - /var/lib/jenkins
Create a new volume in aws ec2 Elastic Block Store, attach volume to ec2 jenkins master instance, run following commmands:
1 | fdisk -l |
Installation of Jenkins from Packages and WAR Files
from Packages
1
2
3
4
5yum -y install java-1.8.0-openjdk
wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install -y jenkins
systemctl start jenkinsIf want to change the jenkins’ home directory vim /etc/sysconfig/jenkins
JENKINS_HOME=from WAR files
1
2
3
4
5
6
7
8
9
10
11
12yum intall -y tomcat
cd /usr/share/tomcat.webapps/
wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
systemctl start tomcat
access by ipaddress:8080/jenkins
systemctl stop tomcat
mkdir -p /opt/jenkins_home
chown -R tomcat:tomcat /opt/jenkins_home
vim /etc/tomcat/contxt.xml
# At the end of file add a new line
<Environment name="JENKINS_HOME" vaule="/opt/jenkins_home" type="java.lang.String" />
systemctl start tomcatuse docker containers
1
2
3
4
5
6yum install -y yum-utils device-mapper-persistent-data lvm2
yum-config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo
yum install -y docker-ce
systemctl start docker
docker pull jenkins/jenkins:lts
docker run --name jenkins_master -d -p 8080:8080 -v jenkins_home:/var/jenkins_home jenkins/jenkins:ltsConfiguring reverse proxy and setting up user interface for jenkins
Install nginx:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30rpm -ihv https://dl.fedoraproject.org/pub/epel/7/x86_64/Packages/e/epel-release-7-11.noarch.rpm
yum install -y nginx
vim /etc/nginx/nginx.conf delete server { part }
vim /etc/nginx/conf.d/jenkins.conf
upstream jenkins {
server 127.0.0.1:8080;
}
server {
listen 80 default;
server_name jenkins.course;
access_log /var/log/nginx/jenkins.access.log;
error_log /var/log/nginx/jenkins.error.log;
proxy_buffers 16 64k;
proxy_buffer_size 128k;
location / {
proxy_pass http://jenkins;
proxy_next_upstream error timeout invalid_header http_500 http_502 http_503 http_504;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
}
}In Jenkins configuration Git plugin put git username and email address
Automating the Jenkins Installation and Configuration Process
- Disabling the manual setup wizard
- Automating the setup wizard steps
- Creating puppet configuration to automate the installation and configuration process
- Automating the process by applying the puppet module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79systemctl stop jenkins
vim /etc/system/jenkins
modify JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true -Djenkins.install.runSetupWizard=false"
mkdir -p /var/lib/jenkins/init/groovy.d
vim /var/lib/jenkins/init/groovy.d/installPlugins.groovy
#!groovy
import jenkins.model.*
import java.util.logging.Logger
def logger = Logger.getLogger("")
def installed = false
def initialized = false
def pluginParameter = "ws-cleanup timestamper credentials-binding build-timeout antisamy-markup-formatter cloudbees-folder pipeline-stage-view pipeline-github-lib github-branch-source workflow-aggregator gradle ant mailer email-ext ldap pam-auth matrix-auth ssh-slaves github git"
def plugins = pluginParameter.split()
logger.info("" + plugins)
def instance = Jenkins.getInstance()
def pm = instance.getPluginManager()
def uc = instance.getUpdateCenter()
plugins.each {
logger.info("Checking " + it)
if (!pm.getPlugin(it)) {
logger.info("Looking UpdateCenter for " + it)
if (!initialized) {
uc.updateAllSites()
initialized = true
}
def plugin = uc.getPlugin(it)
if (plugin) {
logger.info("Installing " + it)
def installFuture = plugin.deploy()
while(!installFuture.isDone()) {
logger.info("Waiting for plugin install: " + it)
sleep(3000)
}
installed = true
}
}
}
if (installed) {
logger.info("Plugins installed, initializing a restart!")
instance.save()
instance.restart()
}
vim /var/lib/jenkins/init/groovy.d/security.groovy
#!groovy
import jenkins.model.*
import hudson.security.*
import jenkins.security.s2m.AdminWhitelistRule
import hudson.security.csrf.DefaultCrumbIssuer
import jenkins.model.Jenkins
def instance = Jenkins.getInstance()
def hudsonRealm = new HudsonPrivateSecurityRealm(false)
hudsonRealm.createAccount("admin", "admin")
instance.setSecurityRealm(hudsonRealm)
def strategy = new FullControlOnceLoggedInAuthorizationStrategy()
strategy.setAllowAnonymousRead(false)
instance.setAuthorizationStrategy(strategy)
instance.save()
Jenkins.instance.getInjector().getInstance(AdminWhitelistRule.class)
def j = Jenkins.instance
if(j.getCrumbIssuer() == null) {
j.setCrumbIssuer(new DefaultCrumbIssuer(true))
j.save()
println 'CSRF Protection configuration has changed. Enabled CSRF Protection.'
}
else {
println 'Nothing changed. CSRF Protection already configured.'
}
chown -R jenkins:jenkins /var/lib/jenkins/init/groovy.d/*.groovy
systemctl start jenkins
tail -f /var/log/jenkins/jenkins.loginstall puppet
go to puppet, copy url link puppetlabs-release-pc1-el-7.noarch.rpm.
on the sever install the package by the command:1
2
3rpm -ihv http://yum.puppetlabs.com/puppetlabs-release-pc1-el-7.noarch.rpm
yum -y install puppet-agent
1 | mkdir puppet |
Creating build jobs from user interface and scripts
1.Create a new freestyle jenkins job called python-job, configure ‘Source Code Management”->’Git’-> Repo URL git@github.com:szhouchoice/python-project.git.
“Build” -> Execute shell, command python *test.py
2.mkdir jenkins_cmd; cd jenkins_cmd
1 | cp /var/lib/jenkins/jobs/python-job/config.xml . |
High-availability, monitoring, and management of jenkins deployments
- High-availability scenario of Jenkins ecosystem and support
- Creating multiple Jenkins master nodes with shared data directory
- Configuring HAProxy as a load balancer for the Jenkins masters
- Testing the setup by failing nodes
Setting up multiple Jenkins Master with Load Balancer for high-availability
1. On aws ec2 create 3 instances with Centos 7 OS. 1 for haproxy 2 for jenkins
2. Create a efs on aws, setup up efs on two jenkins ec2 instances. efs security group need create a new one open nfs port to everywhere
1 | yum -y install nfs-utils |
3. On Jenkins master passive node
1 | vim /opt/jenkins_reload.sh |
4. On HA Proxy server
1 | yum -y install haproxy |
Backing up and restoring Jenkins data
Steps of backup and resotre
- Decide on what to back up (specific directories or everything)
- Set up a dedicated local directory where backups would be stored
- Decide the archiving method to use for the backup (.zip, tar.gz, and so on)
- Set up a schedule for backups to take place
- Configure a highly-available remove location where old backups can be transferred for archiving
- Keep a certain number of the most recent backups to be readily available for restores
- When restoring, unarchive the most recent backup and copy over files
Backup and Restore Methods
- Use periodic Backup plugin available in Jenkins
- Manually copy and archive files using scripts
- Select a remote location for storing data such as S3, EFS, and so on
- Use local tools such as scp, rsync, s3cmd, and son on to transfer data
- Use specialized open source tools such as Amanda or Bacula to perform backups or enterprise tools such as Netbackup
1 | mkdir -p /opt/jenkins_backups |
Install plugin called Periodic Backup Manager, configure it as following:
click button Backup Now!
Monitoring Jenkins components and data
Install plugin monitoring, after that under ‘Manage Jenkins’ will have Monitoring of Jenkins master:
install configure graphite grafana
1 | #Install EPEL repo |
1.Install jenkins plugin call ‘Metrics Graphite Reporting’
2.Go to Manage Jenkins -> Configure Sytem-> Graphite metrics report input Hostname ipaddress Port 2003 Prefix jenkins.
3.Access grafana server ipaddress:3000 -> Add Graphite -> http settings url http://localhost
4.Import grafana dashboard: go to grafana.com/dashboards search for Jenkins: Performance and health overview-> copy id
5. Options grahite choose jenkins-test
Install monit
1 | yum install -y monit |
Enable gmail account Allow less secure apps to ‘on’
1 | systemctl start monit |
Implementing security and roles for Jenkins
Jenkins Security best practices
- Disable job execution on the mater and use slave nodes for builds
- Use job restrictions plugin to confine specific jobs to specific nodes irrespective of the label used
install plugin job restrictions-> Manage Jenkins-> Manage Nodes - Enable CSRF protection and update scripts to use crumbs
- Enable the slave to master access control
- For large encironments, use role and matrix based authorization strategies to isolate project access
install plugin Role-based Authorization Strategyuse LDAP server and role-based strategy
1.ldap server config on centos 7
1 | yum -y install openldap-servers openldap-clients |
Login to ipaddress/phpldapadmin
Ligin DN: cn=Manager,dc=practialjenkins.dc=com
Password:
Under ou=groups create a child entry-> Generic: Posix Group
3 groups: admins, developers, devops
Under ou=users create Generic: User Account a b c
Under cn=admins Add new attribue mumberUid a
same for other groups
Configure Global Security
Group membership filter -> (| (member={0}) (uniqueMember={0}) (memberUid={1}))
Under Authorization choose Role-Based Strategy
Under Manage Jenkins click Mange and Assign Roles -> Manage Role-> Role to add “admins, developers and devops”
Assign Roles-> User/group to add-> admins, developers, and devops
User different user for login:
Using the jenkinss api and automating plugin management
get API token from ‘People’> admin-> configure->API Token
Automatically tirgger the build by:
1 | curl -u admin:20fda2a6ed2ff7a8cf9db9dd50a0c2b0 "http://localhost:8080/api/json?pretty=true" |
wget –auth-no-challenge “http://localhost:8080/jnlpJars/jenkins-cli.jar"
java -jar jenkins-cli.jar -auth admin:20fda2a6ed2ff7a8cf9db9dd50a0c2b0 -s http://localhost:8080 help
java -jar jenkins-cli.jar -auth admin:20fda2a6ed2ff7a8cf9db9dd50a0c2b0 -s http://localhost:8080 install-plugin aws-codebuild -deploy
java -jar jenkins-cli.jar -auth admin:20fda2a6ed2ff7a8cf9db9dd50a0c2b0 -s http://localhost:8080 install-plugin http://updates.jenkins-ci.org/latest/ansicolor.hpi -deploy
java -jar jenkins-cli.jar -auth admin:20fda2a6ed2ff7a8cf9db9dd50a0c2b0 -s http://localhost:8080 install-plugin http://updates.jenkins-ci.org/download/plugins/beaker-builder/1.6/beaker-builder.hpi -deploy
1 | # Integrating Jenkins with external services |
git add -A
git commit -m “adding code”
git push origin master
git checkout -b develop
git push orgin develop
1 | In Jenkins-> Create new Multibranch Pipeline-> |
git checkout -b feature-001
vim src/ConnectTest.php
push feature branch to github
![merge in github](https://i.imgur.com/JOkzC9O.png)
will trigger the build in Jenkins
## Integrating with Sonarqube
- setting up Sonarqube prerequisites for Jenkins
- Install and configure Sonarqube plugin
- Configure Jenkins pipeline for Sonarqube action
- Generate Sonarqube analysis report from Jenkins pipeline