Podman

김재현·2024년 1월 31일
1
post-thumbnail

Podman 이란?

Podman 은 컨테이너화된 애플리케이션을 관리하고 실행하기 위한 도구이다.
리눅스 컨테이너를 관리하기 위한 CLI 도구로 Docker 와 유사한 기능을 갖고 있다.

컨테이너는 소프트웨어 애플리케이션을 패키징하고 실행하기 위한 격리된 환경을 말한다.

1. Podman vs Docker

1. 데몬(Daemon) 존재 여부

  • Docker: 백그라운드에 실행되는 데몬 프로세스가 필요하다.
  • Podman: 데몬 없이 동작한다.

2. 루트리스(Rootless) 컨테이너 지원

  • Docker: 보통은 루트 권한이 필요하고, 다른 사용자의 권한으로 실행할 경우 추가 구성이 필요하다.
  • Podman: 기본적인 루트리스 컨테이너를 지원한다.

3. 네트워크 모델

  • Docker: 기본적으로 'docker0' 브리지를 사용하여 컨테이너 간 및 호스트와의 네트워크 통신을 관리한다.
  • Podman: CNI(Container Network Interface) 플러그인을 사용하여 네트워크를 관리한다.

    CNI(Container Network Interface):
    컨테이너 오케스트레이션 시스템에서 네트워킹을 관리하기 위한 표준 인터페이스이다.
    컨테이너화된 애플리케이션은 종종 다른 애플리케이션 또는 서비스와 통신해야 하는데,
    이러한 네트워킹을 관리하고 제어하기 위한 표준화된 방법을 제공한다.

4. PID 네임스페이스 사용

  • Docker: 컨테이너의 PID 네임스페이스를 공유하는데, 호스트와 컨테이너 간 프로세스 관리에 일부 제약이 있을 수 있다.
  • Podman: 기본적으로 컨테이너 PID 네임스페이스를 공유하지 않으므로 더욱 격리된 환경이 제공된다.

2. Container VS VM

  1. 가상화 수준
  • VM: 전체 운영 체제(라이브러리, 애플리케이션 등)을 가상화 한다.
    자체 게스트 운영 체제를 실행하며, 호스트 운영체제 위에서 동작한다.
  • 컨테이너: 운영 체제의 커널을 공유하며, 애플리케이션과 필요한 라이브러리 및 종속성을 격리된 환경에서 실행한다. 운영 체제를 실행하지 않으므로 가볍고 빠르다.
  1. 자원 사용
  • VM: 자체 운영 체제를 실행하므로 메모리, 디스크 공간 및 CPU 리소스를 많이 사용한다.
  • 컨테이너: 호스트 시스템에서 실행되는 작은 프로세스 급으로 가상 머신에 비해 메모리와 디스크 공간을 적게 사용한다.
  1. 이식성 및 배포
  • VM: 호스트 운영 체제와 분리되어 있어 호스트 운영 체제의 종속성 영향을 받지 않지만, VM 이미지의 크기가 상대적으로 크기 때문에 배포 및 이식이 더 느릴 수 있다.
  • 컨테이너: 독립적이고 가볍기 때문에 배포 및 이식이 빠르고 쉽다.
    또한 컨테이너 이미지는 빌드된 애플리케이션과 종속성만 포함하므로 상대적으로 작고 가볍다.
  1. 성능
  • VM: 추가적인 가상화 레이어로 인해 성능 손실이 발생할 수 있다.
  • 컨테이너: 호스트 운영체제와 커널을 공유함으로써 일반적으로 빠르고 효율적인 성능이 제공된다.

Podman 기본 운영

기본적인 환경은 아래와 같다.

[root@jh-container-rocky86 ~]# hostnamectl
   Static hostname: jh-container-rocky86.example.com
         Icon name: computer-vm
           Chassis: vm
        Machine ID: d183b307543e46639a4c743afa866cb8
           Boot ID: 6cade23a991f43619a0b1eafebe9c3d5
    Virtualization: kvm
  Operating System: Rocky Linux 8.6 (Green Obsidian)
       CPE OS Name: cpe:/o:rocky:rocky:8:GA
            Kernel: Linux 4.18.0-372.9.1.el8.x86_64
      Architecture: x86-64
      
