ℹ️
|
These exercises are an extension of the podman unit and although not required, it is strongly encourage that you complete that unit first.
|
In this unit, we will continue to work with containers and get familiar with Buildah
and Skopeo
.
For these exercises, you will be using the host node3
as user root
.
From host bastion
, ssh to node3
.
ssh node3
Use sudo
to elevate your priviledges.
sudo -i
Verify that you are on the right host for these exercises.
workshop-buildah-checkhost.sh
You are now ready to proceed with these exercises.
In the previous lab on podman
, we pulled down the ubi image and used an OCIFile to build a "webserver" container image. That process used buildah
under the hood, but in this lab we are going to use buildah
directly to create a similar image manually, step by step.
Let’s get started by creating a new working container based off of the ubi image.
buildah from ubi8/ubi
Getting image source signatures Copying blob befb03b11956 done Copying blob ee2244abc66f done Copying config 8121a9f530 done Writing manifest to image destination Storing signatures ubi-working-container
This gives us the name of the "working container" and it is this container image that we will modify with buildah.
Let’s run:
buildah copy ubi-working-container /var/tmp/buildah-dan-cries.txt /var/www/html/dan-cries.txt
34f1621a22ffd90a2ebbd58eba315089dc2704ac69a3d33d60362422e4ec26a1
At this point, you have copied your local dan-cries.txt
into the the ubi-working-container image.
The steps you performed above is equivalent to the following OCIFile (or Dockerfile):
FROM ubi8/ubi COPY /root/dan-cries.txt /var/www/html/
So it’s nice that we can do that with buildah, manually.
But wait there’s more!!!
We need to install an httpd server in our image, and what better way to do that than a simple yum install
.
buildah run ubi-working-container yum install -y httpd
...SNIP... Installed: httpd-2.4.37-16.module+el8.1.0+4134+e6bad0ed.x86_64 apr-util-bdb-1.6.1-6.el8.x86_64 apr-util-openssl-1.6.1-6.el8.x86_64 mailcap-2.1.48-3.el8.noarch redhat-logos-httpd-81.1-1.el8.noarch apr-util-1.6.1-6.el8.x86_64 httpd-tools-2.4.37-16.module+el8.1.0+4134+e6bad0ed.x86_64 apr-1.6.3-9.el8.x86_64 mod_http2-1.11.3-3.module+el8.1.0+4134+e6bad0ed.x86_64 httpd-filesystem-2.4.37-16.module+el8.1.0+4134+e6bad0ed.noarch
Next we set the entry point (command) so when the image deploys it knows what process to launch.
buildah config --cmd "/usr/sbin/httpd -D FOREGROUND" ubi-working-container
Now let us take a peek at our image and validate some of our changes.
Proceed to mount the root filesystem of your container with:
buildah mount ubi-working-container
/var/lib/containers/storage/overlay/3456a159b5b3c9e3056d14b97bde1f0e770500dd1cdd6168c894a52a3b3f12ee/merged
Using the long path provided by your mount command, change directories.
cd /var/lib/containers/storage/overlay/3456a159b5b3c9e3056d14b97bde1f0e770500dd1cdd6168c894a52a3b3f12ee/merged
ls -lah ./var/www/html
total 16K drwxr-xr-x. 2 root root 4.0K Apr 12 21:12 . drwxr-xr-x. 3 root root 4.0K Apr 12 21:12 .. -rw-r--r--. 1 root root 58 Apr 12 21:12 dan-cries.txt
There is our dan-cries.txt
! Let’s add an additional file:
cp /var/tmp/buildah-index.html ./var/www/html/index.html
cat ./var/www/html/index.html
<html> <title>Stop Disabling SELinux</title> <body> <p> Seriously, stop disabling SELinux. Learn how to use it before you blindly shut it off. </p> </body> </html>
Let us just double check contents of the httpd docroot one last time:
ls -lahZ ./var/www/html/
total 20K drwxr-xr-x. 2 root root system_u:object_r:container_file_t:s0:c60,c544 4.0K Apr 12 21:25 . drwxr-xr-x. 3 root root system_u:object_r:container_file_t:s0:c60,c544 4.0K Apr 12 21:12 .. -rw-r--r--. 1 root root system_u:object_r:container_file_t:s0:c60,c544 58 Apr 12 21:12 dan-cries.txt -rw-r--r--. 1 root root system_u:object_r:container_file_t:s0:c60,c544 164 Apr 12 21:24 index.html
When you are done making direct changes to the root filesystem of your container, you can run:
cd /root
buildah unmount ubi-working-container
e918debcaabb5820997b1a4969fbd45284adc0a2869d1f22a1bce78f703ff3c6
At this point, we’ve used buildah to run commands and create a container image similar to those in the OCIFile used in the podman
unit. Go ahead and commit the working container in to an actual container image:
buildah commit ubi-working-container webserver2
Getting image source signatures Copying blob d3ada5af5602 skipped: already exists Copying blob 668db11eda93 skipped: already exists Copying blob 0f75b7e04ec6 done Copying config a831badcea done Writing manifest to image destination Storing signatures a831badcea41e924fd4a37f98431702142c17a64d06bd5444ac4471c1285be50
Let’s look at our images:
podman images
REPOSITORY TAG IMAGE ID CREATED SIZE localhost/webserver2 latest a831badcea41 25 seconds ago 240 MB registry.access.redhat.com/ubi8/ubi latest 8121a9f5303b 12 days ago 240 MB
Finally let’s test our new webserver:
curl http://localhost:8080/
<html> <title>Stop Disabling SELinux</title> <body> <p> Seriously, stop disabling SELinux. Learn how to use it before you blindly shut it off. </p> </body> </html>
and:
curl http://localhost:8080/dan-cries.txt
Every time you run setenforce 0, you make Dan Walsh weep.
As you can see, all of the changes we made with buildah are active and working in this new container image!
Let’s take a look at the webserver2:latest container that we just built:
skopeo inspect containers-storage:localhost/webserver2:latest
{ "Name": "localhost/webserver2", "Digest": "sha256:15ad1feee74c68a16031b2120793873432572d2592e0818bc4cff9842696b651", "RepoTags": [], "Created": "2020-04-13T02:17:40.873320811Z", "DockerVersion": "", "Labels": { "architecture": "x86_64", "authoritative-source-url": "registry.access.redhat.com", "build-date": "2020-03-31T14:54:13.907559", "com.redhat.build-host": "cpt-1007.osbs.prod.upshift.rdu2.redhat.com", "com.redhat.component": "ubi8-container", "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI", "description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "distribution-scope": "public", "io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "io.k8s.display-name": "Red Hat Universal Base Image 8", "io.openshift.expose-services": "", "io.openshift.tags": "base rhel8", "maintainer": "Red Hat, Inc.", "name": "ubi8", "release": "408", "summary": "Provides the latest release of Red Hat Universal Base Image 8.", "url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.1-408", "vcs-ref": "26f36bfa3e3a04c8c866b250924c1aefc34f01c9", "vcs-type": "git", "vendor": "Red Hat, Inc.", "version": "8.1" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:d3ada5af5602bd0da378e4f0144f8fe8bdbe3f5a65f367dd9ebe759756bada68", "sha256:668db11eda933a46ae8030a8643b96088218dae0efeac54bc6dbc88488725c1b", "sha256:d9142adf6c6796bbbccc6065c57508e87138921d3aea0e9fc368f9861606da68" ] }
We will see that this container is based on the Red Hat UBI image.
Let’s look at the ubi8/ubi container that we built this off of and compare the layers section:
skopeo inspect containers-storage:registry.access.redhat.com/ubi8/ubi:latest
{ "Name": "registry.access.redhat.com/ubi8/ubi", "Digest": "sha256:f6648a87c8c52099bacd19b112beb3b65407ae6d3441f9b559ba53c4112c57a4", "RepoTags": [], "Created": "2020-03-31T14:54:42.119985Z", "DockerVersion": "1.13.1", "Labels": { "architecture": "x86_64", "authoritative-source-url": "registry.access.redhat.com", "build-date": "2020-03-31T14:54:13.907559", "com.redhat.build-host": "cpt-1007.osbs.prod.upshift.rdu2.redhat.com", "com.redhat.component": "ubi8-container", "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI", "description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "distribution-scope": "public", "io.k8s.description": "The Universal Base Image is designed and engineered to be the base layer for all of your containerized applications, middleware and utilities. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "io.k8s.display-name": "Red Hat Universal Base Image 8", "io.openshift.expose-services": "", "io.openshift.tags": "base rhel8", "maintainer": "Red Hat, Inc.", "name": "ubi8", "release": "408", "summary": "Provides the latest release of Red Hat Universal Base Image 8.", "url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8/images/8.1-408", "vcs-ref": "26f36bfa3e3a04c8c866b250924c1aefc34f01c9", "vcs-type": "git", "vendor": "Red Hat, Inc.", "version": "8.1" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:ee2244abc66ff9c6a4bf50fe19041fec82a95c87d18ee3a3660368cb274927c7", "sha256:befb03b11956169cf23096fc58081ca35034a6545fc37d63605bf0d200fe5eda" ] }
Comparing the layers section, we can see that our container has 3 layers whereas the original container only has 2 layers. In this, we can tell that there are differences between these containers.
Pretty neat that we can look inside local containers, but what about containers that are in registries? Skopeo can inspect containers on remote registries without the need to pull the image locally. Let’s give that a test:
# skopeo inspect docker://registry.access.redhat.com/ubi8/ubi-minimal:latest
{ "Name": "registry.access.redhat.com/ubi8/ubi-minimal", "Digest": "sha256:df6f9e5d689e4a0b295ff12abc6e2ae2932a1f3e479ae1124ab76cf40c3a8cdd", "RepoTags": [ "8.1", "8.0", "8.1-409-source", "8.0-127", "8.0-204", "8.1-398-source", "8.0-213", "8.0-159", "8.1-328", "8.1-398", "8.1-409", "8.1-407-source", "8.1-407", "8.1-279", "latest", "8.0-131" ], "Created": "2020-03-31T14:52:10.793843Z", "DockerVersion": "1.13.1", "Labels": { "architecture": "x86_64", "authoritative-source-url": "registry.access.redhat.com", "build-date": "2020-03-31T14:51:49.719962", "com.redhat.build-host": "cpt-1002.osbs.prod.upshift.rdu2.redhat.com", "com.redhat.component": "ubi8-minimal-container", "com.redhat.license_terms": "https://www.redhat.com/en/about/red-hat-end-user-license-agreements#UBI", "description": "The Universal Base Image Minimal is a stripped down image that uses microdnf as a package manager. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "distribution-scope": "public", "io.k8s.description": "The Universal Base Image Minimal is a stripped down image that uses microdnf as a package manager. This base image is freely redistributable, but Red Hat only supports Red Hat technologies through subscriptions for Red Hat products. This image is maintained by Red Hat and updated regularly.", "io.k8s.display-name": "Red Hat Universal Base Image 8 Minimal", "io.openshift.expose-services": "", "io.openshift.tags": "minimal rhel8", "maintainer": "Red Hat, Inc.", "name": "ubi8-minimal", "release": "409", "summary": "Provides the latest release of the minimal Red Hat Universal Base Image 8.", "url": "https://access.redhat.com/containers/#/registry.access.redhat.com/ubi8-minimal/images/8.1-409", "vcs-ref": "8c3c7acc321ed054dded6e6e13b5c09c043f42dc", "vcs-type": "git", "vendor": "Red Hat, Inc.", "version": "8.1" }, "Architecture": "amd64", "Os": "linux", "Layers": [ "sha256:b26afdf22be4e9c30220796780a297b91549a3b3041b6fdcbda71bf48a6912e7", "sha256:218f593046abe6e9f194aed3fc2a2ad622065d6800175514dffa55dfce624b56" ] }
The above allows us to look at the registry’s copy of ubi8/ubi.
Next let’s run:
podman images
REPOSITORY TAG IMAGE ID CREATED SIZE localhost/webserver2 latest b660ca86ee4b 7 minutes ago 271 MB registry.access.redhat.com/ubi8/ubi latest 8121a9f5303b 12 days ago 240 MB
Notice that ubi8/ubi-minimal is not local to our registry. Skopeo provided that inspection completely remotely.
Let’s run:
mkdir /root/ubi-tarball
skopeo copy docker://registry.access.redhat.com/ubi8/ubi-minimal:latest dir:/root/ubi-tarball
Getting image source signatures Copying blob b26afdf22be4 done Copying blob 218f593046ab done Copying config 91d23a64fd done Writing manifest to image destination Storing signatures
and now we can do:
cd /root/ubi-tarball
ls -l
total 33888 drwxr-xr-x. 2 root root 4096 Apr 13 09:48 . dr-xr-x---. 5 root root 4096 Apr 13 09:48 .. -rw-r--r--. 1 root root 1529 Apr 13 09:48 218f593046abe6e9f194aed3fc2a2ad622065d6800175514dffa55dfce624b56 -rw-r--r--. 1 root root 4457 Apr 13 09:48 91d23a64fdf259ffce4181b40ce3dafa982a9e4a76ae6a88c1e662c6166c7324 -rw-r--r--. 1 root root 34668948 Apr 13 09:48 b26afdf22be4e9c30220796780a297b91549a3b3041b6fdcbda71bf48a6912e7 -rw-r--r--. 1 root root 737 Apr 13 09:48 manifest.json -rw-r--r--. 1 root root 33 Apr 13 09:48 version
Inspecting the images with the file
command, we discover that these a couple of text file along with a couple of zipped (compressed) tar files.
file *
218f593046abe6e9f194aed3fc2a2ad622065d6800175514dffa55dfce624b56: gzip compressed data, original size 20480 91d23a64fdf259ffce4181b40ce3dafa982a9e4a76ae6a88c1e662c6166c7324: ASCII text, with very long lines b26afdf22be4e9c30220796780a297b91549a3b3041b6fdcbda71bf48a6912e7: gzip compressed data, original size 108462080 manifest.json: ASCII text version: ASCII text
Let’s take a test view of the contents of the largest gzip file (examine "original size"):
# tar tvzf b26afdf22be4e9c30220796780a297b91549a3b3041b6fdcbda71bf48a6912e7
dr-xr-xr-x root/root 0 2020-03-31 10:48 ./ lrwxrwxrwx root/root 0 2018-08-12 05:46 ./lib64 -> usr/lib64 lrwxrwxrwx root/root 0 2018-08-12 05:46 ./lib -> usr/lib drwxr-xr-x root/root 0 2020-03-31 10:48 ./etc/ drwxr-xr-x root/root 0 2020-03-31 10:48 ./etc/libssh/ -rw-r--r-- root/root 178 2019-08-05 10:32 ./etc/libssh/libssh_client.config -rw-r--r-- root/root 179 2019-08-05 10:32 ./etc/libssh/libssh_server.config -rw-r--r-- root/root 22 2019-09-25 14:17 ./etc/issue.net -rw-r--r-- root/root 1498 2019-11-28 12:53 ./etc/nsswitch.conf.bak -rw-r--r-- root/root 55 2020-03-31 10:47 ./etc/resolv.conf drwxr-xr-x root/root 0 2018-08-12 05:46 ./etc/bash_completion.d/ lrwxrwxrwx root/root 0 2018-09-10 10:14 ./etc/rc0.d -> rc.d/rc0.d -rw-r--r-- root/root 9490 2020-03-31 10:48 ./etc/ld.so.cache -rw-r--r-- root/root 58 2018-09-10 07:51 ./etc/networks -rw-r--r-- root/root 1362 2018-09-10 07:51 ./etc/ethertypes ... SNIP...
The output is going to scroll by rather quickly, but just note that this is a complete filesystem for the container image.
ℹ️
|
If you are more curious and would like to inspect the details a little further you could pipe the output to more or less and page through the archive contents. tar tvzf b26afdf22be4e9c30220796780a297b91549a3b3041b6fdcbda71bf48a6912e7 | less
|
The other two numeric files provided in the image download are:
-
a copy of the metadata in text
-
an additional tarball of any container secrets
Lastly, a couple of ASCII text files:
-
oci config info used to build the container
-
version info
-
manifest info
Skopeo can also do the following things:
-
Copy an image (manifest, filesystem layers, signatures) from one location to another. It can convert between manifest types in doing this (oci, v2s1, v2s2)
-
Delete images from registries that you have admin rights to.
-
Push images to registries that you have push rights to.
Examples of how to do these things are available in 'man skopeo'
podman stop --all
podman rm --all
buildah rm --all
podman rmi --all
buildah rmi --all
ℹ️
|
You are not required to reference any additional resources for these exercises. This is informational only. |