Podman 이란?

Red Hat Enterprise Linux 8 / CentOS 8 부터는 Docker 대신 Podman 이라는 도구를 제공합니다.
PodmanDocker 와 동일하게 단일 노드에서 pod, 컨테이너 이미지 및 컨테이너를 관리합니다.
Pod 라고 하는 컨테이너 및 컨테이너 그룹을 관리할 수 있는 libpod 라이브러리를 기반으로 합니다.

이번 포스팅에서는 Podman 의 설치 및 기본 사용법에 대해 확인 해보겠습니다.

Docker VS Podman

DockerPodman 은 아래와 같이 “컨테이너 Cli 가 컨테이너를 어떻게 생성하냐” 의 차이가 있습니다.


- Docker 구조 -
- Podman 구조 -

사진 출처: Red Hat(하단 첨부)

위와 같은 구조적인 차이로 인해 예전에 Docker 에서는 systemd 를 이용하여 docker daemon을 재시작 하거나 중지를 하면 운영중인 컨테이너에 영향을 주었습니다.
하지만 PodmanDocker 와 달리 서로 간섭이 없는 컨테이너를 생성 할 수 있습니다.
일종의 PID 가 다른 프로세서라고 생각하면 됩니다.

Podman 설치

Podman 설치는 Docker 설치 만큼 쉽습니다.
참고로 현재 CentOS 7 에서는 DockerPodman 을 동시에 지원하니 기존에 Docker 로 쓰던 컨테이너를 Podman 으로도 전환이 가능합니다.

[root@fastvm-centos-7-7-41 ~]# yum -y install podman

위와 같이 명령 수행만 하면 설치는 완료됩니다.
설치만 보면 Docker 보다 쉽습니다. 특이한 점은 systemd 설정 할 필요가 없습니다.

[root@fastvm-centos-7-7-41 ~]# systemctl list-units | grep -i pod
[root@fastvm-centos-7-7-41 ~]#

위와 같이 Docker 와 다르게 systemd 로 서비스를 시작할 필요가 없습니다.

Podman 기본 사용법

Podman 의 기본 사용법을 알아보겠습니다.

컨테이너 생성

[root@fastvm-centos-7-7-41 ~]# podman run --help
Run a command in a new container

Description:
  Runs a command in a new container from the given image

Usage:
  podman run [flags] IMAGE [COMMAND [ARG...]]

위와 같은 구문을 이용하여 아래와 같이 컨테이너 생성이 가능합니다.

[root@fastvm-centos-7-7-41 ~]# podman run -ti -d --name web httpd
72f4b9dde39323f8a98188ba96c36552e3d98f30931256504aca71d3024fe01b
[root@fastvm-centos-7-7-41 ~]#

컨테이너 구동 확인

[root@fastvm-centos-7-7-41 ~]# podman ps --help
List containers

Description:
  Prints out information about the containers

Usage:
  podman ps [flags]

위와 같은 구문을 통해 확인이 가능하며, 아래와 같이 컨테이너의 상태를 확인 할 수 있습니다.

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED         STATUS                     PORTS  NAMES
72f4b9dde393  docker.io/library/httpd:latest  httpd-foreground  4 seconds ago   Up 3 seconds ago                  web
ea2aabb1fe18  docker.io/library/httpd:latest  httpd-foreground  20 seconds ago  Exited (0) 17 seconds ago         relaxed_hypatia

컨테이너 중지

stop 이라는 옵션을 통해 컨테이너 중지가 가능하며 ps 구문을 통해 상태 확인이 가능합니다.

[root@fastvm-centos-7-7-41 ~]# podman stop web
72f4b9dde39323f8a98188ba96c36552e3d98f30931256504aca71d3024fe01b

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED             STATUS                         PORTS  NAMES
72f4b9dde393  docker.io/library/httpd:latest  httpd-foreground  51 seconds ago      Exited (0) 2 seconds ago              web
ea2aabb1fe18  docker.io/library/httpd:latest  httpd-foreground  About a minute ago  Exited (0) About a minute ago         relaxed_hypatia

컨테이너 시작

중지된 컨테이너는 start 옵션을 통해 컨테이너 시작이 가능합니다.

[root@fastvm-centos-7-7-41 ~]# podman start web
web

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED             STATUS                         PORTS  NAMES
72f4b9dde393  docker.io/library/httpd:latest  httpd-foreground  About a minute ago  Up 1 second ago                       web
ea2aabb1fe18  docker.io/library/httpd:latest  httpd-foreground  About a minute ago  Exited (0) About a minute ago         relaxed_hypatia

