精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

Tekton 實戰完整示例

開發
本文我們來將這個流水線遷移到 Tekton 上面來,其實整體思路都是一樣的,就是把要整個工作流劃分成不同的任務來執行,前面工作流的階段劃分了以下幾個階段
前面我們講解了使用 Jenkins 流水線來實現 Kubernetes 應用的 CI/CD,現在我們來將這個流水線遷移到 Tekton 上面來,其實整體思路都是一樣的,就是把要整個工作流劃分成不同的任務來執行,前面工作流的階段劃分了以下幾個階段:Clone 代碼 -> 單元測試 -> 編譯打包 -> Docker 鏡像構建/推送 -> Kubectl/Helm 部署服務/。

在 Tekton 中我們就可以將這些階段直接轉換成 Task 任務,Clone 代碼在 Tekton 中不需要我們主動定義一個任務,只需要在執行的任務上面指定一個輸入的代碼資源即可。下面我們就來將上面的工作流一步一步來轉換成 Tekton 流水線,代碼倉庫同樣還是 http://git.k8s.local/course/devops-demo.git。

Clone 代碼

雖然我們可以不用單獨定義一個 Clone 代碼的任務,直接使用 git 類型的輸入資源即可,由于這里涉及到的任務較多,而且很多時候都需要先 Clone 代碼然后再進行操作,所以最好的方式是將代碼 Clone 下來過后通過 Workspace 共享給其他任務,這里我們可以直接使用 Catalog git-clone 來實現這個任務,我們可以根據自己的需求做一些定制,對應的 Task 如下所示:

# task-clone.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: git-clone
labels:
app.kubernetes.io/version: "0.8"
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: >-
These Tasks are Git tasks to work with repositories used by other tasks
in your Pipeline.
The git-clone Task will clone a repo from the provided url into the
output Workspace. By default the repo will be cloned into the root of
your Workspace. You can clone into a subdirectory by setting this Task's
subdirectory param. This Task also supports sparse checkouts. To perform
a sparse checkout, pass a list of comma separated directory patterns to
this Task's sparseCheckoutDirectories param.
workspaces:
- name: output
description: The git repo will be cloned onto the volume backing this Workspace.
- name: ssh-directory
optional: true
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: basic-auth
optional: true
description: |
A Workspace containing a .gitconfig and .git-credentials file. These
will be copied to the user's home before any git commands are run. Any
other files in this Workspace are ignored. It is strongly recommended
to use ssh-directory over basic-auth whenever possible and to bind a
Secret to this Workspace over other volume types. - name: ssl-ca-directory
optional: true
description: |
A workspace containing CA certificates, this will be used by Git to
verify the peer with when fetching or pushing over HTTPS. 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: ""
- name: refspec
description: Refspec to fetch before checking out revision.
default: ""
- name: submodules
description: Initialize and fetch git submodules.
type: string
default: "true"
- 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: crtFileName
description: file name of mounted crt using ssl-ca-directory workspace. default value is ca-bundle.crt.
type: string
default: "ca-bundle.crt"
- name: subdirectory
description: Subdirectory inside the `output` Workspace to clone the repo into.
type: string
default: ""
- name: sparseCheckoutDirectories
description: Define the directory patterns to match or exclude when performing a sparse checkout.
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: "true"
- name: gitInitImage
description: The image providing the git-init binary that this Task runs.
type: string
default: "cnych/tekton-git-init:v0.29.0"
- name: userHome
description: |
Absolute path to the user's home directory. type: string
default: "/home/nonroot"
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_CRT_FILENAME
value: $(params.crtFileName)
- 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: WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND
value: $(workspaces.basic-auth.bound)
- name: WORKSPACE_BASIC_AUTH_DIRECTORY_PATH
value: $(workspaces.basic-auth.path)
- name: WORKSPACE_SSL_CA_DIRECTORY_BOUND
value: $(workspaces.ssl-ca-directory.bound)
- name: WORKSPACE_SSL_CA_DIRECTORY_PATH
value: $(workspaces.ssl-ca-directory.path)
securityContext:
runAsNonRoot: true
runAsUser: 65532
script: |
#!/usr/bin/env sh
set -eu
if [ "${PARAM_VERBOSE}" = "true" ] ; then
set -x
fi


if [ "${WORKSPACE_BASIC_AUTH_DIRECTORY_BOUND}" = "true" ] ; then
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.git-credentials" "${PARAM_USER_HOME}/.git-credentials"
cp "${WORKSPACE_BASIC_AUTH_DIRECTORY_PATH}/.gitconfig" "${PARAM_USER_HOME}/.gitconfig"
chmod 400 "${PARAM_USER_HOME}/.git-credentials"
chmod 400 "${PARAM_USER_HOME}/.gitconfig"
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

if [ "${WORKSPACE_SSL_CA_DIRECTORY_BOUND}" = "true" ] ; then
export GIT_SSL_CAPATH="${WORKSPACE_SSL_CA_DIRECTORY_PATH}"
if [ "${PARAM_CRT_FILENAME}" != "" ] ; then
export GIT_SSL_CAINFO="${WORKSPACE_SSL_CA_DIRECTORY_PATH}/${PARAM_CRT_FILENAME}"
fi
fi
CHECKOUT_DIR="${WORKSPACE_OUTPUT_PATH}/${PARAM_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
}

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="${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}"
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)"

