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

164 lines
5.6 KiB
Markdown
Raw Normal View History

2019-05-09 19:40:27 +06:00
# 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`.
2019-05-09 19:40:27 +06:00
## 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
2019-05-09 19:40:27 +06:00
* `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
2019-05-09 19:40:27 +06:00
* `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:
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
$ 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:
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
$ 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:
2019-05-09 19:40:27 +06:00
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
$ 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
2019-05-09 19:40:27 +06:00
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
$ 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.
2019-05-09 19:40:27 +06:00
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`.
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
kubectl apply -f 07-deployment/01-simple-deployment.yml
```
You can also use `kubectl scale`:
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
kubectl scale --replicas=5 -f 07-deployment/01-simple-deployment.yml
```
You can also edit the manifest in place with `kubectl edit`:
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
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:
2019-05-09 19:40:27 +06:00
2019-05-21 15:10:59 +06:00
```sh
2019-05-23 18:11:41 +06:00
$ kubectl set image deployment/simple-deployment simple-pod=mhausenblas/simpleservice:0.5.0
2019-05-09 19:40:27 +06:00
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*?
2019-05-09 19:40:27 +06:00
## Clean up
2019-05-21 15:10:59 +06:00
```sh
2019-05-09 19:40:27 +06:00
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.
2019-05-09 19:40:27 +06:00
## Links
* https://kubernetes.io/docs/concepts/workloads/controllers/deployment/