Skip to content
CBT Nuggets
DemoBook a Demo

Running Containers with Podman

This skill focuses on using Podman to manage containers, highlighting key operations such as starting, stopping, and executing commands within containers. It delves into the concept of namespaces, which provide isolation for containers, and explores the differences between root and rootless containers. Additionally, the skill covers port mapping to expose container services to external users, emphasizing practical command-line usage for effective container management.

Full skill from Red Hat Certified Specialist in Containers. Preview the IT training 23,000+ organizations trust.

45m

Skill 2 of 8 in Red Hat Certified Specialist in Containers

Introduction

Let's discuss what we plan to learn in this skill!

Starting and Stopping Containers

It's not enough to simply pull container images on to the local system. Rather, we must learn how to actually spawn and manage instances from those images! As such, in this video we learn how to use "podman" to start and stop our containers! Check it out!

Knowledge Check

What command is used to run a container in detached mode using Podman?

Knowledge Check

Which of the following commands are used with Podman to manage container instances? (Select three)

Interactive Shells & Executing Commands

Now that we have the very basics of running containers under our belt, let's explore some more commands. In this video we learn how to create an interactive sessions with our containers. This allows us to navigate the containers inner filesystem via a TTY shell. Once we've done that, we then explore how to execute commands against our containers. Moreover, we also compare the subtle differences between the podman "run" and "exec" commands!

Knowledge Check

What is the primary difference between the 'podman run' and 'podman exec' commands?

Knowledge Check

Which of the following statements about Podman commands are true?

Knowledge Check

Match the Podman commands with their descriptions.

This interactive assessment is available in the full learning experience.

Want to answer questions like this yourself?
with no purchase required. Already have an account?

Namespaces

One of the hallmarks of containerisation is isolation. This ensures that the containers run in a secure fashion. The way this isolation is implemented is via the use of namespaces. However, there are different types of namespaces for different purposes. In this video we discuss namespaces for users, processes, networking and more!

Knowledge Check

Which namespace provides isolation for User IDs in a container?

Knowledge Check

Which of the following namespaces provide isolation in containerization? (Choose three)

Running Containers from Root

Previously we learned how to open an interactive TTY session within our containers created by non-privileged users. However, we noticed that the user account inside the container happened to be "root". Due to user namespaces, however, this is not a security concern. In this video, we turn our attention to the differences we can expect to see when we do in fact run containers from a privileged account on the host machine. Let's discuss the details!

Knowledge Check

Running a container with elevated privileges using Podman results in the container having its own IP address.

Knowledge Check

Which of the following statements are true about running containers with Podman as a privileged user versus a non-privileged user?

Exposing Ports

By default, external users will not be able to access our running containers. For example, it doesn't make much sense to run an nginx container...that cannot receive any traffic. As such we have to find a way to expose the inner workings of the container. In this video we discuss how port-mapping works and highlight some of the differences between root and rootless containers in this context.

Knowledge Check

What is the correct way to expose a container's internal port to an external port on the host system using Podman?

Knowledge Check

Match the Podman command components with their descriptions.

This interactive assessment is available in the full learning experience.

Want to answer questions like this yourself?
with no purchase required. Already have an account?

Knowledge Check

True or False: By default, external users can access running containers without any additional configuration.

Validation

Let's now validate what we've learned in this skill!

Instructions:

1) Use podman to search for all available nginx images, make note of the Fully Qualified Container name of the image sourced from the Docker Hub registry and download it.

2) Create a new container instance from this image and ensure that you leave your terminal environment free to run commands after its creation.

3) List your running containers. Stop the container using the unique container ID.

4) Show the new status of this container.

5) Start the container again using its unique container name. Execute the command "ls" against the "/etc" directory inside of the running container.

6) Ensure that external users on the system are able to access a containerised nginx server over port 1002.

7) Finally, ensure all containers are removed.

Check out the video solution below:

Knowledge Check

Which task do you find the most challenging?

This interactive assessment is available in the full learning experience.

Want to answer questions like this yourself?
with no purchase required. Already have an account?

View Transcript

Introduction

0:00Hey friends and welcome back to another skill.

0:02So on this skill right here, what we're going to be doing is looking at Podman

0:06with a little bit more detail.

0:08We'll get to see how we can start containers, how we can stop containers.

0:11We will discuss the differences between namespaces and containerization.

0:16And we'll also look at how we can actually access our containers via port

0:19mapping.

0:20So with that said, let's just get to it.

Starting and Stopping Containers

0:00Alright friends, so let's begin doing some of the fun stuff, actually working

0:04with Podman

0:05directly on the command line and getting it to the nitty gritty.

0:08So with that said, let's dive in then.

0:11Now in the previous skill, we happened to learn how we could ultimately pull

0:15down an

0:16image from a registry, meaning that we essentially had a local copy of this

0:20image, and we also

0:21discussed the difference between what is actually a container image versus what

0:26is a container

0:27instance.

0:28In the previous skill, we were able to pull down an image, but as we remember,

0:32this is

0:33not actually a running container.

0:34Rather, this is just a blueprint that we can use to actually go and create

0:38these real running

0:39instances.

0:40So there actually are a few commands that we want to learn about.

0:43So the first command we're going to be looking at is the run command.

0:47You can imagine what this actually does.

0:49This is essentially going to allow us to run a container, basically create an

0:54instance

0:54from the image.

0:56So pop quiz, can you remember the command that we can use to actually see the

1:00available

1:01images that we have on the system?

1:02Well, if you say Podman images, that is the correct answer.

1:06Now right now I have a clean system all my previous images have been removed.

1:11So in order to retrieve an image, what we will do is just simply say Podman

1:14pull, and

1:15I'll just say engine X remember, because we have to specify the fully qualified

1:18container

1:19name, we're going to have to be much more explicit about where it is we want to

1:23get

1:23this particular image.

1:25So in my case here, let's go with Docker, so go down here.

1:28And as we can see, we're now beginning to pull in that image.

1:32Okay, so let's just say Podman images once more.

1:35Now we can see we do have this image.

1:37Let's actually create a running instance of that image.

1:40So first thing, let me show you if I just say Podman run, and then what I can

1:44do is

1:45I can give the name of the image itself.

1:47Now if I just happen to say engine X right here, okay, so look what's happened.

1:51We have essentially spun up that instance of the image, but this is kind of

1:55ugly.

1:56We have essentially lost control over our terminal.

1:58See this?

1:59So first thing that I want to do, let me just press control C to stop this.

2:03And that's going to exit.

2:04Instead what I will do is I will say Podman run dash D, and then I can specify

2:10the name

2:10of the image that I want to use.

2:12Now if I try this, things look a little bit different.

2:16So what I've actually done here is by specifying the dash D flag, this actually

2:20means that

2:20we're going to be running in detached mode.

2:23Essentially, this is going to allow us to keep control of our terminal window.

2:27And simple terms, we are essentially running the container in the background.

2:30Alrighty, so let's see if we can actually verify if the container is running.

2:34So what I will do here is I will say Podman, and then I will say PS.

2:38This allows me to see any running container instances, okay?

2:41Now you're going to have to excuse the ugly line wrapping, just let me zoom out

2:44a little

2:44bit.

2:45Let me talk you through some of what we're actually seeing here.

2:47What we can see here is the actual image we have used.

2:49The instance is based off this blueprint, as we discussed.

2:52And we actually see this command right here.

2:55And quite simply, this is a command that's going to automatically run when the

2:58instance

2:59is spun up.

3:00This is kind of hard coded within to the image itself.

3:02Now we see here when the instance was created about a minute ago, and the

3:06status tells us

3:08that it has been running for just about a minute.

3:10Now, very important point here, but see, we actually have the container ID as

3:15well as

3:15the names, both of these can be used to uniquely identify the container

3:20instance.

3:21So you can effectively reference this running instance via this container ID,

3:25which is a

3:26little bit harder to remember.

3:27But we also have this name here, Dreamy Heisenberg, that has been auto

3:31generated.

3:32This is not something that I have created.

3:34You get these weird and wonderful combinations popping up, and they just happen

3:37to be a little

3:37bit more memorable.

3:39Just makes it easier to remember the container you're working with, as opposed

3:42to the strength

3:43of alpha numeric characters.

3:44Now, just to prove that the container instance actually is working, so if I

3:49just say Podman

3:50P.S. again, we can see here, indeed, the container has been running for five

3:53minutes

3:54at this stage.

3:55And if I just leave this container alone, it's just going to continually run

3:59and run.

4:00So what I can do is I can also stop that container.

4:04The way we do this is unlike Podman Run, this time we say Podman stop, and we

4:08're going

4:08to have to uniquely reference the container we want to stop.

4:12Now, we know we have two different ways we can identify this.

4:15I can just grab this little container ID right here.

4:19So let's copy this, and then I can paste this in and to enter, and then we get

4:23this

4:23response back.

4:24And if I say Docker P.S.

4:26We actually see here I no longer have any running containers.

4:29But here's the thing, the container actually does still exist on the system.

4:33And in fact, we can restart it.

4:35So right now I don't have any containers in the running states.

4:38But if I do Podman P.S. dash a for all, we can see containers that were perhaps

4:43stopped

4:43or previously exited or crash that type of things.

4:46If I hit enter here, and I just zoom out a little bit, as you can see right

4:50here, we

4:51have the container name all the same information we can see when it was created

4:54seven minutes

4:54ago, and we can see its status right now it is exited and exited about a minute

5:00ago.

5:01That was because we said Podman our aim with the container ID, but that

5:04container still

5:05does exist.

5:06So if I want to start it up once again, what I could do, just zoom in a little

5:10bit again,

5:11let's just copy this once more, and we'll just say Podman starts and paste this

5:17in.

5:17Now we get the response.

5:18If I just say Podman P.S. the regular command and to enter, we can now see the

5:23status is

5:23up once more.

5:24So that's how we can start and stop the containers utilizing our container ID.

5:29Let's actually try the container name we have this, a dreamy Heisenberg right

5:32here.

5:32So let's copy this.

5:33And if I just say Podman stop and then just reference the name itself, enter,

5:38we see the

5:39response.

5:40If I now say Podman P.S. everything is now empty.

5:43If I say Podman P.S.

5:45Dash A, we can see it just exited eight seconds ago because we stopped it.

5:49And once again, if you want to restart, we can say Podman start this time, I

5:53suppose

5:53using the container ID, we use the container name, and again Podman P.S. we can

5:59indeed

5:59see that the status is back up and running two seconds ago.

Interactive Shells & Executing Commands

0:00So friends, let's continue on exploring the Podman command line interface.

0:04So to demonstrate this next one, what I will do is I will go to Docker Hub,

0:08okay?

0:08And let me just search for an Ubuntu image.

0:11This is a Linux container, okay?

0:13And if I just copy this here, what I'll do is go to my terminal.

0:16Let me just go to the beginning, change the Docker to be Podman.

0:19Like I said, the commands are pretty much exactly the same.

0:22And I'll just give the fully qualified container name of Docker I/O forward

0:26slash library,

0:27and then Ubuntu. And I can even add on, let's just say the latest tag to be

0:31super explicit.

0:32If I hit enter, I'm now going to begin pulling in this image.

0:35And now if I say Podman images, we see we also have this Ubuntu image.

0:40So if I say Podman PS, as we can see, we don't have any running instance of the

0:45Ubuntu image.

0:46Now let me just show you what happens here.

0:47If I say Podman, and I try to run this in detached mode and let's just go with

0:52Ubuntu.

0:53If I hit enter, seems like we have a success, however, if I say Podman PS,

0:58we still don't actually see the running instance.

1:00If I do Podman PS dash a, we actually see here that it did begin to run nine

1:07seconds ago,

1:08but also just exited.

1:10Now because this particular container is an Ubuntu operating system,

1:14there is no particular process like a shell or a web server that is going to

1:18keep

1:19the actual container running. Well, what's going to happen is it's going to

1:23spin up,

1:23have nothing to do, and then just will stop.

1:27So what I want to highlight to you is the ability for us to create an

1:30interactive

1:31TTY session with our container. Let me show you what I mean.

1:35So again, Podman PS, not Ubuntu running.

1:38If I say Podman run, and I say dash IT for interactive TTY, and then Ubuntu,

1:47if I hit enter, look what actually happens, something very, very different.

1:51Look at the prompt, we actually are within the container itself.

1:54Now we'll talk about this more in a little bit more detail very, very shortly,

1:57but for now,

1:58notice I basically have access within the container itself.

2:01This is the file system, the Ubuntu file system inside of this container.

2:06So let's maybe see if I go to the home directory and I create a little file,

2:09let's just say this is a test file and I redirect into file.txt.

2:15If I do an LS, we can see this file.

2:18And if I say catfile.txt, indeed, we have modified the contents within this

2:22particular

2:23container. Again, we have this interactive ability to basically just walk

2:27through this

2:28particular operating system as we ordinarily would within the confines of a

2:32container.

2:33Now again, let me just go back or just to Podman PS.

2:37Notice because I've actually exited the TTY session, what has actually happened

2:41is the

2:41container itself has actually stopped. There is no more shell running.

2:45So if I say PS-A, as we can see this previous Ubuntu image that I just span up,

2:50now just exited. Now, very important point.

2:53This particular command, the run command, this is going to allow us to build

2:57and run a brand

2:59new instance from an image. As we see, we have different options,

3:02detach mode, we can drop straight into an interactive TTY session, but it's

3:06still with

3:06this particular command. What if we have an all ready running container

3:11instance?

3:12Well, if it's already running, we don't have to spin up another instance from

3:16the same image.

3:17Instead, we want to be able to execute commands against this already running

3:21container.

3:22And this is what we're going to talk about next.

3:24This is the exact command. And this is what it allows you to do.

3:27So let me give you an example. Let's do Podman PS-A.

3:31As we can see, we have this particular container that has exited.

3:34If I want to start it up, again, we're not spinning up a new one.

3:37We're starting up a previously exited one. We can use the start command.

3:41And if I enter, watch what happens. Okay, we get the output.

3:44So now if I say Podman PS, we can see that it is. It is now running.

3:48However, let's say I wanted to get that interactive TTY session against this

3:53all ready running container.

3:54Well, what are we going to do? I will say Podman exec-it.

3:59And then I can specify the container that I want to be targeting.

4:02So let's grab the container name. Again, you can use a container ID,

4:05the alphanumeric characters. But in this case, yeah, that's simpler.

4:08Let's go with this. And notice we actually have an error.

4:11This is very, very good to note. When it comes to using the exact command,

4:15we also want to specify the command we want to be executing.

4:18So let's just say Podman exec, and I'll say -it, paste in the container name.

4:25And then also I want to execute a bin basher.

4:28So if I enter, look at this right here.

4:30We have now got access once again inside of that container.

4:34But the difference is this time it wasn't already running container.

4:37So once again, if I exit out Podman PS, notice this time, once we exit the

4:43shell after the exact

4:44command, the status is still up. See that? Now, one thing we can also do is we

4:49can also say Podman

4:50exec and just execute a regular command as you so wish that if I just grabbed

4:54the name

4:55of the container ID right here, paste you in, and just maybe say ls -l.

5:01If I enter, look at this right here.

5:03What we're actually seeing here is the contents within the container.

5:06We have executed the ls -l command at the roots.

5:10Similarly for adderwup, and I maybe just say who am I?

5:14Notice inside the container, I'm not the test user.

5:17I am the roots again. We'll talk about this very, very shortly.

5:20But quite simply, we have the ability to freely execute commands.

5:23So I could run the cat commands and remember inside the home directory,

5:26I did actually create a file called wlfail.txt if I had answer.

5:30As we can see here, I ran the command inside the container and this is the

5:34contents.

Namespaces

0:00So I've actually bumped up against a very important concept,

0:03I think containerization known as namespaces.

0:06You might not have realized that, but yup indeed,

