0% found this document useful (0 votes)
15 views27 pages

DevOps with Microservices and Docker

The document discusses the transition from monolithic applications to microservices, highlighting the advantages of microservices such as scalability, simplicity, and independent deployment. It covers various deployment patterns, data synchronization methods, and database patterns like CQRS and event sourcing. Additionally, it provides insights into DevOps tools, Docker containerization, and practical commands for managing Docker containers and images.

Uploaded by

soham290303
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
15 views27 pages

DevOps with Microservices and Docker

The document discusses the transition from monolithic applications to microservices, highlighting the advantages of microservices such as scalability, simplicity, and independent deployment. It covers various deployment patterns, data synchronization methods, and database patterns like CQRS and event sourcing. Additionally, it provides insights into DevOps tools, Docker containerization, and practical commands for managing Docker containers and images.

Uploaded by

soham290303
Copyright
© All Rights Reserved
We take content rights seriously. If you suspect this is your content, claim it here.
Available Formats
Download as PDF, TXT or read online on Scribd

DAC DevOps

Microservices, Git, Docker, Kubernetes


Atul Kahate Microservices or
API (Application Programming
Interface)

Monolithic Applications Microservices (“API”s)


Search
Microservice

• All code in one JAR/WAR file • One microservice = One Place


Place independent application Order
• Deployed as a single application Order
• Examples: Order Microservice,
Order
Microservice

• Problems Search Microservice, Payment


Microservice

Search
Complexity Search • Advantages Product API Payment
Microservice
• Scalability Product
• Simplicity Gateway Message
Broker
• Deployment • Scalability
• Technology stack lock-in • Deployment Shipping
Microservice
• Technology stack flexibility
• Bug isolation difficult Database
• Bug isolation easy
• Interdependence of teams Server
• Independence of teams
Make Tracking
Make
• Testing challenges Monolithic
• Easy to test
Payment Microservice
Payment E-Commerce
• Maintenance • Low maintenance Clients/Users
application on
• Performance • High performance
Clients/Users the Web Server

Microservice Deployment Patterns Microservices and Databases


• Service Instance per Container • Canary Deployment • Each microservice has its own database
• One microservice = One container • Gradual deployment, first only to a
• Strong isolation and consistent subset of users • Advantage: Loose coupling, Independent changes/evolution
deployment every time • Less risky
• Serverless Deployment • Rolling Deployment Insert
Order
• Serverless ≠ No server • Server instances are incrementally Order
• Deploy on Cloud servers updated with new versions
• No downtimes, easy to rollback microservice Publish OrderCreated Event
• Blue-Green Deployment
• Blue = Live system, Green = New • A/B Testing
version under development • Different versions of the application Message
• Zero downtime deployment, easy to are deployed to different user groups Broker
rollback • Helps decide based on user- Payment
Subscribe OrderCreated Event
experience and feedback
microservice
Create Payment Pending record

Data Synchronization Data Synchronization


• Eventual consistency • Idempotency
• Data across services may not be immediately consistent • Event handlers should be idempotent
• It will become consistent over time as events propagate and are processed • Reprocessing the same event should not lead to inconsistent data
• May not follow ACID properties Payment
Payment User has not received
Order processed payment confirmation, but
Order confirmed Makes payment payment was successful
Order Computer Networks microservice
by Andrew Tanenbaum microservice Screen
hangs!
Book count is The payment
The databases of the two microservices still not Payment must NOT microservice must not
are not immediately consistent, but Inventory updated Payment be processed a process the payment a
Retries payment
they will be eventually consistent second time second time, but just
microservice microservice show success to the user
Success!
Command Query Responsibility Segregation (CQRS)
Command: “Order
Database Patterns for Microservices Places an Order
Order
Record a new placed”
event
Publish
order
microservice

• Database per Service: One microservice = One Database (Discussed


earlier) Payment Query: Note
Subscribe
• Command Query Responsibility Segregation (CQRS): Commands microservice
pending
payment
(Writes) update data, Queries (Reads) retrieve data
• Event Sourcing: Do not store current state, but derive it from a Query: Note Subscribe
Message
Shipping Broker
sequence of events pending
shipment
• Saga: One distributed transaction = Sequence of local transactions microservice

Query: Note
Tracking Subscribe
tracking not
yet available
microservice

Event Sourcing Saga


Deposit 5000 +5000
Order
Starts
Saga
+5000 microservice
Deposit 5000 Account balance is
+5000 Any failure in between will
never stored, but it is Inventory
calculated from stored cause the saga to be run in
+5000 the reverse order from the
Withdraw 2000 +5000 transactions, whenever microservice
needed point of failure
-2000
Message
+5000 Payment Broker
Example: If a payment fails,
Deposit 1000 +5000
microservice the item should be added
-2000 back to the inventory
+1000
Shipping
Ends
7000 Saga
Show balance microservice

DevOps and CI/CD

DevOps

Tools Used DevOps Tools


• Build: Maven, Gradle
• Version control: Git, Jira
• Container creation: Docker
• Orchestration: Kubernetes
• Testing: Junit, Selenium
• CI/CD: Jenkins
• Automate Deployment: Ansible, Terraform
push

Software Deployment Docker


image

Traditional Container-based pull

.java
.sql
Developer Developer
machine machine

Docker: Containerisation
Client: Write code (.java, .sql) Client: Create microservices (.java, .sql)
Client: Compile, test on the client Client: Compile, test on the client
Server: Install Java, MySQL, Spring Boot, … Client: Create .jar/.war file and push Docker
Client: Copy .class/.jar/.war files and .sql files on image
the server Server: Pull Docker image
Server: Test Server: Run Docker image as a Container

[Link]
What is Docker? More on Docker
• Docker: Container technology • Provides an easy way to create images and run as containers
• Container = Complete and isolated software • Ready images can be pulled from DockerHub and used
• Runs an application in a sandbox • Uses a layered file system so that we can add to these base images
• Portable • One container = One application, One VM = Multiple applications
• Contains all dependencies
• Containers are isolated from each other
• We can run several containers on a machine at the same time
• To create our own image, we need to create a Dockerfile
• Self-contained: Do not alter the host system they run on
• Dockerfile: Configuration details for creating an image
• Docker is light-weight, unlike VM
• If something works in Development, it will work in Production, too • Ideal for Microservices/APIs

Image and Container Container versus Virtual Machine


• Build: Create an image
• Run: Run the image as a container Containers Virtual Machines

Container A Container B Container C VM A VM B VM C


docker build Image
App A App B App C
App A App B App C
command Libs Libs Libs
Libs Libs Libs Guest OS Guest OS Guest OS

Docker Hypervisor

Host Operating System Host Operating System

Container Hardware Hardware


Image docker run
command

Docker Installation on Windows Docker Installation on Ubuntu 22.04/Above


• Enable virtualization • How to find what is our current Linux distribution? cat /etc/os-
• Search for ‘Turn Windows Features on or off’ release
• Then check the relevant checkboxes, if required and restart • How to find what is our current Linux release? uname -srm
• Download and install Docker Desktop: • Link: [Link]
[Link] the-repository
• Checking running status: sudo systemctl status docker
• Enabling Docker: sudo systemctl enable docker
• Starting Docker: sudo systemctl start docker
Solve Docker Permission Errors (Linux) Run a Container
• Check current groups for our user: groups • docker run -dit ubuntu
• Add our user to the docker group: sudo usermod -aG docker $USER
• Refresh the group membership: newgrp docker
• Check Docker socket permissions: ls -l /var/run/[Link] • Run the ubuntu OS inside a Docker container on our local machine
• Output should be something like this: • Note: The image is not available locally
• srw-rw---- 1 root docker 0 May 17 10:00 /var/run/[Link] • It is pulling it from DockerHub
• If not, try these commands:
• sudo chown root:docker /var/run/[Link] • -dit: Run in detatched mode and have an interactive terminal open
• sudo chmod 660 /var/run/[Link] • In the end, it shows the container id
• Restart Docker service: sudo systemctl restart docker
• Verify: docker ps

