kubenetes流水线实施清单

news2024/12/26 17:54:00

整体实施方案概述

  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-maven
  namespace: 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-npm
  namespace: 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-secret
  namespace: 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-secret
  namespace: 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-secret
  namespace: cicd
type: Opaque
data:
  smtp-server: c210cC5nbWFpbC5jb20= # smtp.gmail.com
  smtp-port: NTg3 # 587
  smtp-username: dXNlckBnbWFpbC5jb20= # user@gmail.com
  smtp-password: cGFzc3dvcmQxMjM= # password123
  from-email: dXNlckBnbWFpbC5jb20= # user@gmail.com
  to-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-pvc
  namespace: cicd
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    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-sa
  namespace: 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-maven
  namespace: cicd
spec:
  steps:
    - name: setup-maven
      image: maven:3.8.6-jdk-11
      script: |
        #!/bin/sh
        set -e
        echo "初始化 Maven 环境..."
        mvn --version
        # 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: init-npm
  namespace: cicd
spec:
  steps:
    - name: setup-npm
      image: node:16
      script: |
        #!/bin/sh
        set -e
        echo "初始化 NPM 环境..."
        node --version
        npm --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-maven
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-maven-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 Maven 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-maven
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-maven
      secret:
        secretName: git-ssh-key-maven

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: clone-repo-npm
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-npm-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 npm 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-npm
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-npm
      secret:
        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-context
  namespace: cicd
spec:
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: run-script
      image: bash:latest
      script: |
        #!/bin/sh
        set -e
        cd $(workspaces.source.path)
        if [ -f .manifest/dockerContext.sh ]; then
          echo "运行 dockerContext.sh 脚本..."
          chmod +x .manifest/dockerContext.sh
          ./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."
        else
          echo "未找到 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-kaniko
  namespace: cicd
spec:
  params:
    - name: image
      description: Docker 镜像名称
      type: string
    - name: dockerfile
      description: Dockerfile 的路径
      default: ./Dockerfile
      type: string
    - name: context
      description: 构建上下文路径
      default: .
      type: string
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: kaniko
      image: gcr.io/kaniko-project/executor:latest
      command:
        - /kaniko/executor
      args:
        - "--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_CONFIG
          value: /kaniko/.docker/
      volumeMounts:
        - name: kaniko-secret
          mountPath: /kaniko/.docker/
  volumes:
    - name: kaniko-secret
      secret:
        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-kubernetes
  namespace: cicd
spec:
  params:
    - name: namespace
      description: Kubernetes 命名空间
      type: string
    - name: deployment-name
      description: Kubernetes Deployment 名称
      type: string
    - name: image
      description: 要部署的镜像
      type: string
  steps:
    - name: deploy
      image: bitnami/kubectl
      script: |
        #!/bin/sh
        set -e
        echo "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."
        kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)
    - name: set-status
      image: alpine
      script: |
        #!/bin/sh
        echo "succeeded" > /tekton/results/status
  results:
    - name: status
      description: 部署状态

应用任务:

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

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: send-email
  namespace: cicd
spec:
  params:
    - name: subject
      type: string
      description: 邮件主题
    - name: body
      type: string
      description: 邮件正文
  steps:
    - name: send-email
      image: curlimages/curl:7.83.1
      script: |
        #!/bin/sh
        set -e

        SMTP_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-secrets
      secret:
        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-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-maven
      taskRef:
        name: init-maven
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-maven
      taskRef:
        name: clone-repo-maven
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **Maven 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
      workspaces:
        - name: source
          workspace: source
8.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: npm-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-npm
      taskRef:
        name: init-npm
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-npm
      taskRef:
        name: clone-repo-npm
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **NPM 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
      workspaces:
        - name: source
          workspace: 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 -e