0:08we have indeed seen these namespaces in action.

0:11So at its core, what a namespace is going to allow us to do,

0:14it's going to provide a level of isolation

0:16for the container itself.

0:18This is very, very important.

0:20Quite simply, when we happen to start a container with Podman,

0:24the container started with a particular user.

0:27It's going to run in a particular user namespace.

0:29This is where the isolation is happening.

0:31Let me briefly show you what I mean.

0:32Right now, who am I?

0:34We can see I am the test user.

0:36Whereas if I say Podman, run and let's grab an interactive

0:40TTY session, let's use the Ubuntu image.

0:43And if I hit enter, I now say who am I?

0:46Well, it says I am the root account.

0:48Now by virtue of us accessing the root account within this

0:51container, it does not actually mean any type of security

0:54compromise on the host itself.

0:56After all, we are a regular user.

0:58We did not use any elevated privileges.

1:01We shouldn't have access to a root account that could really

1:04affect the main system that the container is running within.

1:08And like I say, namespace is how we actually manage this.

1:12Quite simply, it provides isolation for the user ID.

1:15Now the user namespace is providing isolation

1:18for this particular component.

1:20But with respect to containers, there actually

1:22is a lot more things to consider.

1:24And honestly, the user namespace

1:26did not provide isolation for absolutely everything.

1:29It's just targeting this particular thing.

1:31So we also have other namespaces.

1:33And I just want to highlight some of the most important ones.

1:36One would be the PID namespace.

1:40And this is the process ID namespace.

1:43Essentially, this is going to allow us to isolate.

1:45Once again, it's all about isolation.

1:47Just a different thing about isolating.

1:49This time we are isolating the process IDs from the host

1:53and inside of the containers themselves.

1:55Because quite simply, if we only just use the user namespace--

1:59and that was only separation and isolation

2:01we had-- processes running inside the container,

2:04such as the engine X server running inside the container,

2:07that could actually see other processes running

2:10on the host system itself, which means they

2:12have the ability to maybe affect those processes.

2:15All right, so namespace for users,

2:17namespace for processes.

2:19What is the next one?

2:20Well, we also have a namespace known as the network namespace.

2:24So the previous solutions for isolation

2:25did not isolate things such as IP addresses.

2:28Nor does it isolate interfaces between the containers

2:31and the actual host, whereas the network namespace

2:34is going to do this.

2:35So that means that the host machine, once again,

2:37is going to have a strong level of protection

2:39between the networking within the container itself.

2:42If you can imagine the container that you happen to spin up

2:44had some type of vulnerability with respect to its networking

2:48and it could also communicate and freely interact

2:51with the host machine.

2:52But then once again, it could potentially endanger

2:56the actual host itself.

2:57Now, we also have something known as a mount namespace.

3:00This is related to the accessibility of files

3:03on the file system.

3:04So imagine you had some type of host machine,

3:06let's just say it is Red Hat Enterprise Linux on that system.

3:09There is going to be a file system with all the directories,

3:11such as the Etsy directory, the Dev directory, so on and so

3:14forth.

3:15And if we spin up a container on this host system,

3:18we don't necessarily just want the ability for the container

3:21to just write in and modify particular files

3:24within these different directories.

3:26That is obviously a potential security issue once again.

3:28So now we have just briefly skimmed the subject of namespaces.

3:31We understand that it's going to provide isolation

3:33in many different forms.

3:35What I want to do now is to take some of that information

3:37and apply it and see how containers act

3:40when they are run with a regular account

3:42versus when they are run via a root account.

Running Containers from Root

0:00Alright friends, we've now just talked about the concept of namespaces. Let's

0:03look at the

0:04running of our containers as a privilege user versus a non-privileged regular

0:09user.

0:09So remember in the previous skill when we talked about Docker, Docker by

0:13default is going to require

0:14elevated privileges in order to be able to run and manage our containers due to

0:18the architecture

0:19of utilizing demons. And by having to invoke sudo to run these Docker commands,

0:24well it does

0:24present this security concern. That said, as we know Podman allows us to run

0:29containers as a

0:31non-privileged user, but that doesn't mean that Podman does not also have the

0:35ability to also

0:36invoke the sudo command. So we just want to look at some of the differences of

0:40how these two

0:41implementations operate. So let me just say sudo, Podman, I'm going to run in

0:46detached mode and

0:47let's just take my engine X server case. We'll spin up a new instance from this

0:50image. Okay,

0:51so I'm told I'm going to have to use my elevated privileges because I've used

0:54the sudo command.

0:55Let's do this, specify where it is we want to get the image from via the FQ CN.

1:00Let's go with

1:01the Docker I/O image. So we begin pulling this down. Now remember the reason

1:05why we're not just using

1:06the locally accessible image is because that image is accessible to the test

1:10user. By invoking sudo,

1:12we are working in different environments. For example, if I say Podman images,

1:17we're seeing the images available for the regular user, but if I say sudo, Pod

1:21man images, the only

1:22one we're going to see here is the engine X one we just downloaded. Now

1:25remember we ran the image,

1:27wasn't available to the elevated user. So we pulled it and then we did run

1:31automatically.

1:32That means if we check the PS command, it should actually be in the running

1:36state. But remember,

1:37if we just say Podman PS, we're not going to see that container because this is

1:41just for the

1:43non-privileged user. Whereas isolated completely, if I say sudo, Podman PS,

1:47look at this right here,

