https://github.com/cscfi/rahti-course-2019-exercises
Exercises for Rahti course held in November 2019
https://github.com/cscfi/rahti-course-2019-exercises
Last synced: 12 months ago
JSON representation
Exercises for Rahti course held in November 2019
- Host: GitHub
- URL: https://github.com/cscfi/rahti-course-2019-exercises
- Owner: CSCfi
- Created: 2019-11-13T08:10:15.000Z (over 6 years ago)
- Default Branch: master
- Last Pushed: 2019-11-14T14:08:10.000Z (over 6 years ago)
- Last Synced: 2025-02-25T00:28:23.003Z (over 1 year ago)
- Language: Python
- Size: 248 KB
- Stars: 1
- Watchers: 2
- Forks: 2
- Open Issues: 0
-
Metadata Files:
- Readme: readme.md
Awesome Lists containing this project
README
# 1. Authorizing client session and creating a project
Create a project named `course-training-` using the `oc` command
line interface (CLI) tool.
Locate the project in the web console and verify that it exists using the `oc`
tool.
# 2. Execute a container in a pod
Pre-requisites: *Exercise 1*
## The Docker's hello-world
* Run container image [`hello-world`](https://hub.docker.com/_/hello-world) in
a pod called hello-pod.
* Get the standard output of the container.
* Verify that the container is crash-looping. Fix it so that it isn't. Replace
the container with fixed pod specification.
## Custom "Hello, world"
* Run command `echo Hello, world!` inside container from image `alpine:edge`.
Name the pod as `custom-hello-pod`.
* Verify that the standard output of the container really is "Hello, world!".
## Sleeping pod
* Create a pod based on `alpine:edge` image that sleeps for 7200 seconds and
then exits. Name it `sleeping-pod`.
## Cleanup
* Remove the pods named `hello-pod` and `custom-hello-pod`. Let the sleeping pod sleep.
# 3. Navigate Rahti Console
Pre-requisites: *Exercise 1, 2*
## Terminal session
Open terminal session to your sleeping pod using the Rahti GUI console.
* What is the user id? (`id -u`)
* What is the group id? (`id -g`)
* Try creating file `/hello` containing string `hello`. Did it work? (`echo hello > /hello`)
* Try that with `/tmp/hello`
* Kill the process that sleeps. Did the pod disappear?
## Cleanup
* Remove the pod `sleeping-pod` using console GUI
# 4. Python application in Rahti
Pre-requisites: 1
Create a Python 3.6 application using the service catalog template named
"Python".
For sources code of the application, make a fork of the code located at
`https://github.com/cscfi/rahti-flask-hello` under your own github account.
Place the application in the project you created in Exercise 1.
Name the application `hello-flask-`, where `` is the number in
your training account.
Once the application is running, find the URL where it is available in the
internet.
# 5. Liveness and Readiness probes
Pre-requisites: *Exercise 1*
The following pod waits for 30 seconds, then creates the file `/tmp/alive`
inside the container, then waits again for 30 seconds and deletes the file.
* Edit the specification so that the container is "ready" and "live" only if
the file `/tmp/alive` exists.
* Wait for 30 seconds before starting to check if the container is live.
* Try what happens if the liveness probing starts immediately when the container is started?
* **Cleanup**: Delete the pod from the cluster afterwards with `oc delete pod probe-tests`.
*Tip #1*: Go to Monitoring page on the Application Console to see the status of
your pod.
*Tip #2*: You can monitor the pod with `watch oc describe pod probe-tests` or
`watch oc get pod probe-tests`
*Tip #3*: The GNU coreutils tool *`cat `* returns 0 if the
exists and everything went fine.
```yaml
kind: Pod
apiVersion: v1
metadata:
name: probe-tests
spec:
containers:
- name: probe-test-container
image: centos:7
command:
- sh
- -c
- >
echo "Waiting for 30 seconds to go live" &&
for i in {1..30}; do echo "."; sleep 1; done &&
touch /tmp/alive &&
echo "Now waiting for 30 seconds to go die" &&
for i in {1..30}; do echo "."; sleep 1; done &&
rm /tmp/alive &&
echo "Going to sleep mode" &&
sleep inf
```
# 6. OOM killer
Create pod yaml-spec that runs the image
`docker-registry.default.svc:5000/rahti-course-2019/oom-killer:1`. That image
contains a python code, listed in `app/app.py` file, that reserves 10MB more memory
every second.
Make sure that the container gets killed when it reserves over 50MB of memory.
# 7. Hello world web server with DeploymentConfig
Pre-requisites: *Exercise 1*
In this exercise, write (or copy-paste from slides) all the API objects in YAML
plaintext and submit them with `oc create -f ...`.
## DeploymentConfig
* Create a DeploymentConfig that will spawn a pod running image
`openshift/hello-openshift`. Name it `hello-openshift` and label it `app:
hello-openshift`. Apply the same label `app: hello-openshift` to the pods to
be spawned as well.
* What is the name of the pod that appeared? *Hint: `oc get pod -l
app=hello-openshift`*.
* Delete the pod.
* What is the name of the pod that appeared?
* List all objects that have metadata label `app: hello-openshift`. What
*Kinds* of objects are listed?
## Service
* Create a Service object that will redirect traffic internally to the pod.
## Route
* Expose the Service to internet at 'hello-rahti-##.rahtiapp.fi', where ## is
the number of the training account you are holding.
* Secure the route with TLS edge termination policy and redirect
insecure traffic to the secure one.
## Cleanup: DeploymentConfig
* If you remove DeploymentConfig, what will happen to the corresponding ReplicationController and Pods?
* Remove DeploymentConfigs. Did you guess correctly?
* *Bonus*: Why did it happen?
## Cleanup: The rest
* Remove the Route and the Service objects.
# 8. Application data on persistent volume
Pre-requisites: *Exercise 4*
In the following exercises you are expected to modify the YAML specification
directly with the Rahti Application Console. At the Application Console page,
the specification can be found by clicking "Applications → Deployments", then
the name of the Deployment and finally clicking the upper right corner "Actions
→ Edit YAML".
This exercise comprises of three parts:
1. Create and mount a persistent volume with the picture
[https://rahti-course-nov-2019.a3s.fi/kitten.jpg](https://rahti-course-nov-2019.a3s.fi/kitten.jpg)
to the application `hello-flask-#` made in exercise 4 at
`/opt/app-root/src/static`.
Navigate to `http://hello-flask-#-course-training-#.rahtiapp.fi/kitten` and
you should see a kitten.
*Note*: It doesn't matter in which order you mount and copy, as long as you
end up with pods with the file `/opt/app-root/src/static/kitten.jpg`.
*Tip #1*: Storage can be added and mounted to the DeploymentConfig with the
web console.
*Tip #2*: `oc cp kitten.jpg :...` or `oc rsh dc/hello-flask-#` and `curl -L -O `
2. Create a configmap from file `custom.json` with the following contents:
```json
{
"greeting": "Custom Hello from custom.json"
}
*Tip #3*: `oc create configmap ...`
```
Place the custom.json file visible in `/opt/app-root/src/config`.
3. Create a secret and use that secret to bring environment variable
"PASSWORD=secretPassword" to the application.
You may change the password above to your liking.
*Tip #4*: `oc create secret generic ...`
Loading urls http://hello-flask-#-course-training-#.rahtiapp.fi/kitten/ and
http://hello-flask-#-course-training-#.rahtiapp.fi/secret-kitten/secretPassword
(with # being the training account number entered earlier) should now display
kittens.
# 9. Webhook to hello-flask
Pre-requisites: *Exercise 4*.
You can now configure GitHub webhook for your hello-flask application, this
will trigger your application builds automatically when there are push events
in your GitHub code.
Configure a GitHub webhook to the fork repository of rahti-flask-hello you made
earlier in Exercise 4.
* To find out the secret in the webhook payload look at the BuildConfig
of the application: `oc get bc hello-flask-# -o yaml` and look for element
`github.secret` in the array `spec.triggers`, where `#` is your training
account number.
* ***Tip #1***: Get the payload URI w/o the secret with `oc describe bc
rahti-flask-#`.
* Edit app.py: Change line 6 to `DefaultTitle="Application from Student
#"` where # is your training account number.
* Commit changes, verify that new build for your application is triggered in
Rahti.
# 10. BuildConfigs and Triggers
Pre-requisites: *Exercise 1*.
## Inlining Dockerfiles for the base image
Create a BuildConfig inlining the following `Dockerfile` (don't be tempted to
uncomment the `#RUN ...` lines yet)
```Dockerfile
FROM nginx:mainline-alpine
#RUN chmod g+rwX /var/cache/nginx /var/run /var/log/nginx
#RUN chgrp -R root /var/cache/nginx
COPY cfg/default.conf /etc/nginx/conf.d/default.conf
COPY cfg/nginx.conf /etc/nginx/nginx.conf
COPY cfg/index.html /usr/share/nginx/html/index.html
#RUN chmod -R g+rX /etc/nginx/
RUN chmod -R g+rX /usr/share/nginx/html
EXPOSE 8080
```
* Use the ConfigMap listed in file `nginx-config.yaml` to provide the files
`cfg/default.conf`, `cfg/nginx.conf` and `cfg/index.html` to the build context.
* **Bonus**: Create the nginx-config.yaml file by yourself from files under
`cfg/` directory.
* ***Tip #1***: `oc create configmap --from-file=
--from-file= ... --dry-run -o yaml`
* Create an ImageStream object named `my-openshift-nginx` and set the output of
your BuildConfig to ImageStreamTag `my-openshift-nginx:latest`.
* ***Tip #2***: Create skeleton code of the objects with `oc new-build my-bc
--dry-run -o yaml --allow-missing-images -D - > bcs.yaml` and copy-paste the
Dockerfile above and press Control-D.
## Actual website from Github
Fork `github.com/cscfi/rahti-httpd-ex` in GitHub. Add the following Dockerfile
to your fork:
```Dockerfile
FROM my-openshift-nginx:latest
COPY ./ /usr/share/nginx/html/
RUN rm /usr/share/nginx/html/Dockerfile
RUN chmod -R g+rX /usr/share/nginx/html
```
Create a scaffolding for a new application with the following command
```bash
$ oc --name new-app my-static-home https://github.com//rahti-httpd-ex \
--dry-run -o yaml > scaffolding.yaml
```
The file `scaffolding.yaml` will now contain multiple API objects in a *List*
object.
Deploy the objects in `scaffolding.yaml` if it looks okay: `oc create -f scaffolding.yaml`.
The container `my-static-home` should be in a crash-loop right now. The lines
starting with `#RUN ...` in the first Dockerfile should not have be commented
out in the first place after all―the correct Dockerfile looks like be:
```Dockerfile
FROM nginx:mainline-alpine
RUN chmod g+rwX /var/cache/nginx /var/run /var/log/nginx
RUN chgrp -R root /var/cache/nginx
COPY cfg/default.conf /etc/nginx/conf.d/default.conf
COPY cfg/nginx.conf /etc/nginx/nginx.conf
COPY cfg/index.html /usr/share/nginx/html/index.html
RUN chmod -R g+rX /etc/nginx/
RUN chmod -R g+rX /usr/share/nginx/html
EXPOSE 8080
```
Modify the BuildConfig housing Dockerfile defined in the first part in and
rebuild the image in ImageStreamTag `my-openshift-nginx:latest`. ***Tip #3***:
You can modify the Dockerfile directly from the web console: Locate the
BuildConfig and click Actions → Edit.
Once build has been completed, the final application should work and you can
make a Route to it.