Reaves.dev

v0.1.0

built using

Phoenix v1.7.12

Building Custom Images With Openshift

Stephen M. Reaves

::

2023-02-01

Building custom images using BuildConfig, from a public image, to a private is

Backstory

I was working with some containers recently on my Openshift cluster and I wanted to debug a pod. I tried to run a fedora image by specifying oc debug pod/<podName> --image quay.io/fedora/fedora --as-root=true. The container created everything fine, but when I tried to ping a resource, I found that the default image didn’t have ping installed. Let me walk you through how I decided to solve this problem.

ImageStream

I decided to build a custom ImageStream (is) that was essentially Fedora + the packages I needed. An is is basically an abstraction over the standard container that allows for rapid consumption in an OpenShift cluster. I could have built my container with Gitlab CICD, but I really only need this to be internal to the cluster. This is exactly what iss are for. Actually, we’ll need two of them.

Overview

Basically, the workflow will look like this, the first is will simply mirror quay.io/fedora/fedora:latest. We can set this to automatically check for a newer upstream version every 15 or so minutes and refresh the local version if needed. This also works as a image cache, since we can pull from the is multiple times and not mess with our docker pull limit.

We also have to define an is for our resulting image. For the purpose of this blog we’ll call them is/fedora-input and is/fedora-output.

In the middle we have a BuildConfig (BC) that applies the transformations. There’s actually quite a lot of options here, but we are simply going to use an inline-dockerfile.

Result

Here is the config that I was able to use to get the tools I needed for debugging:

apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: fedora-input
spec:
  lookupPolicy:
    local: true
  tags:
  - name: latest
    from:
      kind: DockerImage
      name: quay.io/fedora/fedora
    
    importPolicy:
      scheduled: true
    referencePolicy:
      type: Source
 ---
apiVersion: image.openshift.io/v1
kind: ImageStream
metadata:
  name: fedora-output
spec:
  lookupPolicy:
    local: true
 ---
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: fedora-builder
spec:
  runPolicy: Serial
  strategy:
    dockerStrategy: {}
    type: Docker
  source:
    type: Dockerfile
    dockerfile: |
      FROM image-registry.openshift-image-registry.svc:5000/<namespace>/fedora-input:latest

      RUN dnf install -y iputils postgresql
  output:
    to:
      kind: ImageStreamTag
      name: fedora-output:latest
  triggers:
    
    - type: ConfigChange
    
    - type: ImageChange
      imageChange:
        from:
          kind: ImageStreamTag
          name: fedora-input:latest

So now when Fedora publishes new image, that triggers a change in my local is/fedora-input, which kicks off a new build, which finally updates my is/fedora-output. This way, I can use is/fedora-output as my debug image and it’s always up to date with exactly the tools I need.