echo "执行 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-pipeline
  params:
    - name: repo-url
      value: https://github.com/example/maven-app.git
    - name: branch
      value: main
    - name: image
      value: docker.io/example/maven-app:latest
    - name: namespace
      value: dev
    - name: deployment-name
      value: maven-app
  workspaces:
    - name: source
      persistentVolumeClaim:
        claimName: workspace-pvc
  serviceAccountName: 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-pipeline
  params:
    - name: repo-url
      value: https://github.com/example/npm-app.git
    - name: branch
      value: main
    - name: image
      value: docker.io/example/npm-app:latest
    - name: namespace
      value: dev
    - name: deployment-name
      value: npm-app
  workspaces:
    - name: source
      persistentVolumeClaim:
        claimName: workspace-pvc
  serviceAccountName: 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-maven
  namespace: cicd
spec:
  steps:
    - name: setup-maven
      image: maven:3.8.6-jdk-11
      script: |
        #!/bin/sh
        set -e
        echo "初始化 Maven 环境..."
        mvn --version
        # 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖
1.2 npm 初始化任务 (init-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: init-npm
  namespace: cicd
spec:
  steps:
    - name: setup-npm
      image: node:16
      script: |
        #!/bin/sh
        set -e
        echo "初始化 NPM 环境..."
        node --version
        npm --version
        # 在此处添加任何 NPM 相关的初始化步骤,例如安装全局包

2. 拉取代码任务

2.1 拉取 Maven 项目代码任务 (clone-repo-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: clone-repo-maven
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-maven-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 Maven 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-maven
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-maven
      secret:
        secretName: git-ssh-key-maven
2.2 拉取 npm 项目代码任务 (clone-repo-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: clone-repo-npm
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-npm-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 npm 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-npm
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-npm
      secret:
        secretName: git-ssh-key-npm

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: run-docker-context
  namespace: cicd
spec:
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: run-script
      image: bash:latest
      script: |
        #!/bin/sh
        set -e
        cd $(workspaces.source.path)
        if [ -f .manifest/dockerContext.sh ]; then
          echo "运行 dockerContext.sh 脚本..."
          chmod +x .manifest/dockerContext.sh
          ./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."
        else
          echo "未找到 dockerContext.sh 脚本,跳过..."
        fi

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push-kaniko
  namespace: cicd
spec:
  params:
    - name: image
      description: Docker 镜像名称
      type: string
    - name: dockerfile
      description: Dockerfile 的路径
      default: ./Dockerfile
      type: string
    - name: context
      description: 构建上下文路径
      default: .
      type: string
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: kaniko
      image: gcr.io/kaniko-project/executor:latest
      command:
        - /kaniko/executor
      args:
        - "--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_CONFIG
          value: /kaniko/.docker/
      volumeMounts:
        - name: kaniko-secret
          mountPath: /kaniko/.docker/
  volumes:
    - name: kaniko-secret
      secret:
        secretName: kaniko-secret

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: deploy-to-kubernetes
  namespace: cicd
spec:
  params:
    - name: namespace
      description: Kubernetes 命名空间
      type: string
    - name: deployment-name
      description: Kubernetes Deployment 名称
      type: string
    - name: image
      description: 要部署的镜像
      type: string
  steps:
    - name: deploy
      image: bitnami/kubectl
      script: |
        #!/bin/sh
        set -e
        echo "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."
        kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)
    - name: set-status
      image: alpine
      script: |
        #!/bin/sh
        echo "succeeded" > /tekton/results/status
  results:
    - name: status
      description: 部署状态

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

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: send-email
  namespace: cicd
spec:
  params:
    - name: subject
      type: string
      description: 邮件主题
    - name: body
      type: string
      description: 邮件正文
  steps:
    - name: send-email
      image: curlimages/curl:7.83.1
      script: |
        #!/bin/sh
        set -e

        SMTP_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-secrets
      secret:
        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-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-maven
      taskRef:
        name: init-maven
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-maven
      taskRef:
        name: clone-repo-maven
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **Maven 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
  workspaces:
    - name: source
      workspace: source
7.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: npm-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-npm
      taskRef:
        name: init-npm
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-npm
      taskRef:
        name: clone-repo-npm
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **NPM 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
  workspaces:
    - name: source
      workspace: 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 -e

echo "执行 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-pipeline
  params:
    - name: repo-url
      value: https://github.com/example/maven-app.git
    - name: branch
      value: main
    - name: image
      value: docker.io/example/maven-app:latest
    - name: namespace
      value: dev
    - name: deployment-name
      value: maven-app
  workspaces:
    - name: source
      persistentVolumeClaim:
        claimName: workspace-pvc
  serviceAccountName: 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-pipeline
  params:
    - name: repo-url
      value: https://github.com/example/npm-app.git
    - name: branch
      value: main
    - name: image
      value: docker.io/example/npm-app:latest
    - name: namespace
      value: dev
    - name: deployment-name
      value: npm-app
  workspaces:
    - name: source
      persistentVolumeClaim:
        claimName: workspace-pvc
  serviceAccountName: 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-maven
  namespace: cicd
spec:
  steps:
    - name: setup-maven
      image: maven:3.8.6-jdk-11
      script: |
        #!/bin/sh
        set -e
        echo "初始化 Maven 环境..."
        mvn --version
        # 在此处添加任何 Maven 相关的初始化步骤,例如下载依赖
1.2 npm 初始化任务 (init-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: init-npm
  namespace: cicd
spec:
  steps:
    - name: setup-npm
      image: node:16
      script: |
        #!/bin/sh
        set -e
        echo "初始化 NPM 环境..."
        node --version
        npm --version
        # 在此处添加任何 NPM 相关的初始化步骤,例如安装全局包

2. 拉取代码任务

2.1 拉取 Maven 项目代码任务 (clone-repo-maven.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: clone-repo-maven
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-maven-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 Maven 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-maven
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-maven
      secret:
        secretName: git-ssh-key-maven
2.2 拉取 npm 项目代码任务 (clone-repo-npm.yaml)
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: clone-repo-npm
  namespace: cicd
spec:
  params:
    - name: repo-url
      description: Git 仓库地址
      type: string
    - name: revision
      description: Git 分支或标签
      type: string
  workspaces:
    - name: source
      description: 存放拉取代码的工作空间
  steps:
    - name: clone-npm-repo
      image: alpine/git
      script: |
        #!/bin/sh
        set -e
        echo "从 $(params.repo-url) 克隆 npm 仓库..."
        git clone $(params.repo-url) $(workspaces.source.path)
        cd $(workspaces.source.path)
        git checkout $(params.revision)
      volumeMounts:
        - name: ssh-credentials-npm
          mountPath: /root/.ssh
  volumes:
    - name: ssh-credentials-npm
      secret:
        secretName: git-ssh-key-npm

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: run-docker-context
  namespace: cicd
spec:
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: run-script
      image: bash:latest
      script: |
        #!/bin/sh
        set -e
        cd $(workspaces.source.path)
        if [ -f .manifest/dockerContext.sh ]; then
          echo "运行 dockerContext.sh 脚本..."
          chmod +x .manifest/dockerContext.sh
          ./.manifest/dockerContext.sh || echo "dockerContext.sh 执行失败,跳过..."
        else
          echo "未找到 dockerContext.sh 脚本,跳过..."
        fi

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push-kaniko
  namespace: cicd
spec:
  params:
    - name: image
      description: Docker 镜像名称
      type: string
    - name: dockerfile
      description: Dockerfile 的路径
      default: ./Dockerfile
      type: string
    - name: context
      description: 构建上下文路径
      default: .
      type: string
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  steps:
    - name: kaniko
      image: gcr.io/kaniko-project/executor:latest
      command:
        - /kaniko/executor
      args:
        - "--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_CONFIG
          value: /kaniko/.docker/
      volumeMounts:
        - name: kaniko-secret
          mountPath: /kaniko/.docker/
  volumes:
    - name: kaniko-secret
      secret:
        secretName: kaniko-secret

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: deploy-to-kubernetes
  namespace: cicd
spec:
  params:
    - name: namespace
      description: Kubernetes 命名空间
      type: string
    - name: deployment-name
      description: Kubernetes Deployment 名称
      type: string
    - name: image
      description: 要部署的镜像
      type: string
  steps:
    - name: deploy
      image: bitnami/kubectl
      script: |
        #!/bin/sh
        set -e
        echo "将镜像 $(params.image) 部署到命名空间 $(params.namespace)..."
        kubectl set image deployment/$(params.deployment-name) app=$(params.image) -n $(params.namespace)
    - name: set-status
      image: alpine
      script: |
        #!/bin/sh
        echo "succeeded" > /tekton/results/status
  results:
    - name: status
      description: 部署状态

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

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: send-email
  namespace: cicd
spec:
  params:
    - name: subject
      type: string
      description: 邮件主题
    - name: body
      type: string
      description: 邮件正文
  steps:
    - name: send-email
      image: curlimages/curl:7.83.1
      script: |
        #!/bin/sh
        set -e

        SMTP_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-secrets
      secret:
        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-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-maven
      taskRef:
        name: init-maven
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-maven
      taskRef:
        name: clone-repo-maven
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "Maven 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **Maven 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
  workspaces:
    - name: source
      workspace: source
7.2 npm 流水线 (npm-pipeline.yaml)
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: npm-pipeline
  namespace: cicd
spec:
  params:
    - name: repo-url
      type: string
      description: Git 仓库地址
    - name: branch
      type: string
      description: Git 分支名称
    - name: image
      type: string
      description: Docker 镜像名称
    - name: namespace
      type: string
      description: Kubernetes 命名空间
    - name: deployment-name
      type: string
      description: Kubernetes Deployment 名称
  workspaces:
    - name: source
      description: 存放代码和构建上下文的工作空间
  tasks:
    - name: init-npm
      taskRef:
        name: init-npm
      runAfter: []
    - name: clone-repo
      runAfter:
        - init-npm
      taskRef:
        name: clone-repo-npm
      params:
        - name: repo-url
          value: $(params.repo-url)
        - name: revision
          value: $(params.branch)
      workspaces:
        - name: source
          workspace: source
    - name: run-docker-context
      runAfter:
        - clone-repo
      taskRef:
        name: run-docker-context
      workspaces:
        - name: source
          workspace: source
    - name: build-and-push
      runAfter:
        - run-docker-context
      taskRef:
        name: build-and-push-kaniko
      params:
        - name: image
          value: $(params.image)
        - name: dockerfile
          value: ./Dockerfile
        - name: context
          value: .
      workspaces:
        - name: source
          workspace: source
    - name: deploy
      runAfter:
        - build-and-push
      taskRef:
        name: deploy-to-kubernetes
      params:
        - name: namespace
          value: $(params.namespace)
        - name: deployment-name
          value: $(params.deployment-name)
        - name: image
          value: $(params.image)
  finally:
    - name: notify
      taskRef:
        name: send-email
      params:
        - name: subject
          value: "NPM 流水线 $(params.deployment-name) - $(tasks.deploy.results.status)"
        - name: body
          value: |
            流水线 **NPM 流水线** 已完成。
            
            - **仓库**: $(params.repo-url)
            - **分支**: $(params.branch)
            - **镜像**: $(params.image)
            - **命名空间**: $(params.namespace)
            - **部署名称**: $(params.deployment-name)
            
            **状态**: $(tasks.deploy.results.status)
  workspaces:
    - name: source
      workspace: 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 是否正确,依赖是否可用。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2254081.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Kubernetes架构原则和对象设计

云原生学习路线导航页&#xff08;持续更新中&#xff09; 快捷链接 Kubernetes常见问题解答 本文从 Google Borg系统的架构设计开始&#xff0c;深入讲解Kubernetes架构及组件的基本原理 1.什么是云计算 1.1.传统行业应用 假设有10台服务器&#xff0c;两个应用。小规模管…

力扣-图论-1【算法学习day.51】

前言 ###我做这类文章一个重要的目的还是给正在学习的大家提供方向和记录学习过程&#xff08;例如想要掌握基础用法&#xff0c;该刷哪些题&#xff1f;&#xff09;我的解析也不会做的非常详细&#xff0c;只会提供思路和一些关键点&#xff0c;力扣上的大佬们的题解质量是非…

学习笔记056——Docker日志的清理问题

文章目录 Docker日志的清理问题1、Docke日志所在位置2、日志清理 Docker日志的清理问题 Ubuntu上部署Docker&#xff0c;运行一段时间后&#xff0c;会累计很多的日志量。 如果不及时处理&#xff0c;会占用系统空间&#xff0c;影响系统性能。 如何处理日志累计过大的问题&…

Python3:Pytest框架parametrize报错in “parametrize“ the number of names (4)

Python3&#xff1a;Pytest框架parametrize报错in “parametrize“ the number of names (4) 排查原因&#xff1a;是pytest入参时&#xff0c;需要4个参数&#xff0c;但是提供了3个参数 test_tenant_list:- ["http://xx:8081/scheduler/v1/tenancy/list",{"co…

Linux 35.6 + JetPack v5.1.4之RTP实时视频Python框架

Linux 35.6 JetPack v5.1.4之RTP实时视频Python框架 1. 源由2. 思路3. 方法论3.1 扩展思考 - 慎谋而后定3.2 扩展思考 - 拒绝拖延或犹豫3.3 扩展思考 - 哲学思考3.4 逻辑实操 - 方法论 4 准备5. 分析5.1 gst-launch-1.05.1.1 xvimagesink5.1.2 nv3dsink5.1.3 nv3dsink sync05…

GIt (一) Git的安装,项目搭建,远程仓库,分支

文章目录 一、 版本控制1.1 集中式版本控制1.2 分布式版本控制 二、 Git的安装及配置2.1 安装2.2 Git的配置2.2 查看配置 三、 Git基本理论3.1 工作区域3.2 文件状态 四、Git项目的搭建与操作4.1 初始化Git仓库4.2 常见的操作4.2.1 文件添加到暂存区4.2.2 文件提交更新4.2.3 查…

iview upload clearFiles清除回显视图

iview upload 上传完文件之后清除内容&#xff0c;打开会回显视图&#xff0c;清除不掉 关闭弹框时主动清除回显内容即可this.$refs.uploads.clearFiles() <FormItem label"上传附件:" :label-width"formNameWidth"><Upload action"/fms/ap…

JAVA |日常开发中Servlet详解

JAVA &#xff5c;日常开发中Servlet详解 前言一、Servlet 概述1.1 定义1.2 历史背景 二、Servlet 的生命周期2.1 加载和实例化2.2 初始化&#xff08;init 方法&#xff09;2.3 服务&#xff08;service 方法&#xff09;2.4 销毁&#xff08;destroy 方法&#xff09; 三、Se…

【C++】入门【六】

本节目标 一、继承的概念及定义 二、基类和派生类对象赋值转换 三、继承中的作用域 四、派生类的默认成员函数 五、继承与友元 六、继承与静态成员 七、复杂的菱形继承及菱形虚拟继承 八、继承的总结和反思 九、笔试面试题 一、继承的概念及定义 1.继承的概念 继承是面向对象…

Docker--Docker Image(镜像)

什么是Docker Image&#xff1f; Docker镜像&#xff08;Docker Image&#xff09;是Docker容器技术的核心组件之一&#xff0c;它包含了运行应用程序所需的所有依赖、库、代码、运行时环境以及配置文件等。 简单来说&#xff0c;Docker镜像是一个轻量级、可执行的软件包&…

架构05-架构安全性

零、文章目录 架构05-架构安全性 1、软件架构安全的重要性 **系统安全&#xff1a;**不仅包括防御黑客攻击&#xff0c;还包括安全备份与恢复、安全审计、防治病毒等。**关注重点&#xff1a;**认证、授权、凭证、保密、传输安全、验证。 2、认证&#xff08;Authenticatio…

elasticsearch-如何给文档新增/更新的字段

文章目录 前言elasticsearch-如何给文档新增/更新的字段1. 如何给某些文档新增/更新的字段2. 给所有文档添加/更新一个新的字段3. 测试 前言 如果您觉得有用的话&#xff0c;记得给博主点个赞&#xff0c;评论&#xff0c;收藏一键三连啊&#xff0c;写作不易啊^ _ ^。   而且…

Ansible自动化一键部署单节点集群架构

自动化部署利器&#xff1a;Ansible 一键部署脚本 在现代IT基础设施管理中&#xff0c;Ansible以其简洁、强大的自动化能力脱颖而出。以下是精心打造的Ansible自动化一键部署脚本&#xff0c;旨在简化部署流程&#xff0c;提升效率&#xff0c;确保一致性和可靠性。 通过这个…

常见Linux命令(详解)

文章目录 常见Linux命令文件目录类命令pwd 打印当前目录的绝对路径ls 列出目录内容cd 切换路径mkdir 建立目录rmdir 删除目录touch 创建空文件cp 复制文件或目录rm 移除文件或者目录mv 移动文件与目录或重命名cat 查看文件内容more 文件分屏查看器less 分屏显示文件内容head 显…

数据库复习记录

边复习边整理。 数据库 数据库管理系统&#xff08;DBMS&#xff09;&#xff1a;用来管理数据库的系统。 关系型数据库&#xff1a;二维表格&#xff08;即关系&#xff09;来存储数据&#xff0c;一个表对应一个关系&#xff0c;用SQL来查询数据。如MySQL、PostgreSQL、SQ…

Navicat连接SQL Server及SpringBoot连接SQL Server(jtds)

Navicat连接SQL Server 安装自带的SQL Server客户端 去到Navicat安装目录&#xff0c;找到安装程序&#xff0c;安装即可。 安装对应版本的Microsoft ODBC Driver for SQL Server 打开Navicat输入对应的SQL Server相关信息 然后点测试连接&#xff0c;提示连接成功。 Spr…

数字图像处理(15):图像灰度反转和彩色反转

&#xff08;1&#xff09;图像反转&#xff1a;是指对图像的颜色信息进行相反的处理&#xff0c;从而得到一个新的图像。在计算机视觉和图像处理领域&#xff0c;图像反转是一种常见的操作&#xff0c;它可以帮助我们实现不同的图像特效和视觉效果。 &#xff08;2&#xff09…

Linux——基础命令(3)

1.Linux——基础命令&#xff08;1&#xff09;-CSDN博客 2.Linux——基础命令&#xff08;2&#xff09; 文件内容操作-CSDN博客 一、打包压缩 打包压缩 是日常工作中备份文件的一种方式 在不同操作系统中&#xff0c;常用的打包压缩方式是不同的选项 含义 Windows 常用 rar…

【力扣热题100】—— Day4.回文链表

正视自己的懦弱和无能&#xff0c;克服自己的嫉妒与不甘 —— 24.12.3 234. 回文链表 给你一个单链表的头节点 head &#xff0c;请你判断该链表是否为 回文链表 。如果是&#xff0c;返回 true &#xff1b;否则&#xff0c;返回 false 。 示例 1&#xff1a; 输入&#xff1a…

python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250+个项目、26.6GB)

文章目录 源代码下载地址项目介绍预览 项目备注源代码下载地址 源代码下载地址 点击这里下载源码 项目介绍 python源码实例游戏开发小程序办公自动化网络爬虫项目开发源码(250个项目、26.6GB) 预览 项目备注 1、该资源内项目代码都经过测试运行成功&#xff0c;功能ok的情…