1:48we have the actual engine X container that was created about a minute ago. And

1:53notice it's got a

1:54different name and a different ID right here. See this? Well, the one is called

1:57beautiful

1:58stern. And this one is called angry Kepler. Now another thing to actually

2:02notice here,

2:02if I happen to clear the stream and I say IP adder, what I want you to notice

2:07here is that when we

2:08happen to create this elevated account or rather create this container with

2:13elevated privileges,

2:15one thing to note here is the networking has actually changed. This container

2:20actually gets

2:20its own IP address. See this? We've got this Podman zero interface and this IP

2:25address right here.

2:27Now, let me just briefly show you how we can stop our containers. Okay, so we

2:31've got some running,

2:32we'll just say sudo, Podman PS. Here we can see the one here. If I say sudo,

2:36Podman RM,

2:38and then give the name of the container or the container ID, so I'll say angry

2:42Kepler

2:43and to answer and just to be aware there, we can't actually remove it because

2:46it is in the running

2:47state. So what I should do, and this is a good point, is I should say sudo, Pod

2:51man stop angry

2:52Kepler. And once it's in the stop states, if I say sudo, Podman PS, we're not

2:55going to see it.

2:56sudo, Podman PS dash a there it is right there. And then if I just add up, I

3:01can now remove this

3:02particular container. So if I now list it once more, PS, we see nothing here.

3:06PS dash a nothing

3:08there also. And because of this, clear the screen one more time to IP adder,

3:12notice that Podman

3:13zero interface is going with the IP configuration. Now contrast this versus

3:18when you just happen to

3:19spin up a regular container as a non-privileged user. Now, again, just to clear

3:23things up, we'll

3:23just say Podman PS dash a, we have a whole bunch of these. Let's clean them up.

3:27We'll just say Podman

3:28RM, let's just grab this one, let's remove distract to Blackwell. I'm going to

3:33have to stop the other

3:34ones or to stop this first. Let's stop the other ones because they're still in

3:37the running state.

3:38So stop it and stop the Heisenberg and remove them both. All right, so we have

3:42a clean slate,

3:43but we still have our images as we can see right here. So let's go and spin one

3:47up and just check

3:47out the deform circuit. So let's say Podman run dash the engine X, hit enter,

3:52Podman PS,

3:53now it is running. This time though, if I say IP adder, notice we do not have

3:58that Podman zero

3:59interface with the IP address configuration. So this is one thing to note about

4:02our rootless

4:03containers when we happen to create them. They're not going to be configured

4:06with their own interface

4:07and IP address on the regular system. They're also by default going to get much

4:11less access

4:12to the underlying physical file system that is on the host machine. And they're

4:17also not going to

4:17be able to bind to privilege ports. So basically that means it's not going to

4:21bind to ports one

4:22to 1023.

Exposing Ports

0:00So friends, perhaps you're watching this skill and you've seen that you can

0:03start containers,

0:04you've seen that you can stop them, execute commands within them, but we haven

0:08't really had

0:09any type of tangible or rather practical interaction with the container itself.

0:14I mean, we have executed command potential containers, we have created a little

0:19text file

0:19within one, but how useful is that really? For example, one of the images we

0:24have is an

0:25engine X web server. So if it's a web server, we should be able to access it

0:30via a browser,

0:31but we've not seen any of that at all. What we're going to do in this

0:35particular video is we're

0:36going to discuss some of the details that we have to consider when trying to

0:40access these containers.

0:42Let me give an example here, okay. Let's just say Podman PS. So we can see here

0:48, I have my

0:48engine X container. And if I look at my IP address just to IP other, this here

0:54is my IP address

0:55if I just copy this for a moment, let's open up Firefox. If I try to access

0:59this IP address and

1:00say on port 80, which is the default port for web service, it just says unable

1:05to connect.

1:06Now what exactly is the problem here? Well, the good thing is, is that this is

1:10absolutely

1:11expected behavior. And in fact, if it didn't behave this way, then we would

1:15have quite a series

1:16problem. So here is the deal by default, the behavior of containers is such

1:21that external users

1:23cannot access them unless you explicitly allow it. Now why is this the case?

1:27Well, because

1:28containers have a heavy focus on isolation via the namespaces. So if you want

1:33someone,

1:34a regular user such as the regular user on the main host system to access the

1:39web server,

1:40that is inside the container, essentially, well, what we can do is we can map

1:44the network ports

1:46inside the container to one of the ports on the actual host on the system. The

1:50net effect of this

1:51is that ultimately exposes that port or rather exposes the container to that

1:56host system.

1:57So now me as the user on that system can actually see the real web server

2:02within the container

2:03on my browser. So the way we are going to do this is once again, using a

2:07command we've seen before,

2:08we're going to use the run commands. And we're going to use this detached flag

2:12once more,

2:13but we're also going to use it in conjunction with another port or rather not

2:18another port.

2:19Another flag that is the P flag for the port configuration. So the way the

2:24syntax is going to run is

2:25essentially we're going to specify Podman, then run, specify we want to touch

2:29mode and then

2:30specify the port. Now this part here is the crucial components. What we want to

2:34do is we want to

2:35specify the external port that it can be reached on on the host. Say, for

2:39example, I'll just go with

2:403000. Okay, and then have a colon. And then the next number is going to be the

2:45actual port that

2:46the container is using within. So realistically think about it, if I happen to

2:49be using an

