Investigate the replacement from Docker to Podman.

Introduction

There is a flow of replacement from Docker to Podman. With Docker for Mac, I was able to operate Docker transparently from the Mac, and I was able to perform convenient operations with docker-compose, but what about the current situation with podman? In this article, I will summarize that area.

Environmental information

$ sw_vers
ProductName:    Mac OS X
ProductVersion: 10.15.6
BuildVersion:   19G2021

$ VBoxManage -v
6.0.8r130520

$ vagrant -v
Vagrant 2.2.9

Setup

There are two things to do.

--VM Setup in Podman environment --Podman-remote Setup on Mac

VM Setup in Podman environment

There are boot2 podman, podman-machine, and podman-specific VMs to build, but I'll try to build them with the familiar Vagrant. First, prepare a Vagrantfile. The point is to allocate a fixed IP for the private network

Vagrantfile


Vagrant.configure("2") do |config|
  config.vm.box = "fedora/32-cloud-base"

  config.vm.provider "virtualbox" do |vb|
    vb.memory = "2048"
  end

  config.vm.network :private_network, ip: "192.168.33.11"

end

Then start and login

$ vagrant up
...

$ vagrant ssh
[vagrant@localhost ~]$

After vagrant login, set podman.

[vagrant@localhost ~]$ sudo dnf -y install podman

[vagrant@localhost ~]$ systemctl --user enable podman.socket
Created symlink /home/vagrant/.config/systemd/user/sockets.target.wants/podman.socket → /usr/lib/systemd/user/podman.socket.

[vagrant@localhost ~]$ sudo loginctl enable-linger $USER

[vagrant@localhost ~]$ systemctl --user status podman.socket
● podman.socket - Podman API Socket
     Loaded: loaded (/usr/lib/systemd/user/podman.socket; enabled; vendor preset: disabled)
     Active: inactive (dead)
   Triggers: ● podman.service
       Docs: man:podman-system-service(1)
     Listen: /run/user/1000/podman/podman.sock (Stream)

[vagrant@localhost ~]$ systemctl --user start podman.socket

[vagrant@localhost ~]$ systemctl --user status podman.socket
● podman.socket - Podman API Socket
     Loaded: loaded (/usr/lib/systemd/user/podman.socket; enabled; vendor preset: disabled)
     Active: active (listening) since Fri 2020-09-11 06:29:56 UTC; 3s ago
   Triggers: ● podman.service
       Docs: man:podman-system-service(1)
     Listen: /run/user/1000/podman/podman.sock (Stream)
     CGroup: /user.slice/user-1000.slice/[email protected]/podman.socket

Sep 11 06:29:56 localhost.localdomain systemd[2509]: Listening on Podman API Socket.

[vagrant@localhost ~]$ podman --remote info
host:
  arch: amd64
  buildahVersion: 1.15.1
  cgroupVersion: v2
...

That's it.

Podman remote setup on Mac side

$ brew install podman

$ podman --version
podman version 2.0.6

$ podman system connection add vagrant --identity $HOME/podman_env/.vagrant/machines/default/virtualbox/private_key ssh://[email protected]/run/user/1000/podman/podman.sock

$ podman system connection list
Name      Identity                                                                      URI
vagrant*  /Users/seijitada/podman_env/.vagrant/machines/default/virtualbox/private_key  ssh://[email protected]:22/run/user/1000/podman/podman.sock

$ podman info
host:
  arch: amd64
  buildahVersion: 1.15.1
  cgroupVersion: v2
...

That's it.

Operation

I often used docker to do these with podman by the following operations.

--docker-compose like operation --Communication between Containers --Using Volume --Image build --Communication from outside Container

docker compose like operation

podman also has a docker-compose like unofficial tool called podman-compose, I use this because the function to read Kubernetes yaml built in podman is good. Kubernetes yaml seems to be able to be made from scratch if you are used to it, but here I will try to automatically generate it from podman.

$ podman pod create -n pod01
06267e4e35e53ff1c7cf843fd74c617601870a7b82e5eb2404053fdc2f54f1ce

$ podman run --pod pod01 -d --name postgres -e POSTGRES_PASSWORD=password postgres:13
f54a6902a3e0d7b62ec3a1b4c92f637b14c2ea6dd8fbd8856804e9692b870f50

$ podman pod ls
POD ID        NAME    STATUS   CREATED             # OF CONTAINERS  INFRA ID
06267e4e35e5  pod01   Running  About a minute ago  2                2a9e30d39f67

