Podman, Buildah, Skopeo
설치
- Arch Linux
- Debian
sudo pacman -S podman buildah skopeo
yay -S podman-desktop
sudo apt install podman buildah skopeo
flatpak install flathub io.podman_desktop.PodmanDesktop
/etc/containers/registries.conf
unqualified-search-registries = ['docker.io', 'quay.io', 'registry.fedoraproject.org']
이미지 빌드
Dockerfile
buildah bud [<flags>] [<context>]
- flags
-f|--file <path|url>
: Dockerfile 경로-t|--tag <tag>
ShellScript
containerize.sh
#!/usr/bin/env bash
set -x
build=$(buildah from golang:1.17)
build_root=$(buildah mount $build)
buildah copy $build . /app
buildah config --workingdir /app $build
buildah run $build go get -u github.com/gin-gonic/gin
buildah run $build env CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -a -ldflags '-s' -o app
runtime=$(buildah from scratch)
buildah copy $runtime $build_root/app/app /usr/bin/
buildah config --cmd "app" $runtime
buildah commit $runtime ping:1.0.0
buildah rm $runtime
buildah unmount $build_root
buildah rm $build
buildah unshare sh containerize.sh
이미지 관리
레지스트리에 로그인
skopeo login [<flags>] <host>
aws ecr get-login-password --region <region> | skopeo login --username AWS --password-stdin <awsAccountID>.dkr.ecr.<region>.amazonaws.com
aws ecr-public get-login-password --region <region> | skopeo login --username AWS --password-stdin public.ecr.aws/<alias>
이미지 삭제
podman image rm [<flags>] [<image> ...]
-a|--all
-f|--force
이미지 옮기기
skopeo copy [<flags>] <srcImage> <dstImage>
- flags
--dest-creds=<username>:<password>
--dest-tls-verify=treu
- image
containers-storage:localhost/<image>[:tag]
docker://<url>/<image>[:tag]
inspect
skopeo inspect [<flags>] <image>
파일로 저장하고 불러오기
podman save -o <file>.tar <image>
podman load -i <file>.tar
컨테이너 관리
컨테이너 실행하기
podman run [<flags>] <image> [<command> [<arg> ...]]
새로운 컨테이너에 명령어를 실행합니다.
<flags>
--cpus <number>
: CPU limit-d|--detach
: 컨테이너를 백그라운드에서 실행하고 컨테이너 ID를 프린트--entrypoint <command>|'["<command>", "<arg>", ..."]'
: Dockerfile의ENTRYPOINT
에 해당합니다.--env-file <path>
:.env
처럼 환경 변수 값이 있는 파일로 환경 변수 설정-e|--env <key>[=<value>]
: 환경 변수 설정<key>
만 있는 경우 호스트에서 해당 환경 변수를 찾아 설정하고 없으면 설정하지 않습니다.*
glob를 사용할 수 있습니다.
-it
: STDIN를 열고 컨테이너에 가상 터미널 할당-m|--memory <number><unit>
: 메모리 limit<unit>
:b
,k
,m
,g
--name <containerName>
: 컨테이너 이름--network "host"
: 호스트 네트워크 사용-p|--publish <hostPort>:<containerPort>[/<protocol>]
: 포트 포워딩--rm
: 종료 시 컨테이너 삭제-v|--volume <hostDir>:<containerDir>[:<options>]
: 호스트 디렉토리를 컨테이너 디렉토리에 마운트<options>
ro
: 읽기 전용rw
: 읽기 쓰기z
: 공유 볼륨으로 설정하여 모든 컨테이너가 읽고 쓸 수 있습니다.
[<command> [<arg> ...]]
- Dockerfile의
CMD
에 해당합니다.
- Dockerfile의
컨테이너 리스트
podman ps [<flags>]
-a|--all
: 모든 컨테이너 출력-l|--latest
: 마지막 컨테이너 출력-q|--quiet
: 컨테이너 ID만 출력
실행중 컨테이너에 명령어 실행
podman exec [<flags>] <container> <command> [arg ...]
실행중인 컨테이너에 명령어를 실행합니다.
- flags
-it
: STDIN을 열고 컨테이너에 가상 터미널 할당
- container
- container ID 또는 이름
컨테이너 삭제
podman rm [<flags>] <container>
-f|--force
: running 또는 unstable 상태의 컨테이너도 삭제-a|--all
: 모든 컨테이너 삭제
컨테이너 파일 전송
podman cp [<flags>] [<containerID|containerName>:]<srcPath> [<containerID|containerName>:]<destPath>
호스트와 컨테이너 또는 컨테이너와 컨테이너 사이에서 파일을 복사합니다.
유저 네임스페이스 매핑
/etc/subuid
와 /etc/subgid
파일을 사용하여 사용자 네임스페이스에서 사용자가 사용할 수 있는 uid와 gid를 결정하는 기능을 포함한 Linux 배포판에서는 useradd
명령어를 통해 사용자를 추가했을 때 자동으로 65536개의 uid와 gid를 할당합니다.
/etc/subuid, /etc/subgid
hhk7734:100000:65536
sudo useradd test
/etc/subuid, /etc/subgid
hhk7734:100000:65536
test:165536:65536
LDAP 등의 사용으로 이러한 매핑이 없다면, 직접 추가해야합니다.
sudo usermod \
--add-subuids 100000-165535 \
--add-subgids 100000-165535 \
test
podman으로 컨테니어를 실행했을 때, 컨테이너 내부에서 외부 사용자와 내부 사용자가 어떻게 매핑되어 있는지 확인 할 수 있습니다.
podman run alpine cat /proc/self/uid_map
0 1000 1
1 100000 65536
네임스페이스 안 uid | 네임스페이스 밖 uid | 길이 |
---|---|---|
0 | 1000 | 1 |
1 | 100000 | 65536 |
이를 해석하면 내부 uid 0은 외부 uid 1000에 매핑되고, 내부 uid 1 ~ 65536은 외부 uid 100000 ~ 165535에 각각 매핑된다는 것을 알 수 있습니다.
podman 사용중에 매핑을 추가한다면 아래 명령어를 실행 시켜야합니다.(실행 중인 컨테이너가 멈춥니다.)
podman system migrate
경고
NFS 프로토콜에는 사용자 네임스페이스 개념이 없습니다. rootless podman을 사용할 때 기본 graphroot는 $HOME/.local/share/containers/storage
인데, NFS로 홈 디렉토리를 공유하고 있다면 문제가 발생할 수 있습니다.
~/.config/containers/storage.conf
[storage]
driver = "overlay"
runroot = "/run/user/2081"
graphroot = "/var/tmp/hyeonki/containers/storage"
위와 같은 설정을 추가해서 NFS가 아닌 로컬 디스크에 저장하도록 설정할 수 있습니다.