# Kubernetes
## Intro
* Open sourced, container orchestration tool.
## Features
* High availability
* Scalabilty
* High Performance
* Backup and restore
## Component
### Node
* Simple server
* Each node has multiple pods running on it.
### Pod
* Smallest unit of K8.
* Abstraction over container.
* 1 application per pod.
* Each pod gets it's own internal ip address.
* Every time a pod is restarted it gets a new internal ip address.
* Pods communicate with each other using Services.
### Service
* Abstraction which defines a logical set of Pods and a policy by which to access them.
* Permanent IP address.
* Lifecycle of Pod and Service are not connected.
* Load Balancer.
* Pods targetted by a Pod is determined by a LabelSelector
### External Service
* To be accessible through server.
* URL is not practical.
### Internal Service
### Ingress
* Route traffic
* The request first goes to Ingress and it is rerouted to Services.
### ConfigMap
* External configuration of your application.
* Connected to pod.
### Secret
* Used to store secret code like database username and password.
* Connected to pod.
### Volumes
* When a pod is restarted, all the data is lost.
* K8 doesn't manage data persistence.
* For data persistence, we use volumes to store data.
### Deployments for StateLESS
* Blueprint for pods.
* Abstraction of pods.
* Can't replicate database, because they have a state.
### StatefulSet for StateFull
* Should be used for creating databases.
* Sometimes hosted outisde of K8.
## Node Worker
* Nodes do the work
* Three Process must be installed on all nodes.
### 1. Container runtime
### 2. Kubelet interacts with- the container and node.
* Kubelet starts the pods.
### 3. Kube Proxy forwards the request in an efficient manner.
## Master Nodes
* Four process run on master nodes
### 1. API server to interact with client.
1. Cluster gateway
2. Acts as a gatekeeper for auth.
3. Query the state of the cluster, we make a request to API server.
4. Only one entry point into the cluster.
5. Nodes communicate with master using API server
### 2. Sheduler
1. API server will schedule a new node through Scheduler.
2. Decides on where to start the pod among the nodes based on the resources available.
3. It just assigns the new pod to a node, the Kubelet is reponsible for the starting the pod.
### 3. Controller Manager
* Detect state changes like crashing of pods.
* Works with scheduler to spin up new pods to counter failure.
### 4. etcd
* Key value store.
* State information is stored on etcd.
* Data application is stored on volumes.
## Minikube
* Master processes and worker processes in a single machine.
* For development stage
* Node runs in Virtual Box
* 1 Node K8s cluster
### Installation
#### Prerequisites
* 2 CPUs or more
* 2GB of free memory
* 20GB of free disk space
##### Step 1: Update system
Run the following commands to update all system packages to the latest release:
```
sudo apt-get update
sudo apt-get install apt-transport-https
sudo apt-get upgrade
```
##### Step 2: Install a container or virtual machine manager.
We need a virtual machine in which we can set up our single node cluster with Minikube. Depending on our preference, we can use VirtualBox or KVM.
To install VirtualBox on Ubuntu, run the command:
```
sudo apt install virtualbox virtualbox-ext-pack
```
##### Step 3: Download minikube
1. First, download the latest Minikube binary using the wget command:
```
wget https://storage.googleapis.com/minikube/releases/latest/minikube-linux-amd64
```
2. Copy the downloaded file and store it into the /usr/local/bin/minikube directory:
```
sudo cp minikube-linux-amd64 /usr/local/bin/minikube
```
3. Next, give the file executive permission using the chmod command:
```
sudo chmod 755 /usr/local/bin/minikube
```
4. Finally, verify that we have successfully installed Minikube by checking the version of the software:
```
minikube version
```
##### Step 4: Install Kubectl
To deploy and manage clusters,we need to install kubectl, the official command line tool for Kubernetes.
1. Download kubectl with the following command:
```
sudo curl -LO https://storage.googleapis.com/kubernetes-release/release/`curl -s https://storage.googleapis.com/kubernetes-release/release/stable.txt`/bin/linux/amd64/kubectl
```
2. Make the binary executable by typing:
```
chmod +x ./kubectl
```
3. Then, move the binary into your path with the command:
```
sudo mv ./kubectl /usr/local/bin/kubectl
```
4. Verify the installation by checking the version of your kubectl instance:
```
kubectl version -o json
```
##### Step 5: Start Minikube
Once we have set up all the required software, we are ready to start Minikube.
Run the following command:
```
minikube start
```
## Kubectl
* Either through UI, API or KubeCTL to interact with API server.
* client to interact with minikube
## Commands
1. minikube start
2. kubectl get status
3. kubectl get pods
4. kubectl get nodes
5. kubectl create deployement NAME --image=image </br>
eg. kubectl create deployment nginx-depl --image=nginx
6. kubectl get deployment
7. kubectl get pods
8. kubectl get replicaset
Manages replicas of a pod.
```
Deployment manages a
ReplicaSet manages a
Pod is an abstraction og
Container
Everthing below deploymnet is managed by kubectl
```
9. kubectl edit deployment NAME
Predefined default config
```
After editing a pod, a new one is created and older one is terminated.
```
10. kubectl logs PodName
```
After the container is initiliazed
```
12. kubectl describe pod PodName
```
Before the container is initialized.
Provides detailed information of the pod
```
13. kubectl exec -it Podname -- bin/bash
```
To get to the terminal of a container.
```
14. kubectl delete deployment NAME
15. kubectl apply -f FileName.yaml
```
Loading configuration from a file automatically.
```
16. kubectl cluster-info
```
Provides the ip address and dns.
```
17. kubectl proxy
```
pods are running in an isolated private network, to interact with them we use proxy.
```
18. export POD_NAME=$(kubectl get pods -o go-template --template '{{range .items}}{{.metadata.name}}{{"\n"}}{{end}}')
echo Name of the Pod: $POD_NAME
```
Get podname through proxy and store it in a varibale
```
19. http://localhost:8001/api/v1/namespaces/default/pods/$POD_NAME/proxy/
```
To see the output of our pod
```
20. kubectl exec $POD_NAME env
```
To display enviroment variables
```
## Yaml config
1. metadata
2. specification
3. status (automatically created)
## Demo Project Using mongoDB and mongo express
### Project Discription
In this project we'll deploy two applications, mongoDB and mongo, express to setup a simple web application and its database.
### Overview Of K8s Components
1. A mongoDB deployment
2. An internal service to talk to the mongoDB pod
3. A mongo express deployment
4. A ConfigMap with DB url
5. A Secret with DB Username and Pwd
6. An external service to talk to the mongo express pod
### Browesr Request Flow

### Build The Project
* Start minikube
* `minikube start`
* We first make our secret yaml flie.
* 
* [mongo-secret.yaml](https://drive.google.com/file/d/1kkOf0T2jx9TsqPrgEhCQxtL_0Adj3Lko/view?usp=sharing)
* Since we need to reference the secret in the mongoDB deployment we need to apply the secret first.
* `kubectl apply -f mongo-secret.yaml`
* We then make our mongoDB deployment and apply it.
* [mongo.yaml](https://drive.google.com/file/d/1k0BD2fIVgFOZhgg4jU2Tvr2vAc7m_Wqs/view?usp=sharing)
* `kubectl apply -f mongo.yaml`
* The next step is to create and apply the internal service so that other pods can talk to our mongoDB pod.
* 
* [mongo-service.yaml](https://drive.google.com/file/d/12FL1XQLlwa8ZMT7aZnao-watxXBEh9pw/view?usp=sharing)
* `kubectl apply -f mongo-service.yaml`
* Now we create and apply the ConfigMap yaml file. This ConfigMap stores the DB url and will be referenced by the mongo express deployment.
* 
* [mongo-configmap.yaml](https://drive.google.com/file/d/1aKs6f1x9NYVvHYVddN2SSTfY8Wxt_jvo/view?usp=sharing)
* `kubectl apply -f mongo-configmap.yaml
`
* **A common practice in kubernetes is to add the deployment and service to the same yaml file. This is done by seperating the two with `---`, this indicates to yaml that one document has ended and a new one has started.**
* Now its time to create and apply the mongo express deployment and secret yaml file. This service is an external service ie this service has an assigned external IP address.
* 
* [mongo-express.yaml](https://drive.google.com/file/d/1UtSK0Huu9DisoKIE-Zk_xjNm8SOnCUtP/view?usp=sharing)
* `kubectl apply -f mongo-express.yaml
`
* The final step is to now assign a ERL to the external service in minikube, this is done with the following command.
* `minikube service mongo-express-service`
* This will open up our app in the browser
When we create a request in our app this request lands with the ***external service of mongo express*** which then forwards it to the ***mongo express pod*** which conects it to the ***mongoDB internal service*** which then finally forwards the request to the ***mongoDB pod*** and then all the way back to show us the changes in the app.
