[Book] [OK!] GitOps Cookbook: 06. Cloud Native CI/CD: Tekton: 6.7 Create a Tekton Pipeline to Build and Deploy an App to Kubernetes
Делаю:
2024.03.08
Пушим image в dockerhub
$ docker login
***
Login Succeeded
REGISTRY_USER=<your own docker login>
REGISTRY_PASSWORD=<your own docker password>
$ {
export REGISTRY_SERVER=https://index.docker.io/v1/
export REGISTRY_USER=webmakaka
export REGISTRY_PASSWORD=webmakaka-password
echo ${REGISTRY_SERVER}
echo ${REGISTRY_USER}
echo ${REGISTRY_PASSWORD}
}
$ kubectl create secret docker-registry container-registry-secret \
--docker-server=${REGISTRY_SERVER} \
--docker-username=${REGISTRY_USER} \
--docker-password=${REGISTRY_PASSWORD}
$ cat << 'EOF' | kubectl create -f -
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-deployer-sa
secrets:
- name: container-registry-secret
EOF
Define a Role named pipeline-role for the ServiceAccount
$ cat << 'EOF' | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: task-role
rules:
- apiGroups:
- ""
resources:
- pods
- services
- endpoints
- configmaps
- secrets
verbs:
- "*"
- apiGroups:
- apps
resources:
- deployments
- replicasets
verbs:
- "*"
- apiGroups:
- ""
resources:
- pods
verbs:
- get
- apiGroups:
- apps
resources:
- replicasets
verbs:
- get
EOF
Bind the Role to the ServiceAccount
$ cat << 'EOF' | kubectl create -f -
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: task-role-binding
roleRef:
kind: Role
name: task-role
apiGroup: rbac.authorization.k8s.io
subjects:
- kind: ServiceAccount
name: tekton-deployer-sa
EOF
Пример 1
$ cat << 'EOF' | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build-push-app
spec:
workspaces:
- name: source
description: The git repo will be cloned onto the volume backing this work space
params:
- name: contextDir
description: the context dir within source
default: quarkus
- name: tlsVerify
description: tls verify
type: string
default: "false"
- name: url
default: https://github.com/gitops-cookbook/tekton-tutorial-greeter.git
- name: revision
default: master
- name: subdirectory
default: ""
- name: sslVerify
description: defines if http.sslVerify should be set to true or false in the global git config
type: string
default: "false"
- name: storageDriver
type: string
description: Storage driver
default: vfs
- name: destinationImage
description: the fully qualified image name
default: ""
steps:
- image: 'gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.21.0'
name: clone
resources: {}
script: |
CHECKOUT_DIR="$(workspaces.source.path)/$(params.subdirectory)"
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
}
/ko-app/git-init \
-url "$(params.url)" \
-revision "$(params.revision)" \
-path "$CHECKOUT_DIR" \
-sslVerify="$(params.sslVerify)"
cd "$CHECKOUT_DIR"
RESULT_SHA="$(git rev-parse HEAD)"
- name: build-sources
image: gcr.io/cloud-builders/mvn
command:
- mvn
args:
- -DskipTests
- clean
- install
env:
- name: user.home
value: /home/tekton
workingDir: "/workspace/source/$(params.contextDir)"
- name: build-and-push-image
image: quay.io/buildah/stable
script: |
#!/usr/bin/env bash
buildah --storage-driver=$STORAGE_DRIVER bud --layers -t $DESTINATION_IMAGE $CONTEXT_DIR
buildah --storage-driver=$STORAGE_DRIVER push $DESTINATION_IMAGE docker://$DESTINATION_IMAGE
env:
- name: DESTINATION_IMAGE
value: "$(params.destinationImage)"
- name: CONTEXT_DIR
value: "/workspace/source/$(params.contextDir)"
- name: STORAGE_DRIVER
value: "$(params.storageDriver)"
workingDir: "/workspace/source/$(params.contextDir)"
volumeMounts:
- name: varlibc
mountPath: /var/lib/containers
volumes:
- name: varlibc
emptyDir: {}
EOF
$ cat << 'EOF' | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: kubectl
spec:
params:
- name: SCRIPT
description: The kubectl CLI arguments to run
type: string
default: "kubectl help"
steps:
- name: oc
image: quay.io/openshift/origin-cli:latest
script: |
#!/usr/bin/env bash
$(params.SCRIPT)
EOF
$ cat << 'EOF' | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: tekton-greeter-pipeline
spec:
params:
- name: GIT_REPO
type: string
- name: GIT_REF
type: string
- name : DESTINATION_IMAGE
type: string
- name : SCRIPT
type: string
tasks:
- name: build-push-app
taskRef:
name: build-push-app
params:
- name: url
value: "$(params.GIT_REPO)"
- name: revision
value: "$(params.GIT_REF)"
- name: destinationImage
value: "$(params.DESTINATION_IMAGE)"
workspaces:
- name: source
- name: deploy-app
taskRef:
name: kubectl
params:
- name: SCRIPT
value: "$(params.SCRIPT)"
runAfter:
- build-push-app
workspaces:
- name: source
EOF
$ envsubst << 'EOF' | cat | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
generateName: tekton-greeter-pipeline-run-
spec:
serviceAccountName: tekton-deployer-sa
params:
- name: GIT_REPO
value: https://github.com/gitops-cookbook/tekton-tutorial-greeter.git
- name: GIT_REF
value: "master"
- name: DESTINATION_IMAGE
value: webmakaka/tekton-greeter:latest
- name: SCRIPT
value: |
kubectl create deploy tekton-greeter --image=webmakaka/tekton-greeter:latest
pipelineRef:
name: tekton-greeter-pipeline
workspaces:
- name: source
emptyDir: {}
EOF
$ tkn pipelinerun ls
NAME STARTED DURATION STATUS
tekton-greeter-pipeline-run-8rf6v 2 minutes ago 1m59s Succeeded
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
tekton-greeter 1/1 1 1 50s
$ kubectl expose deploy/tekton-greeter --port 8080
$ kubectl port-forward svc/tekton-greeter 8080:8080
$ curl localhost:8080
Meeow!! from Tekton 😺🚀⏎
OK!
https://hub.docker.com/r/webmakaka/tekton-greeter
Пример 2 с использованием специально созданных task
Нужно удалить deploy
https://hub.tekton.dev
$ tkn hub install task git-clone
$ tkn hub install task maven
$ tkn hub install task buildah
$ tkn hub install task kubernetes-actions
$ kubectl get tasks
NAME AGE
buildah 66s
git-clone 82s
kubectl 18m
kubernetes-actions 62s
maven 70s
$ cat << 'EOF' | kubectl create -f -
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: app-source-pvc
spec:
accessModes:
- ReadWriteOnce
resources:
requests:
storage: 1Gi
EOF
$ kubectl get pvc
NAME STATUS VOLUME CAPACITY ACCESS MODES STORAGECLASS AGE
app-source-pvc Bound pvc-c675c620-2268-43a3-835d-8a99743edf69 1Gi RWO standard 5s
$ envsubst << 'EOF' | cat | kubectl create -f -
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: tekton-greeter-pipeline-hub
spec:
params:
- default: https://github.com/gitops-cookbook/tekton-tutorial-greeter.git
name: GIT_REPO
type: string
- default: master
name: GIT_REF
type: string
- default: webmakaka/tekton-greeter:latest
name: DESTINATION_IMAGE
type: string
- default: kubectl create deploy tekton-greeter --image=webmakaka/tekton-greeter:latest
name: SCRIPT
type: string
- default: ./Dockerfile
name: CONTEXT_DIR
type: string
- default: .
name: IMAGE_DOCKERFILE
type: string
- default: .
name: IMAGE_CONTEXT_DIR
type: string
tasks:
- name: fetch-repo
params:
- name: url
value: $(params.GIT_REPO)
- name: revision
value: $(params.GIT_REF)
- name: deleteExisting
value: "true"
- name: verbose
value: "true"
taskRef:
kind: Task
name: git-clone
workspaces:
- name: output
workspace: app-source
- name: build-app
params:
- name: GOALS
value:
- -DskipTests
- clean
- package
- name: CONTEXT_DIR
value: $(params.CONTEXT_DIR)
runAfter:
- fetch-repo
taskRef:
kind: Task
name: maven
workspaces:
- name: maven-settings
workspace: maven-settings
- name: source
workspace: app-source
- name: build-push-image
params:
- name: IMAGE
value: $(params.DESTINATION_IMAGE)
- name: DOCKERFILE
value: $(params.IMAGE_DOCKERFILE)
- name: CONTEXT
value: $(params.IMAGE_CONTEXT_DIR)
runAfter:
- build-app
taskRef:
kind: Task
name: buildah
workspaces:
- name: source
workspace: app-source
- name: deploy
params:
- name: script
value: $(params.SCRIPT)
runAfter:
- build-push-image
taskRef:
kind: Task
name: kubernetes-actions
workspaces:
- name: app-source
- name: maven-settings
EOF
// OK!
$ tkn pipeline start tekton-greeter-pipeline-hub \
--serviceaccount='tekton-deployer-sa' \
--param GIT_REPO='https://github.com/gitops-cookbook/tekton-tutorial-greeter.git' \
--param GIT_REF='master' \
--param CONTEXT_DIR='quarkus' \
--param DESTINATION_IMAGE=webmakaka/tekton-greeter:latest \
--param IMAGE_DOCKERFILE='quarkus/Dockerfile' \
--param IMAGE_CONTEXT_DIR='quarkus' \
--param SCRIPT='kubectl create deploy tekton-greeter --image=webmakaka/tekton-greeter:latest' \
--workspace name=app-source,claimName=app-source-pvc \
--workspace name=maven-settings,emptyDir="" \
--use-param-defaults \
--showlog
$ tkn pipelinerun ls
NAME STARTED DURATION STATUS
tekton-greeter-pipeline-hub-run-42pdx 2 minutes ago 1m39s Succeeded
$ tkn pipelinerun logs tekton-greeter-pipeline-hub-run-vtc84
Посмотреть результаты в UI
$ kubectl --namespace tekton-pipelines port-forward svc/tekton-dashboard 8080:9097
$ localhost:8080 -> PipelineRuns
$ kubectl get deploy
NAME READY UP-TO-DATE AVAILABLE AGE
tekton-greeter 1/1 1 1 73
// $ kubectl expose deploy/tekton-greeter --port 8080
$ kubectl port-forward svc/tekton-greeter 8080:8080
$ curl localhost:8080
Meeow!! from Tekton 😺🚀⏎