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 training IT teams trust.

Updated

45m

Skill 2 of 8 in Red Hat Certified Specialist in Containers

What you'll learn

  • Start, stop, and remove container instances from an image with podman run, podman stop, and podman rm
  • Open an interactive TTY session inside a container with podman run -it and work within its file system
  • Execute commands against an already running container with podman exec using its name or container ID
  • Explain how namespaces isolate containers and why rootless and sudo Podman environments see different images
  • Compare running containers as a regular user versus with sudo, including root privileges for ports 1 to 1023
  • Expose a containerized NGINX server by mapping host ports when the container instance is created

Free 45-minute video lesson with a full transcript and knowledge checks. No account needed to watch.

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)

Select all that apply.

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?

Select all that apply.

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)

Select all that apply.

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?

Select all that apply.

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. So on this skill right here, what we're going to be doing is looking at Podman with a little bit more detail. We'll get to see how we can start containers, how we can stop containers. We will discuss the differences between namespaces and containerization. And we'll also look at how we can actually access our containers via port mapping. So 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 with Podman directly on the command line and getting it to the nitty gritty. So with that said, let's dive in then. Now in the previous skill, we happened to learn how we could ultimately pull down an image from a registry, meaning that we essentially had a local copy of this image, and we also discussed the difference between what is actually a container image versus what is a container instance. In the previous skill, we were able to pull down an image, but as we remember, this is not actually a running container.

0:34Rather, this is just a blueprint that we can use to actually go and create these real running instances. So there actually are a few commands that we want to learn about. So the first command we're going to be looking at is the run command. You can imagine what this actually does. This is essentially going to allow us to run a container, basically create an instance from the image. So pop quiz, can you remember the command that we can use to actually see the available images that we have on the system? Well, 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. So in order to retrieve an image, what we will do is just simply say Podman pull, and I'll just say engine X remember, because we have to specify the fully qualified container name, we're going to have to be much more explicit about where it is we want to get this particular image. So in my case here, let's go with Docker, so go down here. And as we can see, we're now beginning to pull in that image. Okay, so let's just say Podman images once more. Now we can see we do have this image.

1:37Let's actually create a running instance of that image. So first thing, let me show you if I just say Podman run, and then what I can do is I can give the name of the image itself. Now if I just happen to say engine X right here, okay, so look what's happened. We have essentially spun up that instance of the image, but this is kind of ugly. We have essentially lost control over our terminal. See this? So first thing that I want to do, let me just press control C to stop this. And that's going to exit. Instead what I will do is I will say Podman run dash D, and then I can specify the name of the image that I want to use.

2:12Now if I try this, things look a little bit different. So what I've actually done here is by specifying the dash D flag, this actually means that we're going to be running in detached mode. Essentially, this is going to allow us to keep control of our terminal window. And simple terms, we are essentially running the container in the background. Alrighty, so let's see if we can actually verify if the container is running. So what I will do here is I will say Podman, and then I will say PS. This allows me to see any running container instances, okay? Now you're going to have to excuse the ugly line wrapping, just let me zoom out a little bit.

2:45Let me talk you through some of what we're actually seeing here. What we can see here is the actual image we have used. The instance is based off this blueprint, as we discussed. And we actually see this command right here. And quite simply, this is a command that's going to automatically run when the instance is spun up. This is kind of hard coded within to the image itself. Now we see here when the instance was created about a minute ago, and the status tells us that it has been running for just about a minute. Now, very important point here, but see, we actually have the container ID as well as the names, both of these can be used to uniquely identify the container instance.

3:21So you can effectively reference this running instance via this container ID, which is a little bit harder to remember. But we also have this name here, Dreamy Heisenberg, that has been auto generated. This is not something that I have created. You get these weird and wonderful combinations popping up, and they just happen to be a little bit more memorable. Just makes it easier to remember the container you're working with, as opposed to the strength of alpha numeric characters. Now, just to prove that the container instance actually is working, so if I just say Podman P.S. again, we can see here, indeed, the container has been running for five minutes at this stage.