一般來說我們只需要提供 output 這個個用于持久化代碼的 workspace,然后還包括 url 和 revision 這兩個參數,其他使用默認的即可。

單元測試

單元測試階段比較簡單,正常來說也是只是單純執行一個測試命令即可,我們這里沒有真正執行單元測試,所以簡單測試下即可,編寫一個如下所示的 Task:

# task-test.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: test
spec:
steps:
- name: test
image: golang:1.14.2-alpine3.11
command: ["echo"]
args: ["this is a test task"]

編譯打包

然后第二個階段是編譯打包階段,因為我們這個項目的 Dockerfile 不是使用的多階段構建,所以需要先用一個任務去將應用編譯打包成二進制文件,然后將這個編譯過后的文件傳遞到下一個任務進行鏡像構建。

我們已經明確了這個階段要做的事情,編寫任務也就簡單了,創建如下所示的 Task 任務,首先需要通過定義一個 workspace 把 clone 任務里面的代碼關聯過來:

# task-build.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: build
spec:
workspaces:
- name: go-repo
mountPath: /workspace/repo
steps:
- name: build
image: golang:1.14.2-alpine3.11
workingDir: /workspace/repo
script: |
go build -v -o demo-app env:
- name: GOPROXY
value: https://goproxy.cn
- name: GOOS
value: linux
- name: GOARCH
value: amd64

這個構建任務也很簡單,只是我們將需要用到的環境變量直接通過 env? 注入了,當然直接寫入到 script? 中也是可以的,或者直接使用 command? 來執行任務都可以,然后構建生成的 demo-app 這個二進制文件保留在代碼根目錄,這樣也就可以通過 workspace 進行共享了。

Docker 鏡像

接下來就是構建并推送 Docker 鏡像了,前面我們介紹過使用 Kaniko、DooD、DinD 3 種模式的鏡像構建方式,這里我們直接使用 DinD 這種模式,我們這里要構建的鏡像 Dockerfile 非常簡單:

FROM alpine
WORKDIR /home

