How to Run Secure Pods with Podman
What is Podman?
Podman is a Red Hat container engine that allows users to manage containerized applications and their resources. Unlike other container engines such as Docker, Podman operates as a standalone application instead of a daemon. Podman could be a Docker replacement.
As I stated in my previous article Docker, Docker was unsupported by Kubernetes a few years ago. But don't worry! Kubernetes does not support Docker as a runtime (dockershim), but images are still supported; Docker images are Open Container Image (OCI).
More information about this deprecation can be found here.
Return to the main topic! Podman provides a command-line interface (CLI) through which users can create, manage, and deploy containers in either rootless or rootfull mode. Podman runs containers as non-root users in rootless mode, which improves security by lowering the attack surface. Podman can run as the root user in rootfull mode, which provides access to system resources.
One of the key features of Podman is its support for pods, also known as Kubernetes, which are groups of containers that share the same network and storage resources. Pods enable users to deploy and manage complex applications that require communication between multiple containers, such as a database and a web application.
Don't worry! Podman also supports a variety of container image formats, including the Docker format, for close friends Dockerfile. This enables users to easily move containerized applications between container engines and platforms.
First, install Podman on your operational system by following the official instructions.
1. Choosing an image
Because size is an important consideration when selecting an image, let's keep Alpine Linux as our base mage. Just 40MB to lightweight and secure system. Only 40MB are required for a lightweight and secure system.
It is important to note that podman works with any Docker Registry, such as DockerHub images or Red Hat Quay.
2. Creating Containerfile
It's time to use Podman to build your pod. Let's create some asset files so we can build the container image. This time I choose Elixir application, on which I have been working for the last few years. The application will show a random fruit.
Elixir is a fabulous function language that runs on top of Erlang and was created by Brazilian JosΓ© Valim.
- mix.exs
defmodule Fruit.MixProject do
use Mix.Project
def project do
[
app: :fruit,
version: "0.0.1",
elixir: "~> 1.14",
start_permanent: Mix.env() == :prod,
deps: deps()
]
end
# Run "mix help compile.app" to learn about applications
def application do
[
extra_applications: [:logger]
]
end
# Run "mix help deps" to learn about dependencies
defp deps do
[
{:plug_cowboy, "~> 2.5"}
]
end
end
- server.ex
require Logger
defmodule Fruit.Plug do
import Plug.Conn
@fruits [
"π₯",
"π",
"π₯",
"π",
"π",
"π",
"π",
"π",
"π",
"π",
"π₯",
"π
",
"π",
"π",
"π",
"π"
]
def init(options), do: options
def call(conn, _opts) do
fruits_size = Kernel.length(@fruits)
index = :rand.uniform(fruits_size - 1)
fruit = Enum.at(@fruits, index)
conn
|> put_resp_content_type("text/plain">)
|> send_resp(200, "What kind of fruit is that? #{fruit}")
end
end
Logger.info("Starting application")
Plug.Adapters.Cowboy.http(Fruit.Plug, [], ip: {0, 0, 0, 0}, port: 3000)
- Containerfile
I named the file Containerfile, but the syntax is same to Dockerfile.
FROM docker.io/library/elixir:1.14-alpine
ENV MIX_ENV=prod
MAINTAINER [email protected]
WORKDIR /app
RUN mix local.hex --force && \
mix local.rebar --force
COPY mix.exs server.ex ./
RUN mix deps.get --all
RUN mix compile
EXPOSE 3000
CMD mix run --no-halt server.ex
3. Building a pod
Next, we'll use the build to command to convert our Containerfile into an image called my-first-pod.
podman build -t [image-name] [base-directory]
podman build -t my-first-pod .
4. Running a pod
We can run a pod in two modes: foreground mode (with your terminal attached) or background mode (with your terminal detached).
# attached
podman run --name my-first-pod --rm -p 3001:3000 my-first-pod
# detached
podman run -d --name my-first-pod -p 3001:3000 my-first-pod
# run command inside pod
podman exec -it my-first-pod sh
--name
to set a container unique name;--rm
remove container after stop container;-p 3001:3000
indicate that public port 3001 will be forwarded in container to private port 3000;-d
run at background mode with detached terminal;
Testing the pod
Then we'll use curl to send a request to your endpoint (http://localhost:3001/).
curl --location http://localhost:3001/
> What kind of fruit is that? π
Pod inspection
podman ps -a
podman images
podman logs -f my-first-pod
> fruit: π
podman exec -it my-first-pod sh
ps
list all pods available, without argument-a
list only running pods;images
list all built images;logs
inspect what pods are written to sdout or stderr;exec
run a command in a running container,-it
changes our terminal inside the container as interactive mode.
Cleanup
podman stop my-first-pod
podman rm my-first-pod
podman rmi my-first-pod
Final thoughts
If you prefer, you can clone the repository
Today, we'll build a pod with Podman. As you can see, Podman uses the same commands and syntax as Docker, making migration and replacement a breeze. As I said before, Docker is not completely incompatible with Kubernetes; however, Podman is an option; as Rockets(rkt), you should consider what fits your current Project or Team.
In the coming articles, I'll go over how to add multiple containers within pods, just like we did in Kubernetes.
Your kernel has been updated! God bless your day.
Time for feedback!