3:55And if I just leave this container alone, it's just going to continually run and run. So what I can do is I can also stop that container. The way we do this is unlike Podman Run, this time we say Podman stop, and we 're going to have to uniquely reference the container we want to stop. Now, we know we have two different ways we can identify this. I can just grab this little container ID right here. So let's copy this, and then I can paste this in and to enter, and then we get this response back. And if I say Docker P.S.

4:26We actually see here I no longer have any running containers. But here's the thing, the container actually does still exist on the system. And in fact, we can restart it. So right now I don't have any containers in the running states. But if I do Podman P.S. dash a for all, we can see containers that were perhaps stopped or previously exited or crash that type of things. If I hit enter here, and I just zoom out a little bit, as you can see right here, we have the container name all the same information we can see when it was created seven minutes ago, and we can see its status right now it is exited and exited about a minute ago.

5:01That was because we said Podman our aim with the container ID, but that container still does exist. So if I want to start it up once again, what I could do, just zoom in a little bit again, let's just copy this once more, and we'll just say Podman starts and paste this in. Now we get the response. If I just say Podman P.S. the regular command and to enter, we can now see the status is up once more. So that's how we can start and stop the containers utilizing our container ID. Let's actually try the container name we have this, a dreamy Heisenberg right here.

5:32So let's copy this. And if I just say Podman stop and then just reference the name itself, enter, we see the response. If I now say Podman P.S. everything is now empty. If I say Podman P.S. Dash A, we can see it just exited eight seconds ago because we stopped it. And once again, if you want to restart, we can say Podman start this time, I suppose using the container ID, we use the container name, and again Podman P.S. we can indeed see 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. So to demonstrate this next one, what I will do is I will go to Docker Hub, okay? And let me just search for an Ubuntu image. This is a Linux container, okay? And if I just copy this here, what I'll do is go to my terminal. Let me just go to the beginning, change the Docker to be Podman. Like I said, the commands are pretty much exactly the same. And I'll just give the fully qualified container name of Docker I/O forward slash library, and then Ubuntu. And I can even add on, let's just say the latest tag to be super explicit.

0:32If I hit enter, I'm now going to begin pulling in this image. And now if I say Podman images, we see we also have this Ubuntu image. So if I say Podman PS, as we can see, we don't have any running instance of the Ubuntu image. Now let me just show you what happens here. If I say Podman, and I try to run this in detached mode and let's just go with Ubuntu. If I hit enter, seems like we have a success, however, if I say Podman PS, we still don't actually see the running instance. If I do Podman PS dash a, we actually see here that it did begin to run nine seconds ago, but also just exited.

1:10Now because this particular container is an Ubuntu operating system, there is no particular process like a shell or a web server that is going to keep the actual container running. Well, what's going to happen is it's going to spin up, have nothing to do, and then just will stop. So what I want to highlight to you is the ability for us to create an interactive TTY session with our container. Let me show you what I mean. So again, Podman PS, not Ubuntu running. If I say Podman run, and I say dash IT for interactive TTY, and then Ubuntu, if I hit enter, look what actually happens, something very, very different.

1:51Look at the prompt, we actually are within the container itself. Now we'll talk about this more in a little bit more detail very, very shortly, but for now, notice I basically have access within the container itself. This is the file system, the Ubuntu file system inside of this container. So let's maybe see if I go to the home directory and I create a little file, let's just say this is a test file and I redirect into file.txt. If I do an LS, we can see this file. And if I say catfile.txt, indeed, we have modified the contents within this particular container. Again, we have this interactive ability to basically just walk through this particular operating system as we ordinarily would within the confines of a container.

2:33Now again, let me just go back or just to Podman PS. Notice because I've actually exited the TTY session, what has actually happened is the container itself has actually stopped. There is no more shell running. So if I say PS-A, as we can see this previous Ubuntu image that I just span up, now just exited. Now, very important point. This particular command, the run command, this is going to allow us to build and run a brand new instance from an image. As we see, we have different options, detach mode, we can drop straight into an interactive TTY session, but it's still with this particular command. What if we have an all ready running container instance?