2:50engine X container, which by default is going to run over port 80, I specify

2:55this right here.

2:56And I say, Hey, if an external user wants to access the port 80 within the

3:02container,

3:03they can do so on their local system on port 3000. This is going to allow for

3:08this mapping behavior.

3:10So let's actually see it in action. So first things first, if I just say Podman

3:15, p s get the name

3:16of this for the moment. In fact, before I even do this, let me actually

3:19demonstrate this,

3:20this is actually going to be quite important. But we cannot have this port

3:23mapping to a container

3:24that has already been running quite simply if we want to expose the ports, we

3:28're going to have to

3:30kick off a brand new instance from that image and then make sure we use our

3:33port mappings when we

3:35spawn that particular instance. Let me give you an example. Okay. So here is

3:38the name of the

3:39actual running container I have for engine X. Let's copy this. If I tried to

3:43say something like say,

3:44you know, Podman run dash D dash P and let's go with a port mapping of 3000 to

3:5080. If I paste in

3:52the container name, what actually happens, it just thinks that this must be

3:56some type of image name

3:57out in one of the registries, it does not interpret this as a running container

4:01. So watch this control

4:04C to stop this. Even if I happen to stop this particular container. So now if I

4:08say Podman

4:10PS, we can see it's no longer there, Podman PS dash A is now exited. If I try

4:14the same commands,

4:16even from the stop states, it still tries to interpret the command in the same

4:20way. Regardless

4:22of whether or not the container is a running or not, the assumption is because

4:25we're using the run

4:26commands is that this must be an image name. And again, if I press control C,

4:31let's even try Podman

4:32starts start the container. If I try to even do Podman exec D dash P and to

4:38enter. All right. So

4:39hopefully I've really drilled this into your head that the only way we're going

4:42to get this to work

4:43is by spawning a brand new instance with the port mappings explicitly specified

4:49at the beginning.

4:49As we can see, we already have this running container. Let me just stop it. And

4:54we'll just

4:54remove it entirely. Okay. What I will do instead is I will say Podman dash D

4:59dash P and I specify

5:00the port mapping. So again, let's go with 3000 to 80. And now we actually

5:04specify the image,

5:06not container instance. We want to spawn a new instance from an image. So as we

5:11know, one of

5:11the images we have is engine X. If I answer now, we actually get a response.

5:16And because of this,

5:17on port 3000, we should be able to access the internal workings of the engine X

5:22server within

5:23the container. So let's go and try it out again. Once again, if I just do IP

5:27adder, I'll just grab

5:28my IP address, copy you. So let's paste it in. And we'll just say on port 3000

5:34to enter. Look at

5:35this right here. Welcome to engine X, we're actually able to access the

5:39container because we have

5:41exposed these ports. Now, one thing I also want to highlight right here, let me

5:45just close this

5:46down a second. So back to the terminal, let's just stop this copy you case. And

5:50now the container

5:51has stopped. If we try to access the site again, notice we are unable to

5:55connect. The container is

5:56not running anymore after all. Now, what I want to do is to highlight what

6:00happens if I try to

6:01spawn a new instance from this image. But this time we specify a different port

6:05mapping attempting

6:07to use a privilege port. Now, remember, I'm going to create the container from

6:11a non-privileged account.

6:13So what would happen therefore, if I happen to say podman run dash D dash P,

6:18and let's go with ports.

6:20I don't know, let's go with eight for one. Now, remember anything ranging from

6:24one to 1023 is

6:27considered privilege. This is within that range. So if I try to map this to

6:31port 80 on an engine

6:32X image and to enter, look at this right here, a rootless port cannot expose

6:37privilege port

6:38eight for one. See that not allowed. However, if I happen to say pseudo podman

6:43images, we know we

6:44still have the actual image available to us in our roots environment. So what I

6:49could do is I

6:50could spin up a container instance as a root account. So I say pseudo podman

6:56run D dash P.

6:57And because this is a root container, I should be able to expose this privilege

7:01port. So let's try

7:02and enter a hand now actually works. So let's go and access it over the same IP

7:07address. This time

7:08over port eight for one. So paste this in. So I could say port 3000 will no

7:12longer work. But let's try

7:14eight for one and to enter. Look at this right here, one now able to access

7:18this

7:19over port eight for one, because despite being a privilege port this time, we

7:23ran the container

7:24as a root container.

Validation

0:00Alright friends, so let's walk through the validation challenge.

0:04So the very first thing that I would like you to do is to use Podman to search

0:08for all

0:08available engine X images and make notes of the fully qualified container name,

0:14and that should actually be a capital letter there, just noticing that,

0:18fully qualified container name, FQCM, of the image sourced from the Docker Hub

0:24registry,

0:24and I want you to download that particular image. Now once you've done that,

0:28I want you to create a container instance from this image and ensure that you

0:33leave

0:33your terminal environment free to run commands after its creation. Basically,

0:37I don't want you to clog up your terminal so you can't run any subsequent

0:41commands upon

0:42the starting and running of this new container. So like I say, you should have

0:46access to your

0:47command layer interface and because of that, that is going to allow you to list

0:51your running

0:52containers. Now using the output from this command, I want you to stop the

0:57container using the

0:58container's unique container ID. So that's the alpha numeric characters. Okay.

1:03So now the

1:04container should be in the stop state. I want you to validate this by showing

1:09the status of this

1:10container. Okay. Now again, once you've done that, I want you to start the

