-
we write code -> store it in version control (GitHub) -> host in any cloud infrastructure- deploy the artifact (AWS, Azure, GCP)
-
Before merging to GitHub, there should be pre-validation steps:
- no compilation error
- no build failure
- no test failure
- no major vulnerability
-
We need to write script file and then deploy to cloud manually :(
-
What if someone does the pre-validation task and deploy to cloud? Here comes Jenkins (We just need to instruct to Jenkins)
-
Jenkins is an open-source automation server that facilitates the continuous integration and continuous delivery(CI/CD) of software. (automates ompilation, testing and deployment)
- Manual Build and Deployment Processes
- Lack of Automated Testing (Unit tests, Integration tests)
- Inconsistency Across Environments(eg: version incompatibility in env)
- Deployment Challenges (deployment failure due to configuration mismatch)
- Poor Visibility and Monitoring (No tracking, no startup logs)
-
Being a developer you only focus on development. Rest integration and deployment is taken care by Jenins
-
Code -> GitHub -> (Compile->Build->Test->Code Scan)* -> Release(V1) -> Deploy
*Will be taken care by Jenkins
Continuous Integration: Code -> GitHub -> (Compile->Build->Test->Code Scan)
Continuous Delivery Deployment: Release(V1) -> Deploy
https://medium.com/@javatechie/jenkins-installation-steps-in-windows-mac-os-fcdc34b930c3
Jenkins pipeline
------------------------------------
CODE -> GITHUB -> [CLEAN, BUILD, TEST, SCAN] -> DEPLOY
------------------------ ------
CI CD
------------------------------------
- We need to create a pipeline to perform the whole CI/CD we call it Jenkins pipeline
- Pipeline: To execute sequence of action (both CI and CD)
- In today's session, we will do CI/CD using the User Interface
- Code -> GitHub -> (Now we need someone to validate the code) -> Here comes Jenkins (it will pull the code from GitHub and it will compile, test, build) -> Generate WAR file -> Deploy to external tomcat server and push notification (additional feature)
- Steps till compile, test, build it comes under Continuous Integration
- Steps after that comes under Continuous Deployment (except push notification)
- The developer's responsibility is till GitHub, after that Jenkins will take the responsibility
- Push the code to GitHub
- Login to Jenkins and create a job/pipeline
- Give a name and select Freestyle and click Ok
- Give a description and go to Source Code Management
- Select Git and paste the repository URL and go to Build Triggers
- Select Poll SCM and in Schedule write: * * * * * (which means at every minute)
- Select Build Environment (skip as of now)
- Go to Build Steps and select "Invoke top-level Maven targets" since its a Maven project
- In Goals use command: clean install
- FYI We need to add Maven
- Save
- To add Maven:
- Go to Dashboard
- Go to Manage Jenkins and go to Tools
- Go to Maven installations and click Add Maven
- Now give a name and version and select Install Automatically
- Click on Configure and now on the Build Steps, you will get Maven as option
- Select the name you did on Manage jenkins's maven
- Save
- Click on Build now (You might have to change the branch to main instead of */master in configure) and it will build the maven project with "Build Success" message
- With this CI flow is done
- To Start Tomcat server: Goto bin folder > execute startup.sh
- Tomcat runs on 8080 by default, to change it, open conf > server.xml and change the connector port to 9090
- Go to localhost:9090/ to view the tomcat page
- username password can be found on tomcat-users.xml for Manager App
- Go to Jenkins Dashboard > Configure
- Go to Post-build Actions
- You won't find the tomcat option as we need to configure the plugin first
- Go to Dashboard > Manage Jenkins
- Select Plugins > Available Plugin > Search: Deploy to container Plugin and enable it
- Now restart the Jenkins and go to configure
- Now in the Post-build action you will find "Deploy war/ear to a container". Select that option
- Write in WAR/EAR files: **/*war; Context path: jenkinsCiCd (same as WAR name); Add cointainer: Tomcat 9.x and select Username and password option:
- add scope: Global; credentials: username: admin; password: admin; Tomcat URL: http://localhost:9090/
- Save it
- Click on "Build Now"
- In the logs, you will find "Attempting to deploy 1 war file(s)"
- Go to the Tomcat dashboard -> Manager App -> You will find /jenkinsCiCd
- In pom.xml, inside , add another attribute jenkinsCiCd
- Commit and push to remote repository (Ctrl+K)
- Build will be automatically triggered in another minute
- The new WAR file will have the jenkinsCiCd.war
Where do Jenkins store the war?
-> It stores in our local machine itself inside .jenkins folder
- Go to Jenkins dashboard and select your pipeline
- Click configure
- Add another Post build action and select E-mail Notification
- Add recipient: @gmail.com
- Save
- Now we need to tell Jenkins where our mail server is running:
- Go to Dashboard > Manage Jenkins > System > Scroll to Email Notification
- SMTP server: smtp.gmail.com; suffix: @gmail.com
- Go to Advanced > Select Use SMTP Authentication username @gmail.com (from where the mail needs to be sent); password: add the app passcode
- Select use SSL
- SMTP Port: 465; Reply to address: @gmail.com
- Select Test configuration by sending test e-mail, and add an email
- Save
- Now for every failed build, it will trigger the mail (you can find in the console itself)
- Last class we saw how to use UI to automate CI & CD
- Declarative approach is the best practice using script to automate the CI & CD
- Create new pipeline > jenkins-second-demo > select Pipeline > OK
- Now we will get only three option: General, Advanced Options, Pipeline
- Go to Build Trigger: Select Poll SCM: * * * * * (every minute)
- We won't get build step or post build step as we wil be using script
- Go to Pipeline: Definition: Pipeline script, Select: GitHub + Maven
- Script uses Groovy (no prior knowledge required)
- Stages: group of action ; Stage: action
eg:
// stage 1: scm checkout
// stage 2: build (till here CI)
// stage 3: deploy WAR (CD)
// stage 4: email (not a part of CI CD)
pipeline{
agent any
tools{
maven "maven"
}
stages{
stage("SCM checkout"){
steps{
checkout scmGit(branches: [[name: '/main']], extensions: [], userRemoteConfigs: [[url: 'https://github.com/javatechie-devops/jenkins-ci-cd.git']])
}
}
stage("Build Process"){
steps{
script{
sh 'mvn clean install'
}
}
}
stage("Deploy to Container"){
steps{
deploy adapters: [tomcat9(credentialsId: 'tomcat-pwd', path: '', url: 'http://localhost:9090/')], contextPath: 'jenkinsCiCd', war: '**/.war'
}
}
}
post{
always{
emailext attachLog: true,
body: ''' <html>
<body>
<p>Build Status: ${BUILD_STATUS}</p>
<p>Build Number: ${BUILD_NUMBER}</p>
<p>Check the <a href="${BUILD_URL}">console output</a>.</p>
</body>
</html>''',
mimeType: 'text/html',
replyTo: '[email protected]',
subject: 'Pipeline Status : ${BUILD_NUMBER}',
to: '[email protected]'
}
}
}
- Select checkout from version control > give details > Generate Pipeline script > Copy the code generated
- Select Deploy war/ear to container > WAR/EAR: **/.war ; Context path: jenkinsCiCd; Credentials : admin/*** ; Tomcat URL: http://localhost:9090 > Generate the pipeline script > Copy the code generated
- Same process can be done for email as well
- Save it
- Build will start automatically
- We need to not define a separate stage for Notification as it doesn't come under CI/CD (it will come in Post)
To send a email for every build:
System > Extended Email Notification > Select always from a drop down menu
In general practice, we don't write the groovy script from the Jenkins. We attach the script with the code itself (filename: JenkinsFile)
- Create jenkins-third-demo
- Select Pipeline project and select OK
- Select Pipeline script from SCM
- According to docker.com: Docker helps developers build, share, run, and verify applications anywhere — without tedious environment configuration or management.
- Docker helps to build, run, deploy and verify your code
Check the diagrams under class notes directory (Docker_x_9-mar)
For creating e-commerce application we need:
- Java 8
- Spring Boot 3.x
- MongoDB 4.x
- Angular 8
- Kafka 2.7
Now if someone asks for the code, one needs to push the code to GitHub. However, another developer might not be able to run the application as the other developer might not have the required dependency or incompatible (Java 8, Kafka, etc.)
Solution: What if we package all the dependencies and share to others. This packaging is the solution. Docker will do this packaging. So Docker will take all the dependencies and it will create an image. The other developer can take the image and clone it and run it
- A team of three people are developing the same ecommerce application with the same dependencies as above in year 2021
- Now we need to deploy the application to a server,
- So we purchased a server after 3 years
- Now, if I deploy the application after 3 years, will the application work?
- The server might have Kafka 3.x version, etc. (dependency version mismatch or Jar conflict corrupted)
Solution: Docker can package the entire application, i.e., it will create an image. When I deploy in the future, I will have all the required dependencies. (Even if the server does not have anything installed)
- Let's suppose a developer has created an application with MySQL8, and it went to testing
- When code went to a testing team, they are using MySQL5.
- Will the code work in testing? Maybe or maybe not
Why can't we run the application in an isolation manner? I.e., wherever we go the application runs If what dependency the dev is using, the same dependency testing team is using
Possible solution: I can share my OS and pieces of software and my application so that my application runs in all environment But we can't share my operating system to someone else
Solution using Docker: I will create an image, and I will share the image to the testing team
- Server needs to be purchased with some configuration (RAM, HDD, CPU)
- Initially the load was less, but later the traffic increased in where the present server will be unable to run the application
- Now they will buy another server
- After sometime, VMWare was launched. It provided a mechanism called VMWare Work Station which can allow to run multiple OS is a single server
- How VMWare Work Station works? Above the OS layer, it added another layer called "Hypervisor". This Hypervisor helps to create Virtual Machine (Virtualization). Now we can create different VMs. We can install OS on the VMs.
- While creating these VMs, we need to assign configuration (e.g.: RAM) from the local machine
- If the RAM is used up by VMs. we can't create another VM if no memory is left in local
- Also, these VMs use their own OS (We need to take license)
- Hypervisor will take the resources from local machine and distribute to VMs
So the problem with this approach:
- Resource is limited
- Fixed memory size and not re-usable
- Mandatory installation of OS
To overcome these issues, here comes DOCKER
- Docker is an advanced version of the above virtualization knows as Containerization
- The configuration is almost the same as VMWare, but above our OS, instead of Hypervisor we have "Docker Engine"
- Above Docker Engine, instead of VMs, we have Containers
- We can deploy our apps here
- To run any application, we need an operating system, so Docker will take help of the local Operating System.
- Also, docker doesn't allocate memory to a container for a long time. Once done, docker will release the memory
- These local machines are called Host Machine
Installation guide: https://medium.com/@javatechie/docker-installation-steps-in-windows-mac-os-b749fdddf73a
Example:
- I have a java application
- To run java application, we need JDK (for compiling and running)
- To run JAR we need command:
java -jar app.jar
- Can I instruct these informations to Docker? Yes, using Dockerfile
- Using the Dockerfile it will create the image and using container, we can run it
Dockerfile is a simple file that contains instruction about your application. eg: How you will run your application?, What dependencies needed to run your application?
- Create a new Spring Boot project: spring-docker with dependency: spring-web
- Create an endpoint with Get Mapping
- Change the server.port=8282
- Build the application
- Now I want this application to be dockerize
- Create file: Dockerfile
FROM openjdk:17
WORKDIR /appContainer // It wil craete a directory on the container (optional). Else, all things will be stored in root directory
COPY ./target/spring-docker.jar /appContainer
EXPOSE 8282 // which port in container will the aplication run (keep it same as server.port)
CMD ["java", "-jar", "spring-docker.jar"]
- Start the docker engine (docker desktop)
- In the root directory, cmd:
docker build -t spring-docker-app:1.0 .
. It will create an Image - To verify, cmd:
docker images
- To run this particular docker image in docker container, cmd :
docker run -d -p 9090:8282 spring-docker-app:1.0
. 9090 is the localhost, 8282 is the container port. - To verify if the container started or not:
docker ps
- If my application is running on the container, my container must have those certificates with him
- Create a cert.txt in the root directory of the application
- Do these changes in the Dockerfile:
FROM openjdk:17
WORKDIR /appContainer
COPY cert.txt /appContainer/cert.txt
COPY ./target/spring-docker.jar /appContainer
EXPOSE 8282
CMD ["java", "-jar", "spring-docker.jar"]
To create a new image:
- build the application again (mvn clean install)
- Create an image:
docker build -t spring-docker-app:2.0 .
- To verify:
docker images
- To run:
docker run -d -p 7070:8282 spring-docker-app:2.0
- Use cmd:
docker ps
to confirm the container running - Use cmd:
docker exec -it 3a00ffd8779e /bin/bash
to see the cert.txt present or not - To see the logs:
docker logs 3a00ffd8779e
- Now let's suppose we have to do some experiments in the container itself, but I don't want it to break. After doing the experiment, I don't want to touch the existing container, instead I want a new version with the new experiment changes. Basically, we modify a container and crearte another version of it.
- app 2.0 ------> do experiments (success): patch file for PUBG game -------> app 3.0
- Add experimental changes in the code
- build jar
- create image
- run a new container
Rather doing the above steps, docker can create a clone of the existing image as seperate image: Using docker commit
- Go to the spring-docker-app:2.0
- Open bash command:
docker exec -it 3a00ffd8779e /bin/bash
- Do some changes:
echo "index.hyml">index.html
- You can find the new file in the appContainer directory of spring-docker-app:2.0
- But I don't want this new file to be there on the 2.0 container, rather I want to create a new container and clone this new change
- Use cmd:
docker commit <2.0 container id> spring-docker-app:3.0
- Use cmd:
docker images
to see a new 3.0 version of the application - To stop the running container:
docker stop 3a00ffd8779e
- Now run the new docker image:
docker run -d -p 9191:8282 spring-docker-app:3.0
- Run the 2.0 app again:
docker run -d -p 7070:8282 spring-docker-app:2.0
- Now you won't be able to find the index.html on the 2.0 but will be there in the 3.0
Docker Commands: https://github.com/basanta-spring-boot/documents/blob/main/docker-README.md
Write a shell script/batch file which will create a folder called "logmon" in container on application startup and write all your application logs to that "logmon/application.log"
- Google Cloud team designed a plugin for Java application: Google JIB
- It will help us create Docker Image without us taking extra effort of writing Dockerfile, or instructing the information to Docker or without starting the Docker daemon
- Jib handles all steps of packaging your application into a container image. You don't need to know best practicEs for creating Dockerfiles or have Docker installed.
- Google JIB
- Cloud Native BuildPack (Spring Boot 2.3.x onwards) We will understand these two approach. These two are helpful in quick testing, but not recommedned beyond Dev environment.
Will show how using Google JIB: Create Image -> Run the container with that particular image
- We need to add the Google JIB dependency (Firstly remove the Dockerfile):
- Add this plugin in the pom.xml:
<plugin>
<groupId>com.google.cloud.tools</groupId>
<artifactId>jib-maven-plugin</artifactId>
<version>3.2.1</version>
<configuration>
<to>spring-docker:5.0</to>
</configuration>
</plugin>
- Check
mvn -v
mvn compile jib:dockerBuild
(Make sure Docker Desktop is running, it is required initialy as we are not pushing to any registry) (22:46- Go to bash, and go to app/lib, you will find all the dependencies (28:33)
- Buildpack is something like magic box, that can figure out what kind of application you have, and it builds a container for you without looking at Dockerfile
- Comment the plugin added in the previous step, and do a mvn clean
- Now cmd:
mvn spring-boot:build-image
- It will create an image with tag name: 0.0.1-SNAPSHOT
- Now run the image:
docker run -d -p 9191:8282 spring-docker-practice:0.0.1-SNAPSHOT
- To give a customized name:
mvn spring-boot:build-image -Dspring-boot.build-image.imageName=spring-docker-app:v2
- Where Can i store Docker Image from where everyone can access? -> Docker Hub, AWS ECR, GitHub
- Docker Hub is a registry to store your docker images
- Create a Docker Hub account (sign up): https://hub.docker.com/
- Create Docker image*
- Then you can push your images to Docker hub
- Login to Docker Hub from cmd prompt:
docker login
- Give the username and password when prompted (It will create a file called config.json, it will wrap this username and password and create one secret token)
- Tag your image with your username, cmd:
docker tag spring-docker-app:1.0 javatechie4u/spring-docker-app:1.0
- Now when you do
docker images
, you can find another image with your image tagged - Push image to Docker Hub:
docker push javatechie4u/spring-docker-app:1.0
- Go to your Docker Hub -> Repositories: You can find the image here
- You can find the cmd to pull the image:
docker pull javatechie4u/spring-docker-app
- To pull the image: use the cmd:
docker pull javatechie4u/spring-docker-app:1.0
- You can find the image in
docker images
cmd - To run, cmd:
docker run -d -p 9090:8282 javatechie4u/spring-docker-app:1.0
- Send request to
localhost:9090
and you can see the application is running.
*Steps to create Docker image:
- Create Dockerfile
- Build JAR:
mvn clean install
- build docker images:
docker build -t spring-docker-app:1.0 .
- To use MongoDB, we can use Docker Hub to pull the image: bitnami/mongodb ->
docker pull bitnami/mongodb
- To use Kafka, we can use Docker Hub to pull the image: bitnami/kafka ->
docker pull bitnami/kafka
- To use MySQL, we can use Docker Hub to pull the image: mysql ->
docker pull mysql
docker login
docker tag spring-docker:1.0 javatechie/spring-docker:1.0
docker push javatechie/spring-docker:1.0
docker pull javatechie/spring-docker:1.0
* Earlier:
* **CI:** BUILD, TEST, GENERATE WAR
* **CD:** Deploy WAR to Tomcat
* From now on:
* **CI:** BUILD, TEST, Build docker image
* **CD:** Docker login, tag image, Push/Deploy image to Hub
- Earlier: code -> GitHub -> Jenkins (CI) [Compile -> Test ->Build] -> (CD)Generate WAR -> Deploy to Tomcat -> Send email
- In real time, we need to play with containerization:
code -> GitHub -> Jenkins (CI) [Compile -> Test -> Build] -> (CD)Create Docker Image -> Push that image to Docker Hub -> receive mail notification
- Create Dockerfile
- Build Docker image using command (using Docker build)
- Push Docker image to DockerHub :Docker login, Tag your image & push
- Create Dockerfile
FROM openjdk:17
WORKDIR /appContainer
COPY target/jenkinsCiCd.jar /appContainer
EXPOSE 8282
CMD ["java", "-jar", "jenkinsCiCd.jar"]
- Do mvn clean install (In target, you can find the jar file)
- Login to Jenkins: Go to the groovy script.
- CI steps will remain same as before: SCM checkout and Build Process
- Remove step: Deploy to container (which deploy to the tomcat server)
- We just need to configure the CD part
- Replace "Deploy to container" step with:
stage("Build Docker Image"){
steps{
script{
bat 'docker build -t attrayadas/spring-cicd-docker:1.0 .'
}
}
}
- Jenkins needs some plugin: Dashboard > Manage Jenkins > Plugins > Available Plugins > Search for "Docker" > Select Docker, Docker Commons, Docker Pipeline, Docker API, docker-build-step, CloudBees Docker Build and Publish and install them
- Select Restart Jenkins when installation is complete and no jobs are running
- Commit the changes (adding Dockerfile) to GitHub and Build it using Jenkins
pipeline {
agent any
tools{
maven "maven"
}
stages{
stage("SCM checkout"){
steps{
checkout scmGit(branches: [[name: '*/master']], extensions: [], userRemoteConfigs: [[url: 'https://github.com/attrayadas/jenkins-ci-cd-demo.git']])
}
}
stage("Build Process"){
steps{
script{
bat 'mvn clean install'
}
}
}
stage("Build Docker Image"){
steps{
script{
bat 'docker build -t attrayadas/spring-cicd-docker:1.0 .'
}
}
}
}
}
- You will find the docker image in the Docker Desktop
- Now let's push to Docker Hub.
- Add another step: Push to DockerHub and click on Pipeline Syntax
- Select withCredentials: Bind credentials to variables > Select Secret text in Bindings option > Add name in variable "docker-credentials" > Add credentials - Jenkins > Select Kind - Secret text > Now need to add password in Secret (You can add token also from Docker Desktop) > Generate Pipeline Script >
- The new stage to push the image to DockerHub would be:
stage("Deploy Image to DockerHub"){
steps{
withCredentials([string(credentialsId: 'docker-credential', variable: 'docker-credential')]) {
bat 'docker login -u attrayadas -p {%docker-credential}'
bat 'docker push attrayadas/spring-cicd-docker:1.0'
}
}
}
- Now, you will find the image in the Docker Hub
But now, everytime we push some changes, new docker images will be created using version 2.0. But we need to make it dynamic
- In the script, add these environments:
environment{
APP_NAME = "spring-docker-cicd"
RELEASE_NO = "1.0.0"
DOCKER_USER = "attrayadas"
IMAGE_NAME = "${DOCKR_USER}"+"/"+"${APP_NAME}"
IMAGE_TAG = "${RELEASE_NO}-${BUILD_NUMBER}" // Build number is inbuilt
}
- Now we need to change the respective stages:
stage("Build Docker Image"){
steps{
script{
bat "docker build -t ${IMAGE_NAME}:${IMAGE_TAG} ."
}
}
}
stage("Deploy Image to DockerHub"){
steps{
withCredentials([string(credentialsId: 'docker-password', variable: 'docker-password')]) {
bat 'docker login -u attrayadas -p ${docker-password}'
bat "docker push ${IMAGE_NAME}:${IMAGE_TAG}"
}
}
}
- Build it now
pipeline{
agent any
tools{
maven "maven"
}
environment{
APP_NAME = "spring-docker-cicd"
RELEASE_NO= "1.0.0"
DOCKER_USER= "javatechie4u"
IMAGE_NAME= "${DOCKER_USER}"+"/"+"${APP_NAME}"
IMAGE_TAG= "${RELEASE_NO}-${BUILD_NUMBER}"
}
stages{
stage("SCM checkout"){
steps{
checkout scmGit(branches: [[name: '*/main']], extensions: [], userRemoteConfigs: [[url: 'https://github.com/javatechie-devops/jenkins-ci-cd.git']])
}
}
stage("Build Process"){
steps{
script{
sh 'mvn clean install'
}
}
}
stage("Build Image"){
steps{
script{
sh 'docker build -t ${IMAGE_NAME}:${IMAGE_TAG} .'
}
}
}
stage("Deploy Image to Hub"){
steps{
withCredentials([string(credentialsId: 'dp', variable: 'dp')]) {
sh 'docker login -u javatechie4u -p ${dp}'
sh 'docker push ${IMAGE_NAME}:${IMAGE_TAG}'
}
}
}
}
post{
always{
emailext attachLog: true,
body: ''' <html>
<body>
<p>Build Status: ${BUILD_STATUS}</p>
<p>Build Number: ${BUILD_NUMBER}</p>
<p>Check the <a href="${BUILD_URL}">console output</a>.</p>
</body>
</html>''', mimeType: 'text/html', replyTo: '[email protected]', subject: 'Pipeline Status : ${BUILD_NUMBER}', to: '[email protected]'
}
}
}
- We will be having two applications: SpringBoot App and MySQL DB
- We want both to run in two containers
- Create a CRUD Application with MySQL
- Create Dockerfile:
FROM openjdk:17
WORKDIR /myApp
COPY target/transaction-service.jar /myApp
EXPOSE 8181
CMD ["java", "-jar", "transaction-service.jar"]
- Create docker-compose.yaml
version: '3.8'
services:
mysql-db:
image: 'mysql:latest'
environment:
MYSQL_ROOT_PASSWORD: root1234
MYSQL_DATABASE: transactiondb
ports:
- '3307:3306'
application:
build:
context: .
dockerfile: Dockerfile
image: transaction-service:1.0
depends_on:
- mysql-db
ports:
- '9090:8181'
environment:
SPRING_DATASOURCE_URL: 'jdbc:mysql://mysql-db:3306/transactiondb'
SPRING_DATASOURCE_USERNAME: root
SPRING_DATASOURCE_PASSWORD: root1234
- Comment the datasource url, username, password from application.properties in our application
- Build the application: mvn clean install -DskipTests (otherwise it will try to make a db connection)
- After build is successful, open another terminal:
docker-compose up -d
(make sure to start docker desktop in your local) - You will find the image and container. In container, you will under 'some name'
- Now send request to the container port that's tunneled to application port
- Add a connection to Dbeaver with MySQL 3307 port, and you will find the new database there
- To check in the terminal:
- cmd:
docker ps
- Open the mysql using bash:
docker exec -it <container id> bash
bash-4.4# mysql -u root -p
- Enter password
- cmd:
mysql> use transactiondb
- cmd:
mysql> select * from Payment;
and you will find all the data
- cmd:
Configure Kafka in your Spring Boot Application
- Last class we ran two containers: application, database. They both connected with each other to perform database operation
- What if my DB container is stopped, then we will not be able to fetch data from DB (data will be lost from container)
- How to recover the data? Keep backup
- How to avoid data-loss in container: We have Docker Volume
- Start the both containers:
docker-compose up -d
- Add data to the database through the REST Api
- Restart both the containers, data will still be there. But from where did it fetch? (MySQL will create a default anonymous volume)
- How to create your own volume?
- Add these:
volumes:
- mysql-backup:/var/lib/mysql
...
volumes:
mysql-backup:
- Now cmd:
docker-compose up -d
- Now you will see
volume "transaction-service_mysql-backup Created
- What is Kubernetes?
- Why Kubernetes?
- Features of Kubernetes
- Installation guide
- Earlier the application was designed with Monolithic Architecture
- We cannot scale individual feature of a monolithic architecture
- Then we migrated to Microservices where each feature have its own service, and each service will have its own Database
- When our services are deployed to multiple Docker containers, the number of containers will be changing as per the load
- These creating/stopping containers are done manually
- If I want these containers to be managed by someone who can increase/decrease the count of container, we need Kubernetes.
- Auto-scaling is the main feature of Kubernetes
- Kubernetes is an open-source container-orchestration engine or container management tool, it automates deploying, scaling, and managing containerized application.
- It schedules, runs and manages isolated containers which are running on virtual/physical/cloud machine
- Google (2024)—Cloud Native Computing Foundation (CNCF)
- Developed with GoLang
- Auto Scaling
- Auto Healing
- Load Balancing
- Scheduling
- Fault Tolerance
- Rollback
- Batch Execution
- Health Monitoring
- https://medium.com/@javatechie/kubernetes-installation-guide-windows-mac-f65105146127
- For Mac users: https://medium.com/@javatechie/kubernetes-tutorial-install-run-minikube-in-mac-os-k8s-cluster-369b25b0c3f0
- Pods
- Nodes
- Cluster
- Replication Controller Replica Set
- Service
- Deployment
- Secrets
- Config Map
- ETCD
- Service helps to expose your application outside to the pod using DNS Static IP
- Service will also take care of load balancing
- It's a key-value pair database that stores the status of cluster, node and pod
- To create a Kubernetes cluster, we need minimum two nodes:
- Master (Control Plane)
- Worker Node (Minion)
- API Server: This is like the central command center. It receives all the commands and requests from users, other systems, and components within the cluster.
- Controller Manager: Think of this as the taskmaster. It constantly watches over the cluster's state and ensures that everything is working as it should. If something goes wrong, it takes corrective action.
- Scheduler: This is like a matchmaker. It assigns workloads (containers) to the worker nodes based on resource availability and other constraints.
- etcd: This is like the memory bank. It stores all the cluster's configuration data and state information. It's crucial for maintaining consistency and reliability.
- Kubelet: This is like the loyal servant. It takes orders from the master node and makes sure that containers are running as expected on its node
- Kube Proxy: This is like the traffic cop. It handles network communication between the pods (containers) and the outside world, as well as between pods within the cluster.
- If I want to launch my own website
- I need a dedicated server, operating server (licensed)
- Need to install required software like DB, storage, messaging system
- I need to take care of the network related stuff (routing, gateway)
- Since I purchased server, I need employees to maintain it
- The cost can get significantly high and all need to be maintained by myself. This will be the capital expenditure
- The cost can go significantly high if scaling requires
- AWS
- Azure
- GCP
- Infrastructure as a Service (IaaS) --> eg: AWS (Offers complete infrastructure in one go)
- Platform as a Service (PaaS) --> eg: Heroku
- Software as a Service (SaaS) --> eg: Google Drive, Dropbox
AWS free tier account creation: https://medium.com/@javatechie/create-an-aws-free-tier-account-e9993a597204
- After signing up, make sure to select the region nearer to you
- EC2 means a server/virtual machine provided by AWS
-
Go to EC2
-
Select Launch an Instance
-
Give a name > Select OS type and architecture
-
Select Instance type(t2.micro)
-
Select Key pair (login) ->to access a remote from my local I need a private key (give a key pair name, select RSA)
-
Allow SSH from anywhere
-
Select number of instance to be created
-
Click on Launch Instance
-
Select the instance you want to connect to, and click on Connect
-
In the directory having the pem file, cmd:
ssh -i "devops-demo.pem"...
-
Once logged in, you can use the cmd:
whoami
to see the user -
To install java in the server:
sudo yum install -y java-17-amazon-corretto-headless.x86_64
-
Create a jar file of the java application using
maven clean install
-
To copy the jar to the server, use cmd:
scp -i devops-demo.pem /Users/javatechie/Desktop/Devops4Developers/aws-demo/target/spring-app.jar [email protected]:/home/ec2-user/
-
To run the application:
<missing java command>
-
To be able to access the endpoint: open the instance > security >
Region: (Mumbai) -> VPC (Virtual Private Cloud) => 5 1 VPC will have 200 subnet