3:12Well, if it's already running, we don't have to spin up another instance from the same image. Instead, we want to be able to execute commands against this already running container. And this is what we're going to talk about next. This is the exact command. And this is what it allows you to do. So let me give you an example. Let's do Podman PS-A. As we can see, we have this particular container that has exited. If I want to start it up, again, we're not spinning up a new one. We're starting up a previously exited one. We can use the start command. And 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. However, let's say I wanted to get that interactive TTY session against this all ready running container. Well, what are we going to do? I will say Podman exec-it. And then I can specify the container that I want to be targeting. So let's grab the container name. Again, you can use a container ID, the alphanumeric characters. But in this case, yeah, that's simpler. Let's go with this. And notice we actually have an error. This is very, very good to note. When it comes to using the exact command, we 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. And then also I want to execute a bin basher. So if I enter, look at this right here. We have now got access once again inside of that container. But the difference is this time it wasn't already running container. So once again, if I exit out Podman PS, notice this time, once we exit the shell after the exact command, the status is still up. See that? Now, one thing we can also do is we can also say Podman exec and just execute a regular command as you so wish that if I just grabbed the name of the container ID right here, paste you in, and just maybe say ls -l.

5:01If I enter, look at this right here. What we're actually seeing here is the contents within the container. We have executed the ls -l command at the roots. Similarly for adderwup, and I maybe just say who am I? Notice inside the container, I'm not the test user. I am the roots again. We'll talk about this very, very shortly. But quite simply, we have the ability to freely execute commands. So I could run the cat commands and remember inside the home directory, I did actually create a file called wlfail.txt if I had answer. As we can see here, I ran the command inside the container and this is the contents.

Namespaces

0:00So I've actually bumped up against a very important concept, I think containerization known as namespaces. You might not have realized that, but yup indeed, we have indeed seen these namespaces in action. So at its core, what a namespace is going to allow us to do, it's going to provide a level of isolation for the container itself. This is very, very important. Quite simply, when we happen to start a container with Podman, the container started with a particular user. It's going to run in a particular user namespace. This is where the isolation is happening.

0:31Let me briefly show you what I mean. Right now, who am I? We can see I am the test user. Whereas if I say Podman, run and let's grab an interactive TTY session, let's use the Ubuntu image. And if I hit enter, I now say who am I? Well, it says I am the root account. Now by virtue of us accessing the root account within this container, it does not actually mean any type of security compromise on the host itself. After all, we are a regular user. We did not use any elevated privileges. We shouldn't have access to a root account that could really affect the main system that the container is running within.

1:08And like I say, namespace is how we actually manage this. Quite simply, it provides isolation for the user ID. Now the user namespace is providing isolation for this particular component. But with respect to containers, there actually is a lot more things to consider. And honestly, the user namespace did not provide isolation for absolutely everything. It's just targeting this particular thing. So we also have other namespaces. And I just want to highlight some of the most important ones. One would be the PID namespace.

1:40And this is the process ID namespace. Essentially, this is going to allow us to isolate. Once again, it's all about isolation. Just a different thing about isolating. This time we are isolating the process IDs from the host and inside of the containers themselves. Because quite simply, if we only just use the user namespace-- and that was only separation and isolation we had-- processes running inside the container, such as the engine X server running inside the container, that could actually see other processes running on the host system itself, which means they have the ability to maybe affect those processes.

2:15All right, so namespace for users, namespace for processes. What is the next one? Well, we also have a namespace known as the network namespace. So the previous solutions for isolation did not isolate things such as IP addresses. Nor does it isolate interfaces between the containers and the actual host, whereas the network namespace is going to do this. So that means that the host machine, once again, is going to have a strong level of protection between the networking within the container itself. If you can imagine the container that you happen to spin up had some type of vulnerability with respect to its networking and it could also communicate and freely interact with the host machine.

2:52But then once again, it could potentially endanger the actual host itself. Now, we also have something known as a mount namespace. This is related to the accessibility of files on the file system. So imagine you had some type of host machine, let's just say it is Red Hat Enterprise Linux on that system. There is going to be a file system with all the directories, such as the Etsy directory, the Dev directory, so on and so forth. And if we spin up a container on this host system, we don't necessarily just want the ability for the container to just write in and modify particular files within these different directories.