1:14container again,

1:15using its unique container name. So the name this time, not the alpha numeric

1:20characters.

1:20And then once the container is started, I want you to execute the ls command to

1:26list the contents

1:27of the Etsy directory inside of that running container. And then after that, I

1:32would like

1:32you to ensure that external users on the system are able to access a container

1:38ized engine X server

1:39over port 1000 and two. So that means that anyone on the regular system would

1:44be able to open up

1:45their web browser, such as Firefox, and see the engine X server by just

1:50accessing it over its

1:52local IP address. And again, with this very particular port number, consider

1:56what that actually

1:57involves. And then finally, once you are done, all I want you to do is to

2:01ensure that all

2:02containers are removed. Okay, Docs, so boot up your terminal, give it a think,

2:07and I will see you in

2:08the very next video where we discussed the solution.

Validation

0:00Well friends, how did you get on?

0:02Hopefully you were able to solve this particular challenge.

0:05There were a few things that were kind of inferred

0:07that you had to figure out via the awarding of the question.

0:10So good job if you happened to solve this entirely.

0:13All right, so let's walk through the actual solution then.

0:16So the first thing, as we can see here,

0:18is we have to use Podman to search for all available engine

0:21X images and make notes of the FQCN

0:24and make sure it's sourced from the Docker registry

0:27and download it.

0:29So let's go to our terminal then and do just that.

0:31So if you remember from the previous scale,

0:32we can search for images using the Podman search command

0:35to specify engine X and to enter.

0:38Now we're going to see all of the results

0:40that come under the keyword engine X.

0:42Now if you scroll on down and look here,

0:44we can see we have all of our Docker based images.

0:48And on the right hand side, we have our description.

0:51So what I'm going to get here is this one here,

0:53the official build of engine X, okay?

0:56So I'm going to make a note of the FQCN,

0:59let's just copy you,

1:01and I'm going to have to download it.

1:02So remember the command to download an image

1:04is going to be Podman pull,

1:06and then I'll paste in the FQCN.

1:08If I hit enter, we're now going to begin pulling in this image

1:11and have it available to us on the system.

1:14All right, so with that now done,

1:15what we're going to have to do as per the instructions

1:18is we're going to have to create a new container instance

1:20from this image and ensure we leave

1:23our terminal environment free-touring commands after its creation.

1:27Now you may recall the command that we're going to use

1:28in order to start up or rather spin up a new container

1:32is the run command,

1:33but if we just use this command as it is,

1:36we're going to get a splash of output on our terminal screen

1:39and it's going to be clogged up.

1:40So we're going to have to run this in detached mode,

1:44remember this?

1:45So I'll say Podman run dash D,

1:48and then I can specify the name of the image

1:50that I want to use now because it's local,

1:51I can just say engine X.

1:53Now if I hit enter,

1:54we're going to actually see the output right here

1:56and notice this, I actually have the ability

1:58to still use my command line as you can see right here.

2:01Okay, so now that we have access to our terminal,

2:04what I'm going to have to do is to list my running containers

2:06and then use the information from this output

2:09to stop the container using its unique container ID.

2:13So because we have a running container,

2:15what I can do is run the command Podman PS.

2:18Again, we have this ugly line wrapping,

2:20let me just zoom out a little bit.

2:23So we can see here we have some information,

2:25we have the actual image, we see the command that is ran

2:28upon its execution, we can see when it was created,

2:30how long it is up, as well as name here,

2:32which is still a little bit, line wrapped,

2:34but very crucially, we have the container ID right here

2:38and this is the value that we're going to be using.

2:41So let's just copy this right here.

2:42And now we're going to, in fact, let me just zoom in

2:44one more time.

2:45And now we're going to stop this container.

2:47So what I will do is say Podman, stop,

2:50and then paste in the container ID, if I hit enter,

2:53we get a response and what I want to now do

2:56is actually show the new status of this container.

2:59So it should be stopped, we just want to ensure

3:01we can validate this.

3:02Now you may remember, very crucially,

3:04if I just, for example, clear the screen

3:05and I run the command Podman PS,

3:07we're not going to see anything right here,

3:09Podman PS only shows us the running containers,

3:13we want to see the status of a stopped one,

3:15so we can use the dash A fly to get all information.

3:18If I hit enter now, we can indeed see here

3:21that it was created two minutes ago,

3:23but the status is exited, exited 30 seconds ago.

3:27Okay, so very, very important,

3:28we understand the distinction between those commands.

3:30Now the next thing is we're going to have to

3:33start the container again using its unique container name.

3:37So let's focus on that part first.

3:39So we can see its unique container name

3:41is Loving Wilson, very, very nice name that is, okay.

3:45And what I will do here is I will say

3:47Podman starts and then paste in the container name,

3:51hit enter, we get the response,

3:53and if I just happened to verify this

3:55with Podman PS the regular way,

3:57we can see this has been up for eight seconds,

3:59so it is in the running states.

4:01Now because of this, we should be able to run commands

4:03against it and the command we want to run

4:05is the LaaS command against the Etsy directory

4:09inside of this now running container.

4:11So you may recall the command we can use

4:13to execute commands against a running container

4:16is the exact command.

4:18So let's actually try this out.

4:19What I will say is Podman, exec,

4:21and what I'm going to do is I'm going to specify

4:23the name of the container that I'm going to be targeting,

4:27which is this right here.

4:29And then I'll pass in the actual command

