kubernetes-hands-on/07-deployment/README.md

164 lines
5.6 KiB
Markdown
Raw Blame History

This file contains invisible Unicode characters

This file contains invisible Unicode characters that are indistinguishable to humans but may be processed differently by a computer. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Deploying my first application: `deployment`
## Introduction
In this section you will learn how to deploy a stateless application with multiple replicas and scale it.
Managing pods manually is doable, but what if you want to deploy multiple times the same one?
Of course you can copy/paste the yaml files and `apply` them. But remember, pods are **mortal**, so Kubernetes can kill them whenever it feels like it.
So you can either have a look for your Kubernetes cluster to recreate pods when needed, or you can use a `deployment`.
## First deployment
Let's create our first `deployment`:
```yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: simple-deployment
spec:
replicas: 2
selector:
matchLabels:
app: simple-deployment
template:
metadata:
labels:
app: simple-deployment
spec:
containers:
- name: simple-pod
image: mhausenblas/simpleservice:0.4.0
ports:
- containerPort: 9876
```
Let's have a look at the manifest:
* `apiVersion`: the version of the Kubernetes API we will be using, `v1` here
* `kind`: A `deployment` has the kind `Deployment`
* `spec`:
* `replicas`: The number of pods this `deployment` will create
* `selector`: Which pods the deployment should look at. Here `app=simple-deployment`.
* `template`: The template of the pods to start
* `metadata`: The metadata for this template, here only one label `app=simple-deployment`
* `spec`: The `spec` of the pods
* `containers`:
* `image`: the name of the container, here we will use version "0.4.0"
* `ports`: The list of ports to expose internally in the Kubernetes cluster
* `containerPort`: The kind of port we want to expose, here a `containerPort`. So our container will expose one port `9876` in the cluster.
Apply the deployment:
```sh
$ kubectl apply -f 07-deployment/01-simple-deployment.yml
deployment.apps/simple-deployment created
```
## Inside a `deployment`
Let's have a look at what this `deployment` created for us:
```sh
$ kubectl get deployment
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
simple-deployment 2 2 2 2 2m
```
Firstly, Kubernetes created a `deployment`. We see a lot of 2s. It is the number of replicas that are available. Let's have a look at the pods we have running:
```sh
$ kubectl get pod
NAME READY STATUS RESTARTS AGE
simple-deployment-5f7c895db4-wpv6l 1/1 Running 0 1m
simple-deployment-5f7c895db4-wt9j7 1/1 Running 0 1m
```
The `deployment` created 2 pods for us, the number we put in `replicas`. We see that the pods have a unique name, but prefixed with the name of the deployment `simple-deployment`
Did Kubernetes created something else for us? Let's have a look
```sh
$ kubectl get all
NAME READY STATUS RESTARTS AGE
pod/simple-deployment-5f7c895db4-wpv6l 1/1 Running 0 4m
pod/simple-deployment-5f7c895db4-wt9j7 1/1 Running 0 4m
NAME DESIRED CURRENT UP-TO-DATE AVAILABLE AGE
deployment.apps/simple-deployment 2 2 2 2 4m
NAME DESIRED CURRENT READY AGE
replicaset.apps/simple-deployment-5f7c895db4 2 2 2 4m
```
We see 3 things, you might have a section `ClusterIP` ignore it for now:
* `pod`: named `pod/[...]`
* `deployment`: named `deployment.apps/[...]`
* `replicaset`: named `replicaset.apps/[...]`
So in fact Kubernetes created more `kind` than expected.
We won't go into details of what a [`ReplicaSet`](https://kubernetes.io/docs/concepts/workloads/controllers/replicaset/) is, just keep it mind that it ensures that a specified number of pod are running at any time.
## Scale up
Let's play with our `deployment` now.
Update the number of `replicas` in the yaml, to a reasonable number - say `5`.
```sh
kubectl apply -f 07-deployment/01-simple-deployment.yml
```
You can also use `kubectl scale`:
```sh
kubectl scale --replicas=5 -f 07-deployment/01-simple-deployment.yml
```
You can also edit the manifest in place with `kubectl edit`:
```sh
kubectl edit deployment simple-deployment
```
I would recommend to only use `kubectl apply` as it is declarative and local to your computer, so you can commit it afterwards.
What is happening? What changed?
You can use the flag `--watch` to `kubectl`, for example: `kubectl get pod --watch`.
Do not forget the `kubectl logs [...]` command.
## Scale down
Change again the number of replicas to `2`, reapply, see what is happening.
We know how to scale up/down a deployment, but how can we deploy a new version of the application. To achieve this, we need to tell Kubernetes to update the image we are using in our `deployment`, for this:
```sh
$ kubectl set image deployment/simple-deployment simple-pod=mhausenblas/simpleservice:0.5.0
deployment.apps "simple-deployment" image updated
```
Again, see what is happening.
Remember the command `kubectl describe deployment`.
## Exercises
1. Deploy multiple nginx. The image name is `nginx`, see: https://hub.docker.com/_/nginx/.
2. Play with the scaling up/down & the deployment of new versions.
3. Do you think you can access your `deployment` of nginx from outside of Kubernetes, *without changing the manifest*?
## Clean up
```sh
kubectl delete deployment,rs,pod --all
```
## Answers
For 3), nop same as the pod. A `deployment` only creates pods, it doesn't do anything else.
## Links
* https://kubernetes.io/docs/concepts/workloads/controllers/deployment/