$ podman ps
CONTAINER ID  IMAGE                          COMMAND   CREATED             STATUS             PORTS   NAMES
2a9e30d39f67  k8s.gcr.io/pause:3.2                     About a minute ago  Up 21 seconds ago          06267e4e35e5-infra
f54a6902a3e0  docker.io/library/postgres:13  postgres  21 seconds ago      Up 20 seconds ago          postgres

$ podman generate kube pod01 > pod01.yaml

$ cat pod01.yaml
# Generation of Kubernetes YAML is still under development!
#
# Save the output of this file and use kubectl create -f to import
# it into Kubernetes.
#
# Created with podman-2.0.6
apiVersion: v1
kind: Pod

Like this, you can use the podman generate kube command to generate Kubernetes yaml from a pod or container that is currently running. Next, let's load the generated Kubenetes yaml.

$ podman pod rm pod01 -f
06267e4e35e53ff1c7cf843fd74c617601870a7b82e5eb2404053fdc2f54f1ce

$ podman pod ls
POD ID  NAME    STATUS  CREATED  # OF CONTAINERS  INFRA ID

$ podman play kube pod01.yaml
Pod:
4203ed53e966d6c0f8c2ae8008efe9fb9cc42fb73d9a1b06831de664cdfa5843
Container:
f62bf71b3f8ea19b0c2084bf21cd2d7dbfa9f18097d14c213a49fb9c562d3b6e

$ podman pod ls
POD ID        NAME    STATUS   CREATED         # OF CONTAINERS  INFRA ID
4203ed53e966  pod01   Running  11 seconds ago  2                4058387dce44

$ podman ps
CONTAINER ID  IMAGE                 COMMAND  CREATED         STATUS             PORTS   NAMES
4058387dce44  k8s.gcr.io/pause:3.2           22 seconds ago  Up 21 seconds ago          4203ed53e966-infra

$ podman ps -a
CONTAINER ID  IMAGE                          COMMAND   CREATED         STATUS                     PORTS   NAMES
4058387dce44  k8s.gcr.io/pause:3.2                     27 seconds ago  Up 26 seconds ago                  4203ed53e966-infra
f62bf71b3f8e  docker.io/library/postgres:13  postgres  27 seconds ago  Exited (1) 26 seconds ago          pod01-postgres

I can use Kubernetes yaml with the podman play kube command, but somehow postgres isn't working properly. Looking at the log, it seems that I'm trying to give postgres as root.

$ podman logs pod01-postgres
"root" execution of the PostgreSQL server is not permitted.
The server must be started under an unprivileged user ID to prevent
possible system security compromise.  See the documentation for
more information on how to properly start the server.

When I looked it up, it seems that Kubernetes yaml has a specification that overwrites the Entry point of Image by specifying spec.containers.command. It seems that this is specified in Kubernetes yaml generated by podman kube generate. So if you fix it here ok

$ cp pod01.yaml pod01.yaml.bk

# vim pod01.yaml
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2020-09-11T06:56:41Z"
  labels:
    app: pod01
  name: pod01
spec:
  containers:
  - command:               <----Not needed here
    - postgres             <----Not needed here
    env:

$ diff pod01.yaml.bk pod01.yaml
16,18c16
<   - command:
<     - postgres
<     env:
---
>   - env:

$ podman pod rm pod01 -f
4203ed53e966d6c0f8c2ae8008efe9fb9cc42fb73d9a1b06831de664cdfa5843

$ podman play kube pod01.yaml
Pod:
3cd402c2bc67b07fc31f845de84169ba574d8171c263c6a74aeec816fbf0e234
Container:
f6278b9af26d956185618b5424792f240d814cca3ed34d02ca0df63cc2c73fcb

$ podman ps
CONTAINER ID  IMAGE                          COMMAND               CREATED         STATUS             PORTS   NAMES
12f881ec8125  k8s.gcr.io/pause:3.2                                 11 seconds ago  Up 10 seconds ago          3cd402c2bc67-infra
f6278b9af26d  docker.io/library/postgres:13  docker-entrypoint...  10 seconds ago  Up 10 seconds ago          pod01-postgres

Now you can see that you can boot from kubernetes yaml with podman play kube.

Communication between Containers

For communication between Containers, in the case of docker-compose, a network was created so that it could be accessed by the container name. In the case of podman, it is pod (shared ipc, net, uts), so communication on localhost and inter-process communication are possible.

