Add Tekton tasks, pipeline and test Dockerfile
- Add git-clone task for repository cloning - Add kaniko-build task for container image builds - Add container-build pipeline orchestrating clone + build - Add harbor-credentials ExternalSecret for innoventions namespace - Add test-app.Dockerfile for pipeline validation Day 3 deliverables for Tekton Phase 2
This commit is contained in:
38
cluster/platform/innoventions/harbor-credentials.yaml
Normal file
38
cluster/platform/innoventions/harbor-credentials.yaml
Normal file
@@ -0,0 +1,38 @@
|
||||
# ExternalSecret for Tekton robot account credentials
|
||||
# Syncs from 1Password item: harbor-robot-accounts
|
||||
# Creates a docker-registry type secret for Tekton pipeline authentication
|
||||
apiVersion: external-secrets.io/v1beta1
|
||||
kind: ExternalSecret
|
||||
metadata:
|
||||
name: harbor-tekton-robot
|
||||
namespace: innoventions
|
||||
spec:
|
||||
refreshInterval: 1h
|
||||
secretStoreRef:
|
||||
name: onepassword-connect
|
||||
kind: ClusterSecretStore
|
||||
target:
|
||||
name: harbor-credentials
|
||||
creationPolicy: Owner
|
||||
template:
|
||||
type: kubernetes.io/dockerconfigjson
|
||||
data:
|
||||
.dockerconfigjson: |
|
||||
{
|
||||
"auths": {
|
||||
"the-seas.local.mk-labs.cloud": {
|
||||
"username": "{{ .tekton_username }}",
|
||||
"password": "{{ .tekton_password }}",
|
||||
"auth": "{{ printf "%s:%s" .tekton_username .tekton_password | b64enc }}"
|
||||
}
|
||||
}
|
||||
}
|
||||
data:
|
||||
- secretKey: tekton_username
|
||||
remoteRef:
|
||||
key: harbor-robot-accounts
|
||||
property: tekton-builder-username
|
||||
- secretKey: tekton_password
|
||||
remoteRef:
|
||||
key: harbor-robot-accounts
|
||||
property: tekton-builder-password
|
||||
99
cluster/tekton/pipelines/container-build.yaml
Normal file
99
cluster/tekton/pipelines/container-build.yaml
Normal file
@@ -0,0 +1,99 @@
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Pipeline
|
||||
metadata:
|
||||
name: container-build
|
||||
namespace: innoventions
|
||||
labels:
|
||||
app.kubernetes.io/version: "0.1"
|
||||
annotations:
|
||||
tekton.dev/pipelines.minVersion: "0.29.0"
|
||||
tekton.dev/categories: Container Build
|
||||
tekton.dev/tags: git, kaniko, build
|
||||
tekton.dev/displayName: "Container Build Pipeline"
|
||||
spec:
|
||||
description: >-
|
||||
This pipeline clones a git repository and builds a container image from it using Kaniko.
|
||||
|
||||
The pipeline performs the following steps:
|
||||
1. Clone the git repository to a shared workspace
|
||||
2. Build and push the container image to Harbor registry
|
||||
|
||||
params:
|
||||
- name: git-url
|
||||
type: string
|
||||
description: The git repository URL to clone
|
||||
- name: git-revision
|
||||
type: string
|
||||
description: The git revision (branch, tag, sha) to checkout
|
||||
default: "main"
|
||||
- name: image-name
|
||||
type: string
|
||||
description: The complete image name including registry (e.g., the-seas.local.mk-labs.cloud/library/app)
|
||||
- name: image-tag
|
||||
type: string
|
||||
description: The image tag to apply
|
||||
default: "latest"
|
||||
- name: dockerfile
|
||||
type: string
|
||||
description: Path to the Dockerfile relative to the repository root
|
||||
default: "./Dockerfile"
|
||||
- name: context
|
||||
type: string
|
||||
description: Path to the build context relative to the repository root
|
||||
default: "./"
|
||||
|
||||
workspaces:
|
||||
- name: shared-workspace
|
||||
description: |
|
||||
This workspace will hold the cloned git repository and is shared between tasks.
|
||||
It should be backed by a PersistentVolumeClaim or VolumeClaimTemplate.
|
||||
- name: docker-credentials
|
||||
description: |
|
||||
This workspace contains the docker config.json for authenticating to Harbor.
|
||||
It should be backed by a Secret containing .dockerconfigjson
|
||||
|
||||
tasks:
|
||||
- name: fetch-repository
|
||||
taskRef:
|
||||
name: git-clone
|
||||
workspaces:
|
||||
- name: output
|
||||
workspace: shared-workspace
|
||||
params:
|
||||
- name: url
|
||||
value: $(params.git-url)
|
||||
- name: revision
|
||||
value: $(params.git-revision)
|
||||
- name: deleteExisting
|
||||
value: "true"
|
||||
|
||||
- name: build-and-push
|
||||
taskRef:
|
||||
name: kaniko-build
|
||||
runAfter:
|
||||
- fetch-repository
|
||||
workspaces:
|
||||
- name: source
|
||||
workspace: shared-workspace
|
||||
- name: dockerconfig
|
||||
workspace: docker-credentials
|
||||
params:
|
||||
- name: IMAGE
|
||||
value: "$(params.image-name):$(params.image-tag)"
|
||||
- name: DOCKERFILE
|
||||
value: $(params.dockerfile)
|
||||
- name: CONTEXT
|
||||
value: $(params.context)
|
||||
- name: EXTRA_ARGS
|
||||
value:
|
||||
- --skip-tls-verify
|
||||
- --verbosity=info
|
||||
- --skip-unused-stages=true
|
||||
|
||||
results:
|
||||
- name: IMAGE_DIGEST
|
||||
description: The digest of the built image
|
||||
value: $(tasks.build-and-push.results.IMAGE_DIGEST)
|
||||
- name: IMAGE_URL
|
||||
description: The URL of the built image
|
||||
value: $(tasks.build-and-push.results.IMAGE_URL)
|
||||
175
cluster/tekton/tasks/git-clone.yaml
Normal file
175
cluster/tekton/tasks/git-clone.yaml
Normal file
@@ -0,0 +1,175 @@
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: git-clone
|
||||
namespace: innoventions
|
||||
labels:
|
||||
app.kubernetes.io/version: "0.1"
|
||||
annotations:
|
||||
tekton.dev/pipelines.minVersion: "0.29.0"
|
||||
tekton.dev/categories: Git
|
||||
tekton.dev/tags: git
|
||||
tekton.dev/displayName: "git clone"
|
||||
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
|
||||
spec:
|
||||
description: >-
|
||||
Clone a git repository to the output workspace.
|
||||
|
||||
This Task can be used to initialize a workspace by cloning a git repo.
|
||||
It supports public repos and HTTPS authentication via basic auth credentials.
|
||||
|
||||
workspaces:
|
||||
- name: output
|
||||
description: The git repo will be cloned onto the volume backing this Workspace.
|
||||
|
||||
params:
|
||||
- name: url
|
||||
description: Repository URL to clone from.
|
||||
type: string
|
||||
- name: revision
|
||||
description: Revision to checkout. (branch, tag, sha, ref, etc...)
|
||||
type: string
|
||||
default: "main"
|
||||
- name: refspec
|
||||
description: Refspec to fetch before checking out revision.
|
||||
default: ""
|
||||
- name: submodules
|
||||
description: Initialize and fetch git submodules.
|
||||
type: string
|
||||
default: "false"
|
||||
- name: depth
|
||||
description: Perform a shallow clone, fetching only the most recent N commits.
|
||||
type: string
|
||||
default: "1"
|
||||
- name: sslVerify
|
||||
description: Set the `http.sslVerify` global git config. Setting this to `false` is not advised unless you are sure that you trust your git remote.
|
||||
type: string
|
||||
default: "true"
|
||||
- name: subdirectory
|
||||
description: Subdirectory inside the `output` workspace to clone the repo into.
|
||||
type: string
|
||||
default: ""
|
||||
- name: deleteExisting
|
||||
description: Clean out the contents of the destination directory if it already exists before cloning.
|
||||
type: string
|
||||
default: "true"
|
||||
- name: httpProxy
|
||||
description: HTTP proxy server for non-SSL requests.
|
||||
type: string
|
||||
default: ""
|
||||
- name: httpsProxy
|
||||
description: HTTPS proxy server for SSL requests.
|
||||
type: string
|
||||
default: ""
|
||||
- name: noProxy
|
||||
description: Opt out of proxying HTTP/HTTPS requests.
|
||||
type: string
|
||||
default: ""
|
||||
- name: verbose
|
||||
description: Log the commands that are executed during `git-clone`'s operation.
|
||||
type: string
|
||||
default: "false"
|
||||
- name: gitInitImage
|
||||
description: The image providing the git-init binary that this Task runs.
|
||||
type: string
|
||||
default: "gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.40.2"
|
||||
- name: userHome
|
||||
description: |
|
||||
Absolute path to the user's home directory. Set this explicitly if you are running the image as a non-root user or have overridden
|
||||
the gitInitImage param with an image containing custom user configuration.
|
||||
type: string
|
||||
default: "/tekton/home"
|
||||
|
||||
results:
|
||||
- name: commit
|
||||
description: The precise commit SHA that was fetched by this Task.
|
||||
- name: url
|
||||
description: The precise URL that was fetched by this Task.
|
||||
|
||||
steps:
|
||||
- name: clone
|
||||
image: "$(params.gitInitImage)"
|
||||
env:
|
||||
- name: HOME
|
||||
value: "$(params.userHome)"
|
||||
- name: PARAM_URL
|
||||
value: $(params.url)
|
||||
- name: PARAM_REVISION
|
||||
value: $(params.revision)
|
||||
- name: PARAM_REFSPEC
|
||||
value: $(params.refspec)
|
||||
- name: PARAM_SUBMODULES
|
||||
value: $(params.submodules)
|
||||
- name: PARAM_DEPTH
|
||||
value: $(params.depth)
|
||||
- name: PARAM_SSL_VERIFY
|
||||
value: $(params.sslVerify)
|
||||
- name: PARAM_SUBDIRECTORY
|
||||
value: $(params.subdirectory)
|
||||
- name: PARAM_DELETE_EXISTING
|
||||
value: $(params.deleteExisting)
|
||||
- name: PARAM_HTTP_PROXY
|
||||
value: $(params.httpProxy)
|
||||
- name: PARAM_HTTPS_PROXY
|
||||
value: $(params.httpsProxy)
|
||||
- name: PARAM_NO_PROXY
|
||||
value: $(params.noProxy)
|
||||
- name: PARAM_VERBOSE
|
||||
value: $(params.verbose)
|
||||
- name: PARAM_USER_HOME
|
||||
value: $(params.userHome)
|
||||
- name: WORKSPACE_OUTPUT_PATH
|
||||
value: $(workspaces.output.path)
|
||||
script: |
|
||||
#!/usr/bin/env sh
|
||||
set -eu
|
||||
|
||||
if [ "${PARAM_VERBOSE}" = "true" ] ; then
|
||||
set -x
|
||||
fi
|
||||
|
||||
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
|
||||
cleandir() {
|
||||
# Delete any existing contents of the repo directory if it exists.
|
||||
#
|
||||
# We don't just "rm -rf ${CHECKOUT_DIR}" because ${CHECKOUT_DIR} might be "/"
|
||||
# or the root of a mounted volume.
|
||||
if [ -d "${CHECKOUT_DIR}" ] ; then
|
||||
# Delete non-hidden files and directories
|
||||
rm -rf "${CHECKOUT_DIR:?}"/*
|
||||
# Delete files and directories starting with . but excluding ..
|
||||
rm -rf "${CHECKOUT_DIR}"/.[!.]*
|
||||
# Delete files and directories starting with .. plus any other character
|
||||
rm -rf "${CHECKOUT_DIR}"/..?*
|
||||
fi
|
||||
}
|
||||
|
||||
if [ "${PARAM_SUBDIRECTORY}" != "" ] ; then
|
||||
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
|
||||
cleandir
|
||||
else
|
||||
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}"
|
||||
cleandir
|
||||
fi
|
||||
fi
|
||||
|
||||
test -z "${PARAM_HTTP_PROXY}" || export HTTP_PROXY="${PARAM_HTTP_PROXY}"
|
||||
test -z "${PARAM_HTTPS_PROXY}" || export HTTPS_PROXY="${PARAM_HTTPS_PROXY}"
|
||||
test -z "${PARAM_NO_PROXY}" || export NO_PROXY="${PARAM_NO_PROXY}"
|
||||
|
||||
/ko-app/git-init \
|
||||
-url="${PARAM_URL}" \
|
||||
-revision="${PARAM_REVISION}" \
|
||||
-refspec="${PARAM_REFSPEC}" \
|
||||
-path="${CHECKOUT_DIR}" \
|
||||
-sslVerify="${PARAM_SSL_VERIFY}" \
|
||||
-submodules="${PARAM_SUBMODULES}" \
|
||||
-depth="${PARAM_DEPTH}"
|
||||
cd "${CHECKOUT_DIR}"
|
||||
RESULT_SHA="$(git rev-parse HEAD)"
|
||||
EXIT_CODE="$?"
|
||||
if [ "${EXIT_CODE}" != 0 ] ; then
|
||||
exit "${EXIT_CODE}"
|
||||
fi
|
||||
printf "%s" "${RESULT_SHA}" > "$(results.commit.path)"
|
||||
printf "%s" "${PARAM_URL}" > "$(results.url.path)"
|
||||
69
cluster/tekton/tasks/kaniko-build.yaml
Normal file
69
cluster/tekton/tasks/kaniko-build.yaml
Normal file
@@ -0,0 +1,69 @@
|
||||
apiVersion: tekton.dev/v1beta1
|
||||
kind: Task
|
||||
metadata:
|
||||
name: kaniko-build
|
||||
namespace: innoventions
|
||||
labels:
|
||||
app.kubernetes.io/version: "0.1"
|
||||
annotations:
|
||||
tekton.dev/pipelines.minVersion: "0.29.0"
|
||||
tekton.dev/categories: Image Build
|
||||
tekton.dev/tags: image-build, kaniko
|
||||
tekton.dev/displayName: "kaniko build"
|
||||
tekton.dev/platforms: "linux/amd64,linux/arm64"
|
||||
spec:
|
||||
description: >-
|
||||
This Task builds source into a container image using Google's Kaniko tool.
|
||||
|
||||
Kaniko doesn't depend on a Docker daemon and executes each command within a Dockerfile
|
||||
completely in userspace. This enables building container images in environments that
|
||||
can't easily or securely run a Docker daemon, such as a standard Kubernetes cluster.
|
||||
|
||||
params:
|
||||
- name: IMAGE
|
||||
description: Name (reference) of the image to build.
|
||||
- name: DOCKERFILE
|
||||
description: Path to the Dockerfile to build.
|
||||
default: ./Dockerfile
|
||||
- name: CONTEXT
|
||||
description: The build context used by Kaniko.
|
||||
default: ./
|
||||
- name: EXTRA_ARGS
|
||||
type: array
|
||||
default: []
|
||||
- name: BUILDER_IMAGE
|
||||
description: The image on which builds will run (default is v1.23.2)
|
||||
default: gcr.io/kaniko-project/executor:v1.23.2@sha256:7f77bc1c6b96e5da7fdb56fb0dc1c16ba0f7fc8b5d1eeaa75fa5db39ec2f4a4d
|
||||
workspaces:
|
||||
- name: source
|
||||
description: Holds the context and Dockerfile
|
||||
- name: dockerconfig
|
||||
description: Includes a docker `config.json`
|
||||
optional: true
|
||||
mountPath: /kaniko/.docker
|
||||
results:
|
||||
- name: IMAGE_DIGEST
|
||||
description: Digest of the image just built.
|
||||
- name: IMAGE_URL
|
||||
description: URL of the image just built.
|
||||
steps:
|
||||
- name: build-and-push
|
||||
workingDir: $(workspaces.source.path)
|
||||
image: $(params.BUILDER_IMAGE)
|
||||
args:
|
||||
- $(params.EXTRA_ARGS)
|
||||
- --dockerfile=$(params.DOCKERFILE)
|
||||
- --context=$(workspaces.source.path)/$(params.CONTEXT)
|
||||
- --destination=$(params.IMAGE)
|
||||
- --digest-file=$(results.IMAGE_DIGEST.path)
|
||||
# kaniko assumes it is running as root, which means this example fails on platforms
|
||||
# that default to run containers as random uid (like OpenShift). Adding this securityContext
|
||||
# makes it explicit that it needs to run as root.
|
||||
securityContext:
|
||||
runAsUser: 0
|
||||
- name: write-url
|
||||
image: docker.io/library/bash:5.1.4@sha256:c523c636b722339f41b6a431b44588ab2f762c5de5ec3bd7964420ff982fb1d9
|
||||
script: |
|
||||
set -e
|
||||
image="$(params.IMAGE)"
|
||||
echo -n "${image}" | tee "$(results.IMAGE_URL.path)"
|
||||
6
test-app.Dockerfile
Normal file
6
test-app.Dockerfile
Normal file
@@ -0,0 +1,6 @@
|
||||
FROM alpine:3.21
|
||||
RUN apk add --no-cache curl
|
||||
LABEL org.opencontainers.image.source="https://gitea.mk-labs.cloud/rblundon/homelab"
|
||||
LABEL org.opencontainers.image.description="Test application for Tekton pipeline validation"
|
||||
LABEL org.opencontainers.image.title="tekton-test-app"
|
||||
CMD ["echo", "Hello from Tekton Pipeline! Build successful."]
|
||||
Reference in New Issue
Block a user