# Kubernetes 101

## Kubernetes 101

The simplest way to experience Kubernetes is to run an nginx container and then use kubectl to manage it. Kubernetes offers a command similar to `docker run` called `kubectl run`, which conveniently creates a container (actually, it creates a Pod managed by a deployment):

```bash
$ kubectl run --image=nginx:alpine nginx-app --port=80
deployment "nginx-app" created
$ kubectl get pods
NAME                         READY     STATUS    RESTARTS   AGE
nginx-app-4028413181-cnt1i   1/1       Running   0          52s
```

Once the container is up and running, you can operate it using `kubectl` commands, such as:

* `kubectl get` - similar to `docker ps`, to query the list of resources
* `kubectl describe` - similar to `docker inspect`, to get detailed information about a resource
* `kubectl logs` - similar to `docker logs`, to get container logs
* `kubectl exec` - similar to `docker exec`, to execute a command inside a container

```bash
$ kubectl get pods
...
$ kubectl exec nginx-app-4028413181-cnt1i -- ps aux
...
$ kubectl describe pod nginx-app-4028413181-cnt1i
...
$ curl http://172.17.0.3
...
$ kubectl logs nginx-app-4028413181-cnt1i
...
```

### Defining a Pod with yaml

Above, we launched our first Pod using `kubectl run`, but `kubectl run` does not support all functionalities. In Kubernetes, it's more common to define resources using yaml files and to create resources with `kubectl create -f file.yaml`. For example, a simple nginx Pod could be defined as:

```yaml
apiVersion: v1
kind: Pod
metadata:
  name: nginx
  labels:
    app: nginx
spec:
  containers:
  - name: nginx
    image: nginx
    ports:
    - containerPort: 80
```

Previously mentioned, `kubectl run` doesn't directly create a Pod; it first creates a Deployment resource (replicas=1), after which the associated ReplicaSet automatically creates a Pod. This is equivalent to the following configuration:

```yaml
...
```

### Using Volume

Pod lifecycles are typically short, and a new Pod is created to replace it as soon as any issues occur. What about data generated by containers? It vanishes along with the Pod's demise. Volumes exist for the sole purpose of persisting container data. For instance, you could specify a hostPath for a redis container to store data:

```yaml
...
```

Kubernetes volumes support various plugins, allowing selection based on actual needs:

* emptyDir
* hostPath
* gcePersistentDisk
* awsElasticBlockStore
* nfs
* iscsi
* flocker
* glusterfs
* rbd
* cephfs
* gitRepo
* secret
* persistentVolumeClaim
* downwardAPI
* azureFileVolume
* vsphereVolume

### Using Service

Although we've created a Pod, in Kubernetes, it's ill-advised to interact directly with a Pod's IP address since it changes with Pod restarts. So how do we access the services offered by these Pods? By using Service. Service provides a unified entry for a set of Pods (selected via labels), offering load balancing and automatic service discovery. For example, you can create a service for the previous `nginx-app`:

```yaml
$ kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort
service "nginx-app" exposed
$ kubectl describe service nginx-app
...
```

Now, inside the cluster, nginx-app can be accessed via `http://10.0.0.66` and `http://node-ip:30772`. From outside the cluster, only `http://node-ip:30772` is accessible.

***

## Diving into Kubernetes: An Introductory Guide

Eager to get hands-on with Kubernetes? The easiest start is running an nginx container, then bossing it around with kubectl. Picture Kubernetes' `kubectl run` like a beefed-up `docker run`—it spins up a container, but behind the scenes, it's conjuring a Pod managed by a deployment:

```bash
$ kubectl run --image=nginx:alpine nginx-app --port=80
deployment "nginx-app" created
$ kubectl get pods
...
```

After our container hits the 'Running' stage, it's fair game for kubectl commands. Notable moves include:

* `kubectl get` - peek at resources, kind of like peering at your running processes with `docker ps`
* `kubectl describe` - snag that coveted detailed resource intel, much like `docker inspect`
* `kubectl logs` - reel in those container logs, a la `docker logs`
* `kubectl exec` - drop commands into your container, reminiscent of `docker exec`

```bash
$ kubectl get pods
...
$ kubectl exec nginx-app-4028413181-cnt1i -- ps aux
...
$ kubectl describe pod nginx-app-4028413181-cnt1i
...
$ curl http://172.17.0.3
...
$ kubectl logs nginx-app-4028413181-cnt1i
...
```

### Crafting a Pod with yaml

We kicked things off with `kubectl run`, which is easy but not all-powerful. For the full spectrum of control, yaml files are Kubernetes' blueprint of choice, paired with a `kubectl create -f file.yaml` incantation:

```yaml
...
```

Earlier we learned `kubectl run` isn't a straight shot to a Pod; it's more like a detour through Deployment Town. Your command shapes a Deployment (replicas=1), which then commands a ReplicaSet to whip up your Pod, echoing this yaml setup:

```yaml
...
```

### Embracing Volumes

Pods live fast and die young, any hiccup and *poof*, it's clone time. What of your container's precious data? Without volumes, it's dust. Enter volumes, your data's immortality charm. Say you're running redis—just anchor it with a hostPath, and your data's grounded:

```yaml
...
```

Got a specific storage fancy? Kubernetes has volume plugins aplenty to satisfy your whims:

* emptyDir
* hostPath
* gcePersistentDisk
* awsElasticBlockStore
* nfs
* iscsi
* flocker
* glusterfs
* rbd
* cephfs
* gitRepo
* secret
* persistentVolumeClaim
* downwardAPI
* azureFileVolume
* vsphereVolume

### Harnessing Service

Crafting a Pod is a win, but in Kubernetes, nodding to a Pod's IP for chit-chats is a no-no—they're the chameleons of the IP world. Craving some consistency in your network? Service is your ticket. It rallies a pod posse (huddled under label umbrellas) providing a stalwart gateway, load balancing heroes, and service discovery sorcery. Need to expose `nginx-app` to adoring fans? Deploy a service:

```yaml
$ kubectl expose deployment nginx-app --port=80 --target-port=80 --type=NodePort
service "nginx-app" exposed
$ kubectl describe service nginx-app
...
```

Inside the cluster, `http://10.0.0.66` or `http://node-ip:30772` are your golden tickets to nginx-app. From the great beyond? `http://node-ip:30772` is your sole portal.