Use of Volume

docker-compose allowed bind mount and volume mount, but podman play seems to support only hostPath (bind mount) for now. In order to use hostPath, it is necessary to create a path on the vm side in advance, and it is necessary to pay attention to the SELinux related specifications.

[vagrant@localhost ~]$ mkdir -p /tmp/pg_data


$ cat pod01.yaml
...
spec:
  containers:
  ...
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
      seLinuxOptions:
        type: spc_t              <----Host access privileges are granted on SELinux.
    workingDir: /
    volumeMounts:
    - mountPath: /var/lib/postgresql/data
      name: pg_data
  volumes:
  - name: pg_data
    hostPath:
      path: "/tmp/pg_data"

Image build

As for build, it cannot be done like docker-compose, so use the podman command.

$ podman build -t node_app:latest -f Dockerfile ./

Communication from outside Container

For Kubernetes yaml, it is possible by adding spec.containers.ports. You can access from your PC to the fixed IP set in Vagrant.

    ports:
    - containerPort: 5432
      hostPort: 5432
      protocol: TCP

Summary

It's not Docker compatible, but it seems that it can be used at this stage to the extent that it is not a problem for practical use. Expect further expansion in the future.

Reference material

Podman remote clients for macOS and Windows

Recommended Posts

Investigate the replacement from Docker to Podman.
Migrating from vargrant to docker
[Docker] How to access the host from inside the container. http://host.docker.internal:
The road from JavaScript to Java
Update MySQL from 5.7 to 8.0 with Docker
[Ruby] From the basics to the inject method
[Docker] Copy files from docker container to host
How to check the logs in the Docker container
[Rails] I tried to raise the Rails version from 5.0 to 5.2
Migration from Eclipse to IntelliJ (on the way)
How to get a heapdump from a Docker container
Setting to exit from Docker container with VScode
Copy files from docker container to host (docker cp)
I was addicted to not being able to connect to AWS-S3 from the Docker container
Introduce docker to the application you are creating
Push the image to docker hub using Jib
Temporarily move Docker environment from Mac to AWS
3. Create a database to access from the web module
From the introduction of devise to the creation of the users table
[Java] I want to calculate the difference from the date
Tokoro I rewrote in the migration from Wicket 7 to 8
Volume 3 types of Docker Compose considered from the purpose
How to write Scala from the perspective of Java
How to deploy to Heroku from a local docker image
I tried to summarize the state transition of docker
[Java] How to extract the file name from the path
List how to learn from Docker to AKS on AWS
The story of migrating from Paperclip to Active Storage
Communicate from the outside to the container launched by docker-compose
How to determine the look-ahead request (Prefetch) from the browser
[Android] Uploading images from your device to the server
Kotlin may take the world from App to Web
Command to try using Docker for the time being
Push Docker images from GitHub Actions to GitHub Container Registry
Changes from Java 8 to Java 11
Sum from Java_1 to 100
Migrate from JUnit 4 to JUnit 5
The story of migrating a stray batch without an owner from EC2 to a Docker environment
What to do if you change the Listen Address from the settings screen with Mattermost docker
How to install Docker
When I started ansible + docker now, I stumbled from the beginning, but I managed to start it
From Java to Ruby !!
I can't find the docker image after updating to docker desktop 2.4.0.0
The story of raising Spring Boot from 1.5 series to 2.1 series part2
Let's write how to make API with SpringBoot + Docker from 0
How to transition from the [Swift5] app to the iPhone settings screen
Try switching from the RHEL environment to the Ubuntu environment Server installation
Understand the rough flow from request to response in SpringWebMVC
[Introduction to Docker] ~ The shortest explanation until starting jupyter lab ~
The key to running Docker on Raspberry Pi 4 (Ubuntu server 20.04)
[Note] Flow from docker installation to JupyterLab startup on ubuntu
[JDBC] I tried to access the SQLite3 database from Java.
Generate JSON from JVM class files to see the hierarchy
Get to the abbreviations from 5 examples of iterating Java lists
Wait for the container service to start with docker healthcheck
[IOS] How to get the table name from AWS DynamoDB
How to create a form to select a date from the calendar
Android app to select and display images from the gallery
How to get the longest information from Twitter as of 12/12/2016
What I did in the version upgrade from Ruby 2.5.2 to 2.7.1
How to disable Set-Cookie from API on the front side