3:26That is obviously a potential security issue once again. So now we have just briefly skimmed the subject of namespaces. We understand that it's going to provide isolation in many different forms. What I want to do now is to take some of that information and apply it and see how containers act when they are run with a regular account versus 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 look at the running of our containers as a privilege user versus a non-privileged regular user. So remember in the previous skill when we talked about Docker, Docker by default is going to require elevated privileges in order to be able to run and manage our containers due to the architecture of utilizing demons. And by having to invoke sudo to run these Docker commands, well it does present this security concern. That said, as we know Podman allows us to run containers as a non-privileged user, but that doesn't mean that Podman does not also have the ability to also invoke the sudo command. So we just want to look at some of the differences of how these two implementations operate. So let me just say sudo, Podman, I'm going to run in detached mode and let's just take my engine X server case. We'll spin up a new instance from this image. Okay, so I'm told I'm going to have to use my elevated privileges because I've used the sudo command.

0:55Let's do this, specify where it is we want to get the image from via the FQ CN. Let's go with the Docker I/O image. So we begin pulling this down. Now remember the reason why we're not just using the locally accessible image is because that image is accessible to the test user. By invoking sudo, we are working in different environments. For example, if I say Podman images, we're seeing the images available for the regular user, but if I say sudo, Pod man images, the only one we're going to see here is the engine X one we just downloaded. Now remember we ran the image, wasn't available to the elevated user. So we pulled it and then we did run automatically.

1:32That means if we check the PS command, it should actually be in the running state. But remember, if we just say Podman PS, we're not going to see that container because this is just for the non-privileged user. Whereas isolated completely, if I say sudo, Podman PS, look at this right here, we have the actual engine X container that was created about a minute ago. And notice it's got a different name and a different ID right here. See this? Well, the one is called beautiful stern. And this one is called angry Kepler. Now another thing to actually notice here, if I happen to clear the stream and I say IP adder, what I want you to notice here is that when we happen to create this elevated account or rather create this container with elevated privileges, one thing to note here is the networking has actually changed. This container actually gets its own IP address. See this? We've got this Podman zero interface and this IP address right here.

2:27Now, let me just briefly show you how we can stop our containers. Okay, so we 've got some running, we'll just say sudo, Podman PS. Here we can see the one here. If I say sudo, Podman RM, and then give the name of the container or the container ID, so I'll say angry Kepler and to answer and just to be aware there, we can't actually remove it because it is in the running state. So what I should do, and this is a good point, is I should say sudo, Pod man stop angry Kepler. And once it's in the stop states, if I say sudo, Podman PS, we're not going to see it. sudo, Podman PS dash a there it is right there. And then if I just add up, I can now remove this particular container. So if I now list it once more, PS, we see nothing here.

3:06PS dash a nothing there also. And because of this, clear the screen one more time to IP adder, notice that Podman zero interface is going with the IP configuration. Now contrast this versus when you just happen to spin up a regular container as a non-privileged user. Now, again, just to clear things up, we'll just say Podman PS dash a, we have a whole bunch of these. Let's clean them up. We'll just say Podman RM, let's just grab this one, let's remove distract to Blackwell. I'm going to have to stop the other ones or to stop this first. Let's stop the other ones because they're still in the running state.

3:38So stop it and stop the Heisenberg and remove them both. All right, so we have a clean slate, but we still have our images as we can see right here. So let's go and spin one up and just check out the deform circuit. So let's say Podman run dash the engine X, hit enter, Podman PS, now it is running. This time though, if I say IP adder, notice we do not have that Podman zero interface with the IP address configuration. So this is one thing to note about our rootless containers when we happen to create them. They're not going to be configured with their own interface and IP address on the regular system. They're also by default going to get much less access to the underlying physical file system that is on the host machine. And they're also not going to be able to bind to privilege ports. So basically that means it's not going to bind to ports one to 1023.

Exposing Ports

