본문 바로가기
Tools

Podman 설치 및 사용법 - Docker desktop의 대체재

by A6K 2023. 3. 31.

맥과 윈도우에서 쉽게 도커 플랫폼을 사용할 수 있게 도와주는 Docker Desktop이 유료화된지 시간이 꽤 지났다. 개인 사용자는 여전히 제한없이 무료로 사용할 수 있지만 250명이 넘는 규모있는 회사에서 Docker Desktop을 사용할 경우 비용을 지불해야한다. (링크 : docker 유료화 공지)

다만 Docker 자체가 유료화되는 것은 아니다. Docker CLI, Docker Engine 등은 오슨소스 라이센스로 개발되고 있기 때문에 기존과 동일하게 사용할 수 있다. 다만 리눅스에서 구동되는 Docker Engine을 맥과 윈도우에서 구동시키기 위해 VM을 생성하고, Docker를 설치하는 등의 처리를 해주는 Docker Desktop만 유료화된 것이다.

따라서 업무용으로 이것저것 테스트하기 위해서 맥이나 윈도우에서 Docker를 사용하는 경우 Docker Desktop의 대체재를 찾아야 한다.

목차

    Podman이란?

    Podman은 Pod Manager tool이라는 의미로 OCI 컨테이너를 개발하고 관리하고 실행하도록 도와주는 컨테이너 엔진이다. Red Hat Enterprise Linux 8과 CentOS 8부터는 Docker 대신 Podman을 제공하고 있다. Docker와 마찬[가지로 Podman 역시 오픈소스로 관리되고 있는 프로젝트다. (Github Podman Repository)

    Podman은 Docker와 호환되는 CLI 명령을 제공하고 있어 alias docker=podman 설정을 해서 사용할 수 있다. 또 한 Podman은 REST API 서비스도 제공하기 때문에 원격에서 애플리케이션을 실행할 수 있다. 마찬가지로 Docker API를 지원하기 때문에 docker-py, docker-compose 사용자들도 Podman을 사용할 수 있다.

    Docker의 컨테이너 구동 방식

    Docker의 경우 Docker CLI를 통해 Docker 데몬에게 컨테이너에 대한 명령을 전달한다. Docker 데몬은 registry에서 이미지를 pull 받아서 컨테이너를 띄우게 된다. 문제는 Docker 데몬이 root 권한을 필요로하기 때문에 잠재적인 보안 위협 포인트로 작용할 수 있다. 또 한, Docker 데몬이 죽게 되면 컨테이너를 관리할 수 없게 된다. 따라서 Docker 데몬이 시스템의 SPoF(Single Point of Failure)가 될 수도 있다.

    Podman은 Docker와 다르게 데몬을 통해 컨테이너를 구동하지 않는다. 대신 리눅스 커널과 상호작용하기 위해 runC라는 OCI 컨테이너 런타임을 fork/exec으로 생성한다. 따라서 데몬이 죽어서 시스템이 내려갈 일이 없다. 또 한 Podman은 rootless 모드를 통해 root 권한 없이도 컨테이너를 구동할 수 있다.

    buildah 유틸리티는 컨테이너 이미지를 생성하는 Docker build를 대체하며, 이미지 레지스트리와 컨테이너 엔진 사이에 이미지를 전송하기 위한 Docker push는 skopeo가 대체하게 되었다.

    로고도 귀엽고 Docker와 호환되기 때문에 적극적으로 사용해보기로 하자.

    Podman 설치

    Podman은 패키지 관리자를 이용해서 쉽게 설치할 수 있다.

    # CentOS
    yum -y install podman
    
    # Ubuntu
    apt-get -y install runc
    apt-get -y install podman
    
    # mac
    brew install podman
    podman machine init
    podman machine start

    맥의 경우 Podman을 설치하고 QEMU 기반의 가상 머신을 초기화해줘야 한다.

    podman의 경우 docker와 명령이 호환되므로 alias를 걸어주면 편하게 사용할 수 있다.

    alias docker=podman

    테스트로 centos 컨테이너를 하나 띄워보자.

    $ docker run -it centos
    Resolved "centos" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
    Trying to pull quay.io/centos/centos:latest...
    Getting image source signatures
    Copying blob sha256:333cbcae3fb80b9a460da9700fb646ab89206d0cfe213fd
    Copying config sha256:a0477e85b8aebf57d58bfa74a6598eccc380cde2e7300a1b
    Writing manifest to image destination
    Storing signatures
    [root@96af42369c38 /]#

    잘 된다.

    podman-desktop 설치

    맥을 사용하는 경우 podman-desktop이라는 프로그램도 설치할 수 있다. podman-desktop을 사용하면 Docker Desktop처럼 컨테이너 생성, 중지, 삭제 그리고 이미지의 Pull, Build 등을 GUI를 통해서 사용할 수 있다.

    podman-desktop 역시 Homebrew를 통해 쉽게 설치할 수 있다.

    brew install podman-desktop

    설치가 끝나면 Podman Desktop 앱을 실행할 수 있다.

    Podman 사용법 

    Podman의 사용법을 알아보자. Docker를 사용했었다면 익숙할 것이다.

    컨테이너 생성 - run

    user@localhost ~ $ podman run -it centos
    [root@0ecc2effe3db /]#

    podman의 run 명령을 이용해서 컨테이너 생성이 가능하다.

    컨테이너 상태확인 - ps

    user@localhost ~ $ podman ps -a
    CONTAINER ID  IMAGE                         COMMAND     CREATED      STATUS                  PORTS       NAMES
    3cdxd0cb895  quay.io/centos/centos:latest  /bin/bash   11 days ago  Exited (0) 11 days ago              hungry_lovelace

    podman의 ps 명령을 이용해서 현재 생성된 컨테이너의 상태와 기타 정보들을 확인할 수 있다. 기본적으로는 활성화되어 있는 컨테이너만 조회가능하며 실행이 중지된 컨테이너까지 확인하려면 -a 옵션을 붙여주면 된다.

    컨테이너 실행 - start

    user@localhost ~ $ podman start 3cdxd0cb895
    3cdxd0cb895

    생성된 이후 실행이 중지되었던 컨테이너를 다시 실행시키기 위해서 podman의 start 명령을 사용할 수 있다. start 명령의 인자로 다시 시작시킬 컨테이너의 ID 혹은 이름을 넘겨주면 된다.

    컨테이너 중지 - stop

    user@localhost ~ $ podman stop 3cdxd0cb895
    3cdxd0cb895

    컨테이너를 중지하기 위해서 podman의 stop 명령을 사용할 수 있다. stop 명령의 인자로 정지시킬 컨테이너의 ID 혹은 이름을 넘겨주면 된다.

    컨테이너 삭제 - rm

    user@localhost ~ $ podman stop 3cdxd0cb895
    3cd7d016b89
    user@localhost ~ $ podman rm  3cdxd0cb895
    3cd7d016b895
    user@localhost ~ $ podman ps -a
    CONTAINER ID  IMAGE       COMMAND     CREATED     STATUS      PORTS       NAMES

    생성된 컨테이너를 삭제하기 위해서 podman의 rm 명령을 사용할 수 있다. 단 컨테이너를 삭제하기 위해서는 중지 상태여야하기 때문에 stop 명령으로 중지 시킨 후에 삭제해야한다.

    컨테이너 checkpoint / restore

    컨테이너의 현재 상황을 checkpoint 해서 디스크로 저장해뒀다가 restore해서 다시 올릴 수도 있다.

    $ sudo podman container checkpoint --leave-running --export=/tmp/backup.tar my_container
    $ sudo podman stop my_container
    $ sudo podman rm my_container
    $ sudo podman container restore --import=/tmp/backup.tar

    컨테이너 이미지 조회 - images

    user@localhost ~ $ podman images
    REPOSITORY             TAG         IMAGE ID      CREATED      SIZE
    quay.io/centos/centos  latest      a0477e85b8ae  2 years ago  256 MB

    현재 Podman에 받아져있는 컨테이너 이미지들을 조회하기 위해서 images 명령을 사용할 수 있다.

    컨테이너 이미지 빌드 

    podman build -t myProject/myContainer .

    현재 작업 디렉토리에 Dockerfile이 있다면 build 명령으로 컨테이너 이미지를 빌드할 수 있다.

    컨테이너 이미지 pull 

    user@localhost ~ $ podman pull ubuntu
    Resolved "ubuntu" as an alias (/etc/containers/registries.conf.d/000-shortnames.conf)
    Trying to pull docker.io/library/ubuntu:latest...
    Getting image source signatures
    Copying blob sha256:cd741b12a7eaa64357041c2d3f4590c898313a7f8f65cd1577594e6ee03a8c38
    Copying config sha256:bab8ce5c00ca3ef91e0d3eb4c6e6d6ec7cffa9574c447fd8d54a8d96e7c1c80e
    Writing manifest to image destination
    Storing signatures
    bab8ce5c00ca3ef91e0d3eb4c6e6d6ec7cffa9574c447fd8d54a8d96e7c1c80e
    user@localhost ~ $
    user@localhost ~ $
    user@localhost ~ $ podman images
    REPOSITORY                TAG         IMAGE ID      CREATED      SIZE
    docker.io/library/ubuntu  latest      bab8ce5c00ca  3 weeks ago  71.8 MB
    quay.io/centos/centos     latest      a0477e85b8ae  2 years ago  256 MB

    컨테이너 이미지를 Docker hub나 다른 레지스트리에서 받아오기 위해 pull 명령을 사용할 수 있다. pull 명령으로 이미지를 다운받고 images 명령으로 조회하면 새로 받은 이미지를 확인할 수 있다.

    컨테이너 이미지 삭제 - rmi

    user@localhost ~ $ podman rmi bab8ce5c00ca
    Untagged: docker.io/library/ubuntu:latest
    Deleted: bab8ce5c00ca3ef91e0d3eb4c6e6d6ec7cffa9574c447fd8d54a8d96e7c1c80e
    user@localhost ~ $ 
    user@localhost ~ $ 
    user@localhost ~ $ podman images
    REPOSITORY             TAG         IMAGE ID      CREATED      SIZE
    quay.io/centos/centos  latest      a0477e85b8ae  2 years ago  256 MB

    pull 받은 이미지는 rmi 명령을 이용해서 지울 수 있다.

    Pod 생성

    podman pod create --name my-pod

    Pod 조회

    podman pod ls
    podman ps -a --pod

    Pod에 컨테이너 추가

    podman run -dt --pod my-pod  myContainer

    Pod 시작/중지/삭제

    podman pod start <container-id>
    podman pod stop <container-id>
    podman pod rm <container-id>

    Structured data 생성 - generate

    앞서 언급한 것처럼 containerd라는 데몬이 구동되는 Docker와 다르게 podman은 데몬 프로세스를 사용하지 않는다. 따라서 systemd에 서비스를 생성해서 관리하는 방법을 많이 사용한다. systemd를 위한 서비스를 생성하기 위해서는 설정들을 담고 있는 서비스 파일을 만들어야 한다.

    Podman은 generate 명령을 이용해서 systemd 서비스 파일을 생성해준다.

    user@localhost ~ $ docker generate systemd c645dc39fc20
    WARN[0000] The generated units should be placed on your remote system
    # container-c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e.service
    # autogenerated by Podman 4.4.2
    # Sun Mar 26 18:40:06 KST 2023
    
    [Unit]
    Description=Podman container-c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e.service
    Documentation=man:podman-generate-systemd(1)
    Wants=network-online.target
    After=network-online.target
    RequiresMountsFor=/run/user/501/containers
    
    [Service]
    Environment=PODMAN_SYSTEMD_UNIT=%n
    Restart=on-failure
    TimeoutStopSec=70
    ExecStart=/usr/bin/podman start c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e
    ExecStop=/usr/bin/podman stop  \
    	-t 10 c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e
    ExecStopPost=/usr/bin/podman stop  \
    	-t 10 c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e
    PIDFile=/run/user/501/containers/overlay-containers/c645dc39fc20d006f44a8123504dff49c98b6385575ead541074dfd7b0e/userdata/conmon.pid
    Type=forking
    
    [Install]
    WantedBy=default.target

    출력되는 내용을 기반으로 추가적인 설정을 변경해서 systemctl을 이용해서 서비스를 시작할 수 있다.

    podman generate 명령을 이용해서 kubernetes yaml 파일도 생성할 수 있다. 

    user@localhost ~ $ docker generate kube cb131c645dc3
    # Save the output of this file and use kubectl create -f to import
    # it into Kubernetes.
    #
    # Created with podman-4.4.2
    apiVersion: v1
    kind: Pod
    metadata:
      creationTimestamp: "2023-03-26T10:21:31Z"
      labels:
        app: boldshannon-pod
      name: boldshannon-pod
    spec:
      containers:
      - image: quay.io/centos/centos:latest
        name: boldshannon
        stdin: true
        tty: true

    이 파일을 이용해서 K8S에 배포할 수도 있다.

    댓글