Demystifying Containers

About Me

saschagrunert

mail@

.de

About the Series

  • series of blog posts and corresponding talks
  • all about containers from a historic perspective

Part III: Container Images

History of container images

OCI image specification

buildah, podman, skopeo

Trends

Continuous Integration (CI) and Deployment (CD) pipelines inside of Kubernetes

Unifying testing and production infrastructure

Adapt to Succeed

maintain efficient software life cycle

keep security

“As a company, am I able to afford the costs of a healthy Dev(sec)ops strategy?”

“Do my developers really understand what they do if they set up a fully automated CD pipeline, which builds, pushes and canary deploys the latest microservice artifacts in one rush directly to the production environment?”

production

testing

be able to move application from A to B without changing the deployment

apply the same security patterns everywhere

Ship in Containers

Packing containers into Images

2013

   

multiple versions for the image format specification

2016: Docker version 2 schema 1

2017: Docker version 2 schema 2

donated to the Open Container Initiative

2017: OCI image format v1.0.0

The OCI Image Specification

                    

configuration

layers

manifest

index

JSON

JSON

JSON

tarballs

Retrieving an example image

> jq . mysterious-image/index.json
{
  "schemaVersion": 2,
  "manifests": [
    {
      "mediaType": "application/vnd.oci.image.manifest.v1+json",
      "digest": "sha256:703c711516a88a4ec99d742ce59e1a2f0802a51dac916975ab6f2b60212cd713",
      "size": 502,
      "platform": {
        "architecture": "amd64",
        "os": "linux"
      }
    }
  ]
}
index
{
  "schemaVersion": 2,
  "config": {
    "mediaType": "application/vnd.oci.image.config.v1+json",
    "digest": "sha256:8b2633baa7e149fe92e6d74b95e33d61b53ba129021ba251ac0c7ab7eafea825",
    "size": 850
  },
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa",
      "size": 2789742
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:6d8c9f2df98ba6c290b652ac57151eab8bcd6fb7574902fbd16ad9e2912a6753",
      "size": 120
    }
  ]
}
> jq . mysterious-image/blobs/sha256/703c711516a88a4ec99d742ce59e1a2f0802a51dac916975ab6f2b60212cd713
manifest
{
  "created": "2019-08-09T12:09:13.129872299Z",
  "architecture": "amd64",
  "os": "linux",
  "config": {
    "Env": [
      "PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
    ],
    "Cmd": ["/bin/sh"]
  },
  "rootfs": {
    "type": "layers",
    "diff_ids": [
      "sha256:1bfeebd65323b8ddf5bd6a51cc7097b72788bc982e9ab3280d53d3c613adffa7",
      "sha256:56e2c46a3576a8c1a222f9a263dc57ae3c6b8baf6a68d03065f4b3ea6c0ae8d1"
    ]
  },
  "history": [
    {
      "created": "2019-07-11T22:20:52.139709355Z",
      "created_by": "/bin/sh -c #(nop) ADD file:0eb5ea35741d23fe39cbac245b3a5d84856ed6384f4ff07d496369ee6d960bad in / "
    },
    {
      "created": "2019-07-11T22:20:52.375286404Z",
      "created_by": "/bin/sh -c #(nop)  CMD [\"/bin/sh\"]",
      "empty_layer": true
    },
    {
      "created": "2019-08-09T14:09:12.848554218+02:00",
      "created_by": "/bin/sh -c echo Hello",
      "empty_layer": true
    },
    {
      "created": "2019-08-09T12:09:13.129872299Z",
      "created_by": "/bin/sh -c touch my-file"
    }
  ]
}
> jq . mysterious-image/blobs/sha256/8b2633baa7e149fe92e6d74b95e33d61b53ba129021ba251ac0c7ab7eafea825
configuration

Extracting the rootfs

{
  "layers": [
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:0503825856099e6adb39c8297af09547f69684b7016b7f3680ed801aa310baaa",
      "size": 2789742
    },
    {
      "mediaType": "application/vnd.oci.image.layer.v1.tar+gzip",
      "digest": "sha256:6d8c9f2df98ba6c290b652ac57151eab8bcd6fb7574902fbd16ad9e2912a6753",
      "size": 120
    }
  ]
}

Discovering the other layer

{
  "history": [
    {
      "created": "2019-08-09T12:09:13.129872299Z",
      "created_by": "/bin/sh -c touch my-file"
    }
  ]
}
FROM alpine:latest
RUN echo Hello
RUN touch my-file

buildah

2017

creation of OCI images

Build using Dockerfiles

buildah subcommands

Listing running containers?

building container images spawns containers

each modification step can create new history entries or layers

😲

Hijacking the docker build process

Building containers without Dockerfiles

dedicated subcommands for Dockerfile instructions like RUN and COPY

more flexible build process

Working with buildah

Mounting the container’s file system

buildah’ception

rootless

~/.config/containers - configuration

~/.local/share/containers - storage

execution context completely bound to user permissions

podman as buildah’s interface

That’s it.

https://github.com/

saschagrunert/demystifying-containers

Demystifying Containers - Part III: Container Images

By Sascha Grunert

Demystifying Containers - Part III: Container Images

A series of blog posts and talks about the world of containers

  • 1,706