当前位置: 首页 > news >正文

kubenetes流水线实施清单

整体实施方案概述

  1. 创建命名空间(Namespace):创建一个专用于 CI/CD 的命名空间 cicd
  2. 配置 Secrets
    • Git SSH 密钥(分别为 Maven 和 npm 项目)
    • Docker Registry 凭证(Kaniko)
    • SMTP 凭证(邮件通知)
  3. 创建 PersistentVolumeClaim(PVC):用于存储工作空间数据。
  4. 创建 ServiceAccount 和权限绑定:确保 Tekton Pipelines 有足够的权限。
  5. 创建 Tekton Tasks
    • 初始化环境任务(分别为 Maven 和 npm)
    • 拉取代码任务(分别为 Maven 和 npm)
    • 运行 dockerContext.sh 脚本任务
    • 构建并推送镜像任务(使用 Kaniko)
    • 部署到 Kubernetes 任务
    • 发送邮件通知任务
  6. 创建 Tekton Pipelines
    • Maven 流水线
    • npm 流水线
  7. 创建 dockerContext.sh 脚本
  8. 应用所有 Tekton 资源
  9. 测试与运行
  10. 常见问题排查

详细实施步骤

步骤 1:创建命名空间

如果尚未创建,创建一个专用于 CI/CD 的命名空间 cicd

kubectl create namespace cicd

验证命名空间创建成功:

kubectl get namespaces

步骤 2:配置 Git SSH 密钥

2.1 生成 SSH 密钥
  1. 为 Maven 项目生成 SSH 密钥(如果尚未有):

    ssh-keygen -t rsa -b 4096 -C "maven_email@example.com" -f ~/maven_id_rsa
    
  2. 为 npm 项目生成 SSH 密钥(如果尚未有):

    ssh-keygen -t rsa -b 4096 -C "npm_email@example.com" -f ~/npm_id_rsa
    
  3. 将公钥添加到各自 Git 仓库的部署密钥中,以便允许 CI/CD 系统访问私有仓库。

2.2 创建 Kubernetes Secrets 存储 Git SSH 私钥

保存 Maven Git SSH Secret 为 git-ssh-secret-maven.yaml

apiVersion: v1
kind: Secret
metadata:name: git-ssh-key-mavennamespace: cicd
type: kubernetes.io/ssh-auth
data:ssh-privatekey: <BASE64_ENCODED_MAVEN_ID_RSA>

保存 npm Git SSH Secret 为 git-ssh-secret-npm.yaml

apiVersion: v1
kind: Secret
metadata:name: git-ssh-key-npmnamespace: cicd
type: kubernetes.io/ssh-auth
data:ssh-privatekey: <BASE64_ENCODED_NPM_ID_RSA>

生成 Base64 编码的私钥:

# 对 Maven 私钥进行编码
cat ~/maven_id_rsa | base64 -w0# 对 npm 私钥进行编码
cat ~/npm_id_rsa | base64 -w0

将编码后的字符串替换到 <BASE64_ENCODED_MAVEN_ID_RSA><BASE64_ENCODED_NPM_ID_RSA> 中。

应用 Secrets:

kubectl apply -f git-ssh-secret-maven.yaml
kubectl apply -f git-ssh-secret-npm.yaml

验证 Secrets 创建成功:

kubectl get secrets -n cicd

步骤 3:配置 Docker Registry 认证(使用 Kaniko)

3.1 准备 Docker Registry 凭证

确保您有镜像仓库的服务器地址、用户名、密码和邮箱。

3.2 创建 Docker Registry Secret

保存为 kaniko-secret.yaml

apiVersion: v1
kind: Secret
metadata:name: kaniko-secretnamespace: cicd
type: kubernetes.io/dockerconfigjson
data:.dockerconfigjson: <BASE64_ENCODED_DOCKER_CONFIG_JSON>

生成 .dockerconfigjson 的方法:

您可以使用以下命令自动生成:

kubectl create secret docker-registry kaniko-secret \--namespace=cicd \--docker-server=<YOUR_DOCKER_REGISTRY_SERVER> \--docker-username=<YOUR_USERNAME> \--docker-password=<YOUR_PASSWORD> \--docker-email=<YOUR_EMAIL> \--dry-run=client -o jsonpath='{.data.\.dockerconfigjson}' | base64 -w0

将输出结果替换到 kaniko-secret.yaml 中的 <BASE64_ENCODED_DOCKER_CONFIG_JSON>

应用 Secret:

kubectl apply -f kaniko-secret.yaml

验证 Secret 创建成功:

kubectl get secrets -n cicd

步骤 4:创建 SMTP Secret

用于邮件通知。

保存为 smtp-secret.yaml

apiVersion: v1
kind: Secret
metadata:name: smtp-secretnamespace: cicd
type: Opaque
data:smtp-server: <BASE64_ENCODED_SMTP_SERVER>smtp-port: <BASE64_ENCODED_SMTP_PORT>smtp-username: <BASE64_ENCODED_SMTP_USERNAME>smtp-password: <BASE64_ENCODED_SMTP_PASSWORD>from-email: <BASE64_ENCODED_FROM_EMAIL>to-email: <BASE64_ENCODED_TO_EMAIL>

将各字段值进行 Base64 编码:

echo -n 'smtp.gmail.com' | base64 -w0
echo -n '587' | base64 -w0
echo -n 'user@gmail.com' | base64 -w0
echo -n 'password123' | base64 -w0
echo -n 'user@gmail.com' | base64 -w0
echo -n 'admin@example.com' | base64 -w0

示例:

apiVersion: v1
kind: Secret
metadata:name: smtp-secretnamespace: cicd
type: Opaque
data:smtp-server: c210cC5nbWFpbC5jb20= # smtp.gmail.comsmtp-port: NTg3 # 587smtp-username: dXNlckBnbWFpbC5jb20= # user@gmail.comsmtp-password: cGFzc3dvcmQxMjM= # password123from-email: dXNlckBnbWFpbC5jb20= # user@gmail.comto-email: YWRtaW5AZXhhbXBsZS5jb20= # admin@example.com

应用 Secret:

kubectl apply -f smtp-secret.yaml

验证 Secret 创建成功:

kubectl get secrets -n cicd

步骤 5:创建 PersistentVolumeClaim(PVC)

Tekton 需要持久化存储来存放工作空间数据。

保存为 workspace-pvc.yaml

