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.
$ 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
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.
$ 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
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.
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.
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"
As for build, it cannot be done like docker-compose, so use the podman command.
$ podman build -t node_app:latest -f Dockerfile ./
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
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.
Podman remote clients for macOS and Windows
Recommended Posts