Skip to content

Commit b702267

Browse files
committed
SSO integration - Red Hat Container Tools
1 parent 13ed0e5 commit b702267

File tree

13 files changed

+990
-0
lines changed

13 files changed

+990
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
---
2+
slug: 01-overview-container-tools
3+
id: g5dgkjdlk4js
4+
type: challenge
5+
title: An Overview of Container Tools
6+
notes:
7+
- type: text
8+
contents: |
9+
## Background
10+
This lab will help give you a basic understanding of how to use some other OCI compliant tools such as Podman, Buildah, and Skopeo.
11+
12+
By the end of this lab you should be able to:
13+
- FIND, RUN, BUILD, and SHARE containers using OCI compliant tools
14+
- Solve real technical problems by using a small set of daemonless tools
15+
- Be comfortable using with the basics of an alternative set of tools to Docker
16+
17+
## Outline
18+
- Understanding the difference between RHEL Server and CoreOS, as well as the difference between the fast and stable streams provided in RHEL Server
19+
- Understanding how to install the fast and stable streams
20+
- Podman: Familiar Territory: Learning the basics of how to use podman
21+
- Buildah: Granularity & Control: Understanding how a container image is really built
22+
- Skopeo: Moving & Sharing: Simplicity in inspecting, and moving container images around
23+
- CRIU: Checkpoint and restore the memory contents of containers
24+
- Udica: Build and deploy custom SELinux policies for containers
25+
- OSCAP-Podman: verify patched or unpatched vulnerabilities in container images produced by Red Hat
26+
27+
## Other Material
28+
- [Presentation](https://goo.gl/h4VK7j)
29+
- [Lab GitHub Repository](https://github.com/openshift-instruqt/instruqt/tree/3ccc0f45269f895a19406e833392dc9fbc7948d8/instruqt-tracks/subsystems-container-internals-lab-2-0-part-7)
30+
31+
## Start Scenario
32+
Once you have gone through the presentation, continue to the exercises
33+
tabs:
34+
- title: Terminal 1
35+
type: terminal
36+
hostname: rhel
37+
- title: Visual Editor
38+
type: code
39+
hostname: rhel
40+
path: /root
41+
difficulty: intermediate
42+
timelimit: 500
43+
---
44+
In this lab we're going to cover a plethora of container tools available in Red Hat Enterprise Linux (RHEL), including Podman, Buildah, Skopeo, CRIU and Udica. Before we get into the specific tools, it's important to understand how these are tools are provided to the end user in the Red Hat ecosystem.
45+
46+
The RHEL kernel, systemd, and the container tools, centered around github.com/containers and github.com/cri-o/cri-o, serve as the foundation for both RHEL Server as well as RHEL CoreOS. RHEL Server is a flexible, general purpose operating system which can be customized for many different use cases. On the other hand, RHEL CoreOS is a minimal, purpose built operating system intended to be consumed within automated environments like OpenShift. This lab will specifically cover the tools available in RHEL Server, but much of what you learn is useful with CoreOS which is built from the same bits, but packaged specifically for OpenShift and Edge use cases.
47+
48+
Here's a quick overview of how to think about RHEL Server versus RHEL CoreOS:
49+
50+
1. General Purpose: User -> Podman -> RHEL Server
51+
2. OpenShift: User -> Kubernetes API -> Kubelet -> CRI-O -> RHEL CoreOS
52+
53+
In a RHEL Server environment, the end user will create containers directly on the container host with Podman. In an OpenShift environment, the end user will create containers through the Kubernetes API - users generally do not interact directly with CRI-O on individual hosts in the cluster. Stated another way, Podman is the primary container interface in RHEL, while Kubernetes is the primary interface in OpenShift.
54+
55+
For the rest of this lab, we will focus on the container tools provided in RHEL Server. The launch of RHEL8 introduced the concept of [Application Streams](https://www.redhat.com/en/blog/introduction-appstreams-and-modules-red-hat-enterprise-linux), which provide users with access to the latest versions of software like Python, Ruby, and Podman. These Application Streams have different, and often shorter life cycles than RHEL (10+ years). Specifically, RHEL8 Server provides users with two types of Application Streams for Container tools:
56+
57+
1. Fast: Rolling stream which is updated with new versions of Podman and other tools up to every 12 weeks, and only supported until the next version is released. This stream is for users looking for the latest features in Podman.
58+
2. Stable: Traditional streams released once per year, and supported for 24 months. Once released these streams do not update versions of Podman and other tools, and only provide security fixes. This stream is for users looking to put Podman into production depending on stability.
59+
60+
With either stream, the underlying RHEL kernel, systemd, and other packages are treated as a rolling stream. The only choice is is whether to use the fast stream or one of the stable streams. Since RHEL provides a very stable [ABI/API Policy](https://access.redhat.com/articles/rhel8-abi-compatibility) the vast majority of container users will not notice and should not be concerned with kernel, systemd, glibc, etc updates on the container host. If the users selects one of the stable streams, the API to Podman will remains stable and updated for security.
61+
62+
For a deeper dive, check out [RHEL 8 enables containers with the tools of software craftsmanship](https://www.redhat.com/en/blog/rhel-8-enables-containers-tools-software-craftsmanship-0). Now, let's move on to installing and using these different streams of software.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
---
2+
slug: join-red-hat-developer-portal
3+
id: pyxffunx1js2
4+
type: challenge
5+
title: Join Red Hat Developer at no cost
6+
teaser: Join Red Hat Developer at no cost
7+
tabs:
8+
- title: Red Hat Login
9+
type: browser
10+
hostname: rhd-login
11+
difficulty: ""
12+
---
13+
Before you proceed with the next challenge, please take a moment to register for Red Hat Developer. If you already have a Red Hat account, you can use the same login credentials.
14+
15+
This will help us assess user satisfaction and enable us to provide more curated content.
16+
17+
Click on the `Check` button at the bottom once you have registered or logged in.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
#!/bin/bash
2+
set -euxo pipefail
3+
echo 'logincheck'
4+
if [ "${LOGGEDIN-0}" = "1" ]; then
5+
echo 'loggedin'
6+
exit 0
7+
fi
8+
9+
rm -f /home/user/checkResult.json
10+
rm -f /home/user/checkAssets.json
11+
rm -f /home/user/checkError.txt
12+
13+
14+
echo 'dropdown check'
15+
echo '{"location":{"conditions":[{"url":"redhat.com","condition":"contains"}]},"innerText":[{"selector":"html \u003e body","value":"Please click on Check button in the bottom right of your screen to continue with the Lab."}]}' > /home/user/checkAssets.json
16+
until [ -f /home/user/checkResult.json ]; do
17+
sleep 1
18+
done
19+
if grep "SUCCESS" /home/user/checkResult.json; then
20+
echo 'account dropdown'
21+
exit 0
22+
fi
23+
24+
25+
rm -f /home/user/checkResult.json
26+
rm -f /home/user/checkAssets.json
27+
rm -f /home/user/checkError.txt
28+
29+
30+
echo 'email check'
31+
echo '{"location":{"conditions":[]},"innerText":[{"selector":"html \u003e body","value":"Email address verification"}]}' > /home/user/checkAssets.json
32+
until [ -f /home/user/checkResult.json ]; do
33+
sleep 1
34+
done
35+
cat /home/user/checkResult.json
36+
if grep "SUCCESS" /home/user/checkResult.json; then
37+
echo 'email validation'
38+
exit 0
39+
fi
40+
fail-message "Please login and click 'Check' button."
41+
exit 1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
---
2+
slug: 02-different-streams
3+
id: ecpztuba19lq
4+
type: challenge
5+
title: Using the Fast and Stable Streams
6+
tabs:
7+
- title: Terminal 1
8+
type: terminal
9+
hostname: rhel
10+
- title: Visual Editor
11+
type: code
12+
hostname: rhel
13+
path: /root
14+
difficulty: intermediate
15+
timelimit: 600
16+
---
17+
As mentioned in the previous step, there are two main types of streams. To view them, run the following command:
18+
19+
```
20+
yum module list | grep container-tools
21+
```
22+
23+
Notice there are two types:
24+
1. container-tools:rhel8 - this is the fast moving stream, it's updated once every 12 weeks and generally fixes bugs by rolling to new versions
25+
2. container-tools:1.0 - this was released with RHEL 8.0 and supported for 24 months, and receives bug fixes with back ports that keep the API and CLI interfaces stable
26+
3. container-tools:2.0 - this was released with RHEL 8.2 and supported for 24 months, and receives bug fixes with back ports that keep the API and CLI interfaces stable
27+
28+
Now, let's pretend we are developer looking for access to the latest features in RHEL. Let's inspect the description of the fast moving stream. Notice that there are multiple versions of the rhel8 application stream. Every time a package is updated the entire group of packages is version controlled and tested together:
29+
30+
```
31+
yum module info container-tools:rhel8
32+
```
33+
34+
Now, let's install the fast moving container-tools:rhel8 Application Stream like this:
35+
36+
```
37+
yum module install -y container-tools:rhel8
38+
```
39+
40+
We should have a whole set of tools installed:
41+
42+
```
43+
yum module list --installed
44+
```
45+
46+
Look at the packages that were installed as part of this Application Stream:
47+
48+
```
49+
yum module repoquery --installed container-tools
50+
```
51+
52+
Look at the version of Podman that was installed. It should be fairly new, probably within a few months of what's latest upstream:
53+
54+
```
55+
podman -v
56+
```
57+
58+
Let's clean up the environment, and start from scratch:
59+
60+
```
61+
yum module remove -y container-tools
62+
yum module reset -y container-tools
63+
```
64+
65+
OK, now let's pretend we are a systems administrator or SRE that wants a set of stable tools which are supported for 24 months. First, inspect the stable stream that was released in RHEL 8.0. Notice that there are several versions of this Application Stream. Every time a package is updated a new stream version is generated to snapshot the exact versions of each package together as a stream:
66+
67+
```
68+
yum module info container-tools:1.0
69+
```
70+
71+
Now, install it:
72+
73+
```
74+
yum module install -y --allowerasing container-tools:1.0
75+
```
76+
77+
Check the version of Podman again:
78+
79+
```
80+
podman -v
81+
```
82+
83+
Notice that it's an older version of Podman. This version only gets back ports and will never move beyond Podman 1.0.2. Note, there is no connection between the container-tools version number and the Podman version number. It is purely coincidence that these numbers coincide. The container-tools version number is an arbitrary number representing all of the tools tested together in the Application Stream. This includes, Podman, Buildah, Skopeo, CRIU, etc.
84+
85+
Now, let's go back to the latest version of the container-tools for the rest of this module:
86+
87+
```
88+
yum module remove -y container-tools
89+
yum module reset -y container-tools
90+
yum module install -y container-tools:rhel8
91+
```
92+
93+
Notice how easy it was to move between the stable streams and the fast moving stream. This is the power of modularity. Now, let's move on to using the actual tools.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
---
2+
slug: 03-podman
3+
id: poot9tf6vot4
4+
type: challenge
5+
title: 'Podman: Familiar Territory'
6+
tabs:
7+
- title: Terminal 1
8+
type: terminal
9+
hostname: rhel
10+
- title: Visual Editor
11+
type: code
12+
hostname: rhel
13+
path: /root
14+
difficulty: intermediate
15+
timelimit: 500
16+
---
17+
The goal of this lab is to introduce you to Podman and some of the features that make it interesting. If you have ever used Docker, the basics should be pretty familiar. Lets start with some simple commands.
18+
19+
Pull an image:
20+
21+
```
22+
podman pull ubi8
23+
```
24+
25+
List locally cached images:
26+
27+
```
28+
podman images
29+
```
30+
31+
Start a container and run bash interactively in the local terminal. When ready, exit:
32+
33+
```
34+
podman run -it ubi8 bash
35+
```
36+
37+
```
38+
exit
39+
```
40+
41+
List running containers:
42+
43+
```
44+
podman ps -a
45+
```
46+
47+
Now, let's move on to some features that differentiates Podman from Docker. Specifically, let's cover the two most popular reasons - Podman runs with a daemon (daemonless) and without root (rootless). Podman does not have a daemon, it's an interactive command more like bash, and like bash it can be run as a regular user (aka. rootless).
48+
49+
The container host we are working with already has a user called RHEL, so let's switch over to it. Note, we set a couple of environment variables manually because we're using the switch user command. These would normally be set at login:
50+
51+
```
52+
su - rhel
53+
export XDG_RUNTIME_DIR=/home/rhel
54+
```
55+
56+
Now, fire up a simple container in the background:
57+
58+
```
59+
podman run -id ubi8 bash
60+
```
61+
62+
Now, lets analyze a couple of interesting things that makes Podman different than Docker - it doesn't use a client server model, which is useful for wiring it into CI/CD systems, and other schedulers like Yarn:
63+
64+
Inspect the process tree on the system:
65+
66+
```
67+
pstree -Slnc
68+
```
69+
70+
You should see something similar to:
71+
72+
```
73+
└─conmon─┬─{conmon}
74+
└─bash(ipc,mnt,net,pid,uts)
75+
```
76+
77+
There's no Podman process, which might be confusing. Lets explain this a bit. What many people don't know is that containers disconnect from Podman after they are started. Podman keeps track of meta-data in ~/.local/share/containers (/var/lib/containers is only used for containers started by root) which tracks which containers are created, running, and stopped (killed). The meta-data that Podman tracks is what enables a "podman ps" command to work.
78+
79+
In the case of Podman, containers disconnect from their parent processes so that they don't die when Podman exit exits. In the case of Docker and CRI-O which are daemons, containers disconnect from the parent process so that they don't die when the daemon is restarted. For Podman and CRI-O, there is utility which runs before runc called conmon (Container Monitor). The conmon utility disconnects the container from the engine by doing forking twice (called a double fork). That means, the execution chain looks something like this with Podman:
80+
81+
`bash -> podman -> conmon -> conmon -> runc -> bash`
82+
83+
Or like this with CRI-O:
84+
85+
`systemd -> crio -> conmon -> conmon -> runc -> bash`
86+
87+
Or like this with Docker engine:
88+
89+
`systemd -> dockerd -> containerd -> docker-shim -> runc -> bash`
90+
91+
Conmon is a very small C program that monitors the standard in, standard error, and standard out of the containerized process. The conmon utility and docker-shim both serve the same purpose. When the first conmon finishes calling the second, it exits. This disconnects the second conmon and all of its child processes from the container engine. The second conmon then inherits init system (systemd) as its new parent process. This daemonless and simplified model which Podman uses can be quite useful when wiring it into other larger systems, like CI/CD, scripts, etc.
92+
93+
Podman doesn't require a daemon and it doesn't require root. These two features really set Podman apart from Docker. Even when you use the Docker CLI as a user, it connects to a daemon running as root, so the user always has the ability escalate a process to root and do whatever they want on the system. Worse, it bypasses sudo rules so it's not easy to track down who did it.
94+
95+
Now, let's move on to some other really interesting features. Rootless containers use a kernel feature called User Namespaces. This maps the one or more user IDs in the container to one or more user IDs outside of the container. This includes the root user ID in the container as well as any others which might be used by programs like Nginx or Apache.
96+
97+
Podman makes it super easy to see this mapping. Start an nginx container to see the user and group mapping in action:
98+
99+
100+
```
101+
podman run -id registry.access.redhat.com/rhscl/nginx-114-rhel7 nginx -g 'daemon off;'
102+
```
103+
104+
Now, execute the Podman bash command:
105+
106+
```
107+
podman top -l args huser hgroup hpid user group pid seccomp label
108+
```
109+
110+
Notice that the host user, group and process ID ''in'' the container all map to different and real IDs on the host system. The container thinks that nginx is running as the user ''default'' and the group ''root'' but really it's running as an arbitrary user and group. This user and group are selected from a range configured for the ''rhel'' user account on this system. This list can easily be inspected with the following commands:
111+
112+
```
113+
cat /etc/subuid
114+
```
115+
116+
You will see something similar to this:
117+
118+
```
119+
rhel:165536:65536
120+
```
121+
122+
The first number represents the starting user ID, and the second number represents the number of user IDs which can be used from the starting number. So, in this example, our RHEL user can use 65,535 user IDs starting with user ID 165536. The Podman bash command should show you that nginx is running in this range of UIDs.
123+
124+
The user ID mappings on your system might be different because shadow utilities (useradd, usderdel, usermod, groupadd, etc) automatically creates these mappings when a user is added. As a side note, if you've updated from an older version of RHEL, you might need to add entries to /etc/subuid and /etc/subgid manually.
125+
126+
OK, now stop all of the running containers. No more one liners like with Docker, it's just built in with Podman:
127+
128+
```
129+
podman kill --all
130+
```
131+
132+
Remove all of the actively defined containers. It should be noted that this might be described as deleting the copy-on-write layer, config.json (commonly referred to as the Config Bundle) as well as any state data (whether the container is defined, running, etc):
133+
134+
```
135+
podman rm --all
136+
```
137+
138+
We can even delete all of the locally cached images with a single command:
139+
140+
```
141+
podman rmi --all
142+
```
143+
144+
The above commands show how easy and elegant Podman is to use. Podman is like a Chef's knife. It can be used for pretty much anything that you used Docker for, but let's move on to Builah and show some advanced use cases when building container images.

0 commit comments

Comments
 (0)