Friday, March 26, 2021

Kubernetes - StatefulSets

 Kubernetes

Image -> POD  <- RC/RS <- Deployment

Rolling update (update new version)

You have image
- deploy pod using image
- you have RC/RS to manage pods, if goes down, auto restart
- Deployment take care of it.


Start minikube
> minikube start

DB servers
- MySql
- Oracle
- MS SQL



out env is going to be like

- config files
- MySQL
- OS

DB server start

client access the data base

so, we have OS -> install database -> configuration files-> start db server
client will access the database which is stored on storage.

now, rather than create mysql all the time, we create a copy or an image which we can use to build new environment.

Lets look at a scenario
client access data using app -> and store data on database
it can be say mysql database
- our data is very important, performance is also very important.

data is stored in storage, which is harddisk and which is very slow compared other computer component.

Slow I/O kills the performance.

for that, we make our database in such a way that they can perform very fast.
how?
we create a new instance of MySQL DB
what we do is, if there is a data on master or main system it will be copied over to new MySQL instance
it is infact a replica.

So, we set up in such a way that testing team, business analyst team will access the data from the replicas so the production  server will not have performance impact.

the replica copy is also called readReplica copy.


Find a solution
say, you have an image (mysql), launch a mysql database (POD), have a new copy of MySQL
launch new POD with the MySQL image.
- Use deployment to launch
 -One of the MySQL is primary(master) and the second one is secondary.

you can have pods are running parallel. but we don't have to run it parallem.

what happends when replica pod starts first before master pod.
so,
launch multiple PODs and launch master first. or if readReplica starts first, wait until master starts.



- MySQL Image
- POD=MySQL



With LoadBalancer and service


 Here, we wil have same storage and it will impact the performance

but waht we want is we want to ahve a separate storage ofr new replica of MySQL too.

 

 what we want is any new pod, created, we want to have their own storage, not a single central storage (or shared storage)

 

 Requirement
we have to provision multiple pods and depend on each other with one deployment,  and they have their own storage. When request comes from use/clients, send traffic to master-prod server, internal request send it to other pods.

init container(what is it?)
- multi container pod, but this is not applicable in this env.

we don't want to launch multi-container POD, but we want all individual PODs.

in this kind of situation, deployment is not going to help us.
k8s has launch new kind of resource for this kind of situation.
looks like deployment but its little different
- It launch first, and launch 2nd one and third one waits.

This new resource is called Statefulsets.

[hadoop can be alternate for this kind of situation]

> kc get statefulsets
> kc get deploy

note: deployment launch pods parallelly but we don't want it
> kc get pods
> kc get svc
> kc get pvc


Image: MySQL
Resource: Statefulset

- we will replace Deployment to StatefulSet and rest is same.
- after successful launch of first pod, it will gradually launch other pods.
- Deployment creaes on PVC and all pod use same storage
- but statefulset creates seperate pvc and create own

  

 

PVC is replaced with VCT -> template
VTC - volume clean template

Loadbalancer has its own IP and host
POD also has own ip and hostname

when client connects to loadbalancer, they use domain name of LB.
LB balance the load.
what we want is
all client request, we want LB to send connection to master pod.

what can we do?
use IP or hostname of master but there is problem, or goes down?
but when it comes its state or entire state will remain same such as name and other

what stateful does is it launches a seperate LB which only servers the master
this LB does not have ip. (headless service)

IP may change, but host is always same.
when master pod comes, it will have fix host name. 

 

 

 
We have three different services
- NodePort
- Loadbalancer
- ClusterIP (private)

we will be using ClusterIP
it will not allow to connect to outside world. it is good for database.

headless is use for headless with no ip/host.

on headless service,
we will use cluster IP, private database server.

In clusterIP we will make clusterIP to none and it will become headless service.


config of master is on configmap.

1. create a config map
2. Config  for service
3. Config for deployment (stateful)

create loadbalancer file

$ cat sf-svc.ayml
apiVersion: v1
kind:Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  clusterIP: None    # Normal load balancer
  selector:
    app: mysql
---
# client service for connecting to any mysql instance for reads
# for writes, you must instead connect to the primary: mysql-o.mysql.
apiVersion: v1
kind:Service
metadata:
  name: mysql
  labels:
    app: mysql
spec:
  ports:
  - name: mysql
    port: 3306
  selector:
    app: mysql
 
# here is no type, so its clusterIP only.

Plan is to get two loadbalancer.

1. headless
2. Normal loadblalancer

pod1 (primar/mster) is connected to headless
and other loadbalancer to connected to other pods.





lets run it
> kc apply sf-svc.yaml
> kc get svc
you will see one of the service des not have IP address, you see None.
also called headless

first part is done.
now, lets look into config map
- we define configuration file for all config db, web server, they have their own config file and we have to integrate all here.

$ sf_config.yaml
apiVersion: v1
kind: ConfigMap
metadata:
  name: mysql
  labels:
    app: mysql
data:
  primary.cnf: |
    # Apply this config only on the primary. from master
    [mysqld]
    log-bin        # primary
  replica.cnf: |
    # apply this config only on replicas
    [mysqld]
    super-read-only


lets run it
> kc apply -f sf_configmap.yaml
> kc get cm
you see two different configmap
lets see in detail
> kc describe cm mysql
we see for primary serve and replica server.

now we have to launch statefl set

$ cat sf_ss.yaml

apiVersion: v1
kind:StatefulSet
metadata:
  name: mysql
spec:
  selector:
    matchLabels:
      app: mysql
  serviceName: mysql
  replicas: 3
  template:
    metadata:
      labels:
        app: mysql
    spec:
      initContainers:
      - name: init-mysql
        image: mysql:5.7
        command:
        - bash
        - "-c"
        - |
           set -ex
           # Generate mysql server-id from pod ordinal index.
           [[ `hostname` =~ -([0-9]+)$ ]] exit 1
           ordinal=${BASH_REMATCH[1]}
           echo [mysqld] > /mnt/conf.d/server-id.cnf
           # add an offset to avoid reserved server-id=0 value
           echo server-id=$((100 + $ordinal)) >> //mnt/conf.d/server-id.cnf
           # copy apropriate conf.d files from config-map to emptyDir.
           if [[ $ordinal -eq 0 ]]; then
             cp /mnt/config=map/primary.cnf /mnt/conf.d/
           else
             cp /mnt/config-map/replica.cnf /mnt/config.d/
           fi

we define volume clain templates.., pvc stuffs ...
.........................................

now, we will launch the container..


how stateful know which one is lb.?
in stateful, first pod is master.
first pod index0 is the primary
and you define what particular service you connect.

> kc apply -f sf_ss.yaml
> kc get pod
keep checking, you will see when first is on running state you will see 2nd one launching.

> kc get pod --watch.
in case of deployment, you will see all and host name is different
but in stateful you will see with postfix -0, -1 and so on.

domain name: mysql.default.svc.clusterlocal
full name is: mysql-0.mysql.default.svc.clusterlocal


launcing, configuration, second launch
> kc describe pod mysql-1

you will see pvc, scripts ..and more

> kc get pvc
you see two pvc, one for master and one for others

> kc get pv
> kc get statefulset
you see one statefulset
> kc describe statefulset

as you see pods are launching in order


> kc get rs
> kc  get rc
you don't have replica set or controller.

> kc get svc
> kc describe svc mysql  # headless one)

> kc describe svc mysql-read

> kc get pods




No comments:

Post a Comment

Git branch show detached HEAD

  Git branch show detached HEAD 1. List your branch $ git branch * (HEAD detached at f219e03)   00 2. Run re-set hard $ git reset --hard 3. ...