0:00So friends, perhaps you're watching this skill and you've seen that you can start containers, you've seen that you can stop them, execute commands within them, but we haven 't really had any type of tangible or rather practical interaction with the container itself. I mean, we have executed command potential containers, we have created a little text file within one, but how useful is that really? For example, one of the images we have is an engine X web server. So if it's a web server, we should be able to access it via a browser, but we've not seen any of that at all. What we're going to do in this particular video is we're going to discuss some of the details that we have to consider when trying to access these containers.

0:42Let me give an example here, okay. Let's just say Podman PS. So we can see here , I have my engine X container. And if I look at my IP address just to IP other, this here is my IP address if I just copy this for a moment, let's open up Firefox. If I try to access this IP address and say on port 80, which is the default port for web service, it just says unable to connect. Now what exactly is the problem here? Well, the good thing is, is that this is absolutely expected behavior. And in fact, if it didn't behave this way, then we would have quite a series problem. So here is the deal by default, the behavior of containers is such that external users cannot access them unless you explicitly allow it. Now why is this the case?

1:27Well, because containers have a heavy focus on isolation via the namespaces. So if you want someone, a regular user such as the regular user on the main host system to access the web server, that is inside the container, essentially, well, what we can do is we can map the network ports inside the container to one of the ports on the actual host on the system. The net effect of this is that ultimately exposes that port or rather exposes the container to that host system.

1:57So now me as the user on that system can actually see the real web server within the container on my browser. So the way we are going to do this is once again, using a command we've seen before, we're going to use the run commands. And we're going to use this detached flag once more, but we're also going to use it in conjunction with another port or rather not another port. Another flag that is the P flag for the port configuration. So the way the syntax is going to run is essentially we're going to specify Podman, then run, specify we want to touch mode and then specify the port. Now this part here is the crucial components. What we want to do is we want to specify the external port that it can be reached on on the host. Say, for example, I'll just go with 3000. Okay, and then have a colon. And then the next number is going to be the actual port that the container is using within. So realistically think about it, if I happen to be using an engine X container, which by default is going to run over port 80, I specify this right here.

2:56And I say, Hey, if an external user wants to access the port 80 within the container, they can do so on their local system on port 3000. This is going to allow for this mapping behavior. So let's actually see it in action. So first things first, if I just say Podman , p s get the name of this for the moment. In fact, before I even do this, let me actually demonstrate this, this is actually going to be quite important. But we cannot have this port mapping to a container that has already been running quite simply if we want to expose the ports, we 're going to have to kick off a brand new instance from that image and then make sure we use our port mappings when we spawn that particular instance. Let me give you an example. Okay. So here is the name of the actual running container I have for engine X. Let's copy this. If I tried to say something like say, you know, Podman run dash D dash P and let's go with a port mapping of 3000 to 80. If I paste in the container name, what actually happens, it just thinks that this must be some type of image name out in one of the registries, it does not interpret this as a running container . So watch this control C to stop this. Even if I happen to stop this particular container. So now if I say Podman PS, we can see it's no longer there, Podman PS dash A is now exited. If I try

4:14the same commands, even from the stop states, it still tries to interpret the command in the same way. Regardless of whether or not the container is a running or not, the assumption is because we're using the run commands is that this must be an image name. And again, if I press control C, let's even try Podman starts start the container. If I try to even do Podman exec D dash P and to enter. All right. So hopefully I've really drilled this into your head that the only way we're going to get this to work is by spawning a brand new instance with the port mappings explicitly specified at the beginning.

4:49As we can see, we already have this running container. Let me just stop it. And we'll just remove it entirely. Okay. What I will do instead is I will say Podman dash D dash P and I specify the port mapping. So again, let's go with 3000 to 80. And now we actually specify the image, not container instance. We want to spawn a new instance from an image. So as we know, one of the images we have is engine X. If I answer now, we actually get a response. And because of this, on port 3000, we should be able to access the internal workings of the engine X server within the container. So let's go and try it out again. Once again, if I just do IP adder, I'll just grab my IP address, copy you. So let's paste it in. And we'll just say on port 3000 to enter. Look at this right here. Welcome to engine X, we're actually able to access the container because we have exposed these ports. Now, one thing I also want to highlight right here, let me just close this down a second. So back to the terminal, let's just stop this copy you case. And now the container has stopped. If we try to access the site again, notice we are unable to connect. The container is not running anymore after all. Now, what I want to do is to highlight what happens if I try to spawn a new instance from this image. But this time we specify a different port