apiVersion: v1
kind: PersistentVolumeClaim
metadata:name: workspace-pvcnamespace: cicd
spec:accessModes:- ReadWriteOnceresources:requests:storage: 5Gi

应用 PVC:

kubectl apply -f workspace-pvc.yaml

验证 PVC 状态:

kubectl get pvc -n cicd

步骤 6:创建 ServiceAccount 和权限绑定

确保 Tekton Pipelines 有足够的权限访问 Kubernetes API 和相关资源。

保存为 tekton-sa.yaml

apiVersion: v1
kind: ServiceAccount
metadata:name: tekton-sanamespace: cicd

应用 ServiceAccount:

kubectl apply -f tekton-sa.yaml

绑定权限(示例:赋予 edit 权限):

kubectl create rolebinding tekton-sa-edit \--clusterrole=edit \--serviceaccount=cicd:tekton-sa \--namespace=cicd

说明:

  • edit ClusterRole 赋予了在命名空间内编辑资源的权限。根据实际需求,可以调整权限。

步骤 7:创建 Tekton Tasks

我们将为 Maven 和 npm 项目分别创建初始化任务和代码拉取任务。构建、推送镜像、部署和发送邮件的任务可以共用。

7.1 初始化环境任务

7.1.1 初始化 Maven 环境任务 (init-maven.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-mavennamespace: cicd
spec:steps:- name: setup-mavenimage: maven:3.8.6-jdk-11script: |#!/bin/shset -eecho "初始化 Maven 环境..."mvn --version# 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖

7.1.2 初始化 npm 环境任务 (init-npm.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-npmnamespace: cicd
spec:steps:- name: setup-npmimage: node:16script: |#!/bin/shset -eecho "初始化 NPM 环境..."node --versionnpm --version# 在此处添加任何 NPM 相关的初始化步骤,例如安装全局包

应用初始化任务:

kubectl apply -f init-maven.yaml
kubectl apply -f init-npm.yaml
7.2 拉取代码任务

7.2.1 拉取 Maven 项目代码任务 (clone-repo-maven.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-mavennamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-maven-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 Maven 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-mavenmountPath: /root/.sshvolumes:- name: ssh-credentials-mavensecret:secretName: git-ssh-key-maven

7.2.2 拉取 npm 项目代码任务 (clone-repo-npm.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-npmnamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-npm-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 npm 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-npmmountPath: /root/.sshvolumes:- name: ssh-credentials-npmsecret:secretName: git-ssh-key-npm

应用拉取代码任务:

kubectl apply -f clone-repo-maven.yaml
kubectl apply -f clone-repo-npm.yaml
7.3 运行 dockerContext.sh 任务 (run-docker-context.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: run-docker-contextnamespace: cicd
spec:workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: run-scriptimage: bash:latestscript: |#!/bin/shset -ecd $(workspaces.source.path)if [ -f .manifest/dockerContext.sh ]; thenecho "运行 dockerContext.sh 脚本..."chmod +x .manifest/dockerContext.sh./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."elseecho "未找到 dockerContext.sh 脚本,跳过..."fi

应用任务:

kubectl apply -f run-docker-context.yaml
7.4 构建并推送镜像任务(使用 Kaniko) (build-and-push-kaniko.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: build-and-push-kanikonamespace: cicd
spec:params:- name: imagedescription: Docker 镜像名称type: string- name: dockerfiledescription: Dockerfile 的路径default: ./Dockerfiletype: string- name: contextdescription: 构建上下文路径default: .type: stringworkspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: kanikoimage: gcr.io/kaniko-project/executor:latestcommand:- /kaniko/executorargs:- "--context=$(workspaces.source.path)/$(params.context)"- "--dockerfile=$(workspaces.source.path)/$(params.dockerfile)"- "--destination=$(params.image)"- "--oci-layout-path=/kaniko/oci"- "--cache=true"- "--cache-repo=$(params.image)"env:- name: DOCKER_CONFIGvalue: /kaniko/.docker/volumeMounts:- name: kaniko-secretmountPath: /kaniko/.docker/volumes:- name: kaniko-secretsecret:secretName: kaniko-secret

应用任务:

kubectl apply -f build-and-push-kaniko.yaml
7.5 部署到 Kubernetes 任务 (deploy-to-kubernetes.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: deploy-to-kubernetesnamespace: cicd
spec:params:- name: namespacedescription: Kubernetes 命名空间type: string- name: deployment-namedescription: Kubernetes Deployment 名称type: string- name: imagedescription: 要部署的镜像type: stringsteps:- name: deployimage: bitnami/kubectlscript: |#!/bin/shset -eecho "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)- name: set-statusimage: alpinescript: |#!/bin/shecho "succeeded" > /tekton/results/statusresults:- name: statusdescription: 部署状态

应用任务:

kubectl apply -f deploy-to-kubernetes.yaml
7.6 发送邮件通知任务 (send-email.yaml)

(已在上文提供,此处重复以方便参考)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: send-emailnamespace: cicd
spec:params:- name: subjecttype: stringdescription: 邮件主题- name: bodytype: stringdescription: 邮件正文steps:- name: send-emailimage: curlimages/curl:7.83.1script: |#!/bin/shset -eSMTP_SERVER=$(cat /var/secrets/smtp/smtp-server)SMTP_PORT=$(cat /var/secrets/smtp/smtp-port)SMTP_USERNAME=$(cat /var/secrets/smtp/smtp-username)SMTP_PASSWORD=$(cat /var/secrets/smtp/smtp-password)FROM_EMAIL=$(cat /var/secrets/smtp/from-email)TO_EMAIL=$(cat /var/secrets/smtp/to-email)SUBJECT="$(params.subject)"BODY="$(params.body)"echo "正在通过 $SMTP_SERVER:$SMTP_PORT 发送邮件到 $TO_EMAIL..."echo -e "Subject: $SUBJECT\n\n$BODY" | \curl --url "smtp://$SMTP_SERVER:$SMTP_PORT" \--ssl-reqd \--mail-from "$FROM_EMAIL" \--mail-rcpt "$TO_EMAIL" \--user "$SMTP_USERNAME:$SMTP_PASSWORD" \-T -volumes:- name: smtp-secretssecret:secretName: smtp-secret

应用任务:

kubectl apply -f send-email.yaml

步骤 8:创建 Tekton Pipelines

为 Maven 和 npm 项目分别创建独立的流水线。

8.1 Maven 流水线 (maven-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: maven-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-maventaskRef:name: init-mavenrunAfter: []- name: clone-reporunAfter:- init-maventaskRef:name: clone-repo-mavenparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **Maven 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source
8.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: npm-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-npmtaskRef:name: init-npmrunAfter: []- name: clone-reporunAfter:- init-npmtaskRef:name: clone-repo-npmparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **NPM 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source

说明:

  • Maven 和 npm 流水线结构类似,但各自引用不同的初始化和代码拉取任务。
  • finally 部分确保无论前面的任务成功还是失败,都会执行 send-email 任务发送通知。

应用流水线:

kubectl apply -f maven-pipeline.yaml
kubectl apply -f npm-pipeline.yaml

验证流水线创建成功:

kubectl get pipelines -n cicd

步骤 9:创建 dockerContext.sh 脚本

dockerContext.sh 是一个用于处理特定上下文操作的脚本。根据您的需求,您可以在此脚本中添加自定义逻辑。以下是一个示例脚本:

创建 dockerContext.sh 文件:

#!/bin/sh
set -eecho "执行 dockerContext.sh 脚本..."# 示例操作:生成 Docker 镜像标签
TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo "生成的时间戳标签:$TIMESTAMP"# 您可以在此处添加更多自定义操作,例如修改配置文件、生成额外文件等。echo "dockerContext.sh 脚本执行完成。"

说明:

  • 功能:此脚本用于执行构建前的自定义操作,例如生成镜像标签、修改配置文件等。
  • 位置:将此脚本放置在项目的 .manifest/ 目录下,即 .manifest/dockerContext.sh

确保脚本具有执行权限:

chmod +x .manifest/dockerContext.sh

步骤 10:应用所有 Tekton 资源

按照以下顺序依次应用所有 Tekton 任务和流水线配置文件:

kubectl apply -f init-maven.yaml
kubectl apply -f init-npm.yaml
kubectl apply -f clone-repo-maven.yaml
kubectl apply -f clone-repo-npm.yaml
kubectl apply -f run-docker-context.yaml
kubectl apply -f build-and-push-kaniko.yaml
kubectl apply -f deploy-to-kubernetes.yaml
kubectl apply -f send-email.yaml
kubectl apply -f maven-pipeline.yaml
kubectl apply -f npm-pipeline.yaml
kubectl apply -f workspace-pvc.yaml
kubectl apply -f kaniko-secret.yaml
kubectl apply -f smtp-secret.yaml
kubectl apply -f tekton-sa.yaml

验证资源创建成功:

kubectl get tasks,pipelines -n cicd
kubectl get pvc -n cicd
kubectl get secrets -n cicd
kubectl get serviceaccounts -n cicd

步骤 11:测试与运行

11.1 手动触发 Maven 流水线

创建并应用 Maven PipelineRun (maven-pipelinerun.yaml):

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:name: maven-pipelinerun-$(date +%s)namespace: cicd
spec:pipelineRef:name: maven-pipelineparams:- name: repo-urlvalue: https://github.com/example/maven-app.git- name: branchvalue: main- name: imagevalue: docker.io/example/maven-app:latest- name: namespacevalue: dev- name: deployment-namevalue: maven-appworkspaces:- name: sourcepersistentVolumeClaim:claimName: workspace-pvcserviceAccountName: tekton-sa

应用 PipelineRun:

kubectl apply -f maven-pipelinerun.yaml
11.2 手动触发 npm 流水线

创建并应用 npm PipelineRun (npm-pipelinerun.yaml):

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:name: npm-pipelinerun-$(date +%s)namespace: cicd
spec:pipelineRef:name: npm-pipelineparams:- name: repo-urlvalue: https://github.com/example/npm-app.git- name: branchvalue: main- name: imagevalue: docker.io/example/npm-app:latest- name: namespacevalue: dev- name: deployment-namevalue: npm-appworkspaces:- name: sourcepersistentVolumeClaim:claimName: workspace-pvcserviceAccountName: tekton-sa

应用 PipelineRun:

kubectl apply -f npm-pipelinerun.yaml

或者,您也可以使用 tkn CLI 触发 Pipeline:

# 触发 Maven 流水线
tkn pipeline start maven-pipeline \-p repo-url=https://github.com/example/maven-app.git \-p branch=main \-p image=docker.io/example/maven-app:latest \-p namespace=dev \-p deployment-name=maven-app \-w name=source,claimName=workspace-pvc \--serviceaccount=tekton-sa# 触发 npm 流水线
tkn pipeline start npm-pipeline \-p repo-url=https://github.com/example/npm-app.git \-p branch=main \-p image=docker.io/example/npm-app:latest \-p namespace=dev \-p deployment-name=npm-app \-w name=source,claimName=workspace-pvc \--serviceaccount=tekton-sa
11.3 监控流水线运行状态
# 查看流水线列表
kubectl get pipelines -n cicd# 查看 PipelineRun 列表
kubectl get pipelineruns -n cicd# 查看特定 PipelineRun 的日志
tkn pipelinerun logs <pipelinerun-name> -f -n cicd

<pipelinerun-name> 替换为实际的 PipelineRun 名称。

步骤 12:验证邮件通知功能

  1. 触发流水线:按照上述步骤 11.1 或 11.2 触发 Maven 或 npm 流水线。
  2. 检查邮件:确认指定的 to-email 收到相应的通知邮件。
  3. 排查问题
    • 如果邮件未收到,请检查:
      • smtp-secret 是否正确配置,确保所有字段都已正确 Base64 编码。
      • SMTP 服务器是否允许通过 API 或外部应用发送邮件(例如,Gmail 可能需要启用“应用专用密码”)。
      • 查看 send-email 任务的日志,确认 curl 命令是否执行成功。

关键 YAML 文件汇总

1. 初始化环境任务

1.1 Maven 初始化任务 (init-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-mavennamespace: cicd
spec:steps:- name: setup-mavenimage: maven:3.8.6-jdk-11script: |#!/bin/shset -eecho "初始化 Maven 环境..."mvn --version# 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖
1.2 npm 初始化任务 (init-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-npmnamespace: cicd
spec:steps:- name: setup-npmimage: node:16script: |#!/bin/shset -eecho "初始化 NPM 环境..."node --versionnpm --version# 在此处添加任何 NPM 相关的初始化步骤,例如安装全局包

2. 拉取代码任务

2.1 拉取 Maven 项目代码任务 (clone-repo-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-mavennamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-maven-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 Maven 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-mavenmountPath: /root/.sshvolumes:- name: ssh-credentials-mavensecret:secretName: git-ssh-key-maven
2.2 拉取 npm 项目代码任务 (clone-repo-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-npmnamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-npm-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 npm 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-npmmountPath: /root/.sshvolumes:- name: ssh-credentials-npmsecret:secretName: git-ssh-key-npm

3. 运行 dockerContext.sh 任务 (run-docker-context.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: run-docker-contextnamespace: cicd
spec:workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: run-scriptimage: bash:latestscript: |#!/bin/shset -ecd $(workspaces.source.path)if [ -f .manifest/dockerContext.sh ]; thenecho "运行 dockerContext.sh 脚本..."chmod +x .manifest/dockerContext.sh./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."elseecho "未找到 dockerContext.sh 脚本,跳过..."fi

4. 构建并推送镜像任务(使用 Kaniko) (build-and-push-kaniko.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: build-and-push-kanikonamespace: cicd
spec:params:- name: imagedescription: Docker 镜像名称type: string- name: dockerfiledescription: Dockerfile 的路径default: ./Dockerfiletype: string- name: contextdescription: 构建上下文路径default: .type: stringworkspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: kanikoimage: gcr.io/kaniko-project/executor:latestcommand:- /kaniko/executorargs:- "--context=$(workspaces.source.path)/$(params.context)"- "--dockerfile=$(workspaces.source.path)/$(params.dockerfile)"- "--destination=$(params.image)"- "--oci-layout-path=/kaniko/oci"- "--cache=true"- "--cache-repo=$(params.image)"env:- name: DOCKER_CONFIGvalue: /kaniko/.docker/volumeMounts:- name: kaniko-secretmountPath: /kaniko/.docker/volumes:- name: kaniko-secretsecret:secretName: kaniko-secret

5. 部署到 Kubernetes 任务 (deploy-to-kubernetes.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: deploy-to-kubernetesnamespace: cicd
spec:params:- name: namespacedescription: Kubernetes 命名空间type: string- name: deployment-namedescription: Kubernetes Deployment 名称type: string- name: imagedescription: 要部署的镜像type: stringsteps:- name: deployimage: bitnami/kubectlscript: |#!/bin/shset -eecho "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)- name: set-statusimage: alpinescript: |#!/bin/shecho "succeeded" > /tekton/results/statusresults:- name: statusdescription: 部署状态

6. 发送邮件通知任务 (send-email.yaml)

(已在上文提供,此处重复以方便参考)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: send-emailnamespace: cicd
spec:params:- name: subjecttype: stringdescription: 邮件主题- name: bodytype: stringdescription: 邮件正文steps:- name: send-emailimage: curlimages/curl:7.83.1script: |#!/bin/shset -eSMTP_SERVER=$(cat /var/secrets/smtp/smtp-server)SMTP_PORT=$(cat /var/secrets/smtp/smtp-port)SMTP_USERNAME=$(cat /var/secrets/smtp/smtp-username)SMTP_PASSWORD=$(cat /var/secrets/smtp/smtp-password)FROM_EMAIL=$(cat /var/secrets/smtp/from-email)TO_EMAIL=$(cat /var/secrets/smtp/to-email)SUBJECT="$(params.subject)"BODY="$(params.body)"echo "正在通过 $SMTP_SERVER:$SMTP_PORT 发送邮件到 $TO_EMAIL..."echo -e "Subject: $SUBJECT\n\n$BODY" | \curl --url "smtp://$SMTP_SERVER:$SMTP_PORT" \--ssl-reqd \--mail-from "$FROM_EMAIL" \--mail-rcpt "$TO_EMAIL" \--user "$SMTP_USERNAME:$SMTP_PASSWORD" \-T -volumes:- name: smtp-secretssecret:secretName: smtp-secret

应用任务:

kubectl apply -f send-email.yaml

步骤 7:创建 Tekton Pipelines

7.1 Maven 流水线 (maven-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: maven-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-maventaskRef:name: init-mavenrunAfter: []- name: clone-reporunAfter:- init-maventaskRef:name: clone-repo-mavenparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **Maven 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source
7.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: npm-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-npmtaskRef:name: init-npmrunAfter: []- name: clone-reporunAfter:- init-npmtaskRef:name: clone-repo-npmparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **NPM 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source

说明:

  • Maven 和 npm 流水线结构类似,但各自引用不同的初始化和代码拉取任务。
  • finally 部分确保无论前面的任务成功还是失败,都会执行 send-email 任务发送通知。

应用流水线:

kubectl apply -f maven-pipeline.yaml
kubectl apply -f npm-pipeline.yaml

步骤 10:创建 dockerContext.sh 脚本

dockerContext.sh 是一个用于处理特定上下文操作的脚本。根据您的需求,您可以在此脚本中添加自定义逻辑。以下是一个示例脚本:

创建 dockerContext.sh 文件:

将以下内容保存为项目中的 .manifest/dockerContext.sh 文件:

#!/bin/sh
set -eecho "执行 dockerContext.sh 脚本..."# 示例操作:生成 Docker 镜像标签
TIMESTAMP=$(date +%Y%m%d%H%M%S)
echo "生成的时间戳标签:$TIMESTAMP"# 您可以在此处添加更多自定义操作,例如修改配置文件、生成额外文件等。echo "dockerContext.sh 脚本执行完成。"

说明:

  • 功能:此脚本用于执行构建前的自定义操作,例如生成镜像标签、修改配置文件等。
  • 位置:将此脚本放置在项目的 .manifest/ 目录下,即 .manifest/dockerContext.sh

确保脚本具有执行权限:

chmod +x .manifest/dockerContext.sh

步骤 11:应用所有 Tekton 资源

按照以下顺序依次应用所有 Tekton 任务和流水线配置文件:

kubectl apply -f init-maven.yaml
kubectl apply -f init-npm.yaml
kubectl apply -f clone-repo-maven.yaml
kubectl apply -f clone-repo-npm.yaml
kubectl apply -f run-docker-context.yaml
kubectl apply -f build-and-push-kaniko.yaml
kubectl apply -f deploy-to-kubernetes.yaml
kubectl apply -f send-email.yaml
kubectl apply -f maven-pipeline.yaml
kubectl apply -f npm-pipeline.yaml
kubectl apply -f workspace-pvc.yaml
kubectl apply -f kaniko-secret.yaml
kubectl apply -f smtp-secret.yaml
kubectl apply -f tekton-sa.yaml

验证资源创建成功:

kubectl get tasks,pipelines -n cicd
kubectl get pvc -n cicd
kubectl get secrets -n cicd
kubectl get serviceaccounts -n cicd

步骤 12:测试与运行

12.1 手动触发 Maven 流水线

创建并应用 Maven PipelineRun (maven-pipelinerun.yaml):

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:name: maven-pipelinerun-$(date +%s)namespace: cicd
spec:pipelineRef:name: maven-pipelineparams:- name: repo-urlvalue: https://github.com/example/maven-app.git- name: branchvalue: main- name: imagevalue: docker.io/example/maven-app:latest- name: namespacevalue: dev- name: deployment-namevalue: maven-appworkspaces:- name: sourcepersistentVolumeClaim:claimName: workspace-pvcserviceAccountName: tekton-sa

应用 PipelineRun:

kubectl apply -f maven-pipelinerun.yaml
12.2 手动触发 npm 流水线

创建并应用 npm PipelineRun (npm-pipelinerun.yaml):

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:name: npm-pipelinerun-$(date +%s)namespace: cicd
spec:pipelineRef:name: npm-pipelineparams:- name: repo-urlvalue: https://github.com/example/npm-app.git- name: branchvalue: main- name: imagevalue: docker.io/example/npm-app:latest- name: namespacevalue: dev- name: deployment-namevalue: npm-appworkspaces:- name: sourcepersistentVolumeClaim:claimName: workspace-pvcserviceAccountName: tekton-sa

应用 PipelineRun:

kubectl apply -f npm-pipelinerun.yaml

或者,您也可以使用 tkn CLI 触发 Pipeline:

# 触发 Maven 流水线
tkn pipeline start maven-pipeline \-p repo-url=https://github.com/example/maven-app.git \-p branch=main \-p image=docker.io/example/maven-app:latest \-p namespace=dev \-p deployment-name=maven-app \-w name=source,claimName=workspace-pvc \--serviceaccount=tekton-sa# 触发 npm 流水线
tkn pipeline start npm-pipeline \-p repo-url=https://github.com/example/npm-app.git \-p branch=main \-p image=docker.io/example/npm-app:latest \-p namespace=dev \-p deployment-name=npm-app \-w name=source,claimName=workspace-pvc \--serviceaccount=tekton-sa
12.3 监控流水线运行状态
# 查看流水线列表
kubectl get pipelines -n cicd# 查看 PipelineRun 列表
kubectl get pipelineruns -n cicd# 查看特定 PipelineRun 的日志
tkn pipelinerun logs <pipelinerun-name> -f -n cicd

<pipelinerun-name> 替换为实际的 PipelineRun 名称。

步骤 13:验证邮件通知功能

  1. 触发流水线:按照上述步骤 12.1 或 12.2 触发 Maven 或 npm 流水线。
  2. 检查邮件:确认指定的 to-email 收到相应的通知邮件。
  3. 排查问题
    • 如果邮件未收到,请检查:
      • smtp-secret 是否正确配置,确保所有字段都已正确 Base64 编码。
      • SMTP 服务器是否允许通过 API 或外部应用发送邮件(例如,Gmail 可能需要启用“应用专用密码”)。
      • 查看 send-email 任务的日志,确认 curl 命令是否执行成功。

关键 YAML 文件汇总

以下是所有关键 YAML 文件的汇总,供参考:

1. 初始化环境任务

1.1 Maven 初始化任务 (init-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-mavennamespace: cicd
spec:steps:- name: setup-mavenimage: maven:3.8.6-jdk-11script: |#!/bin/shset -eecho "初始化 Maven 环境..."mvn --version# 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖
1.2 npm 初始化任务 (init-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: init-npmnamespace: cicd
spec:steps:- name: setup-npmimage: node:16script: |#!/bin/shset -eecho "初始化 NPM 环境..."node --versionnpm --version# 在此处添加任何 NPM 相关的初始化步骤,例如安装全局包

2. 拉取代码任务

2.1 拉取 Maven 项目代码任务 (clone-repo-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-mavennamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-maven-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 Maven 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-mavenmountPath: /root/.sshvolumes:- name: ssh-credentials-mavensecret:secretName: git-ssh-key-maven
2.2 拉取 npm 项目代码任务 (clone-repo-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: clone-repo-npmnamespace: cicd
spec:params:- name: repo-urldescription: Git 仓库地址type: string- name: revisiondescription: Git 分支或标签type: stringworkspaces:- name: sourcedescription: 存放拉取代码的工作空间steps:- name: clone-npm-repoimage: alpine/gitscript: |#!/bin/shset -eecho "从 $(params.repo-url) 克隆 npm 仓库..."git clone $(params.repo-url) $(workspaces.source.path)cd $(workspaces.source.path)git checkout $(params.revision)volumeMounts:- name: ssh-credentials-npmmountPath: /root/.sshvolumes:- name: ssh-credentials-npmsecret:secretName: git-ssh-key-npm

3. 运行 dockerContext.sh 任务 (run-docker-context.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: run-docker-contextnamespace: cicd
spec:workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: run-scriptimage: bash:latestscript: |#!/bin/shset -ecd $(workspaces.source.path)if [ -f .manifest/dockerContext.sh ]; thenecho "运行 dockerContext.sh 脚本..."chmod +x .manifest/dockerContext.sh./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."elseecho "未找到 dockerContext.sh 脚本,跳过..."fi

4. 构建并推送镜像任务(使用 Kaniko) (build-and-push-kaniko.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: build-and-push-kanikonamespace: cicd
spec:params:- name: imagedescription: Docker 镜像名称type: string- name: dockerfiledescription: Dockerfile 的路径default: ./Dockerfiletype: string- name: contextdescription: 构建上下文路径default: .type: stringworkspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间steps:- name: kanikoimage: gcr.io/kaniko-project/executor:latestcommand:- /kaniko/executorargs:- "--context=$(workspaces.source.path)/$(params.context)"- "--dockerfile=$(workspaces.source.path)/$(params.dockerfile)"- "--destination=$(params.image)"- "--oci-layout-path=/kaniko/oci"- "--cache=true"- "--cache-repo=$(params.image)"env:- name: DOCKER_CONFIGvalue: /kaniko/.docker/volumeMounts:- name: kaniko-secretmountPath: /kaniko/.docker/volumes:- name: kaniko-secretsecret:secretName: kaniko-secret

5. 部署到 Kubernetes 任务 (deploy-to-kubernetes.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: deploy-to-kubernetesnamespace: cicd
spec:params:- name: namespacedescription: Kubernetes 命名空间type: string- name: deployment-namedescription: Kubernetes Deployment 名称type: string- name: imagedescription: 要部署的镜像type: stringsteps:- name: deployimage: bitnami/kubectlscript: |#!/bin/shset -eecho "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)- name: set-statusimage: alpinescript: |#!/bin/shecho "succeeded" > /tekton/results/statusresults:- name: statusdescription: 部署状态

6. 发送邮件通知任务 (send-email.yaml)

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:name: send-emailnamespace: cicd
spec:params:- name: subjecttype: stringdescription: 邮件主题- name: bodytype: stringdescription: 邮件正文steps:- name: send-emailimage: curlimages/curl:7.83.1script: |#!/bin/shset -eSMTP_SERVER=$(cat /var/secrets/smtp/smtp-server)SMTP_PORT=$(cat /var/secrets/smtp/smtp-port)SMTP_USERNAME=$(cat /var/secrets/smtp/smtp-username)SMTP_PASSWORD=$(cat /var/secrets/smtp/smtp-password)FROM_EMAIL=$(cat /var/secrets/smtp/from-email)TO_EMAIL=$(cat /var/secrets/smtp/to-email)SUBJECT="$(params.subject)"BODY="$(params.body)"echo "正在通过 $SMTP_SERVER:$SMTP_PORT 发送邮件到 $TO_EMAIL..."echo -e "Subject: $SUBJECT\n\n$BODY" | \curl --url "smtp://$SMTP_SERVER:$SMTP_PORT" \--ssl-reqd \--mail-from "$FROM_EMAIL" \--mail-rcpt "$TO_EMAIL" \--user "$SMTP_USERNAME:$SMTP_PASSWORD" \-T -volumes:- name: smtp-secretssecret:secretName: smtp-secret

应用任务:

kubectl apply -f send-email.yaml

7. Tekton Pipelines

7.1 Maven 流水线 (maven-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: maven-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-maventaskRef:name: init-mavenrunAfter: []- name: clone-reporunAfter:- init-maventaskRef:name: clone-repo-mavenparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **Maven 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source
7.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:name: npm-pipelinenamespace: cicd
spec:params:- name: repo-urltype: stringdescription: Git 仓库地址- name: branchtype: stringdescription: Git 分支名称- name: imagetype: stringdescription: Docker 镜像名称- name: namespacetype: stringdescription: Kubernetes 命名空间- name: deployment-nametype: stringdescription: Kubernetes Deployment 名称workspaces:- name: sourcedescription: 存放代码和构建上下文的工作空间tasks:- name: init-npmtaskRef:name: init-npmrunAfter: []- name: clone-reporunAfter:- init-npmtaskRef:name: clone-repo-npmparams:- name: repo-urlvalue: $(params.repo-url)- name: revisionvalue: $(params.branch)workspaces:- name: sourceworkspace: source- name: run-docker-contextrunAfter:- clone-repotaskRef:name: run-docker-contextworkspaces:- name: sourceworkspace: source- name: build-and-pushrunAfter:- run-docker-contexttaskRef:name: build-and-push-kanikoparams:- name: imagevalue: $(params.image)- name: dockerfilevalue: ./Dockerfile- name: contextvalue: .workspaces:- name: sourceworkspace: source- name: deployrunAfter:- build-and-pushtaskRef:name: deploy-to-kubernetesparams:- name: namespacevalue: $(params.namespace)- name: deployment-namevalue: $(params.deployment-name)- name: imagevalue: $(params.image)finally:- name: notifytaskRef:name: send-emailparams:- name: subjectvalue: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"- name: bodyvalue: |流水线 **NPM 流水线** 已完成。- **仓库**: $(params.repo-url)- **分支**: $(params.branch)- **镜像**: $(params.image)- **命名空间**: $(params.namespace)- **部署名称**: $(params.deployment-name)**状态**: $(tasks.deploy.results.status)workspaces:- name: sourceworkspace: source

说明:

  • Maven 和 npm 流水线结构类似,但各自引用不同的初始化和代码拉取任务。
  • finally 部分确保无论前面的任务成功还是失败,都会执行 send-email 任务发送通知。

应用流水线:

kubectl apply -f maven-pipeline.yaml
kubectl apply -f npm-pipeline.yaml

步骤 14:优化与容错

  1. 容错机制
    • run-docker-context 任务中已包含对 dockerContext.sh 脚本不存在或执行失败的处理,确保流水线不会因该脚本的问题中断。
  2. 重试策略
    • 根据需要在 Pipeline 或 Task 中配置重试策略,以应对临时性错误。
    • 示例:在任务定义中添加 retries 字段。
      spec:retries: 3
      
  3. 资源限制
    • 为每个 Task 设置资源请求和限制,避免资源争用。
      resources:requests:memory: "512Mi"cpu: "500m"limits:memory: "1Gi"cpu: "1"
      
  4. 日志存储与监控
    • 集成日志收集和监控工具(如 Elasticsearch、Prometheus 和 Grafana),实时监控流水线的执行状态和性能,及时发现并解决问题。

常见问题排查

1. 邮件未发送

  • 检查 SMTP Secret 配置

    • 确保 smtp-secret 中的所有字段(smtp-serversmtp-portsmtp-usernamesmtp-passwordfrom-emailto-email)已正确 Base64 编码并填入 smtp-secret.yaml 中。
  • 验证 SMTP 服务器设置

    • 确保 SMTP 服务器地址和端口正确。
    • 确认 SMTP 服务器允许通过 API 或外部应用发送邮件。
    • 对于 Gmail,可能需要启用“应用专用密码”或调整安全设置。
  • 查看 send-email 任务日志

    • 使用以下命令查看发送邮件任务的详细日志,确认 curl 命令是否执行成功。
    tkn pipelinerun logs <pipelinerun-name> -f -n cicd
    

    <pipelinerun-name> 替换为实际的 PipelineRun 名称。

2. 权限不足

  • 检查 ServiceAccount 权限

    • 确保 tekton-sa ServiceAccount 具有足够的权限访问 Kubernetes API 和相关资源。
  • 验证 RoleBinding 配置

    • 确保 RoleBinding 正确,将 tekton-sa 绑定到适当的 ClusterRole(例如 edit)。
  • 查看 RoleBinding

    kubectl get rolebinding -n cicd
    

3. 持久化存储问题

  • 验证 PVC 状态

    • 确保 workspace-pvc 已正确创建并处于绑定状态。
    kubectl get pvc workspace-pvc -n cicd
    
  • 确认有可用的 PersistentVolume

    • 确保集群中有可用的 PersistentVolume 提供所需的存储。

4. 任务失败

  • 查看失败任务的详细日志

    tkn pipelinerun logs <pipelinerun-name> -f -n cicd
    

    <pipelinerun-name> 替换为实际的 PipelineRun 名称。

  • 根据错误信息调整任务脚本或配置

    • 例如,如果 Maven 任务失败,检查 pom.xml 是否正确,依赖是否可用。

相关文章:

kubenetes流水线实施清单

整体实施方案概述 创建命名空间&#xff08;Namespace&#xff09;&#xff1a;创建一个专用于 CI/CD 的命名空间 cicd。配置 Secrets&#xff1a; Git SSH 密钥&#xff08;分别为 Maven 和 npm 项目&#xff09;Docker Registry 凭证&#xff08;Kaniko&#xff09;SMTP 凭证…...

Redis4——持久化与集群

Redis4——持久化与集群 本文讲述了1.redis在内存占用达到限制后的key值淘汰策略&#xff1b;2.redis主从复制原理&#xff1b;3.redis的哨兵模式&#xff1b;4.redis集群模式。 1. 淘汰策略 设置过期时间 expire key <timeout>只能对主hash表中的键设置过期时间。 查…...

【LeetCode: 94. 二叉树的中序遍历 + 栈】

&#x1f680; 算法题 &#x1f680; &#x1f332; 算法刷题专栏 | 面试必备算法 | 面试高频算法 &#x1f340; &#x1f332; 越难的东西,越要努力坚持&#xff0c;因为它具有很高的价值&#xff0c;算法就是这样✨ &#x1f332; 作者简介&#xff1a;硕风和炜&#xff0c;…...

Python系列 - MQTT协议

Python系列 - MQTT协议 资源连接 MQTT的介绍和应用场景的示例说明 一、什么是MQTT 百度关于MQTT的介绍如下&#xff1a; MQTT(消息队列遥测传输)是ISO 标准(ISO/IEC PRF 20922)下基于发布订阅范式的消息协议。它工作在 TCP/IP协议之上&#xff0c;是为硬件性能低下的远程设…...

同时在github和gitee配置密钥

同时在github和gitee配置密钥 1. 生成不同的 SSH 密钥 为每个平台生成单独的 SSH 密钥。 # 为 GitHub 生成密钥&#xff08;默认文件路径为 ~/.ssh/github_id_rsa&#xff09; ssh-keygen -t rsa -b 4096 -C "your_github_emailexample.com" -f ~/.ssh/github_id_…...

Runway 技术浅析(六):文本到视频(Text-to-Video)

1. 核心组件与工作原理 1.1 自然语言处理&#xff08;NLP&#xff09; 1.1.1 文本解析与语义理解 文本到视频的第一步是将用户输入的自然语言文本解析为机器可理解的语义信息。Runway 使用预训练的 NLP 模型&#xff0c;如 GPT-3 和 BERT&#xff0c;这些模型通过大规模文本数…...

云计算vspere 安装过程

1 材料的准备 1 安装虚拟机 vmware workstation 2 安装esxi 主机 3 在esxi 主机上安装windows 2018 dns 服务器 4 在虚拟机上安装windows 2018 服务器 6 安装vcenter 5 登入界面测试 这里讲一下&#xff0c;由于部署vspere 需要在windows 2012 服务器上部…...

QT 实现QStackedWidget切换页面右移动画

1.实现效果 以下是一个QStackedWidget,放了两个QPushButton在上面,点击切换不同的界面。 为了方便查看动画特效,设置了每个界面的背景图片。 2.实现思路 首先截取当前界面的图片,渲染到一个QLabel上,然后设置QPropertyAnimation动画,动画的作用对象就是这个QLabel,不断…...

Android Camera2采集并编码为H.264

前言 本篇博文主要讲述的是基于Android原生MediaCodec通过Camera2 API进行图像数据采集并编码为H.264的实现过程&#xff0c;如果对此感兴趣的不妨驻足观看&#xff0c;也欢迎大家大家对本文中描述不当或者不正确的地方进行指正。如果对于Camera2预览还不熟悉的可以观看博主上…...

DHCP和DNS

DHCP&#xff08;动态主机配置协议&#xff09;和DNS&#xff08;域名系统&#xff09;是计算机网络中两个重要的协议&#xff0c;它们在网络的管理和使用中发挥着关键作用。 DHCP&#xff08;动态主机配置协议&#xff09; 基本功能 自动分配IP地址&#xff1a;DHCP允许网…...

ONES 功能上新|ONES Project 甘特图再度升级

ONES Project 甘特图支持展示工作项标题、进度百分比、依赖关系延迟时间等信息。 应用场景&#xff1a; 在使用甘特图规划项目任务、编排项目计划时&#xff0c;可以对甘特图区域进行配置&#xff0c;展示工作项的工作项标题、进度百分比以及依赖关系延迟时间等维度&#xff0c…...

<工具 Claude Desktop> 配置 MCP server 连接本地 SQLite, 本机文件夹(目录) 网络驱动器 Windows 11 系统

也是在学习中... 起因&#xff1a; 抖音博客 艾克AI分享 他的视频 #143《Claude开源MCP彻底打破AI的信息孤岛》 提到: Claude开源的MCP太强了&#xff0c;视频后面是快速演示&#xff0c;反正看了好几遍也没弄明白。菜单都不一样&#xff0c;感觉用的不是同一家 Claude. 探…...

GIT的使用方法以及汉化方法

1.下载git软件&#xff0c;可以从官网下载 下载后默认安装即可。 2.找到一个文件夹&#xff0c;或者直接打开gitbash gitbash可以使用cd指令切换目录的 打开后输入 git clone https:[git仓库的网页]即可克隆仓库 就是这个地址 克隆后即可使用代码 如果忘记了命令可以使用 -…...

公因子的数目

给你两个正整数 a 和 b &#xff0c;返回 a 和 b 的 公 因子的数目。 如果 x 可以同时整除 a 和 b &#xff0c;则认为 x 是 a 和 b 的一个 公因子 。 输入&#xff1a;a 12, b 6 输出&#xff1a;4 解释&#xff1a;12 和 6 的公因子是 1、2、3、6 。 class Solution {pu…...

数据结构(三)——双向链表的介绍以及实现

前言 前面两期数据结构的文章我们介绍了顺序表和单向链表&#xff0c;那么本篇博文我们将来了解双向链表&#xff0c;作为最好用的一种链表&#xff0c;双向链表有什么特殊之处呢&#xff0c;接下来就让我们一起了解一下吧。 下面是前两篇数据结构的文章&#xff1a; 数据结…...

Webpack开发模式及处理样式资源

一、开发模式介绍 开发模式顾名思义就是我们开发代码时使用的模式。 这个模式下我们主要做两件事&#xff1a; 编译代码&#xff0c;使浏览器能识别运行 开发时我们有样式资源、字体图标、图片资源、html 资源等&#xff0c;webpack 默认都不能处理这些资源&#xff0c;所以我…...

leetcode--设计链表

707.设计链表 你可以选择使用单链表或者双链表&#xff0c;设计并实现自己的链表。 单链表中的节点应该具备两个属性&#xff1a;val 和 next 。val 是当前节点的值&#xff0c;next 是指向下一个节点的指针/引用。 如果是双向链表&#xff0c;则还需要属性 prev 以指示链表中的…...

【MySQL】:数据库操作

MySQL 数据库基础理论 2.1 数据库系统概述 介绍数据库系统的基本概念、发展历程、分类及 MySQL 在其中的地位与特点。 2.2 MySQL 数据库体系结构 解析 MySQL 的整体架构&#xff0c;包括服务器层与存储引擎层的功能与交互机制&#xff0c;重点探讨 InnoDB、MyISAM 等存…...

刷蓝桥杯历年考题(更新至15届~)

第十五届 CA组省赛 AcWing5980.训练士兵 方法一&#xff1a;树状数组:O(nlogn) self-complete /*先枚举组团&#xff0c;后分析每个士兵&#xff0c;有一个特点&#xff0c;组团费用是固定的&#xff0c;那当然是让所有士兵一块训练&#xff0c;训练完的士兵也不会有损失当还…...

AI与BI的火花:大语言模型如何重塑商业智能的未来

大家好&#xff0c;我是独孤风。 在当今这个数据驱动的时代&#xff0c;企业对于信息的需求如同对于氧气的需求一般至关重要。商业智能&#xff08;BI&#xff09;作为企业获取、分析和呈现数据的关键工具&#xff0c;正在经历一场深刻的变革&#xff0c;而这一变革的催化剂正是…...

Qt 详解QtNFC 读写模式

文章目录 Qt NFC 读写模式详解1. NFC 读写模式简介1.1 什么是 NFC 读写模式&#xff1f;主要功能&#xff1a; 1.2 常见应用场景 2. Qt NFC 读写模式原理3. 配置 QtNFC 模块4. NFC 读写操作实现4.1 NFC 标签读取代码示例功能解析 4.2 NFC 标签写入代码示例功能解析 5. 使用注意…...

增删改查文档

列表 : 列表包含 : 模糊查找 分页 列表jsp页面 : 一 :导入外部文件 (举例 : 用户点进来就可以看到菜单,这是预加载属于,使用文档就绪函数实现) 二 : body 上 ① : 文档就绪函数 ${ function() //获取条件查询的字段 //组装对象 //调用文档就绪函数 } ② : 封装ajax方…...

C语言蓝桥杯2023年省赛真题

文章目录 持续更新中...第一题题目描述输入格式输出格式样例输出提示 2 第二题题目描述 第三题题目描述输入格式输出格式样例输入样例输出 第四题题目描述输入格式输出格式样例输入样例输出提示 第四题题目描述输入格式输出格式样例输入样例输出提示 第五题题目描述输入格式输出…...

Python迭代器-大数据量的处理

一 生成器的实际使用&#xff08;大量数据的导出&#xff09; #分批导出数据然后分批写入excel import pandas as pd import openpyxl from openpyxl.utils.dataframe import dataframe_to_rowsdef execute_query(query):# 假设这是执行 SQL 查询的函数# 返回查询结果passdef …...

自动化包括态交互与感交互,而智能化包括势交互与知交互

“自动化包括态交互与感交互&#xff0c;而智能化包括势交互与知交互”交互框架将交互过程划分为不同类型&#xff0c;有助于更清晰地理解自动化和智能化的本质及其在未来agent应用中的差异与联系。 1. 自动化&#xff1a;态交互与感交互 自动化主要关注的是高效、无差错地执行…...

VideoBooth: Diffusion-based Video Generation with Image Prompts

VideoBooth: Diffusion-based Video Generation with Image Prompts 概括 文章提出了一个视频生成模型VideoBooth&#xff0c;输入一张图片和一个文本提示词&#xff0c;即可输出保持图片中物体且符合文本提示词要求的视频。 方法 粗-细两阶段设计&#xff1a;1&#xff09;…...

模拟简单的iOT工作流

没有实际接触过iOT的流程&#xff0c;应该实际使用比这个接口返回要复杂&#xff0c;只是演示~希望能参与实际的接口接入&#xff0c;而不是只展示个假数据。 启动RabbitQ 使用的是3.8.5 启动命令 RabbitMQ Service - start RabbitMQ Command Prompt rabbitmqctl start_app …...

C++学习0.2: RAII

引用&#xff1a; 【代码质量】RAII在C编程中的必要性_raii 在c中的重要性-CSDN博客 C RAII典型应用之lock_guard和unique_lock模板_raii lock-CSDN博客 前言: 常用的线程间同步/通信&#xff08;IPC&#xff09;方式有锁&#xff08;互斥锁、读写锁、自旋锁&#xff09;、…...

k8s,进一步理解Pod

比如&#xff0c;凡是调度、网络、存储&#xff0c;以及安全相关的属性&#xff0c;基本上是Pod 级别的。 这些属性的共同特征是&#xff0c;它们描述的是“机器”这个整体&#xff0c;而不是里面运行的“程序”。比如&#xff0c;配置这个“机器”的网卡&#xff08;即&#…...

MFC图形函数学习13——在图形界面输出文字

本篇是图形函数学习的最后一篇&#xff0c;相关内容暂告一段落。 在图形界面输出文字&#xff0c;涉及文字字体、大小、颜色、背景、显示等问题&#xff0c;完成这些需要系列函数的支持。下面做简要介绍。 一、输出文本函数 原型&#xff1a;virtual BOOL te…...