컨테이너 이미지 확인

현재 Host 에 Pull 된 컨테이너 이미지를 확인 할 수 있습니다.

[root@fastvm-centos-7-7-41 ~]# podman images
REPOSITORY                TAG      IMAGE ID       CREATED      SIZE
docker.io/library/httpd   latest   c5a012f9cf45   4 days ago   170 MB

컨테이너 이미지 Pull

Red Hat registry 혹은 Docker Hub 의 컨테이너 이미지를 Pull 할 수 있습니다.

[root@fastvm-centos-7-7-41 ~]# podman pull centos
Trying to pull registry.access.redhat.com/centos...ERRO[0001] Error pulling image ref //registry.access.redhat.com/centos:latest: Error initializing source docker://registry.access.redhat.com/centos:latest: Error reading manifest latest in registry.access.redhat.com/centos: name unknown: Repo not found
Failed
Trying to pull docker.io/library/centos...Getting image source signatures
Copying blob 8a29a15cefae done
Copying config 470671670c done
Writing manifest to image destination
Storing signatures
470671670cac686c7cf0081e0b37da2e9f4f768ddc5f6a26102ccd1c6954c1ee

[root@fastvm-centos-7-7-41 ~]# podman images
REPOSITORY                 TAG      IMAGE ID       CREATED       SIZE
docker.io/library/httpd    latest   c5a012f9cf45   5 days ago    170 MB
docker.io/library/centos   latest   470671670cac   6 weeks ago   245 MB

컨테이너 삭제

아래와 같이 rm 옵션을 이용하여 컨테이너를 삭제할 수 있습니다.

[root@fastvm-centos-7-7-41 ~]# podman rm relaxed_hypatia
ea2aabb1fe18e2937131bc76ae7dee0d95d92334865ff2938c67752142c27c21

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS                 PORTS  NAMES
72f4b9dde393  docker.io/library/httpd:latest  httpd-foreground  2 minutes ago  Up About a minute ago         web

컨테이너 Port Mapping

지금까지 기본 사용법을 보면 Docker 와 매우 흡사한 옵션 사용법입니다.
Port Mapping 또한 마찬가지입니다.


[root@fastvm-centos-7-7-41 ~]# podman run -ti -d -p 80:80 --name web httpd
07e14dc469e6247c181daeac723c116a142f466a0273c638f4724bb75a173cbc

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND           CREATED        STATUS            PORTS               NAMES
07e14dc469e6  docker.io/library/httpd:latest  httpd-foreground  4 seconds ago  Up 3 seconds ago  0.0.0.0:80->80/tcp  web

[root@fastvm-centos-7-7-41 ~]# curl 127.0.0.1
<html><body><h1>It works!</h1></body></html>

위와 같이 -p 옵션이 동일하게 존재하며 사용이 가능합니다.

이처럼 명령어들이 Docker 에서 사용하던 방식과 동일합니다.
처음 접하거나 Docker 만 사용하던 사용자도 쉽게 접근이 가능합니다.

Podman 에서만 제공되는 기능

Podman 에는 Podman 에서만 제공되는 특별한 기능이 추가되어 있습니다.

systemd generate 제공

containerd 로 하나로 관리되던 Docker 와 달리 각 프로세서로 생성이 되는 Podman 은 각 컨테이너 별로 systemd 의 서비스 파일을 생성하여 관리를 할 수 있습니다.

generate 구문

[root@fastvm-centos-7-7-41 ~]# podman generate --help
Generate structured data based for a containers and pods

Usage:
  podman generate [command]

Available Commands:
  kube        Generate Kubernetes pod YAML from a container or pod
  systemd     Generate a systemd unit file for a Podman container

생성 방법

1) 일반 컨테이너 생성

[root@fastvm-centos-7-7-41 ~]# podman run -d --name redis_server -p 6379:6379 redis

2) systemd 서비스 파일 생성

[Unit]
Description=Redis container

[Service]
Restart=always
ExecStart=/usr/bin/podman start -a redis_server
ExecStop=/usr/bin/podman stop -t 2 redis_server

[Install]
WantedBy=local.target

위와 같이 /etc/systemd/system/redis_server.service 파일을 생성하거나,

[root@fastvm-centos-7-7-41 system]# podman generate systemd redis_server  > /etc/systemd/system/redis_server.service

[root@fastvm-centos-7-7-41 system]# cat redis_server.service
[Unit]
Description=7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3 Podman Container
[Service]
Restart=on-failure
ExecStart=/usr/bin/podman start 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3
ExecStop=/usr/bin/podman stop -t 10 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3
KillMode=none
Type=forking
PIDFile=/var/lib/containers/storage/overlay-containers/7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3/userdata/7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3.pid
[Install]
WantedBy=multi-user.target