# 修改alpine源為阿里云
RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories && \
apk update && \
apk upgrade && \
apk add ca-certificates && update-ca-certificates && \
apk add --update tzdata && \
rm -rf /var/cache/apk/*

COPY demo-app /home/
ENV TZ=Asia/Shanghai

EXPOSE 8080

ENTRYPOINT ./demo-app

直接將編譯好的二進制文件拷貝到鏡像中即可,所以我們這里同樣需要通過 Workspace 去獲取上一個構建任務的制品,這里我們使用 sidecar 的方式來實現 DinD 模式構建鏡像,創建一個如下所示的任務:

# task-docker.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: docker
spec:
workspaces:
- name: go-repo
params:
- name: image
description: Reference of the image docker will produce.
- name: registry_mirror
description: Specific the docker registry mirror
default: ""
- name: registry_url
description: private docker images registry url
steps:
- name: docker-build # 構建步驟
image: docker:stable
env:
- name: DOCKER_HOST # 用 TLS 形式通過 TCP 鏈接 sidecar
value: tcp://localhost:2376
- name: DOCKER_TLS_VERIFY # 校驗 TLS
value: "1"
- name: DOCKER_CERT_PATH # 使用 sidecar 守護進程生成的證書
value: /certs/client
- name: DOCKER_PASSWORD
valueFrom:
secretKeyRef:
name: harbor-auth
key: password
- name: DOCKER_USERNAME
valueFrom:
secretKeyRef:
name: harbor-auth
key: username
workingDir: $(workspaces.go-repo.path)
script: | # docker 構建命令
docker login $(params.registry_url) -u $DOCKER_USERNAME -p $DOCKER_PASSWORD
docker build --no-cache -f ./Dockerfile -t $(params.image) .
docker push $(params.image)
volumeMounts: # 聲明掛載證書目錄
- mountPath: /certs/client
name: dind-certs
sidecars: # sidecar 模式,提供 docker daemon服務,實現真正的 DinD 模式
- image: docker:dind
name: server
args:
- --storage-driver=vfs
- --userland-proxy=false
- --debug
- --insecure-registry=$(params.registry_url)
- --registry-mirror=$(params.registry_mirror)
securityContext:
privileged: true
env:
- name: DOCKER_TLS_CERTDIR # 將生成的證書寫入與客戶端共享的路徑
value: /certs
volumeMounts:
- mountPath: /certs/client
name: dind-certs
- mountPath: /var/lib/docker
name: docker-root
readinessProbe: # 等待 dind daemon 生成它與客戶端共享的證書
periodSeconds: 1
exec:
command: ["ls", "/certs/client/ca.pem"]
volumes: # 使用 emptyDir 的形式即可
- name: dind-certs
emptyDir: {}
- name: docker-root
persistentVolumeClaim:
claimName: docker-root-pvc

這個任務的重點還是要去聲明一個 Workspace,當執行任務的時候要使用和前面構建任務同一個 Workspace,這樣就可以獲得上面編譯成的 demo-app 這個二進制文件了。

部署

接下來的部署階段,我們同樣可以參考之前 Jenkins 流水線里面的實現,由于項目中我們包含了 Helm Chart 包,所以直接使用 Helm 來部署即可,要實現 Helm 部署,當然我們首先需要一個包含 helm? 命令的鏡像,當然完全可以自己去編寫一個這樣的任務,此外我們還可以直接去 hub.tekton.dev 上面查找 Catalog,因為這上面就有很多比較通用的一些任務了,比如 helm-upgrade-from-source 這個 Task 任務就完全可以滿足我們的需求了:

圖片

這個 Catalog 下面也包含完整的使用文檔了,我們可以將該任務直接下載下來根據我們自己的需求做一些定制修改,如下所示:

# task-deploy.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: deploy
labels:
app.kubernetes.io/version: "0.3"
annotations:
tekton.dev/pipelines.minVersion: "0.12.1"
tekton.dev/categories: Deployment
tekton.dev/tags: helm
tekton.dev/platforms: "linux/amd64,linux/s390x,linux/ppc64le,linux/arm64"
spec:
description: >-
These tasks will install / upgrade a helm chart into your Kubernetes /
OpenShift Cluster using Helm
params:
- name: charts_dir
description: The directory in source that contains the helm chart
- name: release_version
description: The helm release version in semantic versioning format
default: "v1.0.0"
- name: release_name
description: The helm release name
default: "helm-release"
- name: release_namespace
description: The helm release namespace
default: ""
- name: overwrite_values
description: "Specify the values you want to overwrite, comma separated: autoscaling.enabled=true,replicas=1"
default: ""
- name: values_file
description: "The values file to be used"
default: "values.yaml"
- name: helm_image
description: "helm image to be used"
default: "docker.io/lachlanevenson/k8s-helm@sha256:5c792f29950b388de24e7448d378881f68b3df73a7b30769a6aa861061fd08ae" #tag: v3.6.0
- name: upgrade_extra_params
description: "Extra parameters passed for the helm upgrade command"
default: ""
workspaces:
- name: source
results:
- name: helm-status
description: Helm deploy status
steps:
- name: upgrade
image: $(params.helm_image)
workingDir: /workspace/source
script: |
echo current installed helm releases
helm list --namespace "$(params.release_namespace)"
echo installing helm chart...
helm upgrade --install --wait --values "$(params.charts_dir)/$(params.values_file)" --namespace "$(params.release_namespace)" --version "$(params.release_version)" "$(params.release_name)" "$(params.charts_dir)" --debug --set "$(params.overwrite_values)" $(params.upgrade_extra_params)

status=`helm status $(params.release_name) --namespace "$(params.release_namespace)" | awk '/STATUS/ {print $2}'`
echo ${status} | tr -d "\n" | tee $(results.helm-status.path)

因為我們的 Helm Chart 模板就在代碼倉庫中,所以不需要從 Chart Repo 倉庫中獲取,只需要指定 Chart 路徑即可,其他可配置的參數都通過 params 參數暴露出去了,非常靈活,最后我們還獲取了 Helm 部署的狀態,寫入到了 Results 中,方便后續任務處理。

回滾

最后應用部署完成后可能還需要回滾,因為可能部署的應用有錯誤,當然這個回滾動作最好是我們自己去觸發,但是在某些場景下,比如 helm 部署已經明確失敗了,那么我們當然可以自動回滾了,所以就需要判斷當部署失敗的時候再執行回滾,也就是這個任務并不是一定會發生的,只在某些場景下才會出現,我們可以在流水線中通過使用 WhenExpressions? 來實現這個功能。要只在滿足某些條件時運行任務,可以使用 when? 字段來保護任務執行,when 字段允許你列出對 WhenExpressions 的一系列引用。

WhenExpressions? 由 Input、Operator? 和 Values 幾部分組成:

  • Input? 是WhenExpressions 的輸入,它可以是一個靜態的輸入或變量(Params 或 Results),如果未提供輸入,則默認為空字符串
  • Operator? 是一個運算符,表示 Input 和 Values 之間的關系,有效的運算符包括in、notin
  • Values 是一個字符串數組,必須提供一個非空的 Values 數組,它同樣可以包含靜態值或者變量(Params、Results 或者 Workspaces 綁定)

當在一個 Task 任務中配置了 WhenExpressions?,在執行 Task 之前會評估聲明的 WhenExpressions,如果結果為 True,則執行任務,如果為 False,則不會執行該任務。

我們這里創建的回滾任務如下所示:

# task-rollback.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
name: rollback
spec:
params:
- name: release_name
description: The helm release name
- name: release_namespace
description: The helm release namespace
default: ""
- name: helm_image
description: "helm image to be used"
default: "docker.io/lachlanevenson/k8s-helm@sha256:5c792f29950b388de24e7448d378881f68b3df73a7b30769a6aa861061fd08ae" #tag: v3.6.0
steps:
- name: rollback
image: $(params.helm_image)
script: |
echo rollback current installed helm releases
helm rollback $(params.release_name) --namespace $(params.release_namespace)

流水線

現在我們的整個工作流任務都已經創建完成了,接下來我們就可以將這些任務全部串聯起來組成一個 Pipeline 流水線了,將上面定義的幾個 Task 引用到 Pipeline 中來,當然還需要聲明 Task 中用到的 resources 或者 workspaces 這些數據:

# pipeline.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
name: pipeline
spec:
workspaces: # 聲明 workspaces
- name: go-repo-pvc
params:
# 定義代碼倉庫
- name: git_url
- name: revision
type: string
default: "main"
# 定義鏡像參數
- name: image
- name: registry_url
type: string
default: "harbor.k8s.local"
- name: registry_mirror
type: string
default: "https://mirror.baidubce.com"
# 定義 helm charts 參數
- name: charts_dir
- name: release_name
- name: release_namespace
default: "default"
- name: overwrite_values
default: ""
- name: values_file
default: "values.yaml"
tasks: # 添加task到流水線中
- name: clone
taskRef:
name: git-clone
workspaces:
- name: output
workspace: go-repo-pvc
params:
- name: url
value: $(params.git_url)
- name: revision
value: $(params.revision)
- name: test
taskRef:
name: test
runAfter:
- clone
- name: build # 編譯二進制程序
taskRef:
name: build
runAfter: # 測試任務執行之后才執行 build task
- test
- clone
workspaces: # 傳遞 workspaces
- name: go-repo
workspace: go-repo-pvc
- name: docker # 構建并推送 Docker 鏡像
taskRef:
name: docker
runAfter:
- build
workspaces: # 傳遞 workspaces
- name: go-repo
workspace: go-repo-pvc
params: # 傳遞參數
- name: image
value: $(params.image)
- name: registry_url
value: $(params.registry_url)
- name: registry_mirror
value: $(params.registry_mirror)
- name: deploy # 部署應用
taskRef:
name: deploy
runAfter:
- docker
workspaces:
- name: source
workspace: go-repo-pvc
params:
- name: charts_dir
value: $(params.charts_dir)
- name: release_name
value: $(params.release_name)
- name: release_namespace
value: $(params.release_namespace)
- name: overwrite_values
value: $(params.overwrite_values)
- name: values_file
value: $(params.values_file)
- name: rollback # 回滾
taskRef:
name: rollback
when:
- input: "$(tasks.deploy.results.helm-status)"
operator: in
values: ["failed"]
params:
- name: release_name
value: $(params.release_name)
- name: release_namespace
value: $(params.release_namespace)

整體流程比較簡單,就是在 Pipeline 需要先聲明使用到的 Workspace、Resource、Params 這些資源,然后將聲明的數據傳遞到 Task 任務中去,需要注意的是最后一個回滾任務,我們需要根據前面的 deploy? 任務的結果來判斷是否需要執行該任務,所以這里我們使用了 when? 屬性,通過 $(tasks.deploy.results.helm-status) 獲取部署狀態。

執行流水線

現在我們就可以來執行下我們的流水線,看是否符合我們自身的要求,首先我們需要先創建關聯的其他資源對象,比如 Workspace 對應的 PVC、還有 GitLab、Harbor 的認證信息:

# other.yaml
apiVersion: v1
kind: Secret
metadata:
name: gitlab-auth
annotations:
tekton.dev/git-0: http://git.k8s.local
type: kubernetes.io/basic-auth
stringData:
username: root
password: admin321

---
apiVersion: v1
kind: Secret
metadata:
name: harbor-auth
annotations:
tekton.dev/docker-0: http://harbor.k8s.local
type: kubernetes.io/basic-auth
stringData:
username: admin
password: Harbor12345

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-build-sa
secrets:
- name: harbor-auth
- name: gitlab-auth

---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-clusterrole-binding
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: edit
subjects:
- kind: ServiceAccount
name: tekton-build-sa
namespace: default

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: go-repo-pvc
spec:
resources:
requests:
storage: 1Gi
volumeMode: Filesystem
storageClassName: nfs-client # 使用 StorageClass 自動生成 PV
accessModes:
- ReadWriteOnce

---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
name: docker-root-pvc
spec:
resources:
requests:
storage: 2Gi
volumeMode: Filesystem
storageClassName: nfs-client # 使用 StorageClass 自動生成 PV
accessModes:
- ReadWriteOnce

這些關聯的資源對象創建完成后,還需要為上面的 ServiceAccount 綁定一個權限,因為在 Helm 容器中我們要去操作一些集群資源,必然需要先做權限聲明,這里我們可以將 tekton-build-sa? 綁定到 edit 這個 ClusterRole 上去。

我們接下來就可以創建一個 PipelineRun 資源對象來觸發我們的流水線構建了:

# pipelinerun.yaml
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
name: pipelinerun
spec:
serviceAccountName: tekton-build-sa
pipelineRef:
name: pipeline
workspaces:
- name: go-repo-pvc
persistentVolumeClaim:
claimName: go-repo-pvc
params:
- name: git_url
value: http://git.k8s.local/course/devops-demo.git
- name: image
value: "harbor.k8s.local/course/devops-demo:v0.1.0"
- name: charts_dir
value: "./helm"
- name: release_name
value: devops-demo
- name: release_namespace
value: "kube-ops"
- name: overwrite_values
value: "image.repository=harbor.k8s.local/course/devops-demo,image.tag=v0.1.0"
- name: values_file
value: "my-values.yaml"

直接創建上面的資源對象就可以執行我們的 Pipeline 流水線了:

$ kubectl apply -f pipelinerun.yaml
$ tkn pr describe pipelinerun
Name: pipelinerun
Namespace: default
Pipeline Ref: pipeline
Service Account: tekton-build-sa
Timeout: 1h0m0s
Labels:
tekton.dev/pipeline=pipeline

??? Status

STARTED DURATION STATUS
4 minutes ago 2m30s Succeeded(Completed)

? Params

NAME VALUE
? git_url http://git.k8s.local/course/devops-demo.git
? image harbor.k8s.local/course/devops-demo:v0.1.0
? charts_dir ./helm
? release_name devops-demo
? release_namespace kube-ops
? overwrite_values image.repository=harbor.k8s.local/course/devops-demo,image.tag=v0.1.0
? values_file my-values.yaml

?? Workspaces

NAME SUB PATH WORKSPACE BINDING
? go-repo-pvc --- PersistentVolumeClaim (claimName=go-repo-pvc)

?? Taskruns

NAME TASK NAME STARTED DURATION STATUS
? pipelinerun-deploy deploy 3 minutes ago 1m14s Succeeded
? pipelinerun-docker docker 4 minutes ago 55s Succeeded
? pipelinerun-build build 4 minutes ago 11s Succeeded
? pipelinerun-test test 4 minutes ago 4s Succeeded
? pipelinerun-clone clone 4 minutes ago 6s Succeeded

?? Skipped Tasks

NAME
? rollback
# 部署成功了
$ curl devops-demo.k8s.local
{"msg":"Hello DevOps On Kubernetes"}

在 Dashboard 上也可以看到流水線可以正常執行,由于部署成功了,所以 rollback 回滾的任務也就被忽略了:圖片

觸發器

整個流水線已經成功執行了,接下來最后一步就是將 Gitlab 和 Tekton 進行對接,也就是通過 Tekton Trigger 來自動觸發構建。關于 Tekton Trigger 的使用前面我們已經詳細講解過了,細節就不過多討論。

首先添加一個用于 Gitlab Webhook 訪問的 Secret Token,同樣要將這個 Secret 關聯到上面使用的 ServiceAccount 上面去,然后繼續添加對應的 RBAC 權限:

# other.yaml
# ......
apiVersion: v1
kind: Secret
metadata:
name: gitlab-secret
type: Opaque
stringData:
secretToken: "1234567"

---
apiVersion: v1
kind: ServiceAccount
metadata:
name: tekton-build-sa
secrets:
- name: harbor-auth
- name: gitlab-auth
- name: gitlab-secret

---
apiVersion: rbac.authorization.k8s.io/v1
kind: Role
metadata:
name: tekton-triggers-gitlab-minimal
rules:
# EventListeners need to be able to fetch all namespaced resources
- apiGroups: ["triggers.tekton.dev"]
resources:
["eventlisteners", "triggerbindings", "triggertemplates", "triggers"]
verbs: ["get", "list", "watch"]
- apiGroups: [""]
# configmaps is needed for updating logging config
resources: ["configmaps"]
verbs: ["get", "list", "watch"]
# Permissions to create resources in associated TriggerTemplates
- apiGroups: ["tekton.dev"]
resources: ["pipelineruns", "pipelineresources", "taskruns"]
verbs: ["create"]
- apiGroups: [""]
resources: ["serviceaccounts"]
verbs: ["impersonate"]
- apiGroups: ["policy"]
resources: ["podsecuritypolicies"]
resourceNames: ["tekton-triggers"]
verbs: ["use"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: RoleBinding
metadata:
name: tekton-triggers-gitlab-binding
subjects:
- kind: ServiceAccount
name: tekton-build-sa
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: Role
name: tekton-triggers-gitlab-minimal
---
kind: ClusterRole
apiVersion: rbac.authorization.k8s.io/v1
metadata:
name: tekton-triggers-gitlab-clusterrole
rules:
# EventListeners need to be able to fetch any clustertriggerbindings
- apiGroups: ["triggers.tekton.dev"]
resources: ["clustertriggerbindings", "clusterinterceptors"]
verbs: ["get", "list", "watch"]
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
name: tekton-triggers-gitlab-clusterbinding
subjects:
- kind: ServiceAccount
name: tekton-build-sa
namespace: default
roleRef:
apiGroup: rbac.authorization.k8s.io
kind: ClusterRole
name: tekton-triggers-gitlab-clusterrole

接著就可以來創建 EventListener 資源對象了,用來接收 Gitlab 的 Push Event 事件,如下所示:

# gitlab-listener.yaml
apiVersion: triggers.tekton.dev/v1beta1
kind: EventListener
metadata:
name: gitlab-listener # 該事件監聽器會創建一個名為el-gitlab-listener的Service對象
spec:
serviceAccountName: tekton-build-sa
triggers:
- name: gitlab-push-events-trigger
interceptors:
- ref:
name: gitlab
params:
- name: secretRef # 引用 gitlab-secret 的 Secret 對象中的 secretToken 的值
value:
secretName: gitlab-secret
secretKey: secretToken
- name: eventTypes
value:
- Push Hook # 只接收 GitLab Push 事件
bindings: # 定義TriggerBinding,配置參數
- name: gitrevision
value: $(body.checkout_sha)
- name: gitrepositoryurl
value: $(body.repository.git_http_url)
template:
ref: gitlab-template

上面我們通過 TriggerBinding 定義了兩個參數 gitrevision、gitrepositoryurl?,這兩個參數的值可以通過 Gitlab 發送過來的 POST 請求中獲取到數據,然后我們就可以將這兩個參數傳遞到 TriggerTemplate? 對象中去,這里的模板其實也就是將上面我們定義的 PipelineRun 對象模板化而已,主要是替換 git_url 和鏡像 TAG 這兩個參數,如下所示:

# gitlab-template.yaml
apiVersion: triggers.tekton.dev/v1beta1
kind: TriggerTemplate
metadata:
name: gitlab-template
spec:
params: # 定義參數,和 TriggerBinding 中的保持一致
- name: gitrevision
- name: gitrepositoryurl
resourcetemplates: # 定義資源模板
- apiVersion: tekton.dev/v1beta1
kind: PipelineRun # 定義 pipeline 模板
metadata:
generateName: gitlab-run- # TaskRun 名稱前綴
spec:
serviceAccountName: tekton-build-sa
pipelineRef:
name: pipeline
workspaces:
- name: go-repo-pvc
persistentVolumeClaim:
claimName: go-repo-pvc
params:
- name: git_url
value: $(tt.params.gitrepositoryurl)
- name: image
value: "harbor.k8s.local/course/devops-demo:$(tt.params.gitrevision)"
- name: charts_dir
value: "./helm"
- name: release_name
value: devops-demo
- name: release_namespace
value: "kube-ops"
- name: overwrite_values
value: "image.repository=harbor.k8s.local/course/devops-demo,image.tag=$(tt.params.gitrevision)"
- name: values_file
value: "my-values.yaml"

直接創建上面新建的幾個資源對象即可,這會創建一個 eventlistern 服務用來接收 Webhook 請求:

$ kubectl get eventlistener gitlab-listener
NAME ADDRESS AVAILABLE REASON READY REASON
gitlab-listener http://el-gitlab-listener.default.svc.cluster.local:8080 True MinimumReplicasAvailable True

所以一定還要記得在 Gitlab 倉庫中配置上 Webhook:

圖片

這樣我們整個觸發器和監聽器就配置好了,接下來我們去修改下我們的項目代碼,然后提交代碼,正常提交過后就會在集群中創建一個 PipelinRun 對象用來執行我們的流水線了。

圖片

$ kubectl get pipelinerun
NAME SUCCEEDED REASON STARTTIME COMPLETIONTIME
gitlab-run-j77rx True Completed 4m46s 46s
$ curl devops-demo.k8s.local
{"msg":"Hello Tekton On Kubernetes"}

可以看到流水線執行成功后,應用已經成功部署了我們新提交的代碼,到這里我們就完成了使用 Tekton 來重構項目的流水線。

責任編輯:未麗燕 來源: k8s技術圈
相關推薦

2022-04-01 10:51:33

TektonArgoCDGitOps

2022-04-14 07:51:39

TektonTaskRun

2022-04-25 08:07:45

TektonArgocdCI和CD

2022-03-21 09:40:48

TektonJenkinsPipeline

2022-04-08 09:53:56

TektonJenkinsKubesphere

2023-02-19 15:26:51

深度學習數據集

2021-06-25 09:54:49

GitLab Tekton Devops

2022-07-27 07:39:45

Kubernetes云原生

2009-10-27 16:18:58

VB.NET復制刪除文

2021-05-13 18:23:53

Tekton云原生Kubernetes

2021-07-09 06:40:59

TektonArgo CD GitOps

2014-07-10 10:09:11

JSON數據行轉列

2024-06-11 00:00:01

用ReactGraphQLCRUD

2025-09-03 14:01:41

谷歌AI模型

2021-04-27 22:32:01

TektonKubernetesCI

2022-07-29 10:31:33

算法Python

2022-03-18 07:48:58

GhostNode.js開源

2022-05-17 09:14:50

聚類算法python

2022-10-10 17:37:59

分庫分表訂單業務

2021-06-26 14:22:34

Tekton流水線Kubernetes
點贊
收藏

51CTO技術棧公眾號

青娱乐av在线| 青青草精品在线| eeuss影院在线观看| 免播放器亚洲一区| 欧美成人精品不卡视频在线观看| 人妻体内射精一区二区三区| 韩国精品主播一区二区在线观看 | 国产欧美韩日| 国产美女www爽爽爽| 欧美日韩午夜| 一本色道久久综合狠狠躁篇怎么玩 | 国产一二三四五区| 免费一级欧美在线大片| 色综合色狠狠综合色| www.-级毛片线天内射视视| 亚洲欧美综合在线观看| 国产一区欧美二区| 日韩av不卡在线| 免费一级肉体全黄毛片| 欧美日韩黑人| 亚洲激情在线观看视频免费| 国产永久免费网站| 美女日韩欧美| 五月婷婷久久丁香| 日本丰满大乳奶| 丁香在线视频| 91欧美一区二区| av成人观看| 一级淫片免费看| 老司机精品导航| 一区二区三区中文字幕精品精品 | 99久久久国产精品美女| 91久久精品一区二区| 亚洲国产一二三精品无码| 浮生影视网在线观看免费| www.色综合.com| 成人影片在线播放| 999av视频| 久久精品国产精品亚洲红杏| 国产成+人+综合+亚洲欧美丁香花| 国产 日韩 欧美 成人| 亚洲网色网站| 日韩色av导航| 国产又粗又长又黄的视频| 一本久久青青| 亚洲精品视频在线播放 | 国产欧美日韩在线视频| 久久久久一区二区三区| 深夜福利视频网站| av在线综合网| 国产精品三区四区| 国内免费精品视频| 国产精品mv在线观看| 九九热视频这里只有精品| 婷婷久久综合网| 国产精品久久久久av蜜臀| 日韩亚洲欧美成人一区| 自拍一级黄色片| 亚洲va欧美va人人爽成人影院| 91精品国产手机| 男人女人拔萝卜视频| 日韩欧美中文在线观看| 精品美女在线观看| 完美搭档在线观看| 亚洲精品亚洲人成在线观看| 亚洲九九九在线观看| 亚洲精品午夜视频| 久久一级电影| 久久亚洲精品国产亚洲老地址| www.xxxx日本| 亚洲成人直播| 日本国产精品视频| 中文字幕在线观看欧美| 精品亚洲porn| 国产精品一区二区在线观看| 亚洲国产精品久久久久久6q| 99精品视频免费在线观看| 欧美日韩另类综合| 欧美精品hd| 亚洲成a人在线观看| 欧美日韩在线一| 91九色综合| 日韩免费视频一区| 精品人妻少妇嫩草av无码| 国内成人精品| 欧美疯狂性受xxxxx另类| 日本亚洲欧美在线| 日本aⅴ免费视频一区二区三区| 亚洲专区国产精品| 亚洲人妻一区二区三区| 中文字幕免费在线观看视频一区| 四虎影院一区二区| 老司机深夜福利在线观看| 欧美日韩中文字幕一区二区| 91精品国产高清91久久久久久 | 风间由美中文字幕在线看视频国产欧美 | 色噜噜狠狠色综合中国| 天天影视色综合| 日韩精选在线| 久久伊人精品视频| 一级片免费在线播放| 国产麻豆精品在线观看| 久久精品日产第一区二区三区乱码 | 亚洲高清在线精品| 日本爱爱免费视频| 大陆精大陆国产国语精品 | 四虎影视成人| 欧美在线视频日韩| 911亚洲精选| 99热精品久久| 国产成人精品a视频一区www| 亚洲av无码国产精品永久一区| 久久久久久久久久电影| 激情五月婷婷六月| 日韩一区二区三区四区五区| 国产婷婷色综合av蜜臀av | 国产精品chinese| 国产精品视频自拍| 日本在线视频1区| 亚洲一区日韩精品中文字幕| 在线观看免费的av| 久久99国产成人小视频| 97精品久久久中文字幕免费| 国产视频aaa| 欧美极品美女视频| 日韩有码免费视频| 日本在线中文字幕一区| 亚洲成人久久一区| 国产黄色录像片| 日韩av不卡在线观看| 久久久久久亚洲精品不卡4k岛国 | 亚洲影院高清在线| av在线免费一区| 欧洲一区二区三区免费视频| 久久人妻少妇嫩草av无码专区| 欧美片第1页综合| 成人黄色免费网站在线观看| av国产在线观看| 91福利资源站| 性猛交娇小69hd| 久久综合影视| 日韩资源av在线| 日本韩国欧美| 正在播放国产一区| 国产成人精品一区二区色戒| 国产色综合久久| 久久婷婷国产91天堂综合精品| 亚洲伊人春色| 国产suv精品一区二区| 男人天堂亚洲二区| 日本韩国一区二区三区| 加勒比综合在线| 日本aⅴ精品一区二区三区| 天天综合狠狠精品| av成人免费| 色婷婷综合久久久久| 国产乱叫456在线| 依依成人综合视频| 国产精品日日摸夜夜爽| 亚洲国产高清一区| 精品久久一区二区三区蜜桃| 亚洲美女尤物影院| 亚洲欧美一区二区激情| 国产精品午夜一区二区| 自拍偷拍亚洲综合| 久久久男人的天堂| 亚洲国产裸拍裸体视频在线观看乱了中文 | 黄色成人在线网址| 99国产视频| 色戒汤唯在线| 神马久久桃色视频| 国产激情视频在线播放| 亚洲成人免费电影| 国产精品无码一区二区三区| 美女任你摸久久| 国产欧美久久久久| 亚洲精华一区二区三区| 国产精品自拍小视频| 亚洲淫性视频| 精品亚洲aⅴ在线观看| 综合久久中文字幕| 一区二区三区在线免费| 免费a级黄色片| 久久国产剧场电影| 欧美国产视频一区| 欧美欧美黄在线二区| 91久久精品美女| 色老头在线一区二区三区| 综合国产在线观看| 黄色av网站免费在线观看| 在线一区二区三区四区五区| 天天看片中文字幕| 91在线视频网址| 亚洲色图偷拍视频| 亚洲专区在线| 水蜜桃在线免费观看| 久久最新网址| av一区二区三区四区电影| 电影一区二区三| 欧美乱大交xxxxx另类电影| 黄色大片在线看| 日韩欧美色综合网站| 国产又粗又猛又黄视频| 亚洲一本大道在线| 日本黄区免费视频观看| av资源站一区| 性高潮久久久久久| 免费欧美在线视频| 日韩欧美视频网站| 亚洲一区二区日韩| 日韩中文字幕一区二区| 免费日韩一区二区三区| 7777精品伊久久久大香线蕉语言| 成人欧美大片| 性欧美视频videos6一9| 成人午夜在线影视| 中文字幕欧美日韩| 四虎影视精品成人| 精品国精品国产| 国产农村妇女毛片精品久久| 欧美综合一区二区| 天天综合天天干| 亚洲va欧美va人人爽| 26uuu成人网| 国产精品久久综合| 国产又大又粗又爽的毛片| av在线一区二区三区| 大尺度在线观看| 国产精品一卡二卡在线观看| 天堂中文av在线| 美女视频免费一区| 国产成人黄色网址| 免费精品99久久国产综合精品| 欧美色图另类小说| 99热免费精品在线观看| 国产va亚洲va在线va| 澳门久久精品| 91观看网站| 日韩精品一区二区三区中文| 成人亚洲激情网| 四虎成人精品一区二区免费网站| 国产精品视频一区二区三区四| 亚洲成人不卡| 国产成人免费91av在线| 久久野战av| 国产精品香蕉av| 国产精品蜜月aⅴ在线| 国产精品免费看久久久香蕉| 88xx成人网| 国产自产女人91一区在线观看| 国产91在线播放精品| 国产欧美 在线欧美| 少妇精品视频在线观看| 91日本在线观看| 日韩欧美另类中文字幕| 国产精品日韩欧美一区二区| 午夜a一级毛片亚洲欧洲| 就去色蜜桃综合| 九九热精品视频在线观看| 欧美日韩在线观看一区二区三区| 国产剧情在线观看一区| 亚洲高清在线播放| 亚洲精品小说| www.av91| 亚洲欧美日韩一区在线观看| 国产成人手机视频| 美美哒免费高清在线观看视频一区二区| 日本人视频jizz页码69| 国产精品一区久久久久| 在线观看一区二区三区四区| 99久久婷婷国产综合精品电影 | 综合干狼人综合首页| 日本一区二区三区www| 日韩在线观看一区| 成人在线观看毛片| 亚洲色诱最新| 2025韩国理伦片在线观看| 国产一区二区不卡| 日韩片在线观看| 中文字幕不卡一区| 欧美日韩中文字幕在线观看| 精品久久久久久中文字幕| 蜜臀99久久精品久久久久小说 | 一区二区国产在线| 国产3p露脸普通话对白| 青青草国产精品97视觉盛宴| 少妇性l交大片7724com| 久久这里只有精品6| 三级全黄做爰视频| 污片在线观看一区二区| 一区精品在线观看| 亚洲精品在线免费播放| 国产精品一区在线看| 欧美日韩国产第一页| 我爱我色成人网| aa日韩免费精品视频一| 欧美日韩有码| 天天夜碰日日摸日日澡性色av| 日本sm残虐另类| 波多野结衣有码| 18欧美亚洲精品| 国产精品自拍99| 日韩一区二区在线看片| 国产一区精品| 高清亚洲成在人网站天堂| 福利一区和二区| 久久久久久国产精品mv| 欧美a级片网站| 我要看一级黄色大片| 不卡的看片网站| 色在线观看视频| 欧美日韩精品欧美日韩精品一综合| 蜜臀av在线观看| 久热99视频在线观看| 主播大秀视频在线观看一区二区| 国产一区二区三区奇米久涩| 正在播放日韩欧美一页| 三级a在线观看| 91视视频在线直接观看在线看网页在线看| 一级黄色录像视频| 欧美色图免费看| 精品视频三区| 日韩av免费网站| 性欧美lx╳lx╳| 成人午夜免费在线| 国产传媒久久文化传媒| 2017亚洲天堂| 欧美性猛片xxxx免费看久爱| 天堂av中文字幕| 久久久久亚洲精品成人网小说| 精品国产亚洲一区二区三区大结局| 亚洲第一导航| 日本欧美韩国一区三区| 精品人妻无码一区二区三区 | 九九在线高清精品视频| 亚洲人成无码网站久久99热国产| 国产精品一二三在| 国产免费一区二区三区四区| 欧美日韩久久久一区| 第一福利在线| 国产精品久久久久久久久影视| 国产调教一区二区三区| 久久久精品在线视频| 久久久噜噜噜久噜久久综合| 中文字幕国产在线观看| 亚洲欧美激情另类校园| 免费福利视频一区二区三区| 女人一区二区三区| 久久一区二区三区四区五区 | 国产日韩欧美视频在线| 成人网18免费网站| 爱爱爱爱免费视频| 亚洲精品中文在线影院| 精品国产99久久久久久宅男i| 欧美精品生活片| 57pao国产一区二区| 国产日韩亚洲精品| 亚洲午夜一级| 第四色在线视频| 色综合天天在线| 北条麻妃在线| 91手机视频在线观看| 欧美在线观看天堂一区二区三区| 中文字幕无码毛片免费看| 亚洲国产日韩精品| 人操人视频在线观看| 国产精品男女猛烈高潮激情| jizz日韩| 欧美美女一区二区| lutube成人福利在线观看| 91在线观看免费高清| 欧美日韩亚洲一区| 午夜久久久久久久| 91国偷自产一区二区三区观看 | 在线观看中文字幕2021| 精品国产一区二区三区四区在线观看 | 91精品国产一区二区人妖| 俺来也官网欧美久久精品| 玖玖玖精品中文字幕| 激情小说亚洲一区| 国产精品二区一区二区aⅴ| 亚洲精品一区久久久久久| 欧美成人一二区| 日韩精品在线中文字幕| 国产欧美日韩在线看| 亚洲av无码乱码国产麻豆| 日本国产高清不卡| 午夜国产一区| 国产一二三四五区| 日韩一区二区电影| 中文在线资源| 伊人久久在线观看| 久久久久久日产精品| 国产成人三级在线播放| 日本国产高清不卡| 国产综合精品| 五月婷婷婷婷婷| 日韩精品久久久久久福利| 亚洲狼人综合| 国产aaa一级片|