Showing posts with label kubernetes. Show all posts
Showing posts with label kubernetes. Show all posts

Sunday, May 16, 2021

Kubernetes : Basics


Kubernetes : Basics


Kubernetes

Problem with VM:

  • Virtual machines comes with unwanted apps and services Eg: Browser
  • All process / Threads were not is user control .
  • Memory allocation was not in user control.
  • Syncing Virtual machines is not easy
  • Lot of configuration was needed
  • To delete and reconfigure was a nightmare.

Kubernetes

  • configure, automate, and manage applications using containers Image
  • Open Source
  • Facility for scheduling of containers
  • Creation, deletion, and movement of containers
  • Easy scaling of containers
  • Monitoring

kubernetes local :

Terminoloy :

- Cluster: A collection of nodes(Computer) represent a cluster.
- Pod:
	- Runs Container Image
	- unique ip address
	- Pods are the smallest unit in kubernetes
	- private, isolated network.
- Container Image : code 
- kubectl: Command creates a proxy ,forwarding communications into the cluster using API. 

SetUP (Project )

minikube start
minikube stop
kubectl create namespaces somename                                                                              
kubectl config set-context --current --namespace=somename

Basic 1 Pod :

kubectl run -it alpine --image=alpine   # Create a Pod
kubectl get pod
kubectl exec -it <pod-id> bash #exit
kubectl logs <podname>

Basic with Deployment with 2 Pods

# Create a Deployment with 2 pods
kubectl create deployment mydep --image=nginx --replicas=2  
		#configmap(env) , secret , cronJob
kubectl get deployment
kubectl describe deployment mydep

# Create a service to expose deployment
kubectl expose deployment mydep --port=80 --type=LoadBalancer
kubectl get services
kubectl describe service mydep

#Port forward to outside world
kubectl port-forward svc/mydep 8080:80&
#open browser > localhost:8080

kubectl get deployment mydep -o yaml >> mydep.yml
kubectl get service mydep -o yaml >> mydepsvc.yml

kubectl delete deployment mydep
kubectl delete service mydep

kubectl apply -f mydep.yml
kubectl apply -f mydepsvc.yml
kubectl port-forward svc/mydepsvc 8080:80&

Env Variables

kubectl create configmap env --from-literal=key=1
kubectl get configmap env -o yaml
kubectl get configmap env -o=jsonpath='{.data.key}'

Secret

kubectl create secret my-secret literal-token --from-literal pass="123"
kubectl get secret my-secret -o=jsonpath='{.data.pass}' | base64 --decode

CronJob /Job

kubectl create cronjob hello --image=busybox:1.28  --schedule="*/1 * * * *" -- echo "Hello World"
kubectl create job hello --image=busybox:1.28 -- echo "Hello World"

Export Yaml kubectl create deployment html --image=nginx --dry-run=client -o yaml > deployment.yaml # Volume Mount

Stateful Vs Stateless

Stateful

  • All Databases ie., Relational and Non-Relational
  • All replicas are synced (maintain Data Consistency)
  • Mandatory Persistant Volumes ( Fault Tolerance)
  • Have Serial ID alloted from 0 to n
  • Complex to create
  • Not Recommened to use Databases in Kubernetes*
  • Uses Master and Slave :
    • Master is id-0
    • only one allowed to change data
    • Data gets transfered from id-0 > id-1> id-2 ....

Stateless:

  • Eg: Rest Api Server
  • Not Synced
  • Not mandatory Persistant Volumes

YML

	apiVersion: v1
	kind: Pod
	metadata:
	  name: myapp
	spec:
	  containers:
	    - name: myapp
	      image: dockerimage
	      command: [ "env" ] # print env var
  • SERVICE Git:
    • Service /portForward (Testing only)
    • ClusterIp (Within Cluster)
    • Loadbalancer (Commonly Used to expose Application)
    • Ingress

Simple Service/port-forward (Used for Testing Only - )

apiVersion: v1
kind: Service
metadata:
  name: newservice
spec:
  selector:
    app: targetappname
  ports:
  - port: 8085
    targetPort: 8085
    name: httpTest

#kubectl get service
#kubectl port-forward svc/newservice 8085:80
#kubectl delete service newservice

ClusterIP - Within Cluster Only http://localhost:8080/api/v1/proxy/namespaces/<NAMESPACE>/services/<SERVICE-NAME>:<PORT-NAME>/

apiVersion: v1
kind: Service
metadata:  
  name: clusterservice
spec:
  selector:    
    app: targetappname
  type: ClusterIP
  ports:  
  - name: http
    port: 80
    targetPort: 80
    protocol: TCP

#kubectl proxy --port=8080

LoadBalancer - load balancer functionality - Only Used in Cloud Services ( AWS, GCP ,Azure ..) - Each service needs new LoadBalancer and new IP address.

apiVersion: v1
kind: Service
metadata:
  name: myloadbalancer
spec:
  type: LoadBalancer
  selector:
    app: targetappname
  ports:
    - port: 8000
      targetPort: app_port

Ingress (Similar to port-forward / Simple Service ) - Ingress is an object that allows access to your Kubernetes services from outside - Needs ingress controller running. - Ingress controller ( will not run by default ) - Ingress Resource

			kubectl get pods --all-namespaces | grep ingress
			kubectl get service --all-namespaces | grep ingress
			kubectl get Ingress ingress-name
			kubectl delete ingress ingress-name

ConfigMap (Environment variables)

apiVersion: v1
kind: ConfigMap
metadata:
  name: myconfig
data:
  TEST_ENV: test
---
apiVersion: v1
kind: Pod
metadata:
  name: myapp