6:05mapping attempting to use a privilege port. Now, remember, I'm going to create the container from a non-privileged account. So what would happen therefore, if I happen to say podman run dash D dash P, and let's go with ports. I don't know, let's go with eight for one. Now, remember anything ranging from one to 1023 is considered privilege. This is within that range. So if I try to map this to port 80 on an engine X image and to enter, look at this right here, a rootless port cannot expose privilege port eight for one. See that not allowed. However, if I happen to say pseudo podman images, we know we still have the actual image available to us in our roots environment. So what I could do is I could spin up a container instance as a root account. So I say pseudo podman run D dash P.

6:57And because this is a root container, I should be able to expose this privilege port. So let's try and enter a hand now actually works. So let's go and access it over the same IP address. This time over port eight for one. So paste this in. So I could say port 3000 will no longer work. But let's try eight for one and to enter. Look at this right here, one now able to access this over port eight for one, because despite being a privilege port this time, we ran the container as a root container.

Validation

0:00Alright friends, so let's walk through the validation challenge. So the very first thing that I would like you to do is to use Podman to search for all available engine X images and make notes of the fully qualified container name, and that should actually be a capital letter there, just noticing that, fully qualified container name, FQCM, of the image sourced from the Docker Hub registry, and I want you to download that particular image. Now once you've done that, I want you to create a container instance from this image and ensure that you leave your terminal environment free to run commands after its creation. Basically, I don't want you to clog up your terminal so you can't run any subsequent commands upon the starting and running of this new container. So like I say, you should have access to your command layer interface and because of that, that is going to allow you to list your running containers. Now using the output from this command, I want you to stop the container using the container's unique container ID. So that's the alpha numeric characters. Okay.

1:03So now the container should be in the stop state. I want you to validate this by showing the status of this container. Okay. Now again, once you've done that, I want you to start the container again, using its unique container name. So the name this time, not the alpha numeric characters. And then once the container is started, I want you to execute the ls command to list the contents of the Etsy directory inside of that running container. And then after that, I would like you to ensure that external users on the system are able to access a container ized engine X server over port 1000 and two. So that means that anyone on the regular system would be able to open up their web browser, such as Firefox, and see the engine X server by just accessing it over its local IP address. And again, with this very particular port number, consider what that actually involves. And then finally, once you are done, all I want you to do is to ensure that all containers are removed. Okay, Docs, so boot up your terminal, give it a think, and I will see you in the very next video where we discussed the solution.

Validation

0:00Well friends, how did you get on? Hopefully you were able to solve this particular challenge. There were a few things that were kind of inferred that you had to figure out via the awarding of the question. So good job if you happened to solve this entirely. All right, so let's walk through the actual solution then. So the first thing, as we can see here, is we have to use Podman to search for all available engine X images and make notes of the FQCN and make sure it's sourced from the Docker registry and download it. So let's go to our terminal then and do just that.

0:31So if you remember from the previous scale, we can search for images using the Podman search command to specify engine X and to enter. Now we're going to see all of the results that come under the keyword engine X. Now if you scroll on down and look here, we can see we have all of our Docker based images. And on the right hand side, we have our description. So what I'm going to get here is this one here, the official build of engine X, okay? So I'm going to make a note of the FQCN, let's just copy you, and I'm going to have to download it.

1:02So remember the command to download an image is going to be Podman pull, and then I'll paste in the FQCN. If I hit enter, we're now going to begin pulling in this image and have it available to us on the system. All right, so with that now done, what we're going to have to do as per the instructions is we're going to have to create a new container instance from this image and ensure we leave our terminal environment free-touring commands after its creation. Now you may recall the command that we're going to use in order to start up or rather spin up a new container is the run command, but if we just use this command as it is, we're going to get a splash of output on our terminal screen and it's going to be clogged up.