위와 같이 generate 옵션을 통해 서비스 파일을 생성하고 Start 구문 및 Stop 구문, 기타 옵션을 컨테이너 실행 상황에 맞게 수정합니다.

3) systemd 를 이용하여 컨테이너 관리

컨테이너 시작

[root@fastvm-centos-7-7-41 ~]# systemctl start redis-container.service

[root@fastvm-centos-7-7-41 ~]# systemctl status redis-container.service
● redis-container.service - Redis container
   Loaded: loaded (/etc/systemd/system/redis-container.service; enabled; vendor preset: disabled)
   Active: active (running) since Mon 2020-03-02 21:34:15 KST; 3s ago
 Main PID: 6508 (podman)
   CGroup: /system.slice/redis-container.service
           └─6508 /usr/bin/podman start -a redis_server

Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:C 02 Mar 2020 12:34:16.140 # oO0OoO0OoO0Oo Redis is starting oO0OoO0OoO0Oo
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:C 02 Mar 2020 12:34:16.140 # Redis version=5.0.7, bits=64, commit=00000000, modified=0, pid=1, just started
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:C 02 Mar 2020 12:34:16.140 # Warning: no config file specified, using the default config. In order to specify a config file use redis-server /path/to/redis.conf
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.141 * Running mode=standalone, port=6379.
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.141 # WARNING: The TCP backlog setting of 511 cannot be enforced because /proc/sys/net/core/somaxconn is set to the lower value of 128.
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.141 # Server initialized
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.141 # WARNING overcommit_memory is set to 0! Background save may fail under low memory condition. To fix this issue add 'vm.overcommit_memory = 1' to /etc/sysctl.conf and th...this to take effect.
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.141 # WARNING you have Transparent Huge Pages (THP) support enabled in your kernel. This will create latency and memory usage issues with Redis. To fix this issue run the command 'echo never > ...
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.142 * DB loaded from disk: 0.000 seconds
Mar 02 21:34:16 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:16.142 * Ready to accept connections
Hint: Some lines were ellipsized, use -l to show in full.

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND               CREATED      STATUS            PORTS                   NAMES
7eac708eb651  docker.io/library/redis:latest  docker-entrypoint...  6 hours ago  Up 8 seconds ago  0.0.0.0:6379->6379/tcp  redis_server

컨테이너 중지

[root@fastvm-centos-7-7-41 ~]# systemctl stop redis-container.service

[root@fastvm-centos-7-7-41 ~]# systemctl status redis-container.service
● redis-container.service - Redis container
   Loaded: loaded (/etc/systemd/system/redis-container.service; enabled; vendor preset: disabled)
   Active: inactive (dead)

Mar 02 21:34:33 fastvm-centos-7-7-41 podman[6508]: 1:signal-handler (1583152473) Received SIGTERM scheduling shutdown...
Mar 02 21:34:33 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:33.902 # User requested shutdown...
Mar 02 21:34:33 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:33.902 * Saving the final RDB snapshot before exiting.
Mar 02 21:34:33 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:33.904 * DB saved on disk
Mar 02 21:34:33 fastvm-centos-7-7-41 podman[6508]: 1:M 02 Mar 2020 12:34:33.904 # Redis is now ready to exit, bye bye...
Mar 02 21:34:34 fastvm-centos-7-7-41 podman[6625]: 2020-03-02 21:34:34.0168744 +0900 KST m=+0.172658043 container died 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3 (image=docker.io/library/redis:latest, name=redis_server)
Mar 02 21:34:34 fastvm-centos-7-7-41 podman[6625]: 2020-03-02 21:34:34.018181553 +0900 KST m=+0.173965114 container stop 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3 (image=docker.io/library/redis:latest, name=redis_server)
Mar 02 21:34:34 fastvm-centos-7-7-41 podman[6625]: 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3
Mar 02 21:34:34 fastvm-centos-7-7-41 podman[6508]: time="2020-03-02T21:34:34+09:00" level=error msg="Error forwarding signal 15 to container 7eac708eb65114d7f37773315f6565c718a440df3cc2211ace17e85cd9699bc3": can only kill running containers. 7eac708eb65114d7f37773315f65...
Mar 02 21:34:34 fastvm-centos-7-7-41 systemd[1]: Stopped Redis container.
Hint: Some lines were ellipsized, use -l to show in full.

[root@fastvm-centos-7-7-41 ~]# podman ps -a
CONTAINER ID  IMAGE                           COMMAND               CREATED      STATUS                    PORTS                   NAMES
7eac708eb651  docker.io/library/redis:latest  docker-entrypoint...  6 hours ago  Exited (0) 6 seconds ago  0.0.0.0:6379->6379/tcp  redis_server

kubernetes yaml generate 제공

Kubernetes 에서 바로 사용이 가능한 Yaml 파일 형식을 생성합니다.
1) Yaml 파일 생성

[root@fastvm-centos-7-7-41 ~]# podman generate kube web
# 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-1.4.4
apiVersion: v1
kind: Pod
metadata:
  creationTimestamp: "2020-03-01T12:53:22Z"
  labels:
    app: web
  name: web
spec:
  containers:
  - command:
    - httpd-foreground
    env:
    - name: PATH
      value: /usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
    - name: TERM
      value: xterm
    - name: HOSTNAME
    - name: container
      value: podman
    - name: HTTPD_PATCHES
    - name: HTTPD_PREFIX
      value: /usr/local/apache2
    - name: HTTPD_VERSION
      value: 2.4.41
    - name: HTTPD_SHA256
      value: 133d48298fe5315ae9366a0ec66282fa4040efa5d566174481077ade7d18ea40
    image: docker.io/library/httpd:latest
    name: web
    ports:
    - containerPort: 80
      hostPort: 80
      protocol: TCP
    resources: {}
    securityContext:
      allowPrivilegeEscalation: true
      capabilities: {}
      privileged: false
      readOnlyRootFilesystem: false
    stdin: true
    tty: true
    workingDir: /usr/local/apache2
status: {}

2) Kubernetes 에 배포

[root@master1 ~]# kubectl create -f podman-gen-web.yml
pod/web created

[root@master1 ~]# kubectl get pod
NAME   READY   STATUS    RESTARTS   AGE
web    1/1     Running   0          5s

3) Pod 상세 내용 확인

[root@master1 ~]# kubectl describe pod web
Name:         web
Namespace:    default
Priority:     0
Node:         worker2.example.com/192.168.200.55
Start Time:   Sun, 01 Mar 2020 21:57:52 +0900
Labels:       app=web
Annotations:  <none>
Status:       Running
IP:           10.233.95.5
Containers:
  web:
    Container ID:  docker://b98767502847b34d4653a9a89dc7284b9307d5e02afe7ed1d4118bdf43e7689f
    Image:         docker.io/library/httpd:latest
    Image ID:      docker-pullable://httpd@sha256:946c54069130dbf136903fe658fe7d113bd8db8004de31282e20b262a3e106fb
    Port:          80/TCP
    Host Port:     80/TCP
    Command:
      httpd-foreground
    State:          Running
      Started:      Sun, 01 Mar 2020 21:57:56 +0900
    Ready:          True
    Restart Count:  0
    Environment:
      PATH:           /usr/local/apache2/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
      TERM:           xterm
      HOSTNAME:
      container:      podman
      HTTPD_PATCHES:
      HTTPD_PREFIX:   /usr/local/apache2
      HTTPD_VERSION:  2.4.41
      HTTPD_SHA256:   133d48298fe5315ae9366a0ec66282fa4040efa5d566174481077ade7d18ea40
    Mounts:
      /var/run/secrets/kubernetes.io/serviceaccount from default-token-lr7dh (ro)
Conditions:
  Type              Status
  Initialized       True
  Ready             True
  ContainersReady   True
  PodScheduled      True
Volumes:
  default-token-lr7dh:
    Type:        Secret (a volume populated by a Secret)
    SecretName:  default-token-lr7dh
    Optional:    false
QoS Class:       BestEffort
Node-Selectors:  <none>
Tolerations:     node.kubernetes.io/not-ready:NoExecute for 300s
                 node.kubernetes.io/unreachable:NoExecute for 300s
Events:
  Type    Reason     Age   From                          Message
  ----    ------     ----  ----                          -------
  Normal  Scheduled  100s  default-scheduler             Successfully assigned default/web to worker2.example.com
  Normal  Pulling    99s   kubelet, worker2.example.com  Pulling image "docker.io/library/httpd:latest"
  Normal  Pulled     96s   kubelet, worker2.example.com  Successfully pulled image "docker.io/library/httpd:latest"
  Normal  Created    96s   kubelet, worker2.example.com  Created container web
  Normal  Started    96s   kubelet, worker2.example.com  Started container web

참고 자료

chhanz's profile image

chhanz

2020-03-02

Read more posts by this author