当前位置: 首页 > 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;而这一变革的催化剂正是…...

使用docker在3台服务器上搭建基于redis 6.x的一主两从三台均是哨兵模式

一、环境及版本说明 如果服务器已经安装了docker,则忽略此步骤,如果没有安装,则可以按照一下方式安装: 1. 在线安装(有互联网环境): 请看我这篇文章 传送阵>> 点我查看 2. 离线安装(内网环境):请看我这篇文章 传送阵>> 点我查看 说明&#xff1a;假设每台服务器已…...

未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?

编辑&#xff1a;陈萍萍的公主一点人工一点智能 未来机器人的大脑&#xff1a;如何用神经网络模拟器实现更智能的决策&#xff1f;RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战&#xff0c;在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...

[2025CVPR]DeepVideo-R1:基于难度感知回归GRPO的视频强化微调框架详解

突破视频大语言模型推理瓶颈,在多个视频基准上实现SOTA性能 一、核心问题与创新亮点 1.1 GRPO在视频任务中的两大挑战 ​安全措施依赖问题​ GRPO使用min和clip函数限制策略更新幅度,导致: 梯度抑制:当新旧策略差异过大时梯度消失收敛困难:策略无法充分优化# 传统GRPO的梯…...

【C++从零实现Json-Rpc框架】第六弹 —— 服务端模块划分

一、项目背景回顾 前五弹完成了Json-Rpc协议解析、请求处理、客户端调用等基础模块搭建。 本弹重点聚焦于服务端的模块划分与架构设计&#xff0c;提升代码结构的可维护性与扩展性。 二、服务端模块设计目标 高内聚低耦合&#xff1a;各模块职责清晰&#xff0c;便于独立开发…...

【HarmonyOS 5 开发速记】如何获取用户信息(头像/昵称/手机号)

1.获取 authorizationCode&#xff1a; 2.利用 authorizationCode 获取 accessToken&#xff1a;文档中心 3.获取手机&#xff1a;文档中心 4.获取昵称头像&#xff1a;文档中心 首先创建 request 若要获取手机号&#xff0c;scope必填 phone&#xff0c;permissions 必填 …...

Springboot社区养老保险系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;社区养老保险系统小程序被用户普遍使用&#xff0c;为方…...

使用Matplotlib创建炫酷的3D散点图:数据可视化的新维度

文章目录 基础实现代码代码解析进阶技巧1. 自定义点的大小和颜色2. 添加图例和样式美化3. 真实数据应用示例实用技巧与注意事项完整示例(带样式)应用场景在数据科学和可视化领域,三维图形能为我们提供更丰富的数据洞察。本文将手把手教你如何使用Python的Matplotlib库创建引…...

Python基于历史模拟方法实现投资组合风险管理的VaR与ES模型项目实战

说明&#xff1a;这是一个机器学习实战项目&#xff08;附带数据代码文档&#xff09;&#xff0c;如需数据代码文档可以直接到文章最后关注获取。 1.项目背景 在金融市场日益复杂和波动加剧的背景下&#xff0c;风险管理成为金融机构和个人投资者关注的核心议题之一。VaR&…...

从 GreenPlum 到镜舟数据库:杭银消费金融湖仓一体转型实践

作者&#xff1a;吴岐诗&#xff0c;杭银消费金融大数据应用开发工程师 本文整理自杭银消费金融大数据应用开发工程师在StarRocks Summit Asia 2024的分享 引言&#xff1a;融合数据湖与数仓的创新之路 在数字金融时代&#xff0c;数据已成为金融机构的核心竞争力。杭银消费金…...

MySQL的pymysql操作

本章是MySQL的最后一章&#xff0c;MySQL到此完结&#xff0c;下一站Hadoop&#xff01;&#xff01;&#xff01; 这章很简单&#xff0c;完整代码在最后&#xff0c;详细讲解之前python课程里面也有&#xff0c;感兴趣的可以往前找一下 一、查询操作 我们需要打开pycharm …...