Kaniko, is an open-source tool for building container images from a Dockerfile inside a container or Kubernetes cluster. This can be done without privileged root access.
We run kaniko as a container image that takes in three arguments: a Dockerfile, a build context and the name of the registry to which it should push the final image. This image is built from scratch, and contains only a static Go binary plus the configuration files needed for pushing and pulling images.
Create a dockerfile
mkdir kaniko
cp ~/.docker/config.json .
cat > Dockerfile <<EOF
FROM alpine
ENTRYPOINT ["/bin/bash", "-c", "echo hello"]
EOF
Running locally with docker
docker run \
-it \
--rm \
--name kaniko \
-v `pwd`:/workspace \
-v `pwd`/config.json:/kaniko/.docker/config.json:ro \
gcr.io/kaniko-project/executor:latest \
--dockerfile=Dockerfile \
--verbosity debug \
--insecure \
--skip-tls-verify \
--destination ektowett/alpine:latest
Kubernetes
If you are running in a k8s cluster, do the following:
Create docker push credentials as secret in the same namespace jenkins runs:
kubectl create secret docker-registry docker-credentials \
--docker-username=dockername \
--docker-password='docker-password' \
--docker-email=email@example.com
Have this jenkinsfile for the app:
#!groovy
def podLabel = "kaniko-${UUID.randomUUID().toString()}"
pipeline {
agent {
kubernetes {
label podLabel
defaultContainer 'jnlp'
yaml """
apiVersion: v1
kind: Pod
metadata:
labels:
jenkins-build: app-build
some-label: "build-app-${BUILD_NUMBER}"
spec:
containers:
- name: kaniko
image: gcr.io/kaniko-project/executor:v1.5.1-debug
imagePullPolicy: IfNotPresent
command:
- /busybox/cat
tty: true
volumeMounts:
- name: jenkins-docker-cfg
mountPath: /kaniko/.docker
volumes:
- name: jenkins-docker-cfg
projected:
sources:
- secret:
name: docker-credentials
items:
- key: .dockerconfigjson
path: config.json
"""
}
}
environment {
GITHUB_ACCESS_TOKEN = credentials('github-token')
}
stages {
stage('Checkout Code') {
steps {
checkout scm
}
}
stage('Build with Kaniko') {
steps {
container(name: 'kaniko', shell: '/busybox/sh') {
withEnv(['PATH+EXTRA=/busybox']) {
sh '''#!/busybox/sh -xe
/kaniko/executor \
--dockerfile Dockerfile \
--context `pwd`/ \
--verbosity debug \
--insecure \
--skip-tls-verify \
--destination dockername/myapp:v0.1.0 \
--destination dockername/myapp:latest
'''
}
}
}
}
}
}
If you intend to run shell and inspect:
docker run --rm --name kaniko -it gcr.io/kaniko-project/executor:latest --entrypoint=/busybox/sh