BuildConfigs and ImageStream

Object

To understand how BuildConfigs and ImageStreams are used to create images that are used in Kubernetes containers. The examples that will be used in this tutorial is a Nginx server.

Prerequisites

WARNING

There is no namespaces included with ImageStreams BuildConfig or Pod deployments. When you are using oc command lines to apply a configuration, it will use your existing context. please use the oc project <yournamespace> before running any of these commands

Setup

In order to start this tutorial, login to openshift through the terminal, and then switch to your namespace.

oc project <yournamespace>

The ImageStream

Image streams provide a means of creating and updating container images in an on-going way. As improvements are made to an image, tags can be used to assign new version numbers and keep track of changes. This document describes how image streams are managed.

## oc project <yournamespace>

## Run to deploy nginx ImageStream
oc apply -f https://bcgov.github.io/des-training/code/openshift/nginx-image-stream.yaml
kind: ImageStream
apiVersion: image.openshift.io/v1
metadata:
  name: nginx
  annotations:
    description: Nginx Image stream with templates for NGINX_PORT and NGINX_HOST
  labels:
    name: nginx-image
  • kind: ImageStream - defines the type of resource
  • apiVersion: image.openshift.io/v1 - this gives the specification
  • metadata.name - nginx - will be how we identify this resource

The BuildConfig

The build config is the instruction on how your image will get build, from source, docker or as a multi-build.

Build Config Example 1 from Repository

## oc project <yournamespace>

## Run to deploy nginx BuildConfig
oc apply -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build.yaml
## Create a build and follow
oc start-build -F nginx-build-config
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: nginx-build-config
  annotations:
    description: This builds the nginx image from GIT source.
strategy:
  dockerStrategy:
    forcePull: true
spec:
  successfulBuildsHistoryLimit: 2
  failedBuildsHistoryLimit: 2
  runPolicy: Serial
  source:
    type: Git
    git:
      ref: main
      uri: https://github.com/bcgov/des-training.git
    contextDir: docker/nginx
  strategy:
    type: Docker
    dockerStrategy:
      dockerfilePath: Dockerfile.template
      buildArgs:
      - name: CODE_VERSION
        value:  1.24.0
  output:
    to:
      kind: ImageStreamTag
      name: nginx:template

Dockerfile.template

# Dockerfile.template - used to create an Nginx image with templates.
ARG CODE_VERSION=latest
FROM nginx:${CODE_VERSION}
# As of Nginx 1.19 you can use templates
COPY ./default.conf.template /etc/nginx/templates/
# Fix up permissions
RUN chmod -Rf 0777 /tmp /var /run /etc /mnt || :
# Switch to usermode
USER 104

default.conf.template

#default.conf.template
server {
   listen       ${NGINX_PORT};
   listen  [::]:${NGINX_PORT};
   server_name  ${NGINX_HOST};

   #access_log  /var/log/nginx/host.access.log  main;

   location / {
       root   /usr/share/nginx/html;
       index  index.html index.htm;
   }

   #error_page  404              /404.html;

   # redirect server error pages to the static page /50x.html
   #
   error_page   500 502 503 504  /50x.html;
   location = /50x.html {
       root   /usr/share/nginx/html;
   }
}

Cleanup resources

## oc project <yournamespace>
oc delete -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build.yaml

Build Config Example 2 with Source Image from Repository

## oc project <yournamespace>

## Run to deploy nginx BuildConfig
oc apply -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build-source.yaml
## Create a build and follow
oc start-build -F nginx-build-source-config
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: nginx-build-source-config
  annotations:
    description: This builds the nginx image from GIT source.
strategy:
  dockerStrategy:
    forcePull: true
spec:
  successfulBuildsHistoryLimit: 2
  failedBuildsHistoryLimit: 2
  runPolicy: Serial
  source:
    type: Git
    git:
      ref: main
      uri: https://github.com/bcgov/des-training.git
    contextDir: docker/nginx
  strategy:
    type: Docker
    dockerStrategy:
      from:
        kind: DockerImage
        name: nginx:1.23.3-alpine
      dockerfilePath: Dockerfile.template
      buildArgs:
      - name: CODE_VERSION
        value:  1.24.0
  output:
    to:
      kind: ImageStreamTag
      name: nginx:from-source
  • This works exactly the same as example 1 with these differences
    • It overwrites the FROM image with the image in the strategy.dockerStrategy.from.name
    • This gets build to the nginx image with a tag of from-source nginx:from-source

