Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

K8s basics pods and deployments #1

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 16 additions & 0 deletions basics/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
# Goals
* Understand Basic Kubernetes (k8s) Concepts
* Familiarize with the different parts of a k8s manifest File
* Deploy an application in ~~local~~ k8s
* ~~Interact with Kubernetes locally~~
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm curious as to why these are struck out? Is this a way to indicate that we aren't doing something?

* Access the deployed application from outside the Kubernetes cluster.

# Prerequisite
* [Git CLI](https://git-scm.com/book/en/v2/Getting-Started-Installing-Git)
* [kubectl](https://kubernetes.io/docs/tasks/tools/install-kubectl/)

# Exercises
* [Deploying your application to k8s](deployment/README.md)
* [Accessing your application in k8s](services/README.md)


56 changes: 56 additions & 0 deletions basics/deployment/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
# Deployment Exercise

In this exercise, we are going to deploy the quintessential hello world application in k8s.

*If you are not familiar with a Deployment manifest you can see the explanation for each section of the manifest file [here](manifest.md). (Or you can skip ahead to the instructions on how to deploy the application using the manifest file)*

In the command line terminal (e.g., cmd, powershell, git bash, WSL terminal, etc.), execute the following command.
```console
kubectl apply -f hello/hello-deployment.yaml
```
This creates a [Deployment](https://kubernetes.io/docs/concepts/workloads/controllers/deployment/) resource that will in turn create the [Pods](https://kubernetes.io/docs/concepts/workloads/pods/pod/). *(All of these objects are created in the default namespace because we did not specify one. Use the -n option to specify a namespace on all the kubectl commands. In our private cloud, we require a namespace be provided in the manifest file metadata itself.)*

To see the list of your deployments and its statuses:
```console
kubectl get deployments
```
It should say `1/1` on the `READY` column for your deployment when all the pod is up and running.

Alternatively, you can see the list of pods that are created by the deployment:
```console
kubectl get pod
```
This should also have a `READY` column that will say `1/1` when all the containers in the pod are up and running (in our example there's only 1). The `readinessProbe` determines when a container is considered ready.

If you want to watch the pods or deployments until it is up and running you can pass the -w or --watch ( CTRL+C to exit). For example:
```console
kubectl get pod -w
```
This will block on that command, allowing you to see the status change without having to repeatedly execute the command.

You can check the logs of your pod:
```console
kubectl logs <pod_name>
```
Use the `<pod_name>` from when you listed the pods.

To follow/tail the logs add the -f option ( CTRL+C to exit):
```console
kubectl logs <pod_name> -f
```

Next, we are going to try to delete the pod.

First, get the list of pods
```console
kubectl get pods
```
Take note of the name of one of the `hello-` pods. Use the pod name for the command below.
```console
kubectl delete pod <pod_name>
```
List out the pods again.
```console
kubectl get pods
```
See what happens.
117 changes: 117 additions & 0 deletions basics/deployment/manifest.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,117 @@
# Breaking down a deployment manifest

## Kind
The `apiVersion` and `kind`, together, specifies the API and what kind of resource we are defining in the manifest file. We are creating a *Deployment* manifest file.

```yaml
apiVersion: apps/v1
kind: Deployment

## Metadata
The `name` uniquely identifies this Deployment. `labels` are used for selectors on other resources and log queries.

```yaml
metadata:
name: hello
labels:
app: hello
```
*(Note: In our private cloud, we are required to specify a namespace in the metadata. However, for our exercise we are just using the default namespace.)*

## Spec
The `spec` section of a manifest file contains configurations for that resource type, in this case they are configuration for a deployment.

For example, the first thing we are going to configure is how many `replicas` (of pods) this deployment will have.

```yaml
spec:
replicas: 1
```

Next we need to specify the label `selector` that defines which pods are managed by this deployment, i.e., `spec.selector.matchLabels`.

```yaml
selector:
matchLabels:
app: hello
```

## Pod Template
The next subsection is the `spec.template` which contains the template of the Pod that will be created.

The `spec.template.metadata.labels` must match the selector.matchLabels because this determines which pods the are managed by the deployment.

```yaml
template:
metadata:
labels:
app: hello
```

The pod template also has its own `spec` section which defines the configuration of the pod. This section is where you define the `containers` that will go into the pod.

A container requires a name field.

```yaml
spec:
containers:
- name: hello-app
```

In the container section you'll need to specify which `image` to use for the container.

**TODO: Update image**
```yaml
image: "egineering-llc/hello-micronaut:0.0.1-26_3e59c44"
```

The `spec.template.spec.containers[].ports[]` contains the list `ports` in the container that will be [*exposed*](https://docs.docker.com/engine/reference/commandline/run/#publish-or-expose-port--p---expose). These exposed ports can then be bound to service ports (will be covered later).

```yaml
ports:
- name: http
containerPort: 8080
protocol: TCP
```

## Probes

The `spec.template.spec.containers[].readinessProbe` defines the check that helps kubernetes determine when a container is considered ready to receive requests (the service will start allowing traffic through). In this case, it is using an http `GET` to perform a check. It is considered a success when it returns a status code greater than or equal to `200` and less than `400`.

```yaml
readinessProbe:
httpGet:
path: /hello
port: 8080
initialDelaySeconds: 3
periodSeconds: 10
```
The `spec.template.spec.containers[].livenessProbe` performs its checks in the same way that the `readinessProbe` is done. However, this probe check is used for self-healing instead of determining the readiness of the pod. If the liveness check fails (i.e., the container does not return a status code greater than or equal to 200 and less than 400) it will kill the container and be subjected to its restart policy, which default to `Always`, which means it will perform a restart if it fails the liveness probe. The `initialDelaySeconds` on the livenessProbe is set to a larger number than the `readinessProbe` to avoid a situation where the container is restarted before it is given a chance to fully startup.

```yaml
livenessProbe:
httpGet:
path: /hello
port: 8080
initialDelaySeconds: 30
periodSeconds: 30
```

# Resource Management
The `spec.template.spec.containers[].resources` is the section in the manifest that defines the management of the computer resources. The `limits` is used to set policies for how much resources a container can use. The `requests` defines the minimum resource requirements of a container which is used for determining the required resources for a node to host this pod.

The memory `requests` and `limits` are straightforward and can be taken as the minimum and maximum values of the memory resource, but the CPU values between `requests` and `limits` has some [nuance](https://kubernetes.io/docs/concepts/configuration/manage-compute-resources-container/#how-pods-with-resource-limits-are-run) that you can check out if you are interested. In simple terms, these values can be treated as minimum and maximum boundaries.

`Mi` on the memory values stands for *MebiByte* which differs from *MegaByte* in that a MegaByte is in the power of 10 whereas a MebiByte is in the power of 2. 1 MebiByte is equal to 1024 KibiByte whereas 1 MegaByte is 1000 KiloByte. MebiByte is a more accurate unit to represent memory than the MegaByte but either can be used (i.e., you can use the suffix M for MegaByte).

The `m` unit for CPU stands for 1/1000 of a CPU core.

```yaml
resources:
limits:
memory: 100Mi
cpu: 1
requests:
memory: 10Mi
cpu: 10m
```