1:40So we're going to have to run this in detached mode, remember this? So I'll say Podman run dash D, and then I can specify the name of the image that I want to use now because it's local, I can just say engine X. Now if I hit enter, we're going to actually see the output right here and notice this, I actually have the ability to still use my command line as you can see right here. Okay, so now that we have access to our terminal, what I'm going to have to do is to list my running containers and then use the information from this output to stop the container using its unique container ID.

2:13So because we have a running container, what I can do is run the command Podman PS. Again, we have this ugly line wrapping, let me just zoom out a little bit. So we can see here we have some information, we have the actual image, we see the command that is ran upon its execution, we can see when it was created, how long it is up, as well as name here, which is still a little bit, line wrapped, but very crucially, we have the container ID right here and this is the value that we're going to be using. So let's just copy this right here. And now we're going to, in fact, let me just zoom in one more time.

2:45And now we're going to stop this container. So what I will do is say Podman, stop, and then paste in the container ID, if I hit enter, we get a response and what I want to now do is actually show the new status of this container. So it should be stopped, we just want to ensure we can validate this. Now you may remember, very crucially, if I just, for example, clear the screen and I run the command Podman PS, we're not going to see anything right here, Podman PS only shows us the running containers, we want to see the status of a stopped one, so we can use the dash A fly to get all information.

3:18If I hit enter now, we can indeed see here that it was created two minutes ago, but the status is exited, exited 30 seconds ago. Okay, so very, very important, we understand the distinction between those commands. Now the next thing is we're going to have to start the container again using its unique container name. So let's focus on that part first. So we can see its unique container name is Loving Wilson, very, very nice name that is, okay. And what I will do here is I will say Podman starts and then paste in the container name, hit enter, we get the response, and if I just happened to verify this with Podman PS the regular way, we can see this has been up for eight seconds, so it is in the running states.

4:01Now because of this, we should be able to run commands against it and the command we want to run is the LaaS command against the Etsy directory inside of this now running container. So you may recall the command we can use to execute commands against a running container is the exact command. So let's actually try this out. What I will say is Podman, exec, and what I'm going to do is I'm going to specify the name of the container that I'm going to be targeting, which is this right here. And then I'll pass in the actual command that I want to execute, which is going to be LaaS against the Etsy directory.

4:36If I hit enter, look at this right here, we actually get the contents of all the things that are inside of that particular directory to see this, it's going on up. This is everything inside. And by the way, what we can do is if I so wished I could actually take the container ID right here, copy you. And I could remove the unique name and just as easily substitute in the unique container ID. And if I hit enter, we're going to get the exact same output. So whichever way you happen to do this, absolutely fine, same result. Now, what I have to do next is to ensure that external users on the system are able to access a containerized engine X server over port 1000 and two.

5:14Now, this part here was deliberately worded because I wanted you to try to remember some key components when it comes to actually exposing these particular ports. The first thing I said was are able to access a containerized engine X server, not necessarily the running container right here, because if you remember from the scale, we have to map the ports at the beginning of the container instances creation. We can't just stop the container, kick it off again and then add that port mapping. So this is actually going to have to be a new container instance from the same engine X image.

5:48Now, the second portion of this, which is about a gotcha, or potentially a gotcha, maybe it's not, if you have a despot it, is we're going to have to run this over port 1000 and two. Now, remember, this is actually within the privilege range. The privilege range goes from one to 1023. Those numbers in any of the numbers between those are privileged. So because of this, we're going to have to use super user privileges. What this means, therefore, is if I say pseudo-podman images right now, what you should see on my system is a clear environment, because remember, we have that complete isolation.

6:24So I'm going to have to pull down an image for this particular environment. So what I will do is say podman, or rather pseudo-podman, pull and I will give the FQCN of the Docker image once again, or rather the Docker image for engine X. So Docker I/O, forward slash library, forward slash engine X, if I answer, we're now going to pull that in and it will be available within the elevated privileges environment. Okay, though, so if I now say pseudo-podman images, here we have this image.

