DevOps Lab Manual 2021
DevOps Lab Manual 2021
BE - IT
Even Semester (VIII)
(2020-21)
By:
Prof. Ninad V Gaikwad
(Email: [email protected])
Website:
https://sites.google.com/a/mes.ac.in/ninad
List of Contents
Experiment 02: Git and Github Basics (Distributed Version Control System) 7
Experiment 10: Combining all tools (GIT, Maven, Docker, Ansible and Jenkins) 41
Experiment 01: Introduction to DevOps
Sources
https://www.edureka.co/blog/devops-lifecycle/
Before DevOps
Waterfall Model:
● Sequential model
● Top-Down approach
● Phases such as Requirement Gathering, Software Design,
Implementation, Testing, Deployment, and Maintenance
● Lot of time for software development
● Suitable for projects which had stable requirements
(Requirements should not change with time)
AGILE Methodology:
● Promotes continuous iteration of development and testing
● Brought agility to development, but not on Operations
● Lack of collaboration between Developers and Operation
Engineers
What is DevOps ?
DevOps Tools
1 - Continuous Development
2 - Continuous Testing
3 - Continuous Integration
4 - Continuous Deployment
● This is the stage where the code is deployed to the production
servers
● Configuration management and Containerization tools involve in
this stage
● Configuration management
○ It is the act of releasing deployments to servers,
scheduling updates on all servers and keeping the
configurations consistent across all the servers.
○ Some popular tools that are used here are Puppet, Chef,
SaltStack, and Ansible.
● Containerization
○ Docker and Vagrant are the popular tools used for this
purpose.
○ These tools help produce consistency across Development,
Test, Staging and Production environments. Besides this,
they also help in scaling-up and scaling-down of
instances swiftly.
5 - Continuous Monitoring
Prerequisite
● Install GIT on your local machine:
https://git-scm.com/downloads
● Create/Login to an account on github.com: https://github.com/
One of the most popular VCS tools was a system called RCS, which is
still distributed with many computers today. RCS works by keeping
patch sets (that is, the differences between files) in a special
format on disk; it can then re-create what any file looked like at
any point in time by adding up all the patches.
git --version
Right click on the folder for which you want to create repository and then select Git Bash
Here command and start typing the following commands:
git init
Untrack Directory
rm –rf .git
To check remote
git remote –v
Make two text files (one to ignore other to track). Put some text in both
vi newfile.txt >> Press ‘Insert’ or ‘a’ >> insert some text >>
Press ‘Esc’ >> ‘:wq’
vi ignore.txt >> Press ‘Insert’ or ‘a’ >> insert some text >> Press
‘Esc’ >> ‘:wq’
OR
git status
git diff
git log
git checkout -b newbranch commit-hash // Will create a new branch on the commit
hash specified
OR
git branch
Deleting a Branch
Undo the changes made (in staging area but not commited)
Edit the commit message (changes the hash – recommended if changes made are not
pushed to central repo)
git commit --amend -m “Updated Message” // Change only the commit message
git reset --soft commit-hash //check the log to see changes (Hash should be
one commit old)
git reflog
git log
git branch
git stash apply stash-code // Restore changes but keep stash (applicable between
branches)
git stash pop // Restore changes most recent and remove stash (applicable between
branches)
Use Gitdiff tool (Many other diff tools available online for better UI)
git difftool commit1-hash commit2-hash // View exact changes between the two
commits
Requirements:
This setup offers many advantages, especially over local VCSs. For
example, everyone knows to a certain degree what everyone else on
the project is doing. Administrators have fine-grained control over
who can do what, and it’s far easier to administer a CVCS than it
is to deal with local databases on every client.
However, this setup also has some serious downsides. The most
obvious is the single point of failure that the centralized server
represents. If that server goes down for an hour, then during that
hour nobody can collaborate at all or save versioned changes to
anything they’re working on. If the hard disk the central database
is on becomes corrupted, and proper backups haven’t been kept, you
lose absolutely everything — the entire history of the project
except whatever single snapshots people happen to have on their
local machines. Local VCS systems suffer from this same
problem — whenever you have the entire history of the project in a
single place, you risk losing everything.
SVN Git
It's a Centralized version It's a distributed version
control system control system.
On Server side:
On Client Side:
cd helloworld
cd trunk
svn status
Creating Branches:
// Go to “helloworld” folder
svn commit code.txt -m “Added Comment” // Commit new changes to the branch (Go
to trunk and check new commit not added to trunk)
svn up
// Go to trunk folder
svn commit -m “Merged branch into Trunk” // Merge the Branch into the trunk
svn up
svn rm informal
// go to “Documents” folder
rm -rf helloworld
svn co svn://192.168.56.101/helloworld
cd helloworld/branches
ls
// To Checkout to a previous revision
svn co -r 4 svn://192.168.56.101/helloworld
Experiment 05: Docker Basics (Virtualization and Containerization)
Requirements:
An Account with Docker Hub
Enable hypervisor for windows steps here
(Note: If you have Virtualbox running then you already have
hypervisor ON)
Docker for Windows (Link in Resources): Installation steps here
Installation on Ubuntu:
sudo apt install docker.io
systemctl start docker
Resources:
Download Docker for windows:
https://hub.docker.com/editions/community/docker-ce-desktop-windows
/
User manual for docker windows:
https://docs.docker.com/docker-for-windows/
Docker tutorials: https://www.tutorialspoint.com/docker/index.htm
Introduction:
The initial release of Docker was in March 2013 and since then, it
has become the buzzword for modern world development, especially in
the face of Agile-based projects.
Features of Docker:
Components of Docker:
Docker Images:
Docker Container:
Docker Hub:
Docker Commands:
docker –version
docker help
mkdir python-app
cd python-app
nano app.py
print("Hello from python file")
.. save file ctrl + x -> Y
nano Dockerfile
// Contents of Dockerfile
FROM python
COPY . /src
CMD ["python", "/src/app.py"]
.. save file ctrl + x -> Y
Docker Compose:
postgres:
image: "ninadg89/postgres"
restart: always
environment:
POSTGRES_PASSWORD: postgres
ports:
- "5434:5432"
pgadmin:
image: "ninadg89/pgadmin4"
restart: always
environment:
PGADMIN_DEFAULT_EMAIL : pgadmin
PGADMIN_DEFAULT_PASSWORD : pgadmin
ports:
- "82:80"
webapp:
build: ./tomcat
restart: always
ports:
- "8082:8080"
Contents of “./tomcat/Dockerfile”
FROM tomcat:8.0
EXPOSE 8080
Docker Swarm:
Scaling services:
Prerequisites:
Java version 8 OR 11 installed
What is Jenkins ?
Continuous Integration :
Continuous Integration is a development practice that requires
developers to integrate code into a shared repository at
regular intervals. This concept was meant to remove the problem
of finding later occurrence of issues in the build lifecycle.
Continuous integration requires the developers to have frequent
builds. The common practice is that whenever a code commit
occurs, a build should be triggered.
Prerequisite:
Create Java file “HelloHome.java” on your Desktop with code:
class HelloHome{
public static void main(String args[]){
System.out.println("Hello Home");
}
}
Renaming Project:
Important Links:
Video 1 Jenkins Configuration:
https://drive.google.com/open?id=1lsSXVrS2237QWN3ug-mS-msOiKTDvI5M
Requirements:
[defaults]
host_key_checking=false
Create Host inventory (Either add separate inventory file or add hosts to
/etc/ansible/hosts)
[developers]
local1 ansible_host=192.168.0.106 ansible_ssh_user=lubuntu1
ansible_ssh_pass=ninad ansible_sudo_pass=ninad
[integrators]
local2 ansible_host=192.168.0.107 ansible_ssh_user=lubuntu2
ansible_ssh_pass=ninad ansible_sudo_pass=ninad
[allsys]
local1 ansible_host=192.168.0.106 ansible_ssh_user=lubuntu1
ansible_ssh_pass=ninad ansible_sudo_pass=ninad
local2 ansible_host=192.168.0.107 ansible_ssh_user=lubuntu2
ansible_ssh_pass=ninad ansible_sudo_pass=ninad
---
- hosts: all
become: yes
become_method: sudo
remote_user: lubuntu1
tasks:
- name: Update apt repository
apt: update_cache=yes
---
- hosts: all
become: yes
become_method: sudo
remote_user: lubuntu1
tasks:
- name: uninstall java
command: apt-get autoremove openjdk-8-jdk -y
---
- hosts: developers
become: yes
become_method: sudo
remote_user: lubuntu2
tasks:
- name: ensure jenkins apt repository key is installed
apt_key:
url=https://pkg.jenkins.io/debian-stable/jenkins.io.key
state=present
---
- hosts: local2
become: yes
become_method: sudo
remote_user: lubuntu2
tasks:
- name: Ensure jenkins is Stopped
service: name=jenkins state=stopped
ansible-playbook installjava.yml
Resources:
Video Link : https://www.youtube.com/watch?v=13FpCxCClLY
Git Repository : https://github.com/gaikwadninad89/allinone
For Remote Host [preferably Amazon ec2 instance]: Two - Integration server and
Deployment / Production server
Go to amazon EC2 -> create Ubuntu server instance (Free) -> Keep
default options for “Instance type, Instance Details, Add Storage,
Add Tags” -> In “Configure security Groups” Add Rule “Type = Custom
TCP Rule”, “Port Range = 8080” and “Source as Custom ‘0.0.0.0/0,
::/0’” -> Create a new Key pair and name it “ubuntu-pass” ->
Download the private key “ubuntu-pass.pem”
OR for Windows
On Integration Server:
Install Git -> Install jdk8 (Prerequisite for jenkins) -> Install
Jenkins -> Install Ansible -> Install Docker
Step 1: Create a Java Web Application in Netbeans
Step 2: Create a New Jenkins Pipeline Project and Configure it to Poll SCM (GitHub):
In Jenkins:
1. Create “new Item” -> name it “AllInOneApp”
2. Select type as “Pipeline” -> Click “OK”
3. In Configurations give “Description”
4. Go to pipeline tab in script make following changes
pipeline{
agent any
stages{
stage('Polling SCM'){
steps{
// Code 1
}
}
}
}
For Code 1:
1. Click on ”Pipeline Syntax” link outside Script box
2. Click on “Snippet Generator”
3. In sample step select “git:Git”
4. Provide URL and Branch details
5. For credentials
a. Click on Add
b. Select kind as “Username and Password”
c. Provide Username and Password in the allotted Textbox
d. Give id as “GitHub”
e. Add Description as “GitHub”
f. Click on “Add”
6. Select created GitHub credentials from the list
7. Click on “Generate Pipeline Script”
8. Copy the generated script as “Code 1”
// End Result
pipeline{
agent any
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
}
}
In Jenkins:
1. Go to “manage jenkins”
2. In “Global Tool Configuration” tab
3. Go to “Maven” section
4. Click “Maven Installation” -> “Add Maven”
5. Give name as “maven3”
6. Click on “Install Automatically”
7. Keep the rest as default
8. Click on ”Save”
// End Result
pipeline{
agent any
tools{
maven ‘maven3’
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
}
}
FROM tomcat:8.0
pipeline{
agent any
tools{
maven ‘maven3’
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
stage(‘Build Docker Image’){
steps{
sh "docker build . -t ninadg89/devopsapp:${DOCKER_TAG}"
}
}
}
}
def getVersion(){
def commitHash = // Code 2
return commitHash
}
For Code 2:
1. Go to “Snippet Generator”
2. Select sample step as “sh:Shell Script”
3. In the text box type the command “git rev-parse --short HEAD”
4. Click on “Advanced”
5. Check the “Return Standard output” checkbox
6. Click “Generate Pipeline Script”
7. Copy the script generated in place of “Code 2”
// End Result
pipeline{
agent any
tools{
maven ‘maven3’
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
stage(‘Build Docker Image’){
steps{
sh "docker build . -t ninadg89/devopsapp:${DOCKER_TAG}"
}
}
}
}
def getVersion(){
def commitHash = sh returnStdout: true, script: 'git rev-parse
--short HEAD'
return commitHash
}
// End Result
pipeline{
agent any
tools{
maven ‘maven3’
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
stage(‘Build Docker Image’){
steps{
sh "docker build . -t ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage(‘Push image to DockerHub’){
steps{
withCredentials([string(credentialsId: 'docker-hub', variable:
'dockerHubPwd')]) {
sh "docker login -u ninadg89 -p ${dockerHubPwd}"
}
sh "docker push ninadg89/devopsapp:${DOCKER_TAG}"
}
}
}
}
def getVersion(){
def commitHash = sh returnStdout: true, script: 'git rev-parse
--short HEAD'
return commitHash
}
In Jenkins:
1. Go to “Manage Jenkins” -> “Global Tool Configuration”
2. In ansible section click “Add”
3. Set name as “ansible”
4. Set path to executable as “/usr/bin/”
5. Click “Save”
[dev]
54.146.13.210 ansible_user=ubuntu
---
- hosts: dev
become: yes
become_method: sudo
tasks:
- name: Update apt repository
apt: update_cache=yes
- name: Install python pip
apt:
name: python3-pip
state: present
- name: Install Docker
apt:
name: docker.io
state: present
- name: Start Docker
service:
name: docker
state: started
pipeline{
agent any
tools{
maven ‘maven3’
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
stage(‘Build Docker Image’){
steps{
sh "docker build . -t ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage(‘Push image to DockerHub’){
steps{
withCredentials([string(credentialsId: 'docker-hub', variable:
'dockerHubPwd')]) {
sh "docker login -u ninadg89 -p ${dockerHubPwd}"
}
sh "docker push ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage(‘Deploy webapp using ansible’){
steps{
// Code 3
}
}
}
}
def getVersion(){
def commitHash = sh returnStdout: true, script: 'git rev-parse
--short HEAD'
return commitHash
}
For Code 3:
1. Go to “Snippet Generator”
2. Select sample step as “ansible Playbook:”
3. Write Playbook file path in workspace as “deploy-docker.yml”
4. Write Inventory file path in workspace as “inventory”
5. For Credentials:
6. Click “Add” -> “Jenkins”
a. Select kind as “SSH username and private key”
b. Give id as “dev-server”
c. Description as “dev-server”
d. Username as “ubuntu”
e. In Private key select radio button “Enter directly”
f. Paste the RSA key present in “ubuntu-pass.pem” file
g. Click on “Add”
7. Select the SSH Credentials created
8. Select “Disable the host SSH key check” checkbox
9. Add extra parameters as “-e DOCKER_TAG=${DOCKER_TAG}”
10. Click “Generate Pipeline Script”
11. Copy generated script as Code 3
// End Result
pipeline{
agent any
tools{
maven ‘maven3’
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage(‘Build using Maven’){
steps{
sh “mvn clean package”
}
}
stage(‘Build Docker Image’){
steps{
sh "docker build . -t ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage(‘Push image to DockerHub’){
steps{
withCredentials([string(credentialsId: 'docker-hub', variable:
'dockerHubPwd')]) {
sh "docker login -u ninadg89 -p ${dockerHubPwd}"
}
sh "docker push ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage(‘Deploy webapp using ansible’){
steps{
ansiblePlaybook credentialsId: 'dev-server', disableHostKeyChecking:
true, extras: '-e DOCKER_TAG=${DOCKER_TAG}', installation: 'ansible',
inventory: 'inventory', playbook: 'deploy-docker.yml'
}
}
}
}
def getVersion(){
def commitHash = sh returnStdout: true, script: 'git rev-parse
--short HEAD'
return commitHash
}
pipeline{
agent any
tools{
maven 'maven3'
}
environment {
DOCKER_TAG = getVersion()
}
stages{
stage('Polling SCM'){
steps{
git branch: 'main', credentialsId: 'GitHub', url:
'https://github.com/gaikwadninad89/allinone.git'
}
}
stage('Build using Maven'){
steps{
sh "mvn clean package"
}
}
stage('Build Docker Image'){
steps{
sh "docker build . -t
ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage('Push image to DockerHub'){
steps{
withCredentials([string(credentialsId: 'docker-hub',
variable: 'dockerHubPwd')]) {
sh "docker login -u ninadg89 -p ${dockerHubPwd}"
}
sh "docker push ninadg89/devopsapp:${DOCKER_TAG}"
}
}
stage('Deploy webapp usinng ansible'){
steps{
ansiblePlaybook credentialsId: 'dev-server',
disableHostKeyChecking: true, extras: '-e DOCKER_TAG=${DOCKER_TAG}',
installation: 'ansible', inventory: 'inventory', playbook:
'deploy-docker.yml'
}
}
}
}
def getVersion(){
def commitHash = sh returnStdout: true, script: 'git rev-parse
--short HEAD'
return commitHash
}