164 lines
5.6 KiB
Markdown
164 lines
5.6 KiB
Markdown
# 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/
|