Many people around the world look for ways to build container images in Kubernetes without the need to mount the docker socket or perform any other action that compromises security on your cluster. With the increased need, a famous software engineer, Jessie Frazelle saw the need to introduce Img image builder. This is an open-source, daemon-less, and unprivileged Dockerfile and OCI compatible container image builder. Img is a wrapper around the open-source BuildKit, a building technology embedded within Img.
There are many features associated with the img image builder. Some of them are:
- Img CLI, a responsive CLI that provides a set of commands similar to Docker CLI commands when dealing with container image building, distribution, and image manipulation.
- Rootless Builds: img can be run without requiring the –privileged Docker flag or the equivalent privileged: true security context in Kubernetes.
- BuildKit: defined as one of the next generation build engines for container images.
- Parallel Build Execution: BuildKit assembles an internal representation of the build steps as a Directed Acyclic Graph (DAG), which enables it to determine which build steps can be executed in parallel.
- Cross-Platform/OS Builds: it’s possible to build images for different combinations of architecture and OS on a completely different platform
In this guide, we will take a deep dive into how to build container images on Kubernetes using img image builder.
Setup Pre-requisites
This guide will work best if you have a Kubernetes cluster set up. Below is a list of dedicated guides to help you achieve this:
- Install Kubernetes Cluster on Rocky Linux 8 with Kubeadm & CRI-O
- Install Kubernetes Cluster on Ubuntu using K3s
- Deploy Kubernetes Cluster on Linux With k0s
- Run Kubernetes on Debian with Minikube
This guide will demonstrate how to build container images from Dockerfile using img image builder in Kubernetes with Github. So, you will also need:
- Access to Kubernetes cluster with permissions to create, list, update and delete pods, jobs, and services
- Github repository with a Dockerfile: we will use the repo URL as the path of the Dockerfile
- Dockerhub account: to be able to authenticate and push the Docker image.
#1. Configure Build Contexts
For this guide, we will use a private GitHub repository as our build context. We need to configure it with the required Dockerfile.
The URL to my private git repository used in this article is:
https://github.com/neveropen/kubernetes-demo
In the repository, I will create a Dockerfile with the contents below:
FROM ubuntu
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
Now obtain a Personal Access Token to your git account.
#2. Create the Img Pod Manifest
We will have two containers:
- Git-sync: an init container to clone the private git repository
- img: that builds the docker image and pushes it to docker hub
These two containers share a volume git-repo mounted as emptyDir at /repo
Create a manifest for the pod.
vim pod.yml
Add the below lines to the manifest:
apiVersion: v1
kind: Pod
metadata:
labels:
run: img
name: img
annotations:
container.apparmor.security.beta.kubernetes.io/img: unconfined
spec:
securityContext:
runAsUser: 1000
initContainers:
- name: git-sync
image: k8s.gcr.io/git-sync:v3.1.5
volumeMounts:
- name: git-repo
mountPath: /repo
env:
- name: GIT_SYNC_REPO
value: "https://github.com/neveropen/kubernetes-demo.git" ##Private repo-path-you-want-to-clone
- name: GIT_SYNC_USERNAME
value: "neveropen" ##The username for the Git repository
- name: GIT_SYNC_PASSWORD
value: "ghp_JilxkjTT5EIgJCV........" ##The Personal Access Token for the Git repository
- name: GIT_SYNC_BRANCH
value: "master" ##repo-branch
- name: GIT_SYNC_ROOT
value: /repo
- name: GIT_SYNC_DEST
value: "hello" ##path-where-you-want-to-clone
- name: GIT_SYNC_ONE_TIME
value: "true"
securityContext:
runAsUser: 0
containers:
- image: r.j3ss.co/img
imagePullPolicy: Always
name: img
resources: {}
workingDir: /repo/hello
command: ["/bin/sh"]
args:
- -c
- >-
img build -t docker.io/<dockerhub_username>/helloworld . &&
img login -u <dockerhub_username> -p <dockerhub_password> &&
img push docker.io/<dockerhub_username>/helloworld
volumeMounts:
- name: cache-volume
mountPath: /tmp
- name: git-repo
mountPath: /repo
volumes:
- name: cache-volume
emptyDir: {}
- name: git-repo
emptyDir: {}
restartPolicy: Never
In the above file, replace the values appropriately. You can also notice that the destination folder for git-sync is the working directory for img. If you are using a public git repository, you may not be required to provide the Personal Access Token for the Git repository.
#3. Run img image builder in Kubernetes
Using the manifest, run the pod using the command:
kubectl apply -f pod.yml
Now follow the image build and push process with the command:
kubectl logs img --follow
Output:
From the above output, we are safe to conclude that the image has been successfully pushed to DockerHub
#4. Pull and Test the Image
You can now pull and test the image using:
1. Docker
Ensure that Docker is installed on your system. The below guide can help you achieve this:
Now run a container with the image using the command:
docker run -it <user-name>/<repo-name>
For example:
docker run -it klinsmann1/helloworld:latest
Sample output:
2. Kubernetes
The image pushed can still be used on Kubernetes. Pull and test the image as below;
$ vim deploy.yml
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-world
spec:
selector:
matchLabels:
app: hello
replicas: 1
template:
metadata:
labels:
app: hello
spec:
containers:
- name: hello-world
image: klinsmann1/helloworld:latest
Apply the manifest:
kubectl apply -f deploy.yml
Check the status of the deployment:
$ kubectl get pods
NAME READY STATUS RESTARTS AGE
hello-world-7f68776d79-h4h4z 0/1 Completed 1 (4s ago) 6s
img 0/1 Completed 0 13m
Verify if the execution was successful.
$ kubectl logs hello-world-7f68776d79-h4h4z --follow
hello
The end!
Books For Learning Kubernetes Administration:
We have successfully walked through how to build container images on Kubernetes using img image builder. I hope this was significant to you.
Related posts: