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

Container Images for the Cloud Native Era

Erika Heidi
October 20, 2022

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
Tweet

More Decks by Erika Heidi

Other Decks in Technology

Transcript

  1. Container Images for the
    Cloud-Native Era
    Wolfi, apko, and melange: the OSS
    container image toolkit by Chainguard
    Chainguard.dev | @erikaheidi

    View Slide

  2. Ecosystem Overview

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  6. View Slide

  7. apko deep dive

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  12. Why distroless?

    View Slide

  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

    View Slide

  14. The distroless philosophy: less CVEs = win

    View Slide

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

    View Slide

  16. Dynacover Overview
    ● Dynamic header images
    for Twitter
    ● PHP application built
    with Minicli
    ● Main dependencies: PHP
    (cli), Curl and GD

    View Slide

  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

    View Slide

  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

    View Slide

  19. Migration step 2: finding appropriate apks

    View Slide

  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

    View Slide

  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

    View Slide

  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

    View Slide

  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"]

    View Slide

  24. View Slide

  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

    View Slide

  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

    View Slide

  27. Questions?

    View Slide

  28. Thank You!

    View Slide