Tanzu Build ServiceのCustom Stackを使ってCloud Native BuildpacksのStackにaptのパッケージを追加する

Cloud Native Buildpacks はソースコードからOCIイメージを作成してくれる便利なツールですが、 "Opinionated"な仕組みであるため、Dockerfileを書く場合に比べて自由度が低いです。

よくある要望として、"aptのパッケージを追加して使いたい"があります。

これを実現するには Stack をカスタマイズする必要があります。 変更例は Spring Boot and Cloud Native Buildpacks Hands-on Lab の"6. Update a stack"を参照してください。

この方法のデメリットは、元となるStackが更新されるのに追従してカスタマイズしたStackを更新する必要がある点です。

この作業を自動化する仕組みとして Tanzu Build Service には CustomStack リソースがあります。

ここでは↑のHands-onの例に合わせて、Run Imageにimagemagickを追加してみます。

baseという名前のClusterStackリソースに対して、Run Imageにimagemagickを追加し、base-imagemagick という名前のClusterStackを作成するためのCustomStackリソースの定義は次のようになります。

apiVersion: stacks.stacks-operator.tanzu.vmware.com/v1alpha1
kind: CustomStack
metadata:
  name: base-imagemagick
spec:
  source:
    stack:
      name: base
      apiVersion: kpack.io/v1alpha1
      kind: ClusterStack
  destination:
    build:
      tag: harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-build
    run:
      tag: harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run
    stack:
      name: base-imagemagick
      apiVersion: kpack.io/v1alpha1
      kind: ClusterStack
  packages:
  - name: imagemagick
    phase: run

このリソースを作成します。

kubectl apply -f base-imagemagick.yaml

しばらくするとstack-pod-base-imagemagick-1という名前のPodができて、StatusがCompletedになります。

$ kubectl get pod                                              
NAME                           READY   STATUS      RESTARTS   AGE
stack-pod-base-imagemagick-1   0/2     Completed   0          38s

base-imagemagickという名前のClusterStackも作成されます。

$ kubectl get clusterstack                         
NAME               READY
base               True
base-imagemagick   True
default            True
full               True
tiny               True

このClusterStackの詳細を確認します。

$ kubectl describe clusterstack base-imagemagick
Name:         base-imagemagick
Namespace:    
Labels:       <none>
Annotations:  <none>
API Version:  kpack.io/v1alpha1
Kind:         ClusterStack
Metadata:
  Creation Timestamp:  2021-08-08T14:08:30Z
  Generation:          3
  Managed Fields:
    ...
Spec:
  Build Image:
    Image:  harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-build@sha256:1c3a456eb5aa2ce6b3daab22ca6578ffba868a650cce551649bbe6522da119c2
  Id:       io.buildpacks.stacks.bionic
  Run Image:
    Image:  harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run@sha256:4f594b8906ffddc16668d0e2dd5cfb773be8d12fa140c54b0cc24cdfb925a1d5
