23-Kubernetes Running Notes
23-Kubernetes Running Notes
- Orchestration Platform
- To manage containers
- Developed by Google using Go language
- Google donated K8S to CNCF
- K8S first version released in 2015
- It is free & Open source
3) What is Cluster
- Group Of Servers
- Master Node
- Worker Node(s)
- DevOps Enginner / Developer will give the task to K8S Master
Node
- Master Node will manage worker nodes
- Master Node will schedule tasks to worker nodes
- Our containers will be created in Worker Nodes
4) Kubernetes Architecture
- Web UI Dashboard
===============================
Kubernetes Architecture Components
===============================
=> Etcd : It is internal database in K8S cluster, API Server will store
requests/tasks info in ETCD
=> Kube-Proxy : It will provide network for K8S cluster communication (Master Node
<---> Worker Nodes)
=> Docker Engine : To run our containers Docker Engine is required. Containers will
be created in Worker Nodes.
=> POD : It is a smallest building block that we will create in k8s to run our
containers.
========================
Kubernetes Cluster Setup
========================
2) Provider Managed Cluster (Cloud Provide will give read made cluster) --->
Charges applies
a) AWS EKS
b) Azure AKS
c) GCP GKE
====================
Kubernetes Components
====================
1) Pods
2) Services
3) Namespaces
4) ReplicationConroller
5) ReplicaSet
6) DaemonSet
7) Deployments
8) StatefulSet
9) K8S Volumes
10) ConfigMap & Secrets
11) Ingress Controller
12) K8S Web Dashboard
13) RBAC (Role Based Access in K8S)
14) HELM Charts (Package Manager)
15) Grafana & Promethues (Monitoring Tools)
16) ELK Stack (Log Monitoring)
17) EKS (Provider Managed Cluster - Paid Service)
=============
PODS
=============
---
apiVersion :
kind:
metadata:
spec:
...
-> Once K8S manifest yml is ready then we can execute that using below kubectl
command
================================
Kubernates Sample POD Manifest YML
================================
---
apiVersion: v1
kind: Pod
metadata:
name: javawebapppod
labels :
app: javawebapp
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
...
$ kubectl get pods
***** Note: By default PODS are accessible only with in the Cluster, Outside of the
Cluster We can't access PODS*******
=> To provide PODS access outside of the cluster we will use 'Kubernetes Service'
concept
=============
K8S Service
==============
-> K8S service makes PODs accessible outside of the cluster also
1) Cluster IP
2) Node Port
3) Load Balancer ( Will work only with Provider Managed Cluster - we
will learn this in EKS )
-> We need to Create k8s service manifest to expose PODS outside the cluster
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
Ports:
- port: 80
targetPort: 8080
...
Note: NodePort service will map our pod to a random port Number (Ex: 30002)
-> Enable Node Port in Security Group Inbound Rules
URL : http://node-ip:node-port/java-web-app/
==============
Cluster IP
==============
-> It will expose our k8s service on a cluster with one internal ip
-> Cluster IP type service is accessible only with in cluster using Cluster IP
-> When we access cluster ip, it will redirect the request to POD IP
Note: POD is very short lived object, when pod is re-created POD ip will change
hence it is not at all recommended to access pods using pod ips. To expose PODS
with in cluster we can use 'Cluster IP' service
Note: ClusterIP service is accessible only with in cluster (can't accessed outside
the cluster)
-> To expose POD using service, we will use POD label as a Selector in Service
Manifest file like below
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: ClusterIP
selector:
app: javawebapp # this is pod label
Ports:
- port: 80
targetPort: 8080
...
===========
Node Port
==========
-> Node Port Service is used to expose our PODS outside the cluster also
-> When we use NodePort Service we can specify PORT Number, if we don't specify
port number then k8s will assign one random port number for our service.
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
Ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
Note: Once we expose our POD using NodePort service then we can access our pod
outside the cluster also.
http://pod-running-node-public-ip:nodeport/<context-path>/
=====================================================
Comibining Pod manifest and Service Manifest using single YML
=====================================================
---
apiVersion: v1
kind: Pod
metadata:
name: javawebapppod
labels :
app: javawebapp
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
============
POD Lifecycle
============
-> When we make a request to create a POD then API Server will recieve our request
-> API Server will store our POD creation request in ETCD
-> Schedular will find un-scheduled pods and it will schedule them in Worker Nodes
-> The Node Agent (Kubelet) will see POD Schedule and it will fire Docker Engine
===============
K8S Namespaces
===============
Note: In java we have packages concept to group the classes in k8s we have
namespaces to group k8s components
1) default
2) kube-node-lease
3) kube-public
4) kube-system
Note: If we create any k8s component without giving namespace then k8s will
consider 'default' namespace for that.
-> The remaining 3 namespaces will be used by k8s for cluster management.
-> It is highly recommended to create our k8s components under a custom namespace
-> We can create namespace using declarative approach also (manifest yml)
---
apiVersion: v1
kind: Namespace
metadata:
name: <insert-namespace-name-here>
...
Note: If we delete namespace all the components of that namespace also gets
deleted.
=> When we execute below command the components of 'default' namespace got deleted.
---
apiVersion: v1
kind: Pod
metadata:
name: javawebapppod
labels :
app: javawebapp
namespace: ashokitns
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
namespace: ashokitns
spec:
type: NodePort
selector:
app: javawebapp
ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
-----------------------------------------------------------------------------------
--------
-> As of now we have created K8S POD manually using POD manifest file.
-> If we delete the POD then our application will be down, k8s not re-creating the
POD
1) ReplicationController
2) ReplicaSet
3) Deployment
4) DaemonSet
5) StatefulSet
-> If we create the PODS using above resources then K8S will take care of pods &
Pod lifecycle.
===================
Replication Controller
===================
-> It is responsible to make sure given no.of pods are running for our application
at any point of time
Note: If any pod is crashed then it will replace that pod with new pod.
-> Using Replication Controller we can scale up and scale down our PODS
---
apiVersion: v1
kind: ReplicationController
metadata:
name: javawebapprc
spec:
replicas: 3
selector:
app: javawebapp
template:
metadata:
name: javawebapppod
labels:
app: javawebapp
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
$ kubectl get rc
==============
ReplicaSet
==============
-> ReplicaSet also mantains given no.of pod replicas at any point of time
-> We can scale up and we can scale down our POD replicas using ReplicasSet also
----------------------------------
Equality Based Selector
--------------------------------
selector:
app: javawebapp
---------------------------
Set Based Selector
--------------------------
selector:
matchLabels:
app: javawebapp
version: v1
type: backend
---
apiVersion: apps/v1
kind: ReplicaSet
metadata:
name: javawebapprs
spec:
replicas: 3
selector:
matchLabels:
app: javawebapp
template:
metadata:
name: javawebapppod
labels:
app: javawebapp
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
$ kubectl get rs
-> Deployment is the most recommended approach to deploy our application in k8s
cluster
-> Deployment is used to tell how to create pods on the k8s cluster
-> Using Deployment we can scale up and we can scale down our POD Replicas
1) Deploy a RS
2) Update PODS
-> When we use Deployment concept we can easily update latest code without deleting
Deployment. We can achieve zero downtime.
1) ReCreate
2) RollingUpdate
-> ReCreate strategy means it will delete all the existing pods and it will create
new pods (downtime will be there)
-> RollingUpdate strategy means it will delete the pod and it will re-create the
pod one by one.
Note: If we don't specify deployment strategy in manifest yml, then k8s will
consider 'RollingUpdate' as default deployment strategy.
-> We can use below 'Deployment' manifest yml to create deployment of our java web
application in K8S cluster
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: javawebappdeployment
spec:
replicas: 1
strategy:
type: Recreate
selector:
matchLabels:
app: javawebapp
template:
metadata:
name: javawebapppod
labels:
app: javawebapp
spec:
containers:
- name: javawebappcontainer
image: ashokit/javawebapp
ports:
- containerPort: 8080
---
apiVersion: v1
kind: Service
metadata:
name: javawebappsvc
spec:
type: NodePort
selector:
app: javawebapp
ports:
- port: 80
targetPort: 8080
nodePort: 30002
...
=======================
Blue & Green Deployment
=======================
-> Create 'blue deployment' using below manifest yml (Deployment manifest)
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-boot-demo-deployment-blue
spec:
replicas: 3
strategy:
type: RollingUpdate
selector:
matchLabels:
app: k8s-boot-demo
version: v1
color: blue
template:
metadata:
labels:
app: k8s-boot-demo
version: v1
color: blue
spec:
containers:
- name: k8s-boot-demo
image: ashokit/javawebapp
imagePullPolicy: Always
ports:
- containerPort: 8080
...
---
apiVersion: v1
kind: Service
metadata:
name: k8s-boot-demo-service
spec:
type: NodePort
selector:
app: k8s-boot-demo
version: v1
ports:
- name: app-port-mapping
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30002
...
=> After creating the service access our application using below URL
===============================
Deploying Latest Code as Green
================================
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: k8s-boot-demo-deployment-green
spec:
replicas: 3
strategy:
type: RollingUpdate
selector:
matchLabels:
app: k8s-boot-demo
version: v2
color: green
template:
metadata:
labels:
app: k8s-boot-demo
version: v2
color: green
spec:
containers:
- name: k8s-boot-demo
image: ashokit/mavenwebapp
imagePullPolicy: Always
ports:
- containerPort: 8080
...
---
apiVersion: v1
kind: Service
metadata:
name: k8s-boot-demo-service-preprod
spec:
type: NodePort
selector:
app: k8s-boot-demo
version: v2
ports:
- name: app-port-mapping
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30092
...
http://node-ip:30092/maven-web-app/
Note: Once pre-prod testing completed then v2 pods we need to make live
===========================
How to make Green as Live ?
===========================
-> Go to service-live.yml and change selector to 'v2' and apply
-> After applying live service with v2 then our live service will point to green
pods (latest code)
URL : http://node-ip:30002/maven-web-app/
What is Orchestration
What is K8S
K8S Architecture
K8S Cluster Setup ( Kubeadm )
Pods
Pod Creation
Pod Manifest YML
Services ( ClusterIP, NodePort, LoadBalancer)
Selectors & Labels
Namespaces
Pod Lifecycle
ReplicationController
ReplicaSet
Deployment ( Recreate , RollingUpdate )
Blue - Green Deployment
================
DeamonSet
================
-> It is also one of the k8s resource used to create PODS in k8s cluster
-> DeamonSet will create copy of the pod on each worker node
===================
Config Map & Secrets
===================
-> ConfigMap & Secrets are used to avoid hard coding properties in the application
-> ConfigMap is used to store the data in the form of key-value (non-confidential)
-> If we use ConfigMap concept for application environment properties then we can
deploy our application in any environment without re-creating images.
=====================
Working with ConfigMap
======================
---
apiVersion: v1
kind: ConfigMap
metadata:
name: weshopify-db-config-map
labels:
storage: weshopify-db-storage
data:
DB_DRIVER_NAME_VALUE: com.mysql.cj.jdbc.Driver
DB_HOST_SERVICE_NAME_VALUE: weshopify-app-db-service
DB_SCHEMA_VALUE: weshopify-app
DB_PORT_VALUE: "3306"
...
- name: DB_DRIVER_CLASS
valueFrom :
configMapKeyRef :
name : weshopify-db-config-map
key : DB_DRIVER_NAME_VALUE
==================
Working with Secrets
==================
---
apiVersion: v1
kind: Secret
metadata:
name: weshopify-db-config-secrete
labels:
secrete: weshopify-db-config-secrete
data:
DB_USER_NAME_VALUE: cm9vdA==
DB_PASSWORD_VALUE: cm9vdA==
type: Opaque
...
=> We can get data from Secrets in our POD manifest using below tag
- name: DB_PASSWORD
valueFrom :
secretKeyRef :
name : weshopify-db-config-secrete
key : DB_PASSWORD_VALUE
==============================
Hardcoded Application Properties
=============================
spring:
datasource:
username: ashokit
password: ashokit@123
url: jdbc:mysql://localhost:3306/sbms
driver-class-name: com.mysql.jdbc.Driver
===========================================
Application Properties with Environment Variables
===========================================
spring:
datasource:
username: ${DB_USERNAME:ashokit}
password: ${DB_PASSWORD:ashokit@123}
url: ${DB_URL:jdbc:mysql://localhost:3306/sbms}
driver-class-name: ${DB_DRIVER: com.mysql.jdbc.Driver}
====================================
Deploying MySQL Database in K8S Cluster
===================================
# Create Secret
$ kubectl apply -f <Secret-manifest-yml>
# Create PV
$ kubectl apply -f <PV-manifest-yml>
# Create PVC
$ kubectl apply -f <PVC-manifest-yml>
# Connect to database
$ mysql -h localhost -u root -p
# create a table
$ create table emp(emp_id int, varchar(50));