View Running Container List Stop a Container


• docker container list OR • docker stop b3
• docker ps • Here, b31 is assumed to be the ubuntu container id’s first three
characters
• We can also stop a container by its name
• See all the running containers
• Again run the container and stop by its name
• Note that there is a randomly generated container name and id • docker run -dit ubuntu
• docker stop be
• Assuming that the container name was beautiful joe: Verify it stopped
• docker container list

View Image List Inspect a Container


• docker images • docker inspect 89
• Shows list of Docker images on our local machine • 89 is assumed to be the start of a container’s id
• Note how much size it occupies (generally in MB)

Pull an Image Delete an Image


• docker pull nginx • docker rmi nginx-stable
• Pull the image from DockerHub onto our local machine • It will untag the image (mark it as unused or dangling)
• Check using docker images • docker images
• Note: Pulling an image does not run a container using it • To remove the image completely (like garbage collection)
• See how nginx image was created: docker history nginx • docker image prune
• How much disk space is Docker using?
• docker system df
Give a Name to a Container Remove a Container
• Earlier command: docker run -dit ubuntu • First stop the container: docker stop another_ubuntu
• With name: docker run -dit --name=my_ubuntu ubuntu • Remove: docker rm another_ubuntu
• Verify: docker container list
• See all containers, running or not: docker container list -a
• Run with one more name:
• docker run -dit ubuntu --name=another_ubuntu
• See only the latest container: docker ps -l

View Logs Make a Container Accessible in a Browser


• Suppose we run the hello world container in the background … How • docker run --name my_nginx -d -p 8080:80 nginx
can we see its output? • Map the container’s internal port 80 to the external (i.e. our
• docker run -dit hello-world machine’s) port 8080
• It means that whatever requests we sent on our local machine’s port
• docker logs 55 8080 will be sent to the container on its port 80
• 55: Container id • Open the browser: localhost:8080
• docker logs my_nginx
• docker stop my_nginx

Custom Content in Containers: Volumes Enter and Connect to a Container


• mkdir webpages • docker run -it --name apache httpd /bin/bash
• cd webpages • Run Apache web server in the foreground
• echo ‘Hi from inside our CDAC nginx container!’ > [Link] • Now we can run commands such as pwd, ls, etc inside the container
• cd .. • To come out: exit
Volumes syntax: Host path:Container %cd% = Current directory in Windows
path Same as ${PWD} in Linux • docker ps
• Windows: docker run -p 8080:80 --name=another_nginx -v • The container is stopped, because we did not use the -d option
%cd%/webpages:/usr/share/nginx/html:ro -d nginx • docker run -dit --name second_apache httpd /bin/bash
• Linux: docker run -p 8080:80 --name=another_nginx -v • docker ps
${PWD}/webpages:/usr/share/nginx/html:ro -d nginx
:ro means the container cannot modify the files, it can read only

Build Image Using Dockerfile


• Dockerfile: Contains instructions that we want to give to Docker for
building an image … Main instructions …
Instruction Use
FROM Set the base image

‘Hello World’ in Docker


CMD Command to be executed when the image is run as a container (Or pass options to ENTRYPOINT)
RUN Executes a command to help build our image
EXPOSE Opens network ports
VOLUME Sets a disk share
COPY Copies files from the local disk to the image
ENV Add an environment variable
ENTRYPOINT Determines which executable runs when a container starts (Use CMD to pass options to the
executable)
‘Hello World’ in Java using Docker Create Dockerfile
• Create [Link] in C:\lectures\CDAC\Cloud\docker\hello- • C:\lectures\CDAC\Cloud\docker\hello-world-java\Dockerfile
• # Use the official OpenJDK image as a parent image These will be
world-java\[Link] • FROM openjdk:17-slim created/added
[Link]
• public class HelloWorld { because of the
• # Set the working directory to /app
• public static void main(String[] args) { • WORKDIR /app
commands in
.app folder
Dockerfile
• [Link]("Hello, World");
• } • # Copy the current directory contents into the container at /app
We want JDK, but OpenJDK
•} • COPY . /app
it comes with
Oracle Linux User
• # Compile the Java code Oracle Linux
Space (not
• RUN javac [Link]
• Compile: javac [Link] Kernel)
Docker (VM with a
• Test: java HelloWorld • # Run the program when the container starts
• CMD ["java", "HelloWorld"]
Linux Kernel)
These two are
already there Our OS (Host)

End Result Build and Execute


These will be • # Build the Docker image
created/added
• docker build -t java-hello-world .
[Link]
because of the
commands in
Dockerfile .app folder
[Link] Layer 4
We want JDK, but OpenJDK .app folder Layer 3 • # Run the Docker container
• docker run java-hello-world
it comes with OpenJDK Layer 2
Oracle Linux User Layer 1
Oracle Linux Oracle Linux
Space (not
Kernel)
Docker (VM with a Resulting Docker Image
Linux Kernel)
These two are
already there Our OS (Host)

‘Hello World’ in Java using Docker


• Create [Link] in C:\lectures\CDAC\Cloud\docker\hello-
world-java\[Link]
• public class HelloWorld {
• public static void main(String[] args) {
• [Link]("Hello, World");
• }
‘Hello World’ in Docker •}

• Compile: javac [Link]


• Test: java HelloWorld

Create Dockerfile End Result