Status:
  Build Image:
    Image:         harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-build@sha256:1c3a456eb5aa2ce6b3daab22ca6578ffba868a650cce551649bbe6522da119c2
    Latest Image:  harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-build@sha256:1c3a456eb5aa2ce6b3daab22ca6578ffba868a650cce551649bbe6522da119c2
  Conditions:
    Last Transition Time:  2021-08-08T14:45:00Z
    Status:                True
    Type:                  Ready
  Group Id:                1000
  Id:                      io.buildpacks.stacks.bionic
  Mixins:
    adduser
    apt
    base-files
    base-passwd
    bash
    bsdutils
    bzip2
    ca-certificates
    coreutils
    dash
    debconf
    debianutils
    diffutils
    dpkg
    e2fsprogs
    fdisk
    findutils
    gcc-8-base
    gpgv
    grep
    gzip
    hostname
    init-system-helpers
    libacl1
    libapt-pkg5.0
    libattr1
    libaudit-common
    libaudit1
    libblkid1
    libbz2-1.0
    libc-bin
    libc6
    libcap-ng0
    libcom-err2
    libdb5.3
    libdebconfclient0
    libext2fs2
    libfdisk1
    libffi6
    libgcc1
    libgcrypt20
    libgmp10
    libgnutls30
    libgpg-error0
    libhogweed4
    libidn2-0
    liblz4-1
    liblzma5
    libmount1
    libncurses5
    libncursesw5
    libnettle6
    libp11-kit0
    libpam-modules
    libpam-modules-bin
    libpam-runtime
    libpam0g
    libpcre3
    libprocps6
    libseccomp2
    libselinux1
    libsemanage-common
    libsemanage1
    libsepol1
    libsmartcols1
    libss2
    libssl1.1
    libstdc++6
    libsystemd0
    libtasn1-6
    libtinfo5
    libudev1
    libunistring2
    libuuid1
    libyaml-0-2
    libzstd1
    locales
    login
    lsb-base
    mawk
    mount
    ncurses-base
    ncurses-bin
    netbase
    openssl
    passwd
    perl-base
    procps
    sed
    sensible-utils
    sysvinit-utils
    tar
    tzdata
    ubuntu-keyring
    util-linux
    zlib1g
    build:binutils
    build:binutils-common
    build:binutils-x86-64-linux-gnu
    build:build-essential
    build:cpp
    build:cpp-7
    build:curl
    build:dpkg-dev
    build:g++
    build:g++-7
    build:gcc
    build:gcc-7
    build:gcc-7-base
    build:git
    build:git-man
    build:jq
    build:libasan4
    build:libasn1-8-heimdal
    build:libatomic1
    build:libbinutils
    build:libc-dev-bin
    build:libc6-dev
    build:libcc1-0
    build:libcilkrts5
    build:libcurl3-gnutls
    build:libcurl4
    build:libdpkg-perl
    build:liberror-perl
    build:libexpat1
    build:libgcc-7-dev
    build:libgdbm-compat4
    build:libgdbm5
    build:libgmp-dev
    build:libgmpxx4ldbl
    build:libgomp1
    build:libgssapi-krb5-2
    build:libgssapi3-heimdal
    build:libhcrypto4-heimdal
    build:libheimbase1-heimdal
    build:libheimntlm0-heimdal
    build:libhx509-5-heimdal
    build:libisl19
    build:libitm1
    build:libjq1
    build:libk5crypto3
    build:libkeyutils1
    build:libkrb5-26-heimdal
    build:libkrb5-3
    build:libkrb5support0
    build:libldap-2.4-2
    build:libldap-common
    build:liblsan0
    build:libmpc3
    build:libmpfr6
    build:libmpx2
    build:libnghttp2-14
    build:libonig4
    build:libperl5.26
    build:libpsl5
    build:libquadmath0
    build:libroken18-heimdal
    build:librtmp1
    build:libsasl2-2
    build:libsasl2-modules-db
    build:libsqlite3-0
    build:libstdc++-7-dev
    build:libtsan0
    build:libubsan0
    build:libwind0-heimdal
    build:linux-libc-dev
    build:make
    build:patch
    build:perl
    build:perl-modules-5.26
    build:xz-utils
    build:zlib1g-dev
    run:dbus
    run:fontconfig
    run:fontconfig-config
    run:fonts-dejavu-core
    run:fonts-droid-fallback
    run:fonts-noto-mono
    run:ghostscript
    run:gsfonts
    run:hicolor-icon-theme
    run:imagemagick
    run:imagemagick-6-common
    run:imagemagick-6.q16
    run:krb5-locales
    run:libapparmor1
    run:libavahi-client3
    run:libavahi-common-data
    run:libavahi-common3
    run:libbsd0
    run:libcairo2
    run:libcups2
    run:libcupsfilters1
    run:libcupsimage2
    run:libdatrie1
    run:libdbus-1-3
    run:libdjvulibre-text
    run:libdjvulibre21
    run:libexpat1
    run:libfftw3-double3
    run:libfontconfig1
    run:libfreetype6
    run:libglib2.0-0
    run:libglib2.0-data
    run:libgomp1
    run:libgraphite2-3
    run:libgs9
    run:libgs9-common
    run:libgssapi-krb5-2
    run:libharfbuzz0b
    run:libicu60
    run:libidn11
    run:libijs-0.35
    run:libilmbase12
    run:libjbig0
    run:libjbig2dec0
    run:libjpeg-turbo8
    run:libjpeg8
    run:libk5crypto3
    run:libkeyutils1
    run:libkrb5-3
    run:libkrb5support0
    run:liblcms2-2
    run:liblqr-1-0
    run:libltdl7
    run:libmagickcore-6.q16-3
    run:libmagickcore-6.q16-3-extra
    run:libmagickwand-6.q16-3
    run:libnetpbm10
    run:libopenexr22
    run:libpango-1.0-0
    run:libpangocairo-1.0-0
    run:libpangoft2-1.0-0
    run:libpaper-utils
    run:libpaper1
    run:libpixman-1-0
    run:libpng16-16
    run:libthai-data
    run:libthai0
    run:libtiff5
    run:libwmf0.2-7
    run:libx11-6
    run:libx11-data
    run:libxau6
    run:libxcb-render0
    run:libxcb-shm0
    run:libxcb1
    run:libxdmcp6
    run:libxext6
    run:libxml2
    run:libxrender1
    run:multiarch-support
    run:netpbm
    run:poppler-data
    run:shared-mime-info
    run:ucf
    run:xdg-user-dirs
  Observed Generation:  3
  Run Image:
    Image:         harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run@sha256:4f594b8906ffddc16668d0e2dd5cfb773be8d12fa140c54b0cc24cdfb925a1d5
    Latest Image:  harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run@sha256:4f594b8906ffddc16668d0e2dd5cfb773be8d12fa140c54b0cc24cdfb925a1d5
  User Id:         1000
