Cloud Native Security. Chris Binnie
Читать онлайн книгу.Setting Up Podman
We are going to use the Ubuntu 20.04 Long Term Support (LTS) release to run Podman as rootless. This is because according to the docs (github.com/containers/podman/blob/master/docs/tutorials/rootless_tutorial.md
), if you read this important note about the fuse-overlayfs
package, you need at least version 0.7.6: “This especially needs to be checked on Ubuntu distributions as fuse-overlayfs
is not generally installed by default and the 0.7.6 version is not available natively on Ubuntu releases prior to 20.04.”
To install Podman, notably this time as the root
user, we will first add a source to the apt
package manager this way as one long command which should go on one line:
$ echo "deb https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu _20.04/ /" | sudo tee /etc/apt/sources.list.d/devel:kubic:libcontainers:stable.list
If you're not using Ubuntu 20.04, then alter the 20.04 string in the previous command. If you want to try other Linux distributions, then you can use this page: podman.io/getting-started/installation
.
Next, we need to add the repository's key to our keyring as a trusted source (changing 20.04 if required again) which is one line command:
$ curl -L
https://download.opensuse.org/repositories/devel:/kubic:/libcontainers:/stable/xUbuntu_18.04/Release.key | sudo apt-key add -
A successful response is OK
.
Now, refresh your packages and upgrade any that require upgrading:
$ sudo apt-get update; sudo apt-get upgrade -y
We should now be able to install Podman as follows:
$ apt-get -y install podman
Note the output from that command, shown here, so you can get an idea of the underlying components used:
Recommended packages: crun slirp4netns varlink The following NEW packages will be installed catatonit conmon containernetworking-plugins containers-common containers-golang containers-image crun libyajl2 podman podman-plugins runc slirp4netns uidmap varlink
Check that Podman has installed correctly:
$ podman -v podman version 2.0.4
We need to check our UID and GID mapping settings files to run rootless containers next. Run these commands and delete any entries (only on a development system!) to check that they are empty:
$ cat /etc/subuid $ cat /etc/subgid
This is the point where you might want to create a specific user for running rootless containers. Simply use the adduser
command with a username of your choice, such as poduser
, and follow the prompts:
$ sudo adduser poduser
We will stick with user chris
, however, for continuity.
Now we want to populate the subuid
and subgid
files in the /etc
directory. Use this command to set the ranges of UIDs and GIDS that you want to use, changing the name of the user at the end to suit your requirements:
$ sudo usermod --add-subuids 200000-201000 --add-subgids 200000-201000 chris
Without any more tweaking or fiddling, we are ready to run Podman in rootless mode. It has been a particularly painless process so far.
First, however, remember that Podman is not running as a daemon. Take a look with this command (to be really sure, run this as the root
user to see any hidden processes in the process table, and not only as the chris
user):
$ ps -ef | grep podman
The only output you should see is the grep
command that you've just run. But, if we run this Podman command, we should see a service ready and waiting:
$ podman ps CONTAINER ID IMAGE COMMAND CREATED STATUS PORTS NAMES
It looks remarkably familiar, just as Docker Engine would output. Using the chris
user we can start up a container using another familiar command for Apache:
$ podman run -it -p 8000:80 httpd:latest
We have not added the -d
switch to that command, and Listing 2.4 shows the STDOUT
logging (output straight to the terminal).
Listing 2.4: Podman Running Rootless with Little Effort
AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using 10.0.2.100. Set the 'ServerName' directive globally to suppress this message [Tue Aug 29 14:09:20.303062 2020] [mpm_event:notice] [pid 1:tid 140532155102336] AH00489: Apache/2.4.46 (Unix) configured -- resuming normal operations [Tue Aug 29 14:09:20.304849 2020] [core:notice] [pid 1:tid 140532155102336] AH00094: Command line: 'httpd -D FOREGROUND'
Just as we did before with Docker in rootless mode, let's see how our networking is set up. We will open up another terminal (as the chris
user) and try this command:
$ podman ps CONTAINER ID IMAGE COMMAND CREATED e09883662c2b docker.io/library/httpd:latest httpd-foreground
The abbreviated output proves we have httpd
running as hoped. It is worth noting that other standard users will not have visibility of Podman container processes, but the user chris
certainly does. We can see the container is definitely running, and not as the root
user:
$ ps -ef | grep podman
The abbreviated output from that command shows, among other entries:
chris 6069 6035 podman run -it -p 8000:80 httpd:latest
Do we need to access the container via the host's network, as we did with Docker? We can test with this command:
$ curl localhost 8000 <html><body><h1>It works!</h1></body></html>
The answer is yes, we've exposed a nonprivileged port (TCP port 8000) and can access the container via the localhost
. If you get stuck, check firewalling rules or other container runtimes that are still installed.
One difference between Docker and Podman in rootless mode is that Podman does not allocate an IP address by default. Using the previous podman ps
command, we can see our container's hash ID is e09883662c2b
. The next command should offer us internal IP addresses, but not in Podman containers:
$ podman inspect e098 | grep IP "IPAddress": "", "IPPrefixLen": 0, "IPv6Gateway": "", "GlobalIPv6Address": "", "GlobalIPv6PrefixLen": 0, "LinkLocalIPv6Address": "", "LinkLocalIPv6PrefixLen": 0,
The top line in the output demonstrates that an IP address doesn't appear to be allocated, even though from a container's perspective an IP address is actually allocated via slirp4netns
(the component that provides userspace networking functionality that was installed earlier). The container can apparently only communicate over the network with the host and beyond (and not other containers). There is more information at github.com/rootless-containers/slirp4netns
. Thanks to the fact that Podman provides no default networking bridge, this is a limitation when using slirp4netns
, which is part and parcel or using rootless mode.
If you need to run the ping
command from a rootless container for any reason, you might need to tweak the kernel. You can temporarily adjust the tunable kernel setting with this syntax:
$ sysctl -w "net.ipv4.ping_group_range=0 2000000"
To make sure this setting survives reboots, you should add the following command to copy it to a file:
$ echo "net.ipv4.ping_group_range=0 2000000" >> /etc/sysctl.conf