Skip to content

Commit 94b3bc3

Browse files
author
abregman
committed
Add new exercises
Also added indexes for AWS and Linux.
1 parent a9dc220 commit 94b3bc3

File tree

13 files changed

+2818
-2457
lines changed

13 files changed

+2818
-2457
lines changed

README.md

Lines changed: 188 additions & 2304 deletions
Large diffs are not rendered by default.

exercises/aws/README.md

Lines changed: 226 additions & 130 deletions
Large diffs are not rendered by default.

exercises/containers/README.md

Lines changed: 128 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,25 +1,27 @@
1-
## Containers
1+
# Containers
22

3-
### Containers Exercises
3+
## Containers Exercises
44

55
|Name|Topic|Objective & Instructions|Solution|Comments|
66
|--------|--------|------|----|----|
77
|Running Containers|Basics|[Exercise](running_containers.md)|[Solution](solutions/running_containers.md)
8-
|Containerized Web Server|Basics|[Exercise](containerized_web_server.md)|[Solution](solutions/containerized_web_server.md)
98
|Working with Images|Image|[Exercise](working_with_images.md)|[Solution](solutions/working_with_images.md)
9+
|Containerized Web Server|Applications|[Exercise](containerized_web_server.md)|[Solution](solutions/containerized_web_server.md)
10+
|Containerized Database|Applications|[Exercise](containerized_db.md)|[Solution](solutions/containerized_db.md)
11+
|Containerized Database with Persistent Storage|Applications|[Exercise](containerized_db_persistent_storage.md)|[Solution](solutions/containerized_db_persistent_storage.md)
1012
|My First Dockerfile|Dockerfile|[Exercise](write_dockerfile_run_container.md)|
1113
|Run, Forest, Run!|Restart Policies|[Exercise](run_forest_run.md)|[Solution](solutions/run_forest_run.md)
1214
|Layer by Layer|Image Layers|[Exercise](image_layers.md)|[Solution](solutions/image_layers.md)
1315
|Containerize an application | Containerization |[Exercise](containerize_app.md)|[Solution](solutions/containerize_app.md)
1416
|Multi-Stage Builds|Multi-Stage Builds|[Exercise](multi_stage_builds.md)|[Solution](solutions/multi_stage_builds.md)
1517

16-
### Containers Self Assessment
18+
## Containers Self Assessment
1719

