$30 off During Our Annual Pro Sale. View Details »

Container Images for the Cloud Native Era

Container Images for the Cloud Native Era

Slides for my session at CloudNativeFM about Wolfi, melange, and apko. The video is available here: https://www.youtube.com/watch?v=SmUFKNh0YLI

Erika Heidi

October 20, 2022

More Decks by Erika Heidi

Other Decks in Technology


  1. Container Images for the Cloud-Native Era Wolfi, apko, and melange:

    the OSS container image toolkit by Chainguard Chainguard.dev | @erikaheidi
  2. Ecosystem Overview

  3. Wolfi • Tiny Linux Distribution • "Undistro" because it doesn't

    have stuff that normally goes into a Linux distribution (kernel, man pages, a bunch of other packages that don't make sense for containers) • Based on apk (the Alpine package manager) • Primarily GLIB-C (but MUSL is on the roadmap) • Packages defined as YAML and built with melange
  4. melange • Declarative apk builder tool • Part of the

    building toolkit behind Wolfi / Chainguard Images • Build pipelines are defined in YAML files • Multi-architecture by default (via QUEMU) • Platform-agnostic builds via Docker + apko image
  5. apko • Declarative OCI image builder tool based on apk

    • Part of the building toolkit behind Wolfi / Chainguard Images • Images are defined in YAML files • Builds are fully reproducible • Automatically generates SBOMs for every image • Platform-agnostic builds via Docker + apko image
  6. None
  7. apko deep dive

  8. Example apko.yaml file contents: repositories: - https://dl-cdn.alpinelinux.org/alpine/edge/main packages: - alpine-base

    cmd: /bin/sh -l environment: PATH: /usr/sbin:/sbin:/usr/bin:/bin
  9. Building the image with apko via Docker $ docker run

    --rm -v ${PWD}:/work cgr.dev/chainguard/apko build alpine-base.yaml alpine-base:test alpine-test.tar Testing the image with Docker $ docker load < alpine-test.tar $ docker run -it alpine-base:test
  10. Why apk • Introduced by Alpine, it uses a different

    methodology to handle package management • Package installation or removal is done as a side effect of modifying the system state • This creates the ideal conditions for reproducible and declarative pipelines
  11. Where do packages come from • For Alpine-based images, use

    Alpine apks found at pkgs.alpinelinux.org/packages • For Wolfi-based images, use Wolfi apks that are listed in the wolfi-os repository, hosted at packages.wolfi.dev/os • Don't mix! • You can also create your own apks with melange
  12. Why distroless?

  13. The distroless philosophy • Minimalist container images with only what's

    absolutely necessary to build or execute your application • Popular base images are full of software that only makes sense on bare-metal • No need for package managers or interactive shells on production images • Less dependencies = smaller attack surface, less CVEs
  14. The distroless philosophy: less CVEs = win

  15. Case Study: Dynacover Migrating a PHP image to apko /

  16. Dynacover Overview • Dynamic header images for Twitter • PHP

    application built with Minicli • Main dependencies: PHP (cli), Curl and GD
  17. Dynacover Overview • GitHub Action that runs on schedule •

    Using an image based on the official php:7.4-cli ◦ Size: 589MB ◦ CVEs (Trivy): 331
  18. Migration step 1: collecting dependencies FROM php:7.4-cli ARG user=dynacover ARG

    uid=1000 RUN apt-get update && apt-get install -y git curl libonig-dev libxml2-dev libfreetype6-dev libjpeg62-turbo-dev libpng-dev zip unzip RUN apt-get clean && rm -rf /var/lib/apt/lists/* RUN docker-php-ext-configure gd --with-freetype --with-jpeg && \ docker-php-ext-install pdo_mysql mbstring exif pcntl bcmath gd COPY --from=composer:latest /usr/bin/composer /usr/bin/composer RUN useradd -G sudo,root -u $uid -d /home/$user $user RUN mkdir -p /home/$user/.composer && \ chown -R $user:$user /home/$user USER $user RUN mkdir -p /home/$user/dynacover COPY . /home/$user/dynacover/ WORKDIR /home/$user/dynacover RUN composer install • git • curl • zip • unzip • libonig-dev • libfreetype6-dev • libjpeg62-turbo-dev • libpng-dev • php-mbstring • php-exif • php-pcntl • php-bcmath • php-gd
  19. Migration step 2: finding appropriate apks

  20. Migration step 3: creating the apko.yaml file contents: repositories: -

    https://dl-cdn.alpinelinux.org/alpine/edge/main - https://dl-cdn.alpinelinux.org/alpine/edge/community … … packages: - alpine-baselayout-data - ca-certificates-bundle - curl - git - zip - unzip - libxml2-dev - freetype - freetype-dev - libjpeg-turbo - libjpeg-turbo-dev - libpng - php81 - php81-gd - php81-curl - php81-mbstring - php81-phar - php81-openssl - php81-pcntl
  21. Migration step 3: creating the apko.yaml file entrypoint: command: /usr/bin/php81

    environment: PATH: /usr/sbin:/sbin:/usr/bin:/bin … … accounts: groups: - groupname: minicli gid: 65532 users: - username: minicli uid: 65532 run-as: root - php81-pcntl
  22. Migration step 4: building/pushing the image $ docker run --rm

    -v ${PWD}:/work cgr.dev/chainguard/apko build apko.yaml \ erikaheidi/minicli:php81 minicli-php81.tar $ docker load < minicli-php81.tar $ docker push erikaheidi/minicli:php81
  23. Migration step 5: updating GH Action Dockerfile FROM erikaheidi/minicli:php81 COPY

    --from=composer:latest /usr/bin/composer /usr/bin/composer RUN git clone -b 1.0.1 --depth 1 https://github.com/erikaheidi/dynacover.git && \ cd dynacover && \ composer install --no-progress --no-dev --prefer-dist ENTRYPOINT [ "php81", "/dynacover/dynacover" ] CMD ["cover", "update"]
  24. None
  25. Dynacover base image: before / after • Based on php:7.4-cli

    • Base image total size: 589MB • Total CVEs: 331 • Distroless based on Alpine • Base image total size: 48MB • Total CVEs: 0
  26. Resources to Learn More • minicli:php81 on GitHub • Getting

    Started with apko tutorial on Chainguard Academy • apko on GitHub • Troubleshooting apko builds • Chainguard Images documentation • Wolfi documentation
  27. Questions?

  28. Thank You!