---
# System prepended metadata

title: First Steps with Kubernetes

---

# First Steps with Kubernetes

> Quick guide to start using Kubernetes

## :memo: Docker and Kubernetes
- **docker-compose** scalablity is very limited
- Instances in Kubernetes are treated as "livestock", instead of individualized entities. They are "disposable"

## :memo: What is Kubernetes?
- Kubernetes is a  platform for managing containerized workloads and services :arrow_right: **Orchestration**
- It is portable, extensible and open-source 
- Kubernetes works in a declarative way, using manifests


## :memo: What is it for?

- Kubernetes cluster services requested to "start pods" (containers and replicas are usually specificated)
- Kubernetes will try to distribute containers among the available workers 
- The **scheduler** is in charge of this task
- **Kublets** are agents that run in the workers (1 per node). They are capable of connecting workers and services to each other
- Kubernetes will always try to fulfill the requests (eg: if a container stops, it will be restarted)
![](https://i.imgur.com/yzua33V.jpg)



## :memo: Components

- A **cluster** is obtained by deploying Kubernetes
- A cluster is made up of at least one **node** 
- Nodes run containerized apps
- The **pods** are the components of the app workload and they run 
- **COMPLETAR**

## :memo: kubectl instalation

- **kubectl** is the client app that enables the connection to the cluster
- To install this tool, follow the steps [here](https://kubernetes.io/docs/tasks/tools/)
- To check whether the installation has been succesful type: ```$kubectl version --client```

## :memo: Kubernetes instalation
- There are several options to install Kubernetes
- The easiest way to do this is to install Docker Desktop and select _Preferences > Enable Kubernetes_

## :memo: Kubernetes + Cloud Services Provider
> :bulb:_Recomendation:_ Install Minikube
> It allows the creation of a VM where all Kubernetes dependencies, plugins and components are installed

- DigitalOcean, Google Cloud, Azure or AWS provide Cloud services for these clusters
- Using these, volumes, load balancers and others can be implemented
- In DigitalOcean, version and capacity should be selected to configure Kubernetes 

## :memo: Client-cluster connection
- Contexts are declared in the _kubeconfig_ file
> :bulb:In Linux, ~/.kube/config
- This is an example of a config file:
```yaml=1
apiVersion: v1
clusters:
- cluster:
    certificate-authority: /home/dsdiegosg/.minikube/ca.crt
    extensions:
    - extension:
        last-update: Wed, 21 Jul 2021 00:00:16 CEST
        provider: minikube.sigs.k8s.io
        version: v1.22.0
      name: cluster_info
    server: https://192.168.49.2:8443
  name: minikube
contexts:
- context:
    cluster: minikube
    extensions:
    - extension:
        last-update: Wed, 21 Jul 2021 00:00:16 CEST
        provider: minikube.sigs.k8s.io
        version: v1.22.0
      name: context_info
    namespace: default
    user: minikube
  name: minikube
current-context: minikube
kind: Config
preferences: {}
users:
- name: minikube
  user:
    client-certificate: /home/dsdiegosg/.minikube/profiles/minikube/client.crt
    client-key: /home/dsdiegosg/.minikube/profiles/minikube/client.key
```

## :memo: Kubernetes contexts
- Contexts = Server URL + credentials
- In DigitalOcean: "Download config file"
- With Minikube: "Start"
- Contexts are declared in the _kubeconfig_ file
- This environment variable should be exported:
```$export KUBECONFIG={filePath}```

## :memo: Using kubectl
- To show every node in the cluster:
```$kubectl get nodes```
- To get help:
```$kubectl --help```
- To show/edit/delete a resource:
```$kubectl get/edit/delete <resource>```
- To apply a manifest:
```$kubectl apply <manifest>```
- To execute a command inside a container:
```$kubectl exec...```
- To get the logs from a pod:
```$kubectl logs <pod>```
- Copy files and directories to and from containers:
```$kubectl cp```
- Forward one or more local ports to a pod:
```$kubectl port-forward```
- Drain node in preparation for maintenance
```$kubectl drain```
- Allow/disallow the addition of containers to a pod:
```$kubectl cordon/uncordon```
- Show the config files:
```$kubectl config get contexts```

## :memo: Lens
- Useful GUI for kubectl
- Allows container and resource management among other functions

## :memo: Namespaces
- Logical division of a cluster
- By default, data contained in a namespace can be seen from another namespace
- However, policies concerning this traffic can be modified
- To show the namespaces in the cluster:
```$kubectl get ns``` 
> :bulb: Those namespaces starting with _kube-..._ are reserved for Kubernetes system tools

## :memo: Pods
- A pod is a set of containers (1 or more)
- To get the pods inside a kube-system:
```$kubectl -n kube-system get pods```
- To get more info from the pods:
```$kubectl -n kube-system get pods -o wide```
> :bulb: Kubernetes will restart stopped pods automatically

## :memo: Manifests
- Resources in Kubernetes can be created using files called manifests
- A manifest is a .yaml file
- In order to get the .yaml file of a pod:
```kubectl get pod nginx -o yaml```

## :memo: Simple pod manifest
```yaml=1
#API version for this resource
apiVersion: v1 
#Resource type
kind: Pod
#Names, labels...
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
```
- To apply this manifest:
```$kubectl apply -f manifestFile.yaml```
> :bulb: The default namespace will be used in case it is not specified
- To get running pods:
```$kubectl get pods```

## :memo: exec
- To execute commands inside a pod, we use exec:
```$kubectl exec -it nginx -- sh```
- exec accesses the pods through the Kubernetes API

## :memo: Advanced pod manifest
```yaml=1
apiVersion: v1
kind: Pod
metadata:
  name: nginx
spec:
  containers:
  - name: nginx
    image: nginx:alpine
    #ENVIRONMENT VARIABLES
    env:
    - name: MI_VARIABLE
      value: "pelado"
    - name: MI_OTRA_VARIABLE
      value: "pelade"
    - name: DD_AGENT_HOST
      valueFrom:
        fieldRef:
          fieldPath: status.hostIP
    #MEMORY AND CPU RESOURCES
    resources:
      requests: #Guaranteed values
        memory: "64Mi"
        cpu: "200m"
      limits: #Restarted if higher
        memory: "128Mi"
        cpu: "500m"
    #NOTIFICATION WHEN POD READY TO RECEIVE TRAFFIC
    readinessProbe:
      httpGet: #get to '/' and wait for 200 OK --> pod READY
        path: /
        port: 80
      initialDelaySeconds: 5
      periodSeconds: 10
    #NOTIFICATION THAT THE POD IS ALIVE
    livenessProbe:
      tcpSocket: #Checks that port 80 is open
        port: 80
      initialDelaySeconds: 15
      periodSeconds: 20
    ports:
    - containerPort: 80
```

## :memo: Deployment
- Deployment = "template" for creating pods
- In the deployment, the number of replicas is defined
- Kuberntes restarts automatically any of the replicas when they are stopped

## :memo: Daemonset
- Another way of creating a pod
- The created pod will be deployed in every node
- Typically used for monitoring
- To check if there is 1 pod/node:
```$kubectl get pods -o wide``` 

## :memo: StatefulSet and volumes
- Another way of creating a pod
- Using StatefulSet, pods are linked with a volume (disk or directory)
- Typical example: MySQL
- Typically used for monitoring
- To check if there is 1 pod/node:
```kubectl get pods -o wide``` 
- StatefulSet example:
```yaml=1
apiVersion: apps/v1
kind: StatefulSet
metadata:
  name: my-csi-app-set
spec:
  selector:
    matchLabels:
      app: mypod
  serviceName: "my-frontend"
  replicas: 1
  template:
    metadata:
      labels:
        app: mypod
    spec:
      containers:
      - name: my-frontend
        image: busybox
        args:
        - sleep
        - infinity
        volumeMounts:
        - mountPath: "/data"
          name: csi-pvc
  volumeClaimTemplates:
  - metadata:
      name: csi-pvc
    spec:
      accessModes:
      - ReadWriteOnce
      resources:
        requests:
          #The chosen cloud service will create a 5GB virtual disk, which will be connected to the node where the pod is running
          storage: 5Gi
          #StorageClass is a Kubernetes driver for some providers. It allows the creation of a virtual disk from Kubernetes in the cloud service
      storageClassName: do-block-storage
```
- To show the events (pod-volume link):
```$kubectl describe pod my-csi-app-set-0```
- PVC = Persistent Volume Claim
```
$kubectl get pvc
$kubectl describe pvc --> Describes all PVCs (when not indicating name)
```
- In DigitalOcean, Volumes should show the same output as the previous command
- To get all StatefulSets:
```$kubectl get sts```

## :memo: Networking
- Each node has its own IP address
- IP routing
- Pods communicate to each other using the CNI (Container Networking INterface)
- The CNI is a agent that runs in each of the nodes with the intention of creating a network (similar to a VPN) among all the pods
- Calico creates routes associating an IP address to each of the pods
- All containers inside a pod share an IP address
![](https://i.imgur.com/e0HkYLg.jpg)

## :memo: Services
- Service = Set of pods
- A service works as a interface to communicate to apps
- This communication can occur inside or outside the cluster
**INSERTAR ESQUEMA**

## :memo: ClusterIP
- It allows the creation of a private IP address inside the cluster that will use the selector (labelling) to allow the redirection to the services
- It is not advisable to specify an IP address because its value changes when the pod is restarted
- To check the pods IP address and some other info:
```$kubectl describe srv <serviceName>```
> :bulb: Inside a container, it is posible to use the name of a pod as an alias to its IP address, like: ```$ping <podName>```
- Example:
```yaml=1
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello
spec:
  replicas: 3
  #Specification of the pods that will act as the "backend" for this service -> Traffic will be redirected to those pods with the same label
  selector:
    matchLabels:
      role: hello
  template:
    metadata:
      labels:
        role: hello
    spec:
      containers:
      - name: hello
        image: gcr.io/google-samples/hello-app:1.0
        ports:
        - containerPort: 8080

---
apiVersion: v1
kind: Service
metadata:
  name: hello
spec:
  ports:
  - port: 8080
    targetPort: 8080
  selector:
    role: hello

```
> :bulb: To check the previous example you can try: ```$curl http://hello:8080```

## :memo: NodePort
- Similar to ClusterIP (labels), but a port is exported in each node



:::info
:bulb: **Hint:** You can also apply styling from the toolbar at the top :arrow_upper_left: of the editing area.

![](https://i.imgur.com/Cnle9f9.png)
:::

> Drag-n-drop image from your file system to the editor to paste it!


:::info
:pushpin: Want to learn more? ➜ [HackMD Tutorials](https://hackmd.io/c/tutorials) 
:::

---

## BONUS: More cool ways to HackMD!

- Table

| Features          | Tutorials               |
| ----------------- |:----------------------- |
| GitHub Sync       | [:link:][GitHub-Sync]   |
| Browser Extension | [:link:][HackMD-it]     |
| Book Mode         | [:link:][Book-mode]     |
| Slide Mode        | [:link:][Slide-mode]    | 
| Share & Publish   | [:link:][Share-Publish] |

- Code block with color and line numbers：
```javascript=16
var s = "JavaScript syntax highlighting";
alert(s);
```

- UML diagrams
```sequence
Alice->Bob: Hello Bob, how are you?
Note right of Bob: Bob thinks
Bob-->Alice: I am good thanks!
Note left of Alice: Alice responds
Alice->Bob: Where have you been?
```
- Auto-generated Table of Content
[ToC]

> Leave in-line comments! [color=#3b75c6]

- Embed YouTube Videos

{%youtube PJuNmlE74BQ %}

> Put your cursor right behind an empty bracket {} :arrow_left: and see all your choices.

- And MORE ➜ [HackMD Tutorials](https://hackmd.io/c/tutorials)