[root@jh-container-rocky86 ~]# ip -4 -o a | awk '{print $2" "$4}'
lo 127.0.0.1/8
enp1s0 10.65.121.86/20				# 외부로 통하는 Bridge 대역
cni-podman0 10.88.0.1/16			# Container 에서 사용되는 IP 대역(NAT)

Podman 은 Minimal Install 로 진행할 경우 기본적으로 설치되어 있지 않다.
따라서 ISO 이미지를 Local Repository 로 구성한 후, 설치를 진행한다.

[root@jh-container-rocky86 ~]# dnf repoinfo
Last metadata expiration check: 2:03:27 ago on Thu 01 Feb 2024 07:06:53 AM KST.
Repo-id            : AppStream
Repo-name          : AppStream
Repo-revision      : 8.6
Repo-distro-tags      : [cpe:/o:rocky:rocky:8]:  ,  , 8, L, R, c, i, k, n, o, u, x, y
Repo-updated       : Mon 16 May 2022 06:01:50 AM KST
Repo-pkgs          : 6,549
Repo-available-pkgs: 5,339
Repo-size          : 8.3 G
Repo-baseurl       : file:///root/repo/AppStream
Repo-expire        : 172,800 second(s) (last: Thu 01 Feb 2024 07:06:53 AM KST)
Repo-filename      : /etc/yum.repos.d/local.repo

Repo-id            : BaseOS
Repo-name          : BaseOS
Repo-revision      : 8.6
Repo-distro-tags      : [cpe:/o:rocky:rocky:8]:  ,  , 8, L, R, c, i, k, n, o, u, x, y
Repo-updated       : Mon 16 May 2022 05:59:01 AM KST
Repo-pkgs          : 1,716
Repo-available-pkgs: 1,714
Repo-size          : 1.3 G
Repo-baseurl       : file:///root/repo/BaseOS
Repo-expire        : 172,800 second(s) (last: Thu 01 Feb 2024 07:06:53 AM KST)
Repo-filename      : /etc/yum.repos.d/local.repo
Total packages: 8,265

[root@jh-container-rocky86 ~]# dnf install podman

1. Mariadb 를 활용한 테스트

  1. Mariadb를 사용하여 테스트를 진행할 예정이므로 명령어 사용을 위해 Mariadb 를 설치한다.
    [root@jh-container-rocky86 ~]# dnf install mariadb

  2. 외부에서 이미지를 다운로드 받기 위해서는 방화벽 및 DNS 설정이 필요하다.

[root@jh-container-rocky86 ~]# systemctl disable --now firewalld
[root@jh-container-rocky86 ~]# vim /etc/resolv.conf 
# Generated by NetworkManager
search example.com
nameserver      8.8.8.8

[root@jh-container-rocky86 ~]# vim /etc/selinux/config
...
SELINUX=disabled
...

[root@jh-container-rocky86 ~]# reboot
  1. 외부망과 통신이 가능할 경우, 이미지를 연결 가능한 곳을 선택하여 다운로드한다.
    이미지 다운로드는 # podman pull 명령어를 사용하며 <이미지 이름>:<태그>로 지정한다.
[root@jh-container-rocky86 ~]# podman pull mariadb:latest
? Please select an image: 
    registry.fedoraproject.org/mariadb:latest
    registry.access.redhat.com/mariadb:latest
    registry.centos.org/mariadb:latest
  ▸ docker.io/library/mariadb:latest
  
✔ docker.io/library/mariadb:latest
Trying to pull docker.io/library/mariadb:latest...
Getting image source signatures
Copying blob d1db136ff347 done  
Copying blob 56fc83f4f5a4 done  
Copying blob 8e87ff28f1b5 done  
Copying blob d35acfab0e41 done  
Copying blob a3bf637726fe done  
Copying blob 40fbc2d141b9 done  
Copying blob 4db62f20d419 done  
Copying blob 07943e317bab done  
Copying config 2b54778e06 done  
Writing manifest to image destination
Storing signatures
Loaded image(s): docker.io/library/mariadb:latest

