이재홍의 언제나 최신 Docker - Unit 6.6 Docker 베이스 이미지 생성하기

저작권 안내
  • 책 또는 웹사이트의 내용을 복제하여 다른 곳에 게시하는 것을 금지합니다.
  • 책 또는 웹사이트의 내용을 발췌, 요약하여 발표 자료, 블로그 포스팅 등으로 만드는 것을 금지합니다.

Docker 좀더 활용하기

이재홍 http://www.pyrasis.com

Docker 베이스 이미지 생성하기

보통 Dockerfile로 이미지를 생성할 때 Docker Hub에서 제공하는 공식 이미지를 기반으로 생성합니다. 이번에는 나만의 베이스 이미지를 생성하는 방법을 알아보겠습니다.

우분투 베이스 이미지 생성하기

우분투 리눅스 베이스 이미지를 생성해보겠습니다. 우분투 리눅스용 부트스트랩 바이너리 파일을 받아와야 하기 때문에 우분투 리눅스가 설치된 호스트에서 진행합니다.

먼저 부트스트랩 도구인 debootstrap을 설치합니다.

$ sudo apt install debootstrap

debootstrap으로 우분투 jammy(22.04) 바이너리 파일을 받습니다. jammy는 우분투 리눅스의 코드네임입니다.

$ sudo debootstrap jammy jammy

deboostrap <코드네임> <디렉터리> 형식입니다.

우분투 리눅스 코드네임
우분투 리눅스의 버전별 코드네임 목록은 다음 URL에서 확인할 수 있습니다.

바이너리 파일을 다 받았으면 docker import 명령으로 베이스 이미지를 생성합니다.

$ sudo tar -C jammy -c . | sudo docker import - jammy

tar -C jammy -c .jammy 디렉터리의 내용을 파일 하나로 합쳐서 stdout으로 출력하는 명령입니다. 이 출력 내용을 | (파이프)를 통해 docker import 명령에 전달합니다.

docker import <URL 또는 -> <이미지 이름>:<태그> 형식입니다. 예를 들어 다음과 같이 인터넷에 있는 파일도 사용할 수 있습니다. |를 통해 데이터를 넘겨받는다면 -를 지정합니다.

$ sudo docker import http://example.com/jammy.tgz focal

이미지 목록을 출력합니다.

$ sudo docker images
REPOSITORY                TAG       IMAGE ID       CREATED         SIZE
jammy                     latest    190b8535965c   6 seconds ago   374MB

jammy 이미지가 생성되었습니다. 이제 jammy 이미지로 컨테이너를 생성합니다. 컨테이너의 Bash 셸이 실행되면 /etc/lsb-release 파일의 내용을 확인해봅니다.

$ sudo docker run -i -t --name hello jammy /bin/bash
root@2a2ab29f2d74:/# cat /etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=22.04
DISTRIB_CODENAME=jammy
DISTRIB_DESCRIPTION="Ubuntu 22.04 LTS"

코드네임은 jammy, 릴리스 버전은 22.04로 표시됩니다.

CentOS 베이스 이미지 생성하기

이번에는 CentOS 베이스 이미지를 생성해보겠습니다. CentOS용 부트스트랩 바이너리 파일을 받아와야 하기 때문에 CentOS Stream 9가 설치된 호스트에서 진행합니다.

먼저 부트스트랩 도구인 supermin을 설치합니다.

$ sudo yum install supermin

supermin으로 부트스트랩을 준비합니다.

$ supermin --prepare yum -o supermin.d
$ supermin --build --format chroot supermin.d -o appliance.d
$ mkdir -p appliance.d/etc/yum/vars
$ echo 9 > appliance.d/etc/yum/vars/releasever

부트스트랩을 다 준비했다면 docker import 명령으로 베이스 이미지를 생성합니다.

$ sudo tar -C appliance.d -c . | sudo docker import - centos

sudo tar -C appliance.d -c .는 appliance.d 디렉터리의 내용을 파일 하나로 합쳐서 stdout으로 출력하는 명령입니다. 이 출력 내용을 | (파이프)를 통해 docker import 명령에 전달합니다.