Events:            <none>

base ClusterStackに比べて、imagemagickに関連する次のパッケージが増えています。

>     run:dbus
>     run:fontconfig
>     run:fontconfig-config
>     run:fonts-dejavu-core
>     run:fonts-droid-fallback
>     run:fonts-noto-mono
>     run:ghostscript
>     run:gsfonts
>     run:hicolor-icon-theme
>     run:imagemagick
>     run:imagemagick-6-common
>     run:imagemagick-6.q16
>     run:krb5-locales
>     run:libapparmor1
>     run:libavahi-client3
>     run:libavahi-common-data
>     run:libavahi-common3
>     run:libbsd0
>     run:libcairo2
>     run:libcups2
>     run:libcupsfilters1
>     run:libcupsimage2
>     run:libdatrie1
>     run:libdbus-1-3
>     run:libdjvulibre-text
>     run:libdjvulibre21
>     run:libexpat1
>     run:libfftw3-double3
>     run:libfontconfig1
>     run:libfreetype6
>     run:libglib2.0-0
>     run:libglib2.0-data
>     run:libgomp1
>     run:libgraphite2-3
>     run:libgs9
>     run:libgs9-common
>     run:libgssapi-krb5-2
>     run:libharfbuzz0b
>     run:libicu60
>     run:libidn11
>     run:libijs-0.35
>     run:libilmbase12
>     run:libjbig0
>     run:libjbig2dec0
>     run:libjpeg-turbo8
>     run:libjpeg8
>     run:libk5crypto3
>     run:libkeyutils1
>     run:libkrb5-3
>     run:libkrb5support0
>     run:liblcms2-2
>     run:liblqr-1-0
>     run:libltdl7
>     run:libmagickcore-6.q16-3
>     run:libmagickcore-6.q16-3-extra
>     run:libmagickwand-6.q16-3
>     run:libnetpbm10
>     run:libopenexr22
>     run:libpango-1.0-0
>     run:libpangocairo-1.0-0
>     run:libpangoft2-1.0-0
>     run:libpaper-utils
>     run:libpaper1
>     run:libpixman-1-0
>     run:libpng16-16
>     run:libthai-data
>     run:libthai0
>     run:libtiff5
>     run:libwmf0.2-7
>     run:libx11-6
>     run:libx11-data
>     run:libxau6
>     run:libxcb-render0
>     run:libxcb-shm0
>     run:libxcb1
>     run:libxdmcp6
>     run:libxext6
>     run:libxml2
>     run:libxrender1
>     run:multiarch-support
>     run:netpbm
>     run:poppler-data
>     run:shared-mime-info
>     run:ucf
>     run:xdg-user-dirs

実際にRun Imageを確認してみます。Image名は詳細情報に記載されており、harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run@sha256:4f594b8906ffddc16668d0e2dd5cfb773be8d12fa140c54b0cc24cdfb925a1d5です。

$ docker run --entrypoint bash --rm harbor.orange.maki.lol/tanzu-build-service/build-service/stack-base-imagemagick-run@sha256:4f594b8906ffddc16668d0e2dd5cfb773be8d12fa140c54b0cc24cdfb925a1d5 -c 'convert --version'

Version: ImageMagick 6.9.7-4 Q16 x86_64 20170114 http://www.imagemagick.org
Copyright: © 1999-2017 ImageMagick Studio LLC
License: http://www.imagemagick.org/script/license.php
Features: Cipher DPC Modules OpenMP 
Delegates (built-in): bzlib djvu fftw fontconfig freetype jbig jng jpeg lcms lqr ltdl lzma openexr pangocairo png tiff wmf x xml zlib

ImageMagickがインストールされていることを確認できました。

オープンソースのkpackにはなく、Tanzu Build Service独自の機能ですが、CustomStackを使うことで容易にStackにaptのパッケージを追加し管理できます。