1
0
Signed-off-by: Arnaud Morin <arnaud.morin@ovhcloud.com>
This commit is contained in:
Arnaud Morin
2022-01-08 22:55:03 +01:00
parent d37781f378
commit 977bef4238
83 changed files with 16203 additions and 2 deletions

View File

@@ -0,0 +1,122 @@
# Check your docker installation
Run the hello-world docker container to check if everything is fine.
```
docker run hello-world
```
# Using `debian` docker
You will now use the `debian` image.
So first, pull it from the docker hub
```
# Q: what command are you going to use to download locally the debian image?
your command
```
List the images
```
docker images
...
debian latest 6f4986d78878 2 weeks ago 124MB
...
```
Run your first docker image
```
docker run debian
```
Wait, nothing happened! Is that a bug? Well, no. Behind the scenes, a lot of stuff happened.
When you call `run`, the Docker client finds the image (busybox in this case), loads up the container and then runs a command in that container.
When we run `docker run debian`, we didn't provide any command, so the container booted up, ran an empty command and then exited.
Well, yeah - kind of a bummer. Let's try something more exciting.
```
docker run debian echo "hello from debian!"
```
Nice - finally we see some output.
In this case, the Docker client dutifully ran the `echo` command in our `debian` container and then exited it.
Ok, now it's time to see the `docker ps` command.
The `docker ps` command shows you all containers that are currently running:
```
docker ps
CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
f9c03ce13b09 demo "/usr/sbin/sshd -D" 32 minutes ago Up 32 minutes 127.0.0.2:8080->8080/tcp, 127.0.0.2:2222->22/tcp demo
```
So you see only one container running, named `demo`.
This is not your `debian` container, but the container used in the previous lesson.
Why the `debian` is not visible? Because it's not running anymore!
Q: what command can we use to retrieve all containers, including the stopped ones?
You're probably wondering if there is a way to run more than just one command in a container. Let's try that now:
```
docker run -it debian bash
/ # ls
bin boot dev etc home lib lib64 media mnt opt proc root run sbin srv sys tmp usr var
```
Running the `run` command with the `-it` flags attaches us to an interactive tty in the container. Now we can run as many commands in the container as we want. Take some time to run your favorite commands.
It's now time to clean some of the old stopped containers to avoid filling your system with dead containers:
```
docker ps -a
# grab the ID of the containers you want to clean
docker rm xxyy
```
Q: which parameter to `docker run` could we pass to automate the removal of the container after the execution?
# Clean your environment
Before continuing this training, destroy all running containers using `docker stop` and `docker rm`. Destroy also the `demo` container from previous lesson, we don't need it anymore.
# Real application
It's now time to deploy a real application.
Once again, you will deploy the `demo-flask` application, but this time, by building a docker image of this application instead of installing it using `ansible`.
Start by cloning the app:
```
git clone https://github.com/arnaudmorin/demo-flask.git
cd demo-flask
```
Take a look at the `Dockerfile`:
```
vim Dockerfile
# to exit vim: <esc>:q
```
A [Dockerfile](https://docs.docker.com/engine/reference/builder/) is a simple text file that contains a list of commands that the Docker client calls while creating an image. It's a simple way to automate the image creation process.
There are a lot of different [commands](https://docs.docker.com/engine/reference/builder/#from) you can use in a `Dockerfile`.
Q: try to describe all the commands you see in this `Dockerfile`.
Close the `Dockerfile`.
It's now time to build our image. The `docker build` command does the heavy-lifting of creating a Docker image from a `Dockerfile`:
```
docker build -t yourname/demo-flask .
```
Start now a container from your image:
```
docker run yourname/demo-flask
```
This will start a container with the demo-flask, but the app will not be accessible from outside.
You remember that you installed a `nginx` proxy to access the previous `demo` container?
Q: find the good `docker run` command to run your container in background and expose the port locally so the `nginx` proxy reach your application.
Congrats, you're done with docker101!

View File

@@ -0,0 +1,251 @@
# Kubernetes 101
## Install `k3s`
For this lesson, we will use `k3s` as `kubernetes` flavor.
`k3s` is really easy to install:
```
curl -sfL https://get.k3s.io | sh -
```
### Check
Check the nodes:
```
k get nodes
NAME STATUS ROLES AGE VERSION
ansible101 Ready control-plane,master 100s v1.22.5+k3s1
```
`k3s` will use your server as `control-plane` but also as `worker` (master)
## First deployment
Create your first deployment
```shell
kubectl create deployment first-dep --image=gcr.io/google-samples/kubernetes-bootcamp:v1
```
View the deployment
```shell
kubectl get deployments
NAME READY UP-TO-DATE AVAILABLE AGE
first-dep 1/1 1 1 1m
```
View the pods:
```shell
kubectl get pods
NAME READY STATUS RESTARTS AGE
first-dep-69c7f7c9f4-jzbh8 1/1 Running 0 14s
```
View the events:
```shell
kubectl get events
```
## Create a Service
By default, the Pod is only accessible by its internal IP address within the Kubernetes cluster. To make the `first-dep` container accessible from outside the Kubernetes virtual network, you have to expose the Pod as a Kubernetes [_Service_](https://kubernetes.io/docs/concepts/services-networking/service/).
Expose the Pod to the public internet using the `kubectl expose` command:
```shell
kubectl expose deployment first-dep --type=LoadBalancer --port=8080
```
The `--type=LoadBalancer` flag indicates that you want to expose your Service outside of the cluster.
The application code inside the image `k8s.gcr.io/echoserver` only listens on TCP port 8080. If you used `kubectl expose` to expose a different port, clients could not connect to that other port.
View the Service you created:
```shell
kubectl get services
```
The output is similar to:
```
NAME TYPE CLUSTER-IP EXTERNAL-IP PORT(S) AGE
first-dep LoadBalancer 10.108.144.78 141.95.107.55 8080:30369/TCP 21s
kubernetes ClusterIP 10.96.0.1 <none> 443/TCP 23m
```
Check that the service works as expected.
Q: using curl, which command can you run to perform a HTTP request to your `first-dep` deployment?
List pods again
```
kubectl get pods
```
Q: how many pods do you have? Why?
## Logs
You can check the logs of your pods.
First list your pods:
```
kubectl get pods
```
Then logs:
```
kubectl logs first-dep-69c7f7c9f4-jzbh8
Kubernetes Bootcamp App Started At: 2022-01-08T21:09:13.992Z | Running On: first-dep-69c7f7c9f4-jzbh8
Running On: first-dep-69c7f7c9f4-jzbh8 | Total Requests: 1 | App Uptime: 38.775 seconds | Log Time: 2022-01-08T21:09:52.767Z
Running On: first-dep-69c7f7c9f4-jzbh8 | Total Requests: 2 | App Uptime: 41.24 seconds | Log Time: 2022-01-08T21:09:55.232Z
Running On: first-dep-69c7f7c9f4-jzbh8 | Total Requests: 3 | App Uptime: 41.879 seconds | Log Time: 2022-01-08T21:09:55.871Z
```
## Edit your deployment
```
kubectl describe deployment first-dep
# You will see yaml output
# This will show you what your deployment look like in your k8s environment
```
You can also describe your service:
```
kubectl describe services/first-dep
```
Now edit your deployment
```
kubectl edit deployment first-dep
# This will open vim with the yaml of your deployment
```
Change the `replicas` (in `spec` section) to `2`
Check again the pods
```
kubectl get pods -o wide
```
Q: how can you do a curl request to a specific pod?
Q: how many pods do you have?
Test your application multiple time:
```
curl http://141.95.107.55:8080/
...
curl http://141.95.107.55:8080/
...
curl http://141.95.107.55:8080/
```
Q: is the output always the same? Explain why.
You can also change the replicas using the `scale` command:
```
kubectl scale deployment/first-dep --replicas=3
```
## Execution from pods
We can execute commands directly on the container once the Pod is up and running.
For this, we use the `exec` command and use the name of the Pod as a parameter. Lets list the environment variables:
```
kubectl exec first-dep-69c7f7c9f4-jzbh8 -- env
```
Next lets start a bash session in the Pods container:
```
kubectl exec -it first-dep-69c7f7c9f4-jzbh8 -- bash
```
We have now an open console on the container where we run our NodeJS application. The source code of the app is in the server.js file:
`cat server.js`
You can check that the application is up by running a curl command:
`curl localhost:8080`
_Note: here we used localhost because we executed the command inside the NodeJS Pod. If you cannot connect to localhost:8080, check to make sure you have run the kubectl exec command and are launching the command from within the Pod_
To close your container connection type `exit`.
## Updating the app
To update the image of the application to version 2, use the `set image` command, followed by the deployment name and the new image version:
```
kubectl set image deployments/first-dep kubernetes-bootcamp=jocatalin/kubernetes-bootcamp:v2
```
The command notified the Deployment to use a different image for your app and initiated a rolling update. Check the status of the new Pods, and view the old one terminating with the `get pods` command:
`kubectl get pods`
Verify the update using curl
```
curl http://141.95.107.55:8080/
```
Q: do you see the `v=2`?
You can also check if everything went fine using:
```
kubectl rollout status deployments/first-dep
```
To view the current image version of the app, run the `describe pods` command:
`kubectl describe pods`
In the `Image` field of the output, verify that you are running the latest image version (v2).
## Rollbacking the app
Lets perform another update, and deploy an image tagged with `v10` :
`kubectl set image deployments/first-dep kubernetes-bootcamp=gcr.io/google-samples/kubernetes-bootcamp:v10`
Use `get deployments` to see the status of the deployment:
`kubectl get deployments`
Notice that the output doesn't list the desired number of available Pods. Run the `get pods` command to list all Pods:
`kubectl get pods`
Notice that some of the Pods have a status of `ImagePullBackOff`.
To get more insight into the problem, run the `describe pods` command:
`kubectl describe pods`
In the `Events` section of the output for the affected Pods, notice that the `v10` image version did not exist in the repository.
_Note: you can also use `kubectl get events` to retrieve the error._
To roll back the deployment to your last working version, use the `rollout undo` command:
`kubectl rollout undo deployments/first-dep`
The `rollout undo` command reverts the deployment to the previous known state (v2 of the image). Updates are versioned and you can revert to any previously known state of a deployment.
Use the `get pods` commands to list the Pods again:
`kubectl get pods`
Four Pods are running. To check the image deployed on these Pods, use the `describe pods` command:
`kubectl describe pods`
The deployment is once again using a stable version of the app (v2). The rollback was successful.
## Clean up
Now you can clean up the resources you created in your cluster:
```shell
kubectl delete service first-dep
kubectl delete deployment first-dep
```