spec:
  containers:
    - name: busybox
      image: k8s.gcr.io/busybox
      command: [ "env" ] # print env var
      envFrom:
        - configMapRef:
            name: myconfig

#kubectl apply -f configmap.yaml
#kubectl logs myapp
#kubectl delete -f configmap.yml

Secret

apiVersion: v1
kind: Secret
metadata:
  name: my-secret
type: Opaque
#$echo "test" | base64
data:
  testpassword: dGVzdAo=
---
apiVersion: v1
kind: Pod
metadata:
  name: env-pod
spec:
  containers:
    - name: test
      image: alpine
      command: ['env']
      env:
        - name: USER
          valueFrom:
            secretKeyRef:
              name: my-secret
              key: testpassword
		              
#kubectl describe secrets
#kubectl get secret my-secret -o jsonpath='{.data}'
#echo '[encoded-value]' | base64 --decode
#kubectl delete secret my-secret           

Volume( A Directory accessible to all containers running in a pod.)

apiVersion: v1
kind: ConfigMap
metadata:
  name: test-file
data:
  data.csv: |
    name,age
    sam,1,
    tom,2
---
apiVersion: v1
kind: Pod
metadata:
  name: test-pod
spec:
  restartPolicy: Never
  containers:
    - name: busybox
      image: k8s.gcr.io/busybox
      command: [ "sleep", "3600" ]
      volumeMounts:
        - name: config
          mountPath: "/datadir"
          readOnly: true
  volumes:
    - name: config
      configMap:
        name: test-file

#kubectl apply -f configmap-file.yaml
#kubectl get pod
#kubectl exec -it test-pod sh
# $cat datadir/data.csv
#kubectl delete -f configmap-file.yaml

Create vs Apply :

Create new Only (Cannot give pod in command) :

-	kubectl create -f manifest.yml	#create new Pod  

Create new / Overwrite existing x 3 :

-   kubectl apply -f manifest.yaml   
-   kubectl apply -f https://git.io/vPieo
-   cat <<EOF | kubectl apply -f -
        apiVersion: v1
        kind: Pod
        metadata:
        name: busybox-sleep
        spec:
        containers:
        - name: busybox
            image: busybox:1.28
            args:
            - sleep
            - "1000000"
        EOF

Examples

Pre-Req:

  • $minikube
  • make sure Docker application is running
  • run "eval $(minikube docker-env)" #make use of docker in minikube Docker Tutorial

Example Online:

labs.play-with-docker.com

  • Remove Taint :

          kubectl get nodes //copy node name
          kubectl describe node node1| grep -i taint      //copy name 
          kubectl taint node nodename pasteabove-
    
  • Create namespace:

          kubectl create namespaces somename                                                                              
          kubectl config set-context --current --namespace=somename
    

Example : Using hi.yml file (create)

apiVersion: v1
kind: Pod
# Pod / Job
metadata:
 name: hi
spec:
 containers:
   - name: hi
     image: ubuntu
     command: ['sh', '-c', 'echo "Hello, Kubernetes!" && sleep 3600']
     # imagePullPolicy: Never

kubectl create -f hi.yml
kubectl exec -it hi -- /bin/bash

Activities

Activity : Pull local Docker image into minikube

Create a file with name Dockerfile
Add below lines :
		FROM alpine:3.4
		RUN apk update
		RUN apk add vim 
		RUN apk add curl
open new terminal
minikube start
eval $(minikube docker-env)
docker build -t foo:1.0 . 
docker images #Check if foo is created
kubectl run foo -it --image=foo:1.0 
		-   $cat /proc/version
		-   $exit
kubectl get pods
kubectl get deployments 
kubectl delete deployment foo

Activity :Create "Hello world" python program push and pull from remote Docker Pre-Req:

  • Linux machine
  • Goto Docker-hub and create a account
  • Login to Docker-hub and create a repository
  • Restart your system and Open Bios
  • Enable vt-x / virtualization
  • Turn on Docker application
  • Make sure
  • Create a folder called apps
  • Create 3 files inside it .

Create deployment.yaml

	apiVersion: v1
	kind: Pod
	metadata:
		name: foo
	spec:
		containers:
		- name: whatever
			image: index.docker.io/usn/repo_name:latest
			imagePullPolicy: Always
			imagePullSecrets:
			- name: my_registry

main.py

print('hi')  

Dockerfile" (no extension)

FROM python:3.7
RUN mkdir /app
WORKDIR /app
ADD . /app/
EXPOSE 5000
CMD ["python","-u", "/app/main.py"]

Steps:

-   cd into apps
-   sudo docker images #empty table
-   sudo docker build -t any_name:v1 . # note there is  '.' at the end
-   sudo docker images 
-   sudo docker run -p 4000:80 any_name 
-   sudo docker images #note down the id /name, usually it is latest
-   sudo docker login
-   sudo docker tag TAG_id usn/repo_name:TAG_NAME_of_image
#docker tag 3a4677d31cde usn/test_repo:latest
-   sudo docker push usn/repo_name:TAG_NAME_of_image
#docker push usn/repo:latest
-   kubectl apply -f deployment.yaml #pull image from docker hub & create pod
-   kubectl logs -f foo #hi
-   kubectl get pods #shows all pods
-   kubectl delete pod pod_name #to delete pod

#Status =CrashLoopBackOff. Because we just have 1 print statement , so whenever the application was closing after "hi".The pod try to restart service and had done it mutiple times

Activity : Send arguments from different terminal

kubectl attach redis_container -i

Activity :Forward ports from Pods to your local machine

kubectl port-forward redis-izl09 6379
telnet localhost 6379 	#nc -l -p 6379  

Ref: https://kubernetesbyexample.com/ https://training.play-with-docker.com/ops-s1-hello/