• C:\lectures\CDAC\Cloud\docker\hello-world-java\Dockerfile
These will be
• # Use the official OpenJDK image as a parent image These will be created/added
• FROM openjdk:17-slim created/added [Link]
[Link] because of the
because of the commands in
• # Set the working directory to /app commands in Dockerfile .app folder
• WORKDIR /app Dockerfile .app folder [Link] Layer 4
• # Copy the current directory contents into the container at /app We want JDK, but OpenJDK .app folder Layer 3
• COPY . /app
We want JDK, but OpenJDK it comes with Layer 2
OpenJDK
it comes with Oracle Linux User
Oracle Linux User Oracle Linux Oracle Linux Layer 1
• # Compile the Java code Oracle Linux Space (not
Space (not Kernel)
• RUN javac [Link]
Kernel) Docker (VM with a
Docker (VM with a Resulting Docker Image
• # Run the program when the container starts Linux Kernel)
Linux Kernel) These two are
• CMD ["java", "HelloWorld"]
These two are already there Our OS (Host)
already there Our OS (Host)
Build and Execute Java Program to Find Max of Three Numbers
• # Build the Docker image
• import [Link]; • # Use OpenJDK base image

• FROM openjdk:17-slim

• public class LargestNumber {

• docker build -t java-hello-world . •


public static void main(String[] args) {

Scanner sc = new Scanner([Link]);



# Set working directory

WORKDIR /app

• [Link]("Enter first number: "); • # Copy Java source file into container

• int a = [Link](); • COPY [Link] .

• # Run the Docker container •


[Link]("Enter second number: ");

int b = [Link]();


# Compile Java program

RUN javac [Link]

• docker run java-hello-world •


[Link]("Enter third number: ");

int c = [Link]();


# Default command to run the program

CMD ["java", "LargestNumber"]

• int largest;


if (a >= b && a >= c)

largest = a;
Build: docker build -t java_largest .
• else if (b >= a && b >= c) Run: docker run -it java_largest
• largest = b;

• else

• largest = c;

• [Link]("The largest number is: " + largest);

Saving/Importing Images To/From the Local


Pushing Docker Image to DockerHub
Disk
• # Login to Docker Hub • docker pull ubuntu
• docker login
Replace with your • Save image locally
• # Tag the local image DockerHub id
• docker save -o [Link]
• docker tag java-hello-world newdelthis/java-hello-world:1.0
Replace with your • Copy this file on any machine and create ubuntu image
• # Push the image to Docker Hub
DockerHub id
• docker load -i [Link]
• docker push newdelthis/java-hello-world:1.0

Stop and Remove All Running Containers Docker Volume and Docker Network
• docker stop $(docker ps -a -q) • Docker Volume
• Containers are ephemeral/transient/disposable/stateless
• docker rm $(docker ps -a -q) • Meaning: Short-lived, Can be easily created, destroyed, recreated
• When a container is removed, all information inside it is also destroyed
• Consider MYSQL container – Remove it and all data will also be removed
• Solution: Docker volume = A directory on the local disk
• When a container is removed and restarted, it will regain data from the volume
• Docker Network
• By default, all containers run in a network called bridge network and they can
communicate with each other using their IP addresses
• Risky, because our application containers may now be accessible to other containers
• Solution: Create our own custom network and add our containers to it
• Advantage: Now our containers are isolated from the others and can access each
other by their names also (not just IP addresses)

Docker Network and Volume [Link]


• Directory structure
• import [Link].*;

• import [Link].*;

• docker-java-demo/ •


public class Server {

public static void main(String[] args) throws IOException {

• ├── [Link]
• File logFile = new File("/data/[Link]");

• if (![Link]()) {

• [Link]().mkdirs();

• ├── [Link] •

• }
[Link]();

• ├── Dockerfile •


try (ServerSocket serverSocket = new ServerSocket(5000)) {

[Link]("Server started on port 5000...");

• Socket socket = [Link]();

• BufferedReader input = new BufferedReader(new InputStreamReader([Link]()));

• String message = [Link]();

• [Link]("Received: " + message);

• try (FileWriter writer = new FileWriter(logFile, true)) {

• [Link](message + "\n");

• }

• [Link]();

• }
[Link] Dockerfile
• import [Link].*;
• import [Link].*;
• FROM openjdk:17-slim
• WORKDIR /app
• public class Client {
• public static void main(String[] args) throws IOException { • COPY *.java /app
• // Connect to server container using its name • RUN javac *.java
• Socket socket = new Socket("server-container", 5000);
• PrintWriter out = new PrintWriter([Link](), true);
• [Link]("Hello from client at " + [Link]());
• [Link]();
• [Link]("Message sent to server!");
• }
• }

Commands Commands
• Build Docker image • Keep the first terminal running and open a second terminal to run the
client
• docker build -t java-docker-demo .
• docker run --rm --network my-net java-docker-demo java Client

• Create Docker network


• Output on server
• docker network create my-net
• Server started on port 5000...
• Received: Hello from client at 1728902345678
• Run the server with volume attached
• docker run -it --rm --name server-container --network my-net -v • Output on client
$(pwd)/data:/data java-docker-demo java Server
• Message sent to server!

Output Docker Volume and Docker Network


• On the host machine, check persisted log • Create a Java program to insert three records into a student table and
• cat data/[Link] then display them on the screen
• Hello from client at 1728902345678 • Use MySQL database
• Student table will have three columns: PRN, Name, Course
• Output format is not important
• Both Java program and MySQL should run in their own respective
Docker containers
Custom Docker Network
Docker
Java program container MySQL container Volume

Steps on a Linux Machine Running Docker Commands


• Create a new directory: mkdir docker-java-sql and cd docker-java-sql • First create a docker network
• Write a new Java program: sudo nano [Link] (Code • docker network create my-network
follows) • Start a MySQL container in this network
• Create Dockerfile: sudo nano Dockerfile (Dockerfile follows) • docker run --name mysql --network my-network -d -p 3306:3306 -e
MYSQL_ROOT_PASSWORD=change-me -v mysql:/var/lib/mysql mysql:8
• Open firefox browser on the same virtual machine:
[Link] • Build Docker image
java/8.0.15 • docker build -t java-mysql .
• Under Files, click on jar (2.0 MB) … It will download the file • Run a Docker container of our code with MySQL container
• Copy it in our docker-java-sql directory • docker run --network my-network java-mysql
[Link] Dockerfile
• FROM openjdk
• import [Link].*;

• public class StudentSQL {


public static void main(String[] args) {

Connection con = null;


• WORKDIR /app
• COPY . /app
• Statement stmt = null;

• PreparedStatement pstmt = null;

• ResultSet rs = null;

• try {
• COPY [Link] /app/lib/
• RUN javac *.java
• // Load the MySQL JDBC driver

• [Link]("[Link]");


// Establish the initial connection to create the database

con = [Link]("jdbc:mysql://mysql:3306?useSSL=false&allowPublicKeyRetrieval=true", "root", "change-me"); • CMD ["java", "-cp", "/app/lib/mysql-connector-java-


• stmt = [Link]();
[Link]:.","StudentSQL"]
• // Create the database if it does not exist

• String createDatabaseSQL = "CREATE DATABASE IF NOT EXISTS cdac";

• [Link](createDatabaseSQL);

• // Close the initial connection

• [Link]();

• [Link]();

Output Running a Tomcat Container


• PRN: 1, Name: Student 1, Course: DAC • Pull the latest tomcat image:
• PRN: 2, Name: Student 2, Course: DITISS • docker image pull tomcat:8.0
• PRN: 3, Name: Student 3, Course: DAI

• docker run command with –it option to start the container:


• Check in the MySQL container: • docker container run -it --rm --name tomcat-container -p 8080:8080 tomcat:8.0 /bin/bash
• docker exec -it mysql /bin/bash
• mysql -u root -p
• change-me
• Connect to the interactive terminal
• docker container exec -it tomcat-container /bin/bash
• mysql>show databases;
• mysql>use cdac;
• Run any command, e.g. start tomcat
• mysql>show tables;
• cd /usr/local/tomcat/bin
• mysql>select * from student; • ./[Link] run
• mysql>exit;
• exit • Try accessing it on localhost:8080

Docker Compose Docker Compose Demo


• Docker compose: Tool for automating the building and running of • Create a new directory: mkdir docker-compose-demo
containers • Go to that directory: cd docker-compose-demo
• How: Create a [Link] file • Create [Link]: sudo nano [Link]
• [Link]: Replaces the docker build and docker run • Create Dockerfile: sudo nano dockerfile
commands • Create Docker Compose file: sudo nano [Link]
• Dockerfile: Will still be needed for the actual step-by-step • Build the Docker image: docker compose build (If it does not work,
instructionns try docker-compose in all the commands)
Dockerfile [Link] docker compose build
• Run the container: docker compose up
Usual details for creating Replaces the docker build docker compose up • Stop and remove the container: docker compose down
image and docker run commands docker compose down

[Link] Dockerfile
• public class HelloWorld { • # Use an official OpenJDK runtime as a parent image
• FROM openjdk:17-alpine

• public static void main(String[] args) {


• # Set the working directory in the container
• [Link]("Hello, World!"); • WORKDIR /app

• } • # Copy the current directory contents into the container at /app


• COPY . /app
•}
• # Compile the Java program
• RUN javac [Link]

• # Run the Java program


• CMD ["java", "HelloWorld"]
Running Tomcat With a Custom Home Page
[Link]
using Docker compose
• services: • Create a new directory: mkdir docker-compose-tomcat-demo
• Go to that directory: cd docker-compose-tomcat-demo
• java-helloworld: • Create a new directory inside it: mkdir app
• build: . • Go to that sub-directory: cd app
• Create [Link] page: sudo nano [Link]
• container_name: java-helloworld-container • Come back to the parent directory: cd ..
• command: ["java", "HelloWorld"] • Create [Link] file: sudo nano [Link]
• Start the container: docker compose up
• Test: Open the browser: localhost:8080
• More testing: From a second terminal: sudo docker exec -it tomcat-container /bin/bash
• Inside the container: ls … cd webapps/ROOT … cat [Link]
• Stop and remove the container: docker compose down

[Link] [Link]
• <!DOCTYPE html> • services:
• <html> • tomcat:
• <head> • image: tomcat:8.0
• <title>Welcome to C-DAC</title> • container_name: tomcat-container
• </head>
• ports:
• <body>
• - "8080:8080"
• <h1>Hello from C-DAC ACTS, DAC – August 2025 Batch</h1>
• volumes:
• </body>
• </html> • - ./myapp:/usr/local/tomcat/webapps/ROOT

Copying Files Between Local Windows


Assignment
Machine and Linux Machine
• Install SSH server on the Linux machine on VirtualBox • Create a Tomcat container and a MySQL container
• sudo apt install openssh-server • Demonstrate a connection from Tomcat to MySQL
• sudo systemctl enable ssh
• sudo ufw allow ssh • Note: You will have to install MySQL client in the Tomcat container
• sudo systemctl restart ssh
and try connecting to MySQL server from there
• ip addr … Look for something like 192… • Create a database, a table, and add 1 row:
• Install WinSCP on the Windows client • CREATE DATABASE ditiss;
• Open WinSCP • USE ditiss;
• In the Host name, type the above 192… address • CREATE TABLE student_tbl (prn integer, name char(30));
• User name: Your linux user name, Password: Your linux password • INSERT INTO student_tbl VALUES (1, “My name”);
• Login • SELECT * FROM student_tbl;

Docker Networking Example Docker Networking Example


• Create a new bridge network • Connect to the Tomcat container and verify that it can access MySQL
• docker network create my-network • docker exec -it tomcat-container /bin/bash
• apt-get update
• apt-get install -y mysql-client
• Start a MySQL container and connect it to the my-network network • mysql -h mysql-container -uroot -ppass
• docker container run --name mysql-container -v /data/mysql_data:/var/lib/mysql -
-network my-network -e MYSQL_ROOT_PASSWORD=pass -d mysql:latest • Create a database, a table, and add 1 row:
• CREATE DATABASE ditiss;
• USE ditiss;
• Start Tomcat and connect it to the my-network network • CREATE TABLE student_tbl (prn integer, name char(30));
• docker container run --name tomcat-container --network my-network -p 7777:8080 • INSERT INTO student_tbl VALUES (1, “My name”);
-v /data/mytomcat_data:/usr/local/tomcat/webapps -d tomcat:8 • SELECT * FROM student_tbl;
Same Example using Docker Compose Docker Compose for Java and MySQL
• Use the earlier [Link] program to add three records and
• In a new directory, create [Link] file:

• services:

• mysql:

• image: mysql:8.0 then read and display them in the output


• restart: unless-stopped


environment:

MYSQL_ROOT_PASSWORD: your_mysql_root_password
• Earlier, it was done on the command line
• Now use Docker Compose
• MYSQL_DATABASE: your_database_name

• volumes:

• - mysql_data:/var/lib/mysql

• tomcat:

• image: tomcat:latest

• restart: unless-stopped

• ports:

• - 8080:8080

• volumes:

• - ./your_tomcat_app:/usr/local/tomcat/webapps/your_app.war

• depends_on:

• - mysql

• volumes:

• mysql_data: {}

[Link] [Link]
• networks: • networks:


my-custom-network: # Define a custom network
my-custom-network: # Reference the same custom network
• services:
• cdac-mysql-server: • services:
• image: mysql:latest
• java-app:
• environment:
• MYSQL_ROOT_PASSWORD: change-me # Set password to "change-me" (replace with strong password)
• build: . # Build the image from the current directory (replace if needed)
• MYSQL_DATABASE: cdac • environment:
• ports: • DB_HOST: cdac-mysql-server # Use the service name for MySQL in the network


- "3306:3306" # Map host port 3306 to container port 3306
DB_PORT: 3306
• volumes:
• - mysql-data:/var/lib/mysql # Optional volume for persistent data • DB_NAME: cdac
• networks: • DB_PASSWORD: change-me
• - my-custom-network # Connect to the custom network
• # Secure DB credentials using environment variables from a separate file (recommended)
• volumes:
• networks:
• mysql-data: # Define the volume • - my-custom-network # Connect to the custom network

Same Example using Docker Compose Docker Compose for Java and MySQL
• Start containers: docker compose up • Create a new directory: mkdir docker-compose-java-mysql
• Verify: docker ps • Go to that directory: cd docker-compose-java-mysql
• Verify: localhost:8080 • Create [Link] (See earlier)
• Optional: Install MySQL client in Tomcat container and connect to • Create Dockerfile (See earlier)
MySQL server • Copy mysql connector (See earlier)
• Stop containers: docker compose down • Create [Link] (Follows): sudo nano [Link]
• Create [Link] (Follows): sudo nano [Link]

Docker Compose for Java and MySQL AWS and Docker


• Deploy mysql container: docker compose -f [Link] up • Create an EC2 instance using any Linux image. Install a web server in it
• Deploy Java container: docker compose -f [Link] up as docker container. Display a message "Welcome to <your city
name>“.

• Cleanup mysql container: docker compose -f [Link] down


• Cleanup Java container: docker compose -f [Link] up
Launch Instance and Connect to it Run a Web Server in Docker on AWS
• Launch an EC2 instance: Ensure ports 80 and 443 are open • Pull an nginx image
• sudo docker pull nginx:latest
• Connect to it using SSH
• Install Docker: • Run an nginx container with our volume containing the welcome page
• sudo docker run -d --name my-nginx -v $(pwd)/[Link]
• sudo yum update -y :/usr/share/nginx/html/[Link] nginx:latest
• sudo yum install docker -y
• Create [Link] in the AWS machine
• sudo systemctl start docker • sudo nano [Link]
• sudo systemctl enable docker • Type ‘Welcome …’ and save

• Access the instance on its public URL

Create a Hello World Microservice


• Use Spring Initialzr to create a Hello World spring boot application
• Project directory: C:\code\spring\hello

Microservice Deployment Using


Docker

C:\code\spring\hello\src\main\java\com\exa C:\code\spring\hello\src\main\java\com\exa
mple\hello\[Link] mple\hello\[Link]
• package [Link];
• package [Link];
• import [Link];
• import [Link]; • import [Link];

• import [Link];
import [Link];
• import [Link];

• import [Link].*;
• @SpringBootApplication
• public class HelloApplication {
• //@CrossOrigin(origins="[Link]
• @RestController
• public class WebController { • public static void main(String[] args) {
• [Link]([Link], args);


@RequestMapping(value="/helloworld", method=[Link])
• public String index(){
}
• return "Hello there - Spring Boot";

• }
}
• }

C:\code\spring\hello\[Link] C:\code\spring\hello\Dockerfile
• FROM openjdk:8-jdk-alpine
• plugins {

• id '[Link]' version '2.6.3'

• id '[Link]-management' version '[Link]'

• id 'java'

• id 'application'

• }
• WORKDIR /app
• COPY build/libs/[Link] /app/hello-0.0.1-
• group = '[Link]'

• version = '0.0.1-SNAPSHOT'

• sourceCompatibility = '1.8'
[Link]
• repositories {

• mavenCentral()

• EXPOSE 8080
• }

• dependencies {

• implementation '[Link]:spring-boot-starter-web'

• testImplementation '[Link]:spring-boot-starter-test'

• // Add other dependencies as needed • ENTRYPOINT ["java", "-jar", "[Link]"]


• }

• application {

• // Define the main class for the application.

• mainClass = '[Link]'
Build and Test
• C:\code\spring\hello>gradle build

• C:\code\spring\hello>docker build -t spring-boot-docker-hello .

• C:\code\spring\hello>docker run -p 8080:8080 spring-boot-docker-


hello
Docker Swarm
• Browser/Postman: [Link]

What is Docker Swarm? Checking if Docker Swarm is Installed


• Docker Swarm is Docker’s built-in container orchestration tool • On the command prompt/terminal, type docker info
• Alternative to Kubernetes • It will show if Swarm is active or not
• Not so popular

• If it is not active, type docker swarm init


• This swarm is a single node cluster
• Check the node: docker node ls

Service in Docker Swarm Docker Swarm Service Example


• Earlier: docker run nginx: Run a SINGLE container • docker service create nginx
• Now: docker service create nginx: Run using Docker Swarm
• Docker swarm: We can increase/decrease the number of containers • Get more details: docker service ls
to create a cluster of containers

Docker Swarm Service Example Docker Swarm Service Example


• docker service ps <service id> • Scale up the service
• See details of the container • docker service update <service id> --replicas <Number>
• See details of the container
Docker Swarm Service Example Docker Swarm Service Example
• Verify the scaling up of the service • Stop a container
• docker container ls • docker container rm -f <id>

• Repeat the docker container ls command a second time, and we will see a
new container launched to replace the removed one

Docker Swarm Service Example Docker Swarm Service Example


• See history of the containers • Remove the service itself
• docker service ps <container name> • docker service rm <service name>

Docker Stack
• Docker Stack: Collection of Docker services that allows us to deploy multi-
container applications using a [Link] file
• Makes use of Docker Compose and Docker Swarm
• Steps:
• Create a [Link] file (Sample on next slide)
• Initialize Docker swarm: docker swarm init
Docker Stack •

Deploy the stack: docker stack deploy --compose-file [Link] my_stack
See the contents of the stack: docker stack ls
• List the services in the stack: docker stack services my_stack
• List the tasks in the stack: docker stack ps my_stack
• Remove the stack: docker stack rm my_stack
• Leave Docker swarm: docker swarm leave –force
• Verify Docker swarm status: docker info

Sample [Link] file


• version: '3.8'

• services:
• web:
• image: nginx:latest
• ports:
• - "80:80"



db:
image: mysql:5.7
environment:
Kubernetes (K8S)
• MYSQL_ROOT_PASSWORD: example

• networks:
• default:
• driver: overlay
Kubernetes and Container Orchestration Why Container Orchestration?
Kubernetes • Requirement: We want 10 instances of Microservice A container, 15
instances of Microservice B container and ....
Application Application Application
• Typical Features:
Frameworks Frameworks Frameworks
• Auto Scaling - Scale containers based on demand
• Service Discovery - Help microservices find one another
Libraries Libraries Libraries
• Load Balancer - Distribute load among multiple instances of a microservice
Container Container Container • Self Healing - Do health checks and replace failing instances
• Zero Downtime Deployments - Release new versions without downtime
Docker
Operating System
Hardware

Kubernetes Architecture
Physical Architecture: Cluster, Nodes
• Physical architecture • Logical architecture
Deployment

ReplicaSet

Pod • Cluster: Gets created when we install Kubernetes


Container • Contains One/more master nodes and one or more worker nodes
• Master node: Performs management
• Worker node: Contains pods
• Remember NPC – Node contains • If one node fails, the other takes over
Pod contains Container
Service

• Also helps in load balancing

Physical Architecture: Pod Logical Architecture


Deployment
• Pod: A Single instance of an application Object Use
ReplicaSet
• Docker = Image->Container, Kubernetes = Container->Pod Pod A Docker container with an IP
• Pod = Container with an internal/a private IP address Pod address
Container Replicaset A group of identical pods
Service Exposes a replicaset to the outside
world with a consistent external IP
address
Service

Deployment Overall management structure

Workflow E-Commerce
Application
Kubernetes Installation
• Cluster options
• Windows: Enable Kubernetes in Docker Desktop
• Linux: Use Microk8s, since Minikube gives problems ([Link]
• Command line
Static IP
address • The kubectl utility ([Link]

For the entire application, One Deployment = One


there will be one service, so Microservice
one static IP address
So, we will have many
Deployments in this application
Linux Installation (Ubuntu 22.04 LTS) using
kubectl command
Microk8s (A Kubernetes Engine)
• sudo apt install snapd
• sudo systemctl enable --now snapd
• sudo snap install microk8s --classic --channel=1.28
• sudo usermod -a -G microk8s $USER
• sudo chown -f -R $USER ~/.kube
• su - $USER
• microk8s status --wait-ready
• microk8s kubectl get nodes
• microk8s kubectl get services
• alias kubectl='microk8s kubectl'
• kubectl get nodes

Create a Pod Directly or Using a Deployment


• Run a pod
• kubectl run my-nginx --image nginx … We must give a name to every pod
• kubectl get pods

• Create a deployment (and a pod inside it)


• kubectl create deployment my-nginx --image nginx
Using Kubernetes •

kubectl get pods
kubectl get all
… Note how the two nginx pods look different
… Note a replicaset was automatically created by the deployment

• Cleanup
• kubectl delete pod my-nginx
• kubectl delete deployment my-nginx

Main Service Types


Replicaset and Service Service Type Details Use case

ClusterIP Default … Pods are accessible only Backend pod (e.g. MySQL) can have a
• kubectl create deployment my-apache --image httpd inside the cluster … Service gets ClusterIP, meaning it can only be
• kubectl scale deployment my-apache --replicas 2 an IP address and all the pods accessed from the inside by the frontend
also get the same IP address … web application … Cannot be accessed
• kubectl expose deployment my-apache --type=NodePort --port=80 When the service receives by anyone from outside …
requests, it load balances them
among the pods …
NodePort Accessible from outside the A developer may want to test the
cluster … A static port (NodePort) application before exposing it using
on the Kubernetes cluster is used LoadBalancer
to expose the service … No load
balancing takes place …
LoadBalancer Accessible from the outside with A real application hosted on a public
an external static IP address … server/cloud

Sample YAML file


Deployment using YAML Files
(C:\lectures\CDAC\DAC\[Link])
• Declarative approach • apiVersion: v1
• Mostly used in the real world • kind: Pod
This YAML file can be used to
• Command: kubectl apply -f <[Link]> deploy nginx into a pod
• metadata:
• Each file contains one or more manifests • name: nginx
• Manifest: Describes one API object (deployment, job)
• spec: kubectl apply -f [Link]
• Each manifest has four parts
• apiVersion: • containers:
• kind: • - name: nginx
• metadata: kubectl delete -f [Link]
• spec:
• image: nginx:1.17.3
Sample YAML file (C:\lectures\CDAC\DAC\nginx-
[Link])
Port Forwarding
• When a pod is deployed inside a deployment but without a service, it is not
• apiVersion: apps/v1
• kind: Deployment
• metadata: accessible outside of the cluster


name: nginx-deployment
spec:
This YAML file can be used to • Try: localhost:80 in the browser … Not accessible


selector:
matchLabels:
deploy nginx as a deployment • Solution: Port forwarding: Forward requests coming to the pod to another


app: nginx
replicas: 2
port on the local host


template:
metadata:
• Example: Our nginx deployment has deployed nginx pod on port 80, so
• labels: port number inside the container is 80
• Run this command: kubectl port-forward nginx-deployment-7b767787b6-
• app: nginx

kubectl apply -f [Link]
spec:


containers:
- name: nginx
246tl 9999:80 (Replace pod id with one of the actual pod ids by doing
• image: nginx:1.17.3 kubectl get pods)
• Now try [Link]:9999 in the browser – Should show nginx page
• ports:
• - containerPort: 80 kubectl delete -f [Link]

Sample YAML file (C:\lectures\CDAC\DAC\nginx-


[Link])
Opening a Terminal Inside a Pod
• First get a pod’s id: kubectl get pods
• apiVersion: apps/v1

• kind: Deployment

• metadata:


name: my-nginx

labels:
This YAML file can be used to deploy nginx • Open a terminal inside it: kubectl exec -it my-nginx-7c79c4bf97-bzrq9

• spec:
app: nginx
as a service /bin/bash
• Now we can run any Linux command
• replicas: 3

• selector:

• matchLabels:


app: nginx

template:
• Example: hostname hostname -i ls
kubectl apply -f [Link]
• What application is the Pod running? curl localhost:80
• metadata:

• labels:

• app: nginx


spec:

containers: kubectl delete -f [Link] • It should show the HTML code for default nginx home page
• - name: nginx

• image: nginx:latest

• ports:

• - containerPort: 80

• ---

• apiVersion: v1

• kind: Service

• metadata:

Scaling the Application Cleanup (If needed)


• Check pods first: kubectl get pods -l app=nginx • kubectl delete deployment <deployment name>
• kubectl delete service <service name>

• Change replicas from 2 to 4 in the [Link] file


and redeploy and again check the pods • To delete everything (DANGEROUS)
• kubectl apply -f [Link] • kubectl delete --all all -n default
• kubectl get pods -l app=nginx
• Try deleting pods manually and see what happens

Deploy a Tomcat Container in Docker


• Get a proper tomcat image from Docker Hub
• docker pull tomcat:8.5.38-jre8-alpine

Deploying a “Hello World” JSP as • Note: If we get the latest default tomcat image, we may have to open
an interactive terminal inside it, and then install nano:
a Kubernetes Service • docker container run -d --name mytomcat -p 9999:8080 tomcat
• docker exec -it mytomcat /bin/bash
• Then at the bash prompt:
• apt-get update
• apt install nano
Open Bash in the Container Create necessary Files
OR
• Open bash in the container • cd webapps apt-get update • cd ./..
• mkdir cdac apt install nano • vi [Link]
• docker container run -d --name mytomcat -p 9999:8080 • cd cdac • i to insert
tomcat:8.5.38-jre8-alpine • mkdir WEB-INF
• docker exec -it mytomcat /bin/bash • cd WEB-INF • <%
• vi [Link] • [Link] ("Hello from Docker and
• i to insert Kubernetes at C-DAC ACTS!");
• <?xml version="1.0"?> • %>
• <web-app>
• </web-app> • Press :x and ENTER to save and exit
• Press ESC :x and ENTER to save and exit

Commit Changes to Docker Image Test


• Docker containers lose changes when stopped and return to their • Open browser and test localhost:9999/cdac/[Link]
original state
• So, if we stop this container, we would lose these changes This is the
Docker image
• How would Kuberenets get these changes then? containing our

• Solution: Commit changes to the Docker image itself


changes

• docker commit <container id> mytomcat-changed

Push the Changed Tomcat Image to Docker Push the Changed Tomcat Image to Docker
Hub Hub
• On the command prompt: docker login • Tag and push the image to Docker Hub
• docker tag <image id> newdelthis/mytomcat-changed:1.0

• Check images: docker image list and copy our image’s id • docker push <your Docker hub user name>/mytomcat-changed:1.0

Create deployment file


Deploying [Link] as a Kubernetes Pod (C:\lectures\CDAC\DAC\[Link])
• Let us first stop and remove the running Docker container (Otherwise,
• apiVersion: v1

• kind: Service

• metadata:

we will not know whether we are getting output from the running • name: my-tomcat-service

• spec:
Here, port 9999 is assigned
Docker container or Kubernets pod) • selector:
to load balancer to accept

• docker container stop <container id>


app: my-tomcat

• type: LoadBalancer user requests and redirect


• ports:
them to one of the three
• docker container rm <container id>
• - protocol: "TCP"

• port: 9999
pods in the replica set
• targetPort: 8080

• ---

• apiVersion: apps/v1

• kind: Deployment

• metadata:

• name: my-tomcat

• labels:

• app: my-tomcat

• spec:

• replicas: 3

• selector:

• matchLabels:

• app: my-tomcat

• template:
Deploy in Kubernetes Test – Windows
• kubectl apply -f [Link] • [Link]

• kubectl get pods

Testing in Linux (MicroK8s cluster) Cleanup


• Start Kubernetes Dashboard on the terminal: microk8s dashboard-proxy • kubectl delete -f [Link]
• Open browser and access [Link]
• Paste the token from the terminal here
• We will see Kubernetes dashboard • OR
• Click on Pods and then click the three dots against any pod and select Exec
• A terminal will open inside the pod
• apk update
• kubectl delete service my-tomcat-service
• apk add curl • kubectl delete deployment my-tomcat
• hostname -i
• Whatever IP address we see, curl <ip address>:8080/cdac/[Link]
• We should be able to see the contents of [Link] file

Deployment Options Rolling Updates


• Rolling deployment/update (See next slide) • Users expect applications to be available all the time and developers
are expected to deploy new versions of them several times a day
• Instantaneous switch
• Also called blue-green deployment • In Kubernetes this is done with rolling updates
• Create version:green deployment, make sure it is ready, and then delete • Rolling updates allow Deployments' update to take place with zero
version:blue deployment downtime by incrementally updating Pods instances with new ones
• Canary deployment • Rolling updates allow the following actions:
• Also called A/B deployment • Promote an application from one environment to another (via container
image updates)
• Deploy the new version only to say 5% users, collect feedback through logs • Rollback to previous versions
etc, and then roll out update to more users
• Continuous Integration and Continuous Delivery (CICD) of applications with
zero downtime

First Deploy nginx Version 1.17 Test


• kubectl get pods
• apiVersion: apps/v1

• kind: Deployment

• metadata:
File: C:\lectures\CDAC\DAC\ nginx-deployment-


labels:

environment: test [Link] • kubectl describe pods


• kubectl get all
• name: testdeploy

• spec:


replicas: 3

selector:
To deploy: kubectl apply -f nginx-deployment-


matchLabels:

environment: test
[Link]
• minReadySeconds: 10

• strategy:

• rollingUpdate:

• maxSurge: 1 # The maximum number of newly created pods beyond the "desired state" number of pods (e.g. we have 3 replicas, and here we have 1, so we can have at the most 4 pods running at a time; during the rolling deployment and then finally it would go back to 3)

• maxUnavailable: 0 # The number of pods that can be unavailable during the update process, 0 means we must have pods equal to the number specified in replicas available at all times (in our example, 3 pods)

• type: RollingUpdate

• template:

• metadata:

• labels:

• environment: test

• spec:

• containers:

• - image: nginx:1.17

• name: nginx
Now Upgrade to Version 1.18 Cleanup
• Change to nginx:1.18 in the yaml file and redeploy: kubectl apply -f • kubectl delete deployment testdeploy
[Link]
• Verify: kubectl get all
• Check again
• kubectl get pods
• kubectl describe pods
• kubectl get all

Kubernetes Assignment Run a Tomcat Container


• Dockerize a Tomcat-based application: • docker pull tomcat:8.5.38-jre8-alpine
• Use Tomcat (any version) • docker container run -d --name mytomcat -p 9999:8080 tomcat:8.5.38-
• Create an application called cdac jre8-alpine
• In the application, add a JSP page that displays ‘Welcome to Version 1 of our • docker exec -it mytomcat /bin/bash
application’ when the user accesses it • bash-4.4# ls
• Deploy this application with 3 replicas using an appropriate YAML file • bash-4.4# cd webapps
• Test the application
• bash-4.4# mkdir cdac
• Now update the application to say ‘Welcome to Version 1 of our application’
when the user accesses it • bash-4.4# cd cdac
• Perform a rolling update to upgrade the application from version 1 to version • bash-4.4# pwd
2 • /usr/local/tomcat/webapps/cdac

Save the Modified Container as a New Image


Create Version 1 of the Application
and Push to Docker Hub New image name
Container id
• bash-4.4# mkdir WEB-INF • C:\>docker commit 7784 assignment-docker-kubernetes
• bash-4.4# cd WEB-INF • C:\>docker login
• bash-4.4# vi [Link] -> Now create [Link] file • C:\>docker image list and copy the image id for the above image
• bash-4.4# cd .. • C:\>docker tag 0d927d0ed84d newdelthis/assignment-docker-
• bash-4.4# vi [Link] -> Now create the JSP file kubernetes:1.0 Image id
• bash-4.4# exit • C:\>docker push newdelthis/assignment-docker-kubernetes:1.0
• Test: Open browser and try localhost:9999/cdac/[Link] • C:\>docker container stop 7784
• C:\>docker container rm 7784

Deploy Version 1 as a Kubernetes Deployment Deploy Version 1 and Test


• C:\lectures\CDAC\DAC>kubectl apply -f assignment-docker-
• apiVersion: v1

• kind: Service


metadata:

name: assignment-docker-kubernetes
File name: C:\lectures\CDAC\DAC\ [Link]
• spec:
[Link]


selector:

app: assignment-docker-kubernetes
• C:\lectures\CDAC\DAC>kubectl get all
• type: LoadBalancer

• ports:

• - protocol: "TCP"


port: 9999

targetPort: 8080
• Browser: localhost:9999/cdac/[Link]
• ---

• apiVersion: apps/v1

• kind: Deployment

• metadata:

• name: assignment-docker-kubernetes

• labels:

• app: assignment-docker-kubernetes

• spec:

• replicas: 3

• selector:

• matchLabels:

• app: assignment-docker-kubernetes

• minReadySeconds: 10
Save the Modified Container as a New Image
Deploy Version 2 of the Application
and Push to Docker Hub
• Repeat the earlier steps to have a message Welcome to Version 2 of our • C:\>docker commit ae7a assignment-docker-Kubernetes-v2
Application in the JSP
• For this, create a new Docker container • C:\>docker login
• docker container run -d --name mytomcat -p 8888:8080 tomcat:8.5.38-jre8- • C:\>docker image list and copy the image id for the above image
alpine
• docker exec -it mytomcat /bin/bash • C:\>C:\lectures\CDAC\DAC>docker tag b30436191245
• bash-4.4# ls newdelthis/assignment-docker-kubernetes:2.0
• bash-4.4# cd webapps • C:\>docker push newdelthis/assignment-docker-kubernetes:1.0
• bash-4.4# mkdir cdac
• bash-4.4# cd cdac
• C:\>docker container stop ae7
• bash-4.4# pwd • C:\>docker container rm ae7
• /usr/local/tomcat/webapps/cdac

Change YAML to Specify Version 2.0, Instead


Test
of 1.0
• Change the file • kubectl get pods

• Redeploy • Browser: [Link]


• C:\lectures\CDAC\DAC>kubectl apply -f assignment-docker-
[Link]

Automated Tomcat Deployment With a Custom


Cleanup Page Exposed as a Service (tomcat-deployment-
[Link])
• C:\lectures\CDAC\DAC>kubectl delete deployment assignment-
• apiVersion: apps/v1

• kind: ReplicaSet

• metadata:

docker-kubernetes • name: tomcat-replicaset

• labels:

• C:\lectures\CDAC\DAC>kubectl delete service assignment-docker- •


app: tomcat

spec:

kubernetes •


replicas: 5

selector:

• matchLabels:

• app: tomcat

• template:

• metadata:

• labels:

• app: tomcat

• spec:

• containers:

• - name: tomcat

• image: tomcat:8.0

• ports:

• - containerPort: 8080

• volumeMounts:

• - name: myapp-volume

• mountPath: /usr/local/tomcat/webapps/ROOT

• volumes:

Version Control
• Real-life situation: Different developers work on same/different parts
of code files for code enhancements/bug fixes
• Problems
• Simultaneous changes done by multiple developers at the same time
• Accidental overwriting of each other’s work
Git and GitHub •

Not taking the correct base file for making code changes
Not uploading the correct file after changes are done
• Solution: Version control software
Version control example Version control example
• Developer 1 wants to push version 1.0 of the code to an application • Now a team member asks for her code
server

• This team member has a folder called Version 2.0 and has deployed
• After the push, the server runs code version 1.0 this version of the code on the server

Version control example Problem summary


• Unfortunately, his code was not
properly tested, and hence,
crashes

• Rolling back to version 1.0 is not


easy – it is all mixed up

Version Control System and Repository If another team member wants the code …
• Developers now push the code to a repository • Fetch
Repository = A centralized storage
for managing and tracking changes
to a collection of files and
directories

• Code will be deployed from the repository • Modify and push

Deploy the new version Git


• Deployed • Problems? Go back to version 1 • Git: Leading version control system
• Free and open source
• Git ≠ GitHub
• Git = Local version control software on our machine
• GitHub (Created in 2008, Now owned by Microsoft) = Cloud/Internet-
based repository
• GitHub has a free version and a paid version
Types of Version Control System Git and GitHub Parts
• Centralized • Distributed
• Distributed

• Local copy per user and one common central • Local copy and local repository per user and
repository one common central repository
• Single point of failure • More scalable
• Requires constant connectivity • e.g. Mercurial, Git
• e.g. Subversion, Endevor

Git and GitHub Workflow Stages Git Workflow – 1


• Workspace – Area where the developer is working and • When user says git add file1, it will get added to the staging area
creating/modifying code
• Index/Staging area – Area that closely mimics the local repository
• Local repository – The local area for all the code

• Remote repository – The remote area (GitHub) for all the code

Git Workflow – 2 Git Workflow – 3


• When user says git commit file1 –m “Added file1”, it will get added to the local • When user says git push, the changes will go to the remote repository
repository

Git Download and Setup Configure Git


• On Linux and Mac, Git is a part of the OS • On the local machine …
• To verify: git --version • Check current configuration
• On Windows, we need to install • git config [Link]
• If it is not there, visit [Link] • git config [Link]

• Download and install • Set user name and email id for local git set up
• git config --global [Link] “Atul Kahate”
• Accept all default options • git config --global [Link] “newdelthis@[Link]”
• Visit [Link] and sign up • Replace the highlighted portions with your own details
• Remember the login details
Creating Our Own Repository – Option 2 –
Creating Our Own Repository: Two Options
Creating a git Repository on GitHub
• Create a repository on our local machine first and then push it to • Go to GitHub website
GitHub • Make sure we are logged in
git push
• Click on the New button here if we already have some repositories

• Create a repository on GitHub first and clone it onto our local • Otherwise, we will see a Create Repository button for first-time users
machine
• Go ahead and create a repository
git clone

Getting the git Repository On the Local


Using PAT
Machine
• Inside the repository, click on Code • To clone a repository, now we need to use syntax:
• We can download zip • git clone [Link]
• Another option: Copy the https link shown on the GitHub site • Earlier, it was:
• Open command prompt, go to a directory which is already not a • git clone [Link]
repository (To verify, use git status – It should show no repository in
that directory)
• Example with the token:
• Then type git clone pasted https link
• [Link]
• It will clone the repository onto our local machine om/demo_account/my_java_project.git

Git Steps [Link]


• Create a new repository on GitHub called branch-demo • public class HelloWorld {
• On the host machine, clone it: c:\delthis>git clone • public static void main(String[] args) {
[Link]
• [Link]("Hello, World!");
• Create a [Link] program in this directory
• Push it to GitHub • }
• C:\delthis\branch-test>git add . •}
• C:\delthis\branch-test>git commit -m "first commit“
• C:\delthis\branch-test>git branch -M main
• C:\delthis\branch-test>git remote add origin
[Link] Ignore warning
• C:\delthis\branch-test>git push -u origin main

GitHub Token Generation Branches


• Profile Picture • Developer-1 wants to add a line [Link](“This from
Branch-1”);
• Developer-2 wants to add a line [Link](“This from
• Settings->Developer settings->Personal access tokens->Tokens Branch-2”);
(classic)->Generate new token->Generate new token (classic)->Give
• Simulate these steps as if they are happening on different machines,
some name->Expiration: No expiration->Give all permissions->Save in but in reality on our single machine …
a file on your PC and email/WhatsApp to yourself
• C:\delthis\branch-test>git checkout -b bug-1-branch … Create a
bug-1-branch on Developer-1’s machine
• C:\delthis\branch-test>git checkout -b bug-2-branch … Create a
bug-2-branch on Developer-2’s machine
Branches Branch Merging
• C:\delthis\branch-test>git checkout bug-1-branch … Switch to Developer- • C:\delthis\branch-test>git merge bug-1-branch … Try to merge bug-1-branch into bug-2-branch,
but we will get an error
1’s branch • Open [Link] in an editor … It will look like this, so we need to manually merge conflicts:
• Here, add a line to the Java program as mentioned earlier • public class HelloWorld {
• C:\delthis\branch-test>git add . • public static void main(String[] args) {

• C:\delthis\branch-test>git commit -m "Fix bug 1“ [Link]("Hello, World!");
• <<<<<<< HEAD
• C:\delthis\branch-test>git checkout bug-2-branch … Switch to Developer- • [Link]("Developer 2");
2’s branch • =======
• Here, add the other line to the Java program as mentioned earlier • [Link]("Developer 1");
• C:\delthis\branch-test>git add . • >>>>>>> bug-1-branch
• }
• C:\delthis\branch-test>git commit -m "Fix bug 2“ • }

Branch Merging Deleting a Branch


• After the file is saved … • Verify which all branches exist: git branch
• C:\delthis\branch-test>git add . • We can now delete the bugfix branches:
• C:\delthis\branch-test>git commit -m “Merge conflict handled” • git branch -d bug-1-branch
• C:\delthis\branch-test>git merge bug-1-branch • git branch -d bug-2-branch
• C:\delthis\branch-test>git switch main
• C:\delthis\branch-test>git merge bug-1-branch
• C:\delthis\branch-test>git merge bug-2-branch
• C:\delthis\branch-test>git push origin main

Kubernetes and Container Orchestration


Kubernetes

Application Application Application


Frameworks Frameworks Frameworks

Kubernetes (K8S) Libraries Libraries Libraries

Container Container Container

Docker
Operating System
Hardware

Kubernetes Architecture
Why Container Orchestration?
• Physical architecture • Logical architecture
• Requirement: We want 10 instances of Microservice A container, 15 Deployment
instances of Microservice B container and ....
• Typical Features:
ReplicaSet

• Auto Scaling - Scale containers based on demand


Pod
• Service Discovery - Help microservices find one another
• Load Balancer - Distribute load among multiple instances of a microservice Container

• Self Healing - Do health checks and replace failing instances


• Zero Downtime Deployments - Release new versions without downtime
• Remember NPC – Node contains
Pod contains Container
Service
Physical Architecture: Cluster, Nodes Physical Architecture: Pod
• Pod: A Single instance of an application
• Docker = Image->Container, Kubernetes = Container->Pod
• Pod = Container with an internal/a private IP address
• Cluster: Gets created when we install Kubernetes
• Contains One/more master nodes and one or more worker nodes
• Master node: Performs management
• Worker node: Contains pods
• If one node fails, the other takes over
• Also helps in load balancing

E-Commerce
Logical Architecture Workflow Application
Deployment

ReplicaSet Object Use


Pod A Docker container with an IP
Pod address
Container Replicaset A group of identical pods Static IP
Service Exposes a replicaset to the outside address
world with a consistent external IP
address For the entire application, One Deployment = One
Service

there will be one service, so


Deployment Overall management structure one static IP address
Microservice

So, we will have many


Deployments in this application

Linux Installation (Ubuntu 22.04 LTS) using


Kubernetes Installation
Microk8s (A Kubernetes Engine)
• Cluster options • sudo apt install snapd
• Windows: Enable Kubernetes in Docker Desktop • sudo systemctl enable --now snapd
• Linux: Use Microk8s, since Minikube gives problems ([Link] • sudo snap install microk8s --classic --channel=1.28
• sudo usermod -a -G microk8s $USER
• Command line • sudo chown -f -R $USER ~/.kube
• The kubectl utility ([Link] • su - $USER
• microk8s status --wait-ready
• microk8s kubectl get nodes
• microk8s kubectl get services
• alias kubectl='microk8s kubectl'
• kubectl get nodes

kubectl command

Using Kubernetes
Create a Pod Directly or Using a Deployment Replicaset and Service
• Run a pod • kubectl create deployment my-apache --image httpd
• kubectl run my-nginx --image nginx … We must give a name to every pod
• kubectl get pods • kubectl scale deployment my-apache --replicas 2
• kubectl expose deployment my-apache --type=NodePort --port=80
• Create a deployment (and a pod inside it)
• kubectl create deployment my-nginx --image nginx
• kubectl get pods … Note how the two nginx pods look different
• kubectl get all … Note a replicaset was automatically created by the deployment

• Cleanup
• kubectl delete pod my-nginx
• kubectl delete deployment my-nginx

Main Service Types


Service Type Details Use case Deployment using YAML Files
ClusterIP Default … Pods are accessible only Backend pod (e.g. MySQL) can have a
inside the cluster … Service gets ClusterIP, meaning it can only be • Declarative approach
an IP address and all the pods accessed from the inside by the frontend • Mostly used in the real world
also get the same IP address … web application … Cannot be accessed
• Command: kubectl apply -f <[Link]>
When the service receives by anyone from outside …
requests, it load balances them • Each file contains one or more manifests
among the pods … • Manifest: Describes one API object (deployment, job)
NodePort Accessible from outside the A developer may want to test the • Each manifest has four parts
cluster … A static port (NodePort) application before exposing it using • apiVersion:
on the Kubernetes cluster is used LoadBalancer • kind:
to expose the service … No load • metadata:
balancing takes place … • spec:
LoadBalancer Accessible from the outside with A real application hosted on a public
an external static IP address … server/cloud

Sample YAML file Sample YAML file (C:\lectures\CDAC\DAC\nginx-


(C:\lectures\CDAC\DAC\[Link]) [Link])
• apiVersion: v1
• apiVersion: apps/v1
• kind: Deployment

This YAML file can be used to •

• kind: Pod
metadata:
• name: nginx-deployment
This YAML file can be used to
deploy nginx into a pod • spec:

• metadata: •

selector:
matchLabels:
deploy nginx as a deployment
• name: nginx
• app: nginx
• replicas: 2

• spec:
template:

kubectl apply -f [Link] •



metadata:
labels:

• containers: •

app: nginx

kubectl apply -f [Link]


spec:

• - name: nginx •

containers:
- name: nginx
kubectl delete -f [Link]
• image: nginx:1.17.3
• image: nginx:1.17.3
• ports:
• - containerPort: 80 kubectl delete -f [Link]

Sample YAML file (C:\lectures\CDAC\DAC\nginx-


Port Forwarding [Link])
• When a pod is deployed inside a deployment but without a service, it is not
• apiVersion: apps/v1

• kind: Deployment

accessible outside of the cluster • metadata:

• name: my-nginx
This YAML file can be used to deploy nginx
• Try: localhost:80 in the browser … Not accessible • labels:

• app: nginx
as a service
• Solution: Port forwarding: Forward requests coming to the pod to another
• spec:

• replicas: 3

port on the local host •


selector:

matchLabels:

• Example: Our nginx deployment has deployed nginx pod on port 80, so •


app: nginx

template:

port number inside the container is 80 •


metadata:

labels:
kubectl apply -f [Link]
• Run this command: kubectl port-forward nginx-deployment-7b767787b6- • app: nginx

246tl 9999:80 (Replace pod id with one of the actual pod ids by doing


spec:

containers: kubectl delete -f [Link]


kubectl get pods) •


- name: nginx

image: nginx:latest

• Now try [Link]:9999 in the browser – Should show nginx page •


ports:

- containerPort: 80

• ---

• apiVersion: v1

• kind: Service

• metadata:

You might also like