docker import <tar 파일 URL 또는 -> <이미지 이름>:<태그> 형식입니다. 예를 들어 다음과 같이 인터넷에 있는 파일을 사용할 수도 있습니다. |(파이프)를 통해 데이터를 넘겨받는다면 -를 지정합니다.

$ sudo docker import http://example.com/centos.tgz centos

이미지 목록을 출력합니다.

$ sudo docker images
REPOSITORY                   TAG       IMAGE ID       CREATED              SIZE
centos                       latest    6f4877487603   About a minute ago   187MB

centos 이미지가 생성되었습니다. centos 이미지로 컨테이너를 생성합니다. 컨테이너의 Bash 셸이 실행되면 /etc/centos-release 파일의 내용을 확인해봅니다.

$ sudo docker run -i -t --name hello centos /bin/bash
bash-5.1# cat /etc/centos-release
CentOS Stream release 9

배포판 버전이 CentOS Stream release 9로 표시됩니다.

빈 베이스 이미지 생성하기

아무것도 들어있지 않은 베이스 이미지를 생성하는 방법입니다. Docker에서는 빈 베이스 이미지를 scratch 이미지라고 부릅니다.

/dev/null 장치를 이용하여 빈 tar 파일을 만들어서 docker import 명령에 전달합니다.

$ tar cv --files-from /dev/null | sudo docker import - scratch

scratch 이미지는 안에 아무것도 없기 때문에 컨테이너로 생성이 되지 않습니다. 여기서 Dockerfile을 작성하여 여러분이 만든 실행 파일을 넣으면 됩니다.

간단하게 C 언어로 만든 프로그램을 scratch 이미지에 넣어보겠습니다. 먼저 hello 디렉터리를 생성한 뒤 hello 디렉터리로 이동합니다.

$ mkdir hello
$ cd hello

다음 내용을 hello.c로 저장합니다.

hello.c
#include <stdio.h>

int main ()
{
    printf("Hello Docker\n");
    return 0;
}

hello.c 파일을 컴파일하여 실행 파일로 만듭니다. scratch 이미지에는 아무 라이브러리도 없으므로 반드시 정적(static) 바이너리로 컴파일해야 합니다.

~/hello$ gcc hello.c -static -o hello

컴파일러 설치

우분투
$ sudo apt install gcc
CentOS
$ sudo yum config-manager --set-enabled crb
$ sudo yum install gcc
$ sudo yum install glibc-static

다음 내용을 Dockerfile로 저장합니다.

Dockerfile
FROM scratch
ADD ./hello /hello
CMD ["/hello"]

scratch 이미지를 기반으로 새로운 이미지를 생성합니다.

  • FROM: 어떤 이미지를 기반으로 할지 설정합니다. Docker 이미지는 기존에 만들어진 이미지를 기반으로 생성합니다. <이미지 이름>:<태그> 형식입니다. 여기서는 앞에서 만든 scratch 이미지를 설정합니다.
  • ADD: 이미지에 포함할 파일을 설정합니다. <로컬 경로> <이미지 경로> 형식입니다. 앞에서 hello.c 파일을 컴파일하여 생성한 hello 파일을 설정합니다.
  • CMD: 컨테이너가 시작되었을 때 실행할 실행 파일 또는 스크립트입니다. hello 파일이 실행되도록 설정합니다.

docker build 명령으로 이미지를 생성합니다.

~/hello$ sudo docker build --tag hello:0.1 .

이제 scratch 이미지를 이용해서 만든 hello:0.1 이미지를 컨테이너로 생성합니다.

$ sudo docker run --rm hello:0.1
Hello Docker

Hello Docker가 출력되면 실행 파일이 정상적으로 실행된 것입니다.


저작권 안내

이 웹사이트에 게시된 모든 글의 무단 복제 및 도용을 금지합니다.
  • 블로그, 게시판 등에 퍼가는 것을 금지합니다.
  • 비공개 포스트에 퍼가는 것을 금지합니다.
  • 글 내용, 그림을 발췌 및 요약하는 것을 금지합니다.
  • 링크 및 SNS 공유는 허용합니다.

Published

2022-10-03