1820
* [Containers 101](#questions-containers-101)
1921
* [OCI](#questions-oci)
2022
* [Images](#questions-images)
2123
* [Basic Commands](#questions-basic-commands)
22-
* [Volume](#questions-volume)
24+
* [Storage](#questions-containers-storage)
2325
* [Dockerfile](#questions-dockerfile)
2426
* [Architecture](#questions-architecture)
2527
* [Docker Architecture](#questions-docker-architecture)
@@ -29,9 +31,10 @@
2931
* [Docker Networking](#questions-docker-networking)
3032
* [Security](#questions-security)
3133
* [Docker In Production](#questions-docker-in-production)
34+
* [Rootless Containers](#questions-rootless-containers)
3235

3336
<a name="questions-containers-101"></a>
34-
#### Containers 101
37+
### Containers 101
3538

3639
<details>
3740
<summary>What is a Container?</summary><br><b>
@@ -98,7 +101,7 @@ You should choose containers when:
98101
</b></details>
99102

100103
<a name="questions-oci"></a>
101-
#### Containers - OCI
104+
### OCI
102105

103106
<details>
104107
<summary>What is the OCI?</summary><br><b>
@@ -118,7 +121,7 @@ Create, Kill, Delete, Start and Query State.
118121
</b></details>
119122

120123
<a name="questions-images"></a>
121-
#### Containers - Images
124+
### Images
122125

123126
<details>
124127
<summary>What is a container image?</summary><br><b>
@@ -154,7 +157,7 @@ docker.io docker.io/rahulgadre/snake-game
154157
<details>
155158
<summary>How to list the container images on certain host?</summary><br><b>
156159

157-
CONTAINER_BINARY=podman # or docker
160+
CONTAINER_BINARY=podman
158161
$CONTAINER_BINARY images
159162
```
160163
@@ -165,7 +168,7 @@ Note: you can also use `$CONTAINER_RUNTIME image ls`
165168
<summary>How to download/pull a container image without actually running a container?</summary><br><b>
166169
167170
```
168-
CONTAINER_BINARY=podman # or docker
171+
CONTAINER_BINARY=podman
169172
$CONTAINER_BINARY pull rhel
170173
```
171174
</b></details>
@@ -375,7 +378,7 @@ Cons:
375378
</b></details>
376379
377380
<a name="questions-basic-commands"></a>
378-
#### Containers - Basic Commands
381+
### Basic Commands
379382
380383
<details>
381384
<summary>How to list all the containers on a given host?</summary><br><b>
@@ -437,18 +440,73 @@ With the -d flag. It will run in the background and will not attach it to the te
437440
`docker container run -d httpd` or `podman container run -d httpd`
438441
</b></details>
439442
443+
<details>
444+
<summary>If you'll run <code>sleep 100</code> inside a container, will you see it when listing all the processes of the host on which the container runs? Why?</summary><br><b>
445+
</b></details>
446+
447+
<details>
448+
<summary>True or False? If image <code>httpd-service</code> has an entry point for running the httpd service then, the following will run the container and eventually the httpd service <code>podman run httpd-service ls</code></summary><br><b>
449+
450+
False. Running that command will override the entry point so the httpd service won't run and instead podman will run the `ls` command.
451+
</b></details>
452+
453+
<details>
454+
<summary>True or False? Running <code>podman restart CONTAINER_NAME</code> kills the main process inside the container and runs it again from scratch</summary><br><b>
455+
456+
False. `podman restart` creates an entirely new container with the same ID while reusing the filesystem and state of the original container.
457+
</b></details>
458+
459+
<a name="questions-containers-storage"></a>
460+
### Storage
461+
462+
<details>
463+
<summary>Container storage is said to be ephemeral. What does it mean?</summary><br><b>
464+
465+
It means the contents of the container and the data generated by it, is gone when the container is removed.
466+
</b></details>
467+
468+
<details>
469+
<summary>True or False? Applications running on containers, should use the container storage to store persistent data</summary><br><b>
470+
471+
False. Containers are not built to store persistent data and even if it's possible with some implementations, it might not perform well in case of applications with intensive I/O operations.
472+
</b></details>
473+
474+
<details>
475+
<summary>You stopped a running container but, it still uses the storage in case you ever resume it. How to reclaim the storage of a container?</summary><br><b>
440476
441-
<a name="questions-volume"></a>
442-
#### Containers - Volume
477+
In order to reclaim the storage of a container, you have to remove it.
478+
</b></details>
443479
444480
<details>
445481
<summary>How to create a new volume?</summary><br><b>
446482
447-
`docker volume create some_volume`
483+
```
484+
CONTAINER_BINARY=podman
485+
$CONTAINER_BINARY volume create some_volume
486+
```
487+
</b></details>
488+
489+
<details>
490+
<summary>How to mount a directory from the host to a container?</summary><br><b>
491+
492+
```
493+
CONTAINER_BINARY=podman
494+
mkdir /tmp/dir_on_the_host
495+
496+
$CONTAINER_BINARY run -v /tmp/dir_on_the_host:/tmp/dir_on_the_container IMAGE_NAME
497+
```
498+
499+
In some systems you'll have also to adjust security on the host itself:
500+
501+
```
502+
podman unshare chown -R UID:GUID /tmp/dir_on_the_host
503+
sudo semanage fcontext -a -t container_file_t '/tmp/dir_on_the_host(/.*)?'
504+
sudo restorecon -Rv /tmp/dir_on_the_host
505+
```
448506
</b></details>
449507
450508
<a name="questions-dockerfile"></a>
451-
#### Containers - Dockerfile
509+
### Dockerfile
452510
453511
<details>
454512
<summary>What is a Dockerfile?</summary><br><b>
@@ -539,7 +597,7 @@ Instructions such as ENTRYPOINT, ENV, EXPOSE, create image metadata and they don
539597
</b></details>
540598
541599
<a name="questions-architecture"></a>
542-
#### Containers - Architecture
600+
### Architecture
543601
544602
<details>
545603
<summary>How container achieve isolation from the rest of the system?</summary><br><b>
@@ -613,8 +671,14 @@ Multiple namespaces: pid,net, mnt, uts, ipc, user
613671
* SElinux
614672
</b></details>
615673
674+
<details>
675+
<summary>True or False? Containers have ephemeral storage layer</summary><br><b>
676+
677+
True. The ephemeral storage layer is added on top of the base image layer and is exclusive to the running container. This way, containers created from the same base image, don't share the same storage.
678+
</b></details>
679+
616680
<a name="questions-docker-architecture"></a>
617-
#### Containers - Docker Architecture
681+
### Docker Architecture
618682
619683
<details>
620684
<summary>Which components/layers compose the Docker technology?</summary><br><b>
@@ -791,7 +855,7 @@ Because each container has its own writable container layer, and all changes are
791855
</b></details>
792856
793857
<a name="questions-docker-compose"></a>
794-
#### Containers - Docker Compose
858+
### Docker Compose
795859
796860
<details>
797861
<summary>Explain what is Docker compose and what is it used for</summary><br><b>
@@ -810,7 +874,7 @@ In general, it's useful for running applications which composed out of several d
810874
</b></details>
811875
812876
<a name="questions-docker-images"></a>
813-
#### Containers - Docker Images
877+
### Docker Images
814878
815879
<details>
816880
<summary>What is Docker Hub?</summary><br><b>
@@ -867,7 +931,7 @@ By default, Docker uses everything (all the files and directories) in the direct
867931
</b></details>
868932
869933
<a name="questions-networking"></a>
870-
#### Containers - Networking
934+
### Networking
871935
872936
<details>
873937
<summary>What container network standards or architectures are you familiar with?</summary><br><b>
@@ -880,7 +944,7 @@ CNI (Container Network Interface):
880944
</b></details>
881945
882946
<a name="questions-docker-networking"></a>
883-
#### Containers - Docker Networking
947+
### Docker Networking
884948
885949
<details>
886950
<summary>What network specification Docker is using and how its implementation is called?</summary><br><b>
@@ -916,7 +980,7 @@ True. An endpoint can connect only to a single network.
916980
</b></details>
917981
918982
<a name="questions-security"></a>
919-
#### Containers - Security
983+
### Security
920984
921985
<details>
922986
<summary>What security best practices are there regarding containers?</summary><br><b>
@@ -937,7 +1001,7 @@ True. An endpoint can connect only to a single network.
9371001
</b></details>
9381002
9391003
<a name="questions-docker-in-production"></a>
940-
#### Containers - Docker in Production
1004+
### Docker in Production
9411005
9421006
<details>
9431007
<summary>What are some best practices you following in regards to using containers in production?</summary><br><b>
@@ -973,3 +1037,44 @@ Restart Policies. It allows you to automatically restart containers after certai
9731037
* no: don't restart the container at any point (default policy)
9741038
* on-failure: restart the container when it exists due to an error (= exit code different than zero)
9751039
</b></details>
1040+
1041+
<a name="questions-rootless-containers"></a>
1042+
1043+
<details>
1044+
<summary>Explain Rootless Containers</summary><br><b>
1045+
1046+
Historically, user needed root privileges to run containers. One of the most basic security recommendations is to provide users with minimum privileges for what they need.
1047+
1048+
For containers it's been the situation for a long time and still for running some containers today from docker.io, you'll need to have root privileges.
1049+
</b></details>
1050+
1051+
<details>
1052+
<summary>Are there disadvantages in running rootless containers?</summary><br><b>
1053+
1054+
Yes, the full list can be found [here](https://github.com/containers/podman/blob/main/rootless.md).
1055+
1056+
Some worth to mention:
1057+
1058+
- No binding to ports smaller than 1024
1059+
- No images sharing CRI-O or other rootful users
1060+
- No support running on NFS or parallel filesystem homerdirs
1061+
- Some commands don't work (mount, podman stats, checkpoint, restore, ...)
1062+
</b></details>
1063+
1064+
<details>
1065+
<summary>Give one example of rootless containers are more safe from security perspective</summary><br><b>
1066+
1067+
In rootless containers, user namespace appears to be running as root but it doesn't, it's executed with regular user privileges. If an attacker manages to get out of the user space to the host with the same privileges, there's not much he can do because it's not root privileges as opposed to containers that run with root privileges.
1068+
</b></details>
1069+
1070+
<details>
1071+
<summary>When running a container, usually a virtual ethernet device is created. To do so, root privileges are required. How is it then managed in rootless containers?</summary><br><b>
1072+
1073+
Networking is usually managed by Slirp in rootless containers. Slirp creates a tap device which is also the default route and it creates it in the network namepsace of the container. This device's file descriptor passed to the parent who runs it in the default namespace and the default namespace connected to the internet. This enables communication externally and internally.
1074+
</b></details>
1075+
1076+
<details>
1077+
<summary>When running a container, usually a layered file system is created, but it requires root privileges. How is it then managed in rootless containers?</summary><br><b>
1078+
1079+
New drivers were created to allow creating filesystems in a user namespaces. Drivers like the FUSE-OverlayFS.
1080+
</b></details>
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
## Containerized DB
2+
3+
1. Run a container with a database of any type of you prefer (MySql, PostgreSQL, Mongo, etc.)
4+
2. Verify the container is running
5+
3. Access the container and create a new table (or collection, depends on which DB type you chose) for students
6+
4. Insert a row (or document) of a student
7+
5. Verify the row/document was added
8+
9+
Click [here for the solution](solutions/containerized_db.md)
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
# Containerized DB with Persistent Storage
2+
3+
1. Run a container with a database of any type of you prefer (MySql, PostgreSQL, Mongo, etc.)
4+
1. Use a mount point on the host for the database instead of using the container storage for that
5+
2. Explain why using the host storage instead of the container one might be a better choice
6+
2. Verify the container is running

exercises/containers/containerized_web_server.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,3 +3,5 @@
33
1. Run a containerized web server in the background and bind its port (8080) to a local port
44
2. Verify the port (8080) is bound
55
3. Reach the webserver from your local host
6+
7+
Click [here for the solution](solutions/containerized_web_server.md)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
# Containerized DB
2+
3+
1. Run a container with a database of any type of you prefer (MySql, PostgreSQL, Mongo, etc.)
4+
2. Verify the container is running
5+
3. Access the container and create a new table (or collection, depends on which DB type you chose) for students
6+
4. Insert a row (or document) of a student
7+
5. Verify the row/document was added
8+
9+
10+
## Solution
11+
12+
```
13+
# Run the container
14+
podman run --name mysql -e MYSQL_USER=mario -e MYSQL_PASSWORD=tooManyMushrooms -e MYSQL_DATABASE=university -e MYSQL_ROOT_PASSWORD=MushroomsPizza -d mysql
15+
16+
# Verify it's running
17+
podman ps
18+
19+
# Add student row to the database
20+
podman exec -it mysql /bin/bash
21+
mysql -u root
22+
use university;
23+
CREATE TABLE Students (id int NOT NULL, name varchar(255) DEFAULT NULL, PRIMARY KEY (id));
24+
insert into Projects (id, name) values (1,'Luigi');
25+
select * from Students;
26+
```
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
# Containerized DB with Persistent Storage
2+
3+
1. Run a container with a database of any type of you prefer (MySql, PostgreSQL, Mongo, etc.)
4+
1. Use a mount point on the host for the database instead of using the container storage for that
5+
2. Explain why using the host storage instead of the container one might be a better choice
6+
2. Verify the container is running
7+
8+
9+
## Solution
10+
11+
```
12+
# Create the directory for the DB on host
13+
mkdir -pv ~/local/mysql
14+
sudo semanage fcontext -a -t container_file_t '/home/USERNAME/local/mysql(/.*)?'
15+
sudo restorecon -R /home/USERNAME/local/mysql
16+
17+
# Run the container
18+
podman run --name mysql -e MYSQL_USER=mario -e MYSQL_PASSWORD=tooManyMushrooms -e MYSQL_DATABASE=university -e MYSQL_ROOT_PASSWORD=MushroomsPizza -d mysql -v /home/USERNAME/local/mysql:/var/lib/mysql/db
19+
20+
# Verify it's running
21+
podman ps
22+
```
23+
24+
It's better to use the storage host because in case the container ever gets removed (or storage reclaimed) you have the DB data still available.

0 commit comments

Comments
 (0)