6:54And what I'm going to do is I'm going to start off this container instance from this image. Also, pseudo-podman run, we'll run in detached nodes, and we're also going to specify the port mapping. Now, the port mapping is going to have to expose the external port first, which is 1,002. This is what we want to be able to access the server over and the internal port, well, it's a web server. So by default, it's going to be port number 80. And now we just specify the image that we want to use. Now, because we have downloaded this image, we can effectively short-hand it.

7:26So in our local environment, after all, I can just say engine X. If I enter now, we get the response, and the thing is now is to actually confirm this. So what I do is just say IP adder, we can get my IP address, which is this right here, and copy here. Let's go to Firefox. And let me just paste in the IP address. And it's going to be on port 1,002. If I enter, as we can see here, we get access to the engine X7. And just one thing, by the way, just for clarity, we also have this IP address known as the lookback address. We'll see this in the future.

7:57And this just means the local host. So you can also use 1,000 or rather 1,000. 1,2, 7, 0, 0, 1, on port 1,002 as well. That should also render the web page to. Now, we also have one final task, and that is to ensure that all containers are removed. Now, remember, we actually have containers in two different environments. And also, if we try to remove them whilst they are running, well, we're going to get an error. For example, if I say pseudo-podman.ps, we can see this container is in the upstate. And if I happen to take the name here, and I say pseudo-podman RM, page to 10, going to get that error right there.

8:33So make sure that we have the container stopped first. OK, this is another thing that was inferred. So let's stop this. Now it stopped. If I add it up and now try to remove it, it has been removed. Now, this is just for the elevated environment. If I say Podman PS, we can see we also have a running one within the test user environment. So again, we have the actual name here, as well as the alphanumeric ID, which should go with the name, and find it a little bit easier. And let's just say Podman, stop, page to 10, hit enter.

9:05And then finally, we can say Podman RM on loving Wilson. And if I just say Podman PS, we don't have anything running, do Podman PSA. That is also clear as well as pseudo-podman PS. That is clear as well as pseudo-podman PS-A, also clear. So friends, that is us for our validation challenge. I hope this has been informative for you, and I'd like to thank you for viewing.

Frequently asked questions

What does the Running Containers with Podman lesson cover?

The learner on your team practices starting, stopping, and removing container instances with podman run, podman stop, and podman rm, opening an interactive TTY session with podman run -it, and running commands in a live container with podman exec. The lesson also covers how namespaces isolate containers, how rootless and sudo Podman differ, and how to expose a containerized NGINX server through host port mapping.

What is the difference between podman run -it and podman exec?

Podman run builds and starts a brand new instance from an image, and the -it option drops the learner into an interactive TTY session inside that container's file system. Podman exec runs a command against a container that is already running, targeted by either its name or its container ID, so there is no need to spin up another instance from the same image.

Why do rootless Podman and sudo Podman show different container images?

Namespaces provide isolation, so running Podman as a regular user and running it with sudo are separate environments with their own images and containers. In the lesson, an NGINX image available to the regular user does not appear under sudo podman images, so it has to be pulled again for the elevated user.

Why does mapping a container to host port 1002 require sudo in Podman?

Ports 1 through 1023 are in the privileged range, so binding one of them on the host requires super user privileges. The lesson also shows that port mapping must be set when the container instance is created, which means a new NGINX instance is started from the same image rather than restarting an existing one.

How long is this Podman lesson and how does it fit the EX188 course?

The lesson runs about 45 minutes and is one part of the Red Hat Certified Developer in Cloud-native Applications (EX188) course, which is about 6 hours, 16 minutes per learner. It builds on the previous skill on pulling images and image versus instance, and leads into course topics such as custom images, private registries, storage, permissions, troubleshooting, and autostart behavior.

What should a team member know before starting the Running Containers with Podman lesson?

The lesson assumes the learner has already pulled an image from a registry and understands that an image is a blueprint while a container instance is the running copy, both covered in the prior skill. For IT Directors and Team Leads, the course is positioned for DevOps engineers or platform-focused practitioners with 3 to 5 years of DevOps tooling experience.

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