Cleanup resources

## oc project <yournamespace>
oc delete -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build-source.yaml

Build Config Example 3 Inline Dockerfile

## oc project <yournamespace>

## Run to deploy nginx BuildConfig
oc apply -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build-inline.yaml
## Create a build and follow
oc start-build -F nginx-build-inline-config
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: nginx-build-inline-config
  annotations:
    description: This builds the nginx image from inline dockerfile.
strategy:
  dockerStrategy:
    forcePull: true
spec:
  successfulBuildsHistoryLimit: 2
  failedBuildsHistoryLimit: 2
  runPolicy: Serial
  source:
    dockerfile: |-
      # Dockerfile.sed - used to create an Nginx image with new port defined by $PORT
      ARG CODE_VERSION=latest
      FROM nginx:${CODE_VERSION}
      # Using sed to change port 80 to ${PORT} as port 80 is a privileged port.
      RUN ["/bin/bash", "-c", "sed -i 's/80/38081/g' /etc/nginx/conf.d/default.conf"]
      # Fix up permissions
      RUN chmod -Rf 0777 /tmp /var /run /etc /mnt || :
      # Switch to usermode
      USER 104
  strategy:
    type: Docker
    dockerStrategy:
      buildArgs:
      - name: CODE_VERSION
        value:  1.25.3
      - name: PORT
        value: 38081
  output:
    to:
      kind: ImageStreamTag
      name: nginx:port38081
  • This build uses a Docker strategy, that uses an inline Docker file.
  • It passes the buildArgs to pass the port and the version.
  • This gets build to the nginx image with a tag of port38081 nginx:port38081

Cleanup resources

## oc project <yournamespace>
oc delete -f https://bcgov.github.io/des-training/code/openshift/nginx-image-build-inline.yaml

Build Config Example 4 Inline Dockerfile with ConfigMap

## oc project <yournamespace>

## Run to deploy nginx BuildConfig
oc apply -f https://bcgov.github.io/des-training/code/openshift/composer-build-with-config.yaml
## Create a build and follow
oc start-build -F des-training-composer-build

# The config map which will contain the composer.json file for the s2i build.
kind: ConfigMap
apiVersion: v1
metadata:
  name: des-training-composer-file
  annotations:
    description: Training, Configmap that stores a composer.json file, used for building an image.
data:
  composer.json: |
    {
      "name": "bcgov/sample-composer-project",
      "type": "project",
      "license": "MIT",
      "require": {
          "monolog/monolog": "3.5.0"
      },
      "config": {
        "php": "8.3"
      }
    }
---
# Image stream
kind: ImageStream
apiVersion: image.openshift.io/v1
metadata:
  name: des-training-composer
  annotations:
    description: Training, Image that has the composer install on a composer.json from buildConfig
---
# The Build config to run composer.json defined in config map
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
  name: des-training-composer-build
  labels:
    name: training
spec:
  output:
    to:
      kind: ImageStreamTag
      name: 'des-training-composer:latest'
  resources:
    limits:
      cpu: '0.4'
      memory: 400Mi
    
  successfulBuildsHistoryLimit: 1
  failedBuildsHistoryLimit: 1
  completionDeadlineSeconds: 1800
  strategy:
    type: Docker
  source:
    type: Dockerfile
    dockerfile: |-
      FROM composer-source AS composer
      WORKDIR /var/www/html
      # Because there is a dockerfile and not using github for s2i, it uses the configmap for composer.json
      COPY composer.json /var/www/html
      RUN composer install
    images:
      - from:
          kind: DockerImage
          name: 'composer:lts'
        as:
          - composer-source
    configMaps:
      - configMap:
          name: des-training-composer-file
      # - configMap:
      #     name: some-other-config-map
  runPolicy: Parallel
  • This build uses a Docker strategy, that uses an inline Docker file.
  • It passes the composer.json file from the configMap
  • For more information on input secrets and config mapsopen in new window
  • This gets build to the des-training-composer image with a tag of latest des-training-composer:latest

Cleanup resources

## oc project <yournamespace>
oc delete -f https://bcgov.github.io/des-training/code/openshift/composer-build-with-config.yaml
Last Updated:
Contributors: Shawn