4:31that I want to execute, which is going to be LaaS

4:34against the Etsy directory.

4:36If I hit enter, look at this right here,

4:38we actually get the contents of all the things

4:40that are inside of that particular directory

4:42to see this, it's going on up.

4:43This is everything inside.

4:44And by the way, what we can do is if I so wished

4:47I could actually take the container ID right here, copy you.

4:51And I could remove the unique name

4:53and just as easily substitute in the unique container ID.

4:57And if I hit enter, we're going to get the exact same output.

4:59So whichever way you happen to do this,

5:01absolutely fine, same result.

5:03Now, what I have to do next is to ensure

5:06that external users on the system are able to access

5:09a containerized engine X server over port 1000 and two.

5:14Now, this part here was deliberately worded

5:16because I wanted you to try to remember some key components

5:19when it comes to actually exposing these particular ports.

5:22The first thing I said was are able to access

5:25a containerized engine X server, not necessarily

5:29the running container right here,

5:31because if you remember from the scale,

5:33we have to map the ports at the beginning

5:36of the container instances creation.

5:38We can't just stop the container, kick it off again

5:40and then add that port mapping.

5:42So this is actually going to have to be a new container instance

5:46from the same engine X image.

5:48Now, the second portion of this,

5:50which is about a gotcha, or potentially a gotcha,

5:53maybe it's not, if you have a despot it,

5:55is we're going to have to run this over port 1000 and two.

5:59Now, remember, this is actually within the privilege range.

6:02The privilege range goes from one to 1023.

6:06Those numbers in any of the numbers between those

6:09are privileged.

6:10So because of this, we're going to have to use

6:12super user privileges.

6:14What this means, therefore, is if I say pseudo-podman

6:17images right now, what you should see on my system

6:20is a clear environment, because remember,

6:22we have that complete isolation.

6:24So I'm going to have to pull down an image

6:26for this particular environment.

6:28So what I will do is say podman,

6:29or rather pseudo-podman, pull and I will give the FQCN

6:34of the Docker image once again,

6:36or rather the Docker image for engine X.

6:38So Docker I/O, forward slash library, forward slash engine X,

6:42if I answer, we're now going to pull that in

6:44and it will be available within the elevated privileges

6:48environment.

6:49Okay, though, so if I now say pseudo-podman images,

6:53here we have this image.

6:54And what I'm going to do is I'm going to start off

6:58this container instance from this image.

7:00Also, pseudo-podman run, we'll run in detached nodes,

7:03and we're also going to specify the port mapping.

7:05Now, the port mapping is going to have to expose

7:08the external port first, which is 1,002.

7:11This is what we want to be able to access the server over

7:14and the internal port, well, it's a web server.

7:16So by default, it's going to be port number 80.

7:19And now we just specify the image that we want to use.

7:21Now, because we have downloaded this image,

7:23we can effectively short-hand it.

7:26So in our local environment, after all,

7:27I can just say engine X.

7:28If I enter now, we get the response,

7:31and the thing is now is to actually confirm this.

7:33So what I do is just say IP adder,

7:35we can get my IP address, which is this right here,

7:38and copy here.

7:39Let's go to Firefox.

7:40And let me just paste in the IP address.

7:42And it's going to be on port 1,002.

7:45If I enter, as we can see here,

7:48we get access to the engine X7.

7:50And just one thing, by the way, just for clarity,

7:52we also have this IP address known as the lookback address.

7:55We'll see this in the future.

7:57And this just means the local host.

7:58So you can also use 1,000 or rather 1,000.

8:011,2, 7, 0, 0, 1, on port 1,002 as well.

8:05That should also render the web page to.

8:08Now, we also have one final task,

8:10and that is to ensure that all containers are removed.

8:12Now, remember, we actually have containers

8:14in two different environments.

8:16And also, if we try to remove them whilst they are running,

8:19well, we're going to get an error.

8:21For example, if I say pseudo-podman.ps,

8:22we can see this container is in the upstate.

8:25And if I happen to take the name here,

8:29and I say pseudo-podman RM, page to 10,

8:32going to get that error right there.

8:33So make sure that we have the container stopped first.

8:35OK, this is another thing that was inferred.

8:37So let's stop this.

8:39Now it stopped.

8:40If I add it up and now try to remove it, it has been removed.

8:44Now, this is just for the elevated environment.

8:46If I say Podman PS, we can see we also have a running one

8:51within the test user environment.

8:53So again, we have the actual name here,

8:56as well as the alphanumeric ID,

8:58which should go with the name,

8:58and find it a little bit easier.

9:00And let's just say Podman, stop, page to 10, hit enter.

9:05And then finally, we can say Podman RM on loving Wilson.

9:09And if I just say Podman PS, we don't have anything running,

9:13do Podman PSA.

9:14That is also clear as well as pseudo-podman PS.

9:17That is clear as well as pseudo-podman PS-A, also clear.

9:21So friends, that is us for our validation challenge.

9:25I hope this has been informative for you,

9:26and I'd like to thank you for viewing.

What's next?

Ready to keep going?

For your team

Bring this training to your team

See how CBT Nuggets helps IT teams close skills gaps, hit compliance targets, and prove training ROI.

Book a Demo
Just need Red Hat Certified Specialist in Containers?

Learning on your own? Browse individual plans ($49/month, billed annually)

Not ready to buy?
with no purchase required. Already have an account?
Book a Demo