openshift tekton pipeline으로 gradle build하고 빌드 결과를 별도의 manifest 저장소에 업데이트해서
gitOps가 autoSync할 수 있도록 해보자.
전체적인 파이프라인은 다음과 같다.
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: sample-gradle-pipe
namespace: sample
spec:
params:
- default: boot-app-gradle
name: IMAGE_NAME
type: string
- default: /sample/boot-app-gradle.git
name: GIT_REPO
type: string
- default: dev
name: GIT_REVISION
type: string
tasks:
- name: fetch-repository
params:
- name: url
value: $(params.GIT_REPO)
- name: revision
value: $(params.GIT_REVISION)
- name: deleteExisting
value: 'true'
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: workspace
- name: gradle-build
runAfter:
- fetch-repository
taskRef:
kind: Task
name: gradle-jdk11
workspaces:
- name: source
workspace: workspace
- name: deploy
params:
- name: ARGS #docker build 후 빌드된 이미지 태그 정보를 가져오는 스크립트
value:
- >-
mkdir -p /tmp/binary/target && find /tmp/src/build/libs -maxdepth
1 -name "*.jar" -o -name "*.war" | xargs -I{} cp {}
/tmp/binary/target/ && cp -rf /tmp/src/scouter /tmp/binary/scouter
&& cp /tmp/src/Dockerfile /tmp/binary/ && ls -rl /tmp/binary/ &&
oc start-build boot-app-gradle --from-dir /tmp/binary --follow
--wait && current_builds=$(oc get builds -o
jsonpath="{.items[?(@.metadata.labels.buildconfig=='boot-app-gradle')].metadata.name}"
| tr ' ' '_' | tr '\\\\' '\\n' | tr '_' ' ' | sort -rn | head -n
5) && for build in $current_builds; do if oc get build $build -o
jsonpath='{.status.phase}' | grep -q 'Complete'; then
latest_build=$build; break; fi; done && echo $latest_build && echo
$(oc get build $latest_build -o
jsonpath='{.status.output.to.imageDigest}') && image_digest=$(oc
get build $latest_build -o
jsonpath='{.status.output.to.imageDigest}' | tr -d '\\n') && echo
$image_digest && echo -n $image_digest > $(results.DIGEST.path)
runAfter:
- gradle-build
taskRef:
kind: Task
name: ocp-cli-task
workspaces:
- name: source
workspace: workspace
- name: update-manifest # YQ를 통해 deployment.yaml의 image 태그부분을 업데이트
params:
- name: repo
value: sample/boot-app-gradle.git
- name: app
value: boot-app-gradle
- name: SCRIPT
value: >
yq eval '.spec.template.spec.containers[0].image =
"<이미지레지스트리정보>/sample/boot-app-gradle@$(tasks.deploy.results.DIGEST)"'
-i ./boot-app-gradle/base/deployment.yaml && sed -i 's/ *$//'
./boot-app-gradle/base/deployment.yaml
runAfter:
- deploy
taskRef:
kind: Task
name: yq
workspaces:
- name: source
workspace: workspace
workspaces:
- name: workspace
각 태스크는 다음과 같다.
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
annotations:
manifestival: new
tekton.dev/categories: Git
tekton.dev/displayName: git clone
tekton.dev/pipelines.minVersion: 0.29.0
tekton.dev/platforms: 'linux/amd64,linux/s390x,linux/ppc64le,linux/arm64'
tekton.dev/tags: git
name: git-clone
namespace: sample
labels:
app.kubernetes.io/version: '0.8'
operator.tekton.dev/operand-name: openshift-pipelines-addons
operator.tekton.dev/provider-type: redhat
spec:
description: For Sample
params:
- description: Repository URL to clone from.
name: url
type: string
- default: ''
description: 'Revision to checkout. (branch, tag, sha, ref, etc...)'
name: revision
type: string
- default: ''
description: Refspec to fetch before checking out revision.
name: refspec
type: string
- default: 'true'
description: Initialize and fetch git submodules.
name: submodules
type: string
- default: '1'
description: 'Perform a shallow clone, fetching only the most recent N commits.'
name: depth
type: string
- default: 'false'
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.
name: sslVerify
type: string
- default: ''
description: Subdirectory inside the `output` Workspace to clone the repo into.
name: subdirectory
type: string
- default: ''
description: >-
Define the directory patterns to match or exclude when performing a
sparse checkout.
name: sparseCheckoutDirectories
type: string
- default: 'true'
description: >-
Clean out the contents of the destination directory if it already exists
before cloning.
name: deleteExisting
type: string
- default: ''
description: HTTP proxy server for non-SSL requests.
name: httpProxy
type: string
- default: ''
description: HTTPS proxy server for SSL requests.
name: httpsProxy
type: string
- default: ''
description: Opt out of proxying HTTP/HTTPS requests.
name: noProxy
type: string
- default: 'true'
description: Log the commands that are executed during `git-clone`'s operation.
name: verbose
type: string
- default: >-
registry.redhat.io/openshift-pipelines/pipelines-git-init-rhel8@sha256:dde6d6d4b40f87ccc6737f1e317c13f6ff153155da4ebc48a2a5ebf31582f727
description: The image providing the git-init binary that this Task runs.
name: gitInitImage
type: string
- default: /tekton/home
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.
name: userHome
type: string
results:
- description: The precise commit SHA that was fetched by this Task.
name: commit
type: string
- description: The precise URL that was fetched by this Task.
name: url
type: string
steps:
- 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_SPARSE_CHECKOUT_DIRECTORIES
value: $(params.sparseCheckoutDirectories)
- name: PARAM_USER_HOME
value: $(params.userHome)
- name: WORKSPACE_OUTPUT_PATH
value: $(workspaces.output.path)
- name: WORKSPACE_SSH_DIRECTORY_BOUND
value: $(workspaces.ssh-directory.bound)
- name: WORKSPACE_SSH_DIRECTORY_PATH
value: $(workspaces.ssh-directory.path)
- name: GIT_CREDENTIALS
valueFrom:
secretKeyRef:
key: .git-credentials
name: gitlab-config
- name: GITCONFIG
valueFrom:
secretKeyRef:
key: .git-config
name: gitlab-config
- name: GITLAB_URL
valueFrom:
secretKeyRef:
key: .gitlab-url
name: gitlab-config
image: $(params.gitInitImage)
name: clone
resources: {}
script: >
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi
if [ "true" = "true" ] ; then
echo $GIT_CREDENTIALS > ${PARAM_USER_HOME}/.git-credentials
echo $GITCONFIG > ${PARAM_USER_HOME}/.gitconfig
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
git config --global pack.windowMemory "200m"
git config --global pack.packSizeLimit "200m"
git config --global pack.threads "1"
git config --global pack.window "0"
git config --global http.postBuffer 3194304000
fi
if [ "${WORKSPACE_SSH_DIRECTORY_BOUND}" = "true" ] ; then
cp -R "${WORKSPACE_SSH_DIRECTORY_PATH}" "${PARAM_USER_HOME}"/.ssh
chmod 700 "${PARAM_USER_HOME}"/.ssh
chmod -R 400 "${PARAM_USER_HOME}"/.ssh/*
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_SUBDIRECTORY}"
cleandir() {
if [ -d "${CHECKOUT_DIR}" ] ; then
rm -rf "${CHECKOUT_DIR:?}"/*
rm -rf "${CHECKOUT_DIR}"/.[!.]*
rm -rf "${CHECKOUT_DIR}"/..?*
fi
}
if [ "${PARAM_DELETE_EXISTING}" = "true" ] ; then
cleandir
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="${GITLAB_URL}${PARAM_URL}" \
-revision="${PARAM_REVISION}" \
-refspec="${PARAM_REFSPEC}" \
-path="${CHECKOUT_DIR}" \
-sslVerify="${PARAM_SSL_VERIFY}" \
-submodules="${PARAM_SUBMODULES}" \
-depth="${PARAM_DEPTH}" \
-sparseCheckoutDirectories="${PARAM_SPARSE_CHECKOUT_DIRECTORIES}"
cd "${CHECKOUT_DIR}"
git config --global credential.helper store
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" "${GITLAB_URL}${PARAM_URL}" > "$(results.url.path)"
workspaces:
- description: The git repo will be cloned onto the volume backing this Workspace.
name: output
- description: |
A .ssh directory with private key, known_hosts, config, etc. Copied to
the user's home before git commands are executed. Used to authenticate
with the git remote when performing the clone. Binding a Secret to this
Workspace is strongly recommended over other volume types.
name: ssh-directory
optional: true
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
annotations:
tekton.dev/categories: Build Tools
tekton.dev/displayName: Gradle
tekton.dev/pipelines.minVersion: 0.17.0
tekton.dev/platforms: 'linux/amd64,linux/s390x,linux/ppc64le'
tekton.dev/tags: build-tool
name: gradle-jdk11
namespace: sample
labels:
app.kubernetes.io/version: '0.4'
spec:
description: This Task can be used to run a Gradle build.
params:
- default: >-
docker.io/gradle:jdk11@sha256:8942456a1b0a1d3ab52fc8ebb248f13a308aac6f40423d2e5537553a69c5c7f8
description: Gradle base image.
name: GRADLE_IMAGE
type: string
- default: .
description: The directory containing build.gradle
name: PROJECT_DIR
type: string
- default:
- build
description: 'The gradle tasks to run (default: build)'
name: TASKS
type: array
steps:
- args:
- $(params.TASKS)
env:
- name: GRADLE_USER_HOME
value: /home/gradle
image: $(params.GRADLE_IMAGE)
name: gradle-tasks
resources: {}
script: |
#!/usr/bin/env bash
if [[ -f gradlew ]]; then
cmd="./gradlew $*"
else
cmd="gradle $*"
fi
echo "Running gradle task with command below"
echo "$cmd"
eval "$cmd"
volumeMounts:
- mountPath: /home/gradle
name: empty-dir
workingDir: $(workspaces.source.path)/$(params.PROJECT_DIR)
volumes:
- emptyDir: {}
name: empty-dir
workspaces:
- description: The workspace consisting of the gradle project.
name: source
- description: >-
The workspace consisting of the custom gradle properties provided by the
user.
name: gradle-config
optional: true
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: ocp-cli-task
namespace: sample
spec:
params:
- default:
- cd /tmp/src && pwd && ls
description: The OpenShift CLI arguments to run
name: ARGS
type: array
results:
- description: the digest of the image built.
name: DIGEST
type: string
steps:
- args:
- $(params.ARGS)
command:
- /bin/bash
- '-c'
env:
- name: GIT_CREDENTIALS
valueFrom:
secretKeyRef:
key: .git-credentials
name: gitlab-config
- name: GITCONFIG
valueFrom:
secretKeyRef:
key: .git-config
name: gitlab-config
image: '<이미지레지스트리주소>/openshift/cli:latest' #quay.io/openshift/origin-cli:$(params.VERSION)
name: oc
resources: {}
workspaces:
- mountPath: /tmp/src
name: source
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
annotations:
tekton.dev/categories: Developer Tools
tekton.dev/displayName: YQ
tekton.dev/pipelines.minVersion: 0.12.1
tekton.dev/platforms: linux/amd64
tekton.dev/tags: yq
name: yq
namespace: sample
labels:
app.kubernetes.io/version: '0.4'
spec:
description: >-
This task can be used to replace fields in YAML files. For example for
altering helm charts on GitOps repos.
params:
- default: ''
description: The yq script to execute. Can be multiple lines for complex tasks.
name: SCRIPT
type: string
- default: >-
image-registry.openshift-image-registry.svc:5000/sample/yq-git@sha256:776657b787969e2c938360997b8bcf9c1f16fa20a83ae7ef97d28f206d4bdac6
description: The yq image to use.
name: image
type: string
- default: []
description: >-
(deprecated, use SCRIPT instead) A list of files to execute the
expression on. Needs to be relative to the source workspace.
name: files
type: array
- default: 'spec.template.spec.containers[0].image.name'
description: >-
(deprecated, use SCRIPT instead) The yq expression to apply. Can be used
to replace yaml fields.
name: expression
type: string
- default: /tekton/home
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.
name: userHome
type: string
- name: repo
type: string
- name: app
type: string
results:
- description: >-
The result from your yq command. You can write to it using
`$(results.yq.path)`
name: yq
type: string
steps:
- args:
- '$(params.files[*])'
env:
- name: HOME
value: $(params.userHome)
- name: GIT_CREDENTIALS
valueFrom:
secretKeyRef:
key: .git-credentials
name: gitlab-config
- name: GITCONFIG
valueFrom:
secretKeyRef:
key: .git-config
name: gitlab-config
- name: GITLAB_URL
valueFrom:
secretKeyRef:
key: .gitlab-url
name: gitlab-config
- name: REPO
value: $(params.repo)
- name: APP
value: $(params.app)
image: $(params.image)
name: yq-script
resources: {}
script: >
/usr/bin/env sh
set -e
set -x
if [ "true" = "true" ] ; then
echo $GIT_CREDENTIALS > ${PARAM_USER_HOME}/.git-credentials
echo $GITCONFIG > ${PARAM_USER_HOME}/.gitconfig
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
git config --global pack.windowMemory "200m"
git config --global pack.packSizeLimit "200m"
git config --global pack.threads "1"
git config --global pack.window "0"
git config --global http.postBuffer 3194304000
git config --global user.name root
git config --global user.email admin@example.org
git config --global credential.helper store
#git config --global pull.rebase true
fi
git clone
http://<id:token>@<git주소>/sample/boot-manifests.git
cd boot-manifests
$(params.SCRIPT) # 변경 스크립트 실행
cat ./$APP/base/deployment.yaml # 변경대상 YAML확인
git add . # 변경소스 staging
git commit -m "tag-updated" # comment
git push -u origin # push
securityContext:
runAsUser: 0
workingDir: $(workspaces.source.path)
workspaces:
- description: A workspace that contains the file which needs to be altered.
name: source
빌드컨피그는 다음과 같다.
kind: BuildConfig
apiVersion: build.openshift.io/v1
metadata:
name: boot-app-gradle
namespace: sample
labels:
app: boot-app-gradle
spec:
nodeSelector: null
output:
to:
kind: ImageStreamTag
namespace: sample
name: 'boot-app-gradle:latest'
resources: {}
successfulBuildsHistoryLimit: 1
failedBuildsHistoryLimit: 1
strategy:
type: Docker
dockerStrategy:
dockerfilePath: Dockerfile
postCommit: {}
source:
type: Binary
binary: {}
runPolicy: Serial
이제 파이프 라인을 실행해보자.
728x90
'CloudNative > App Definition & Developement' 카테고리의 다른 글
| argocd applicationSet (2) | 2024.11.26 |
|---|---|
| argocd (0) | 2024.11.25 |
| confluentinc/cp-kafka KRaft yaml (zookeeper out) (2) | 2024.11.20 |
| confluentinc/cp-kafka, zookeeper, kafka-ui (1) | 2024.11.18 |
| kafka-ui yaml (1) | 2024.11.08 |