[root@jh-container-rocky86 ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED       SIZE
docker.io/library/mariadb  latest      2b54778e06a3  2 months ago  411 MB
  1. # podman run 명령어를 사용하여 컨테이너를 실행한다.
[root@jh-container-rocky86 ~]# podman run -itd -p 13306:3306 -e MYSQL_ROOT_PASSWORD=1234 \
--restart always --name jh-mariadb01 mariadb:latest
9a2565811de67b54ca6fc1db6d41905be7ece6bccc4d88d44ddb4189669db655

-i > 컨테이너와 상호작용을 위해 표준입력(STDIN)을 유지
-t > TTY(터미널)을 할당
-d > 컨테이너를 백그라운드로 실행
-p 13306:3306 > 호스트의 포트 13306을 컨테이너 포트 3306에 매핑
이 옵션을 사용하면 호스트 시스템에서 컨테이너 내부의 MySQL 서버에 접속할 수 있다.

-e MYSQL_ROOT_PASSWORD=1234 > 컨테이너 내에서 사용할 환경 변수 설정
--restart always > 컨테이너가 비정상적으로 종료될 경우 자동으로 다시 시작하도록 설정
-- name > 컨테이너에 이름 부여
mariadb:latest > 실행할 이미지를 지정

# podman ps 명령어로 실행중인 컨테이너를 확인할 수 있다.

[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND     CREATED         STATUS             PORTS                    NAMES
9a2565811de6  docker.io/library/mariadb:latest  mariadbd    21 minutes ago  Up 21 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01

2. 컨테이너 진입

  1. # podman exec -it <container ID> bash 명령어를 사용하여 실행중인 컨테이너에 진입할 수 있다.
[root@jh-container-rocky86 ~]# podman exec -it jh-mariadb01 bash
root@9a2565811de6:/#
root@9a2565811de6:/# mariadb -uroot -p
Enter password: <컨테이너 실행  설정한 root 유저 비밀번호>
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 6
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 
  1. NAT 네트워크로 접속하기
    기본적으로 Podman 을 설치할 경우 cni-podman0 라는 네트워크가 생성되는데, NAT 기능을 해주는 내부 네트워크이다.
    해당 네트워크를 통하여 컨테이너 내부에 진입하지 않고도 접속이 가능하다.
[root@jh-container-rocky86 ~]# ip -4 -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: enp1s0    inet 10.65.121.86/20 brd 10.65.127.255 scope global noprefixroute enp1s0\       valid_lft forever preferred_lft forever
3: cni-podman0    inet 10.88.0.1/16 brd 10.88.255.255 scope global cni-podman0\       valid_lft forever preferred_lft forever

아래와 같이 컨테이너 내부에 접속한 후 IP를 확인해보면 cni-podman0 네트워크 대역대와 동일한 대역으로 IP가 할당된 것을 확인할 수 있다.

[root@jh-container-rocky86 ~]# podman exec -it jh-mariadb01 bash
root@9a2565811de6:/#
root@9a2565811de6:/# ip -4 -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: eth0    inet 10.88.0.3/16 brd 10.88.255.255 scope global eth0\       valid_lft forever preferred_lft forever

-h 옵션을 사용하여 해당 IP로 접속을 시도한다.

[root@jh-container-rocky86 ~]# mysql -uroot -p -h 10.88.0.3
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 7
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 
  1. 외부에서 컨테이너로 기동된 mariadb 접속
    cni-podman0 네트워크 대역은 NAT 기능을 제공하는 내부 네트워크이다.
    즉, 다른 서버에서는 10.88.0.0/16 대역에 접근할 수 없다.
    이러한 문제점을 Port Forwarding 기능으로 해결이 가능하다.
    컨테이너를 실행하기 위해 # podman run 명령어를 사용할 때 -p 13306:3306 옵션을 사용한 것을 확인할 수 있는데, 외부망 접속 IP(예시에서는 10.65.121.86)의 13306 포트로 접속하면 호스트 OS에서 해당 요청을 인식하여 10.88.0.3 IP의 3306 포트로 요청을 Forwarding 한다.
    포트 요청을 받기 위해서는 방화벽에서 13306 포트를 허용해야 하는데, 예시에서는 firewalld 데몬을 비활성화한 상태로 생략한다.
    포트를 허용하는 방법은 아래와 같다.
[root@jh-container-rocky86 ~]# firewall-cmd --zone=public --add-port=13306/tcp --permanent
success
[root@jh-container-rocky86 ~]# firewall-cmd --list-all
public (active)
 target: default
 icmp-block-inversion: no
 interfaces: enp1s0
 sources:
 services: cockpit dhcpv6-client ssh
 ports: 13306/tcp
 protocols:
 forward: no
 masquerade: no
 forward-ports:
 source-ports:
 icmp-blocks:
 rich rules

다른 서버에서 접속을 시도한다.

[root@jh-up-test-rhel84 ~]# ip -4 -o a
1: lo    inet 127.0.0.1/8 scope host lo\       valid_lft forever preferred_lft forever
2: enp1s0    inet 10.65.121.84/20 brd 10.65.127.255 scope global noprefixroute enp1s0\       valid_lft forever preferred_lft forever

[root@jh-up-test-rhel84 ~]# mysql -uroot -p -h 10.65.121.86 -P 13306
Enter password: 
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 8
Server version: 11.2.2-MariaDB-1:11.2.2+maria~ubu2204 mariadb.org binary distribution

Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.

Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.

MariaDB [(none)]> 

3. 이미지 저장/불러오기

다운로드 받은 이미지를 파일로 저장할 수 있다.

[root@jh-container-rocky86 ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED       SIZE
docker.io/library/mariadb  latest      2b54778e06a3  2 months ago  411 MB
[root@jh-container-rocky86 ~]# podman save docker.io/library/mariadb:latest > jh-mariadb01.tar.gz
[root@jh-container-rocky86 ~]# ls
anaconda-ks.cfg  jh-mariadb01.tar.gz 

파일로 저장된 이미지를 불러올 수 있다.

[root@jh-container-rocky86 ~]# podman load < jh-mariadb01.tar.gz 
Getting image source signatures
Copying blob d1db136ff347 done  
Copying blob d35acfab0e41 done  
Copying blob a3bf637726fe done  
Copying blob 56fc83f4f5a4 done  
Copying blob 8e87ff28f1b5 done  
Copying blob 40fbc2d141b9 done  
Copying blob 4db62f20d419 done  
Copying blob 07943e317bab done  
Copying config 2b54778e06 done  
Writing manifest to image destination
Storing signatures
Loaded image(s): docker.io/library/mariadb:latest

4. 이미지 정보 확인

실행중인 컨테이너의 이미지 정보를 확인할 때 # podman inspect 명령어를 사용한다.
아래 예시에는 컨테이너에 할당된 IP를 확인한다.

[root@jh-container-rocky86 ~]# clear
[root@jh-container-rocky86 ~]# podman inspect --format='{{.NetworkSettings.IPAddress}}' jh-mariadb01
10.88.0.4

[root@jh-container-rocky86 ~]# podman inspect jh-mariadb01
[
     {
          "Id": "43682ed58c14f6c53163412039f90c878d4c16a4d199ba0c17f5871f992fa19e",
          "Created": "2024-02-06T08:54:51.522232562+09:00",
          "Path": "docker-entrypoint.sh",
          "Args": [
               "mariadbd"
          ],
          "State": {
               "OciVersion": "1.0.2-dev",
...

5. 컨테이너 중지/시작/삭제

  1. 실행중인 컨테이너를 확인하는 명령어는 # podman ps 이다.
    --all 옵션을 사용하여 중지된 컨테이너도 확인 가능하다.
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND     CREATED        STATUS            PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd    8 minutes ago  Up 8 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
  1. 컨테이너를 중지하는 명령어는 # podman stop 이다.
    --all 옵션을 사용하여 모든 컨테이너를 중지할 수 있다.
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND       CREATED         STATUS            PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd      17 minutes ago  Up 7 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
6638de0a26f6  docker.io/library/mariadb:latest  --port 23306  6 minutes ago   Up 6 minutes ago                           jh-mariadb02
9a6f109f77ed  docker.io/library/mariadb:latest  --port 33306  6 minutes ago   Up 6 minutes ago                           jh-mariadb03

[root@jh-container-rocky86 ~]# podman stop jh-mariadb01
jh-mariadb01

[root@jh-container-rocky86 ~]# podman stop -a
6638de0a26f681dde68485d4d1c995fef72bbc4f7c1122441757a6eb7be85c84
9a6f109f77edcdd8a3a4999ec7d07b24728085cf29918c4cb422be8e378b2495
43682ed58c14f6c53163412039f90c878d4c16a4d199ba0c17f5871f992fa19e

[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

[root@jh-container-rocky86 ~]# podman ps -a
CONTAINER ID  IMAGE                             COMMAND       CREATED         STATUS                    PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd      25 minutes ago  Exited (0) 7 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
6638de0a26f6  docker.io/library/mariadb:latest  --port 23306  14 minutes ago  Exited (0) 7 minutes ago                           jh-mariadb02
9a6f109f77ed  docker.io/library/mariadb:latest  --port 33306  13 minutes ago  Exited (0) 7 minutes ago                           jh-mariadb03
  1. 컨테이너를 시작하는 명령어는 # podman start 이다.
    --all 명령어로 중지된 모든 컨테이너를 시작할 수 있다.
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

[root@jh-container-rocky86 ~]# podman start jh-mariadb01
jh-mariadb01

[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND     CREATED         STATUS            PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd    27 minutes ago  Up 5 seconds ago  0.0.0.0:13306->3306/tcp  jh-mariadb01

[root@jh-container-rocky86 ~]# podman start --all
6638de0a26f681dde68485d4d1c995fef72bbc4f7c1122441757a6eb7be85c84
9a6f109f77edcdd8a3a4999ec7d07b24728085cf29918c4cb422be8e378b2495

[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND       CREATED         STATUS             PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd      27 minutes ago  Up 10 seconds ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
6638de0a26f6  docker.io/library/mariadb:latest  --port 23306  16 minutes ago  Up 2 seconds ago                            jh-mariadb02
9a6f109f77ed  docker.io/library/mariadb:latest  --port 33306  16 minutes ago  Up 1 second ago                             jh-mariadb03
  1. 컨테이너를 삭제하는 명령어는 # podman rm 이며,
    이미지를 삭제하는 명령어는 # podman rmi 이다.
    컨테이너/이미지를 삭제할 때 해당 컨테이너가 실행중이면 삭제되지 않는다.
    -f 옵션으로 강제 삭제가 가능하지만 중지 후 삭제하는 걸 권장한다.
    --all 옵션으로 모든 중지된 컨테이너를 삭제한다.
[root@jh-container-rocky86 ~]# podman ps
CONTAINER ID  IMAGE                             COMMAND       CREATED         STATUS            PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd      33 minutes ago  Up 6 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
6638de0a26f6  docker.io/library/mariadb:latest  --port 23306  22 minutes ago  Up 6 minutes ago                           jh-mariadb02
9a6f109f77ed  docker.io/library/mariadb:latest  --port 33306  22 minutes ago  Up 6 minutes ago                           jh-mariadb03

[root@jh-container-rocky86 ~]# podman rm jh-mariadb03
Error: cannot remove container 9a6f109f77edcdd8a3a4999ec7d07b24728085cf29918c4cb422be8e378b2495 as it is running - running or paused containers cannot be removed without force: container state improper	
<컨테이너 실행중 삭제를 시도할  발생하는 에러 메시지>

[root@jh-container-rocky86 ~]# podman stop jh-mariadb03
jh-mariadb03

[root@jh-container-rocky86 ~]# podman rm jh-mariadb03
9a6f109f77edcdd8a3a4999ec7d07b24728085cf29918c4cb422be8e378b2495

[root@jh-container-rocky86 ~]# podman ps --all
CONTAINER ID  IMAGE                             COMMAND       CREATED         STATUS             PORTS                    NAMES
43682ed58c14  docker.io/library/mariadb:latest  mariadbd      40 minutes ago  Up 13 minutes ago  0.0.0.0:13306->3306/tcp  jh-mariadb01
6638de0a26f6  docker.io/library/mariadb:latest  --port 23306  29 minutes ago  Up 12 minutes ago                           jh-mariadb02

아래 예시에서는 이미지를 삭제한다.

[root@jh-container-rocky86 ~]# podman images
REPOSITORY                 TAG         IMAGE ID      CREATED       SIZE
docker.io/library/mariadb  latest      2b54778e06a3  2 months ago  411 MB

[root@jh-container-rocky86 ~]# podman rmi 2b54778e06a3
Untagged: docker.io/library/mariadb:latest
Deleted: 2b54778e06a3050394a36e4dfcd153796f404397b84cb1737fd044b74c3bccbf

[root@jh-container-rocky86 ~]# podman images
REPOSITORY  TAG         IMAGE ID    CREATED     SIZE
profile
Linux/Cluster/Infra Engineer

0개의 댓글