暂无图片
暂无图片
暂无图片
暂无图片
暂无图片

Kubernetes 原生 CI/CD 框架 — Tekton CI

ProdanLabs 2021-06-15
1318


Tekton 是一个基于 Kubernetes 的云原生 CI/CD 开源框架,Tekton 的前身是 Knative 的子项目 build-pipeline,现在是 CD 基金会的项目。Tekton 抽象了底层实现,功能强大而灵活,让每个人都能更轻松地进行 CI/CD。


01

Tekton 关键的资源对象

Tekton 提供了多种 Kubernetes CRD 资源对象,使用 Kubernetes 声明式风格来定义 CI/CD,主要有以下几个资源对象:


  • PipelineResource:定义 Task 的输入输出资源,比如源码地址、镜像仓库地址等

  • Task:定义任务模版,可以有多个 Step,每个 Step 表示一个动作,比如编译源码、构建镜像等,每个 Step 由一个 Container 来执行。

  • TaskRun:是 Task 的实际执行。一个 TaskRun 控制一个 Pod,Task 中的 Step 对应 Pod 中的 Container。

  • Pipeline:由一个或多个 Task 组成,定义一个完整的流水线。

  • PipelineRun:与 task 和 taskRun 的关系类似,pipelineRun 也是代表 pipeline 的一次实际运行。


02

Tekton 安装

Tekton 提供了 Operator ,可以在 Kubernetes 集群上轻松安装、升级和管理 Pipelines, Dashboard, Triggers 

$ kubectl apply -f https://storage.googleapis.com/tekton-releases/operator/latest/release.yaml
# all 安装清单是 pipelines, triggers , dashboard 组件
$ kubectl apply -f https://raw.githubusercontent.com/tektoncd/operator/main/config/crs/kubernetes/config/all/operator_v1alpha1_config_cr.yaml


查看

tekton-operator    tekton-operator-8c9c44b6-vvtcc                       1/1     Running     0          24h
tekton-pipelines   tekton-dashboard-59d7b97b9f-8fmst                    1/1     Running     0          24h
tekton-pipelines   tekton-operator-proxy-webhook-56c8d77bcd-6bsnb       1/1     Running     0          24h
tekton-pipelines   tekton-pipelines-controller-7f6fb87656-9pkrc         1/1     Running     0          24h
tekton-pipelines   tekton-pipelines-webhook-86cd649b94-cqqpt            1/1     Running     0          24h
tekton-pipelines   tekton-triggers-controller-68554d875c-gltdb          1/1     Running     0          24h
tekton-pipelines   tekton-triggers-core-interceptors-66fb9db589-b8dfr   1/1     Running     0          24h
tekton-pipelines   tekton-triggers-webhook-d8f7d59d-4qlv9               1/1     Running     0          24h


可以使用 Ingress 来访问 Tekton 的 Dashboard ,也可以使用 NodePort

---
apiVersion: networking.k8s.io/v1
kind: Ingress
metadata:
  name: tekton-dashboard
  namespace: tekton-pipelines
  annotations:
    kubernetes.io/ingress.class: nginx
    ingress.kubernetes.io/force-ssl-redirect: "true"
    kubernetes.io/tls-acme: "true"
spec:
  rules:
  - host: "xxx.xxx.xxx"
    http:
      paths:
      - pathType: Prefix
        path"/"
        backend:
          service:
            name: tekton-dashboard
            port:
              number: 9097
  tls:
   - secretName: tekton-dashboard-cert


可以安装 Tekton CLI 工具, 更方便,比如 TaskRun ,tkn task start 就可以,而无需 kubectl 创建 TaskRun 资源对象。

$ wget https://github.com/tektoncd/cli/releases/download/v0.19.0/tkn_0.19.0_Linux_x86_64.tar.gz
$ tar -zxvf tkn_0.19.0_Linux_x86_64.tar.gz
$ mv tkn /usr/local/bin/


03

运行第一个 Tekton 流水线

创建 hello Task

# cat task-hello.yaml 
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: hello
spec:
  steps:
    - name: hello
      image: ubuntu
      command:
        - echo
      args:
        - "Hello World!"
# kubectl create -f  task-hello.yaml 
task.tekton.dev/hello created


运行 hello Task

# tkn task start hello
TaskRun started: hello-run-9p8cs

In order to track the TaskRun progress run:
tkn taskrun logs hello-run-9p8cs -f -n default
# 或
# cat taskRun-hello.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  generateName: hello-run-
spec:
  taskRef:
    name: hello
# kubectl create -f taskRun-hello.yaml


可以在 dashboard 或使用 kubectl 查看

$ kubectl get po 
NAME                                             READY   STATUS      RESTARTS   AGE
hello-run-9p8cs-pod-2zvs8                        0/1     Completed   0          3m42s


创建 goodbye Task

$ cat task-goodbye.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: goodbye
spec:
  steps:
    - name: goodbye
      image: ubuntu
      script: |
        #!/bin/bash
        echo "Goodbye World!"
$ kubectl create -f  task-goodbye.yaml
task.tekton.dev/goodbye created


创建 Pipeline ,把 hello Task 和 goodbye Task 组成到一起

$ cat pipeline-hello-goodbye.yaml
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: hello-goodbye
spec:
  tasks:
  - name: hello
    taskRef:
      name: hello
  - name: goodbye
    runAfter:
     - hello
    taskRef:
      name: goodbye
$ kubectl create -f  pipeline-hello-goodbye.yaml
pipeline.tekton.dev/hello-goodbye created


运行 Pipeline

$ cat pipelineRun-hello-goodbye.yaml 
apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  generateName: hello-goodbye-run-
spec:
  pipelineRef:
    name: hello-goodbye
$ kubectl create -f pipelineRun-hello-goodbye.yaml
pipelinerun.tekton.dev/hello-goodbye-run-88kpx created


查看


04

Go Pipeline example

以 Go 项目为例来创建一个流水线,在流水线中运行应用程序的单元测试、构建镜像并推送到 Docker 仓库。

1、PipelineResource 对象,定义输入的信息

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: github-tekton-examples
  namespace: default
spec:
  type: git
  params:
    - name: url
      value: https://github.com/prodanlabs/tekton-examples
    - name: revision
      value: main


2、git 仓库的用户密码,在实际的环境中项目应该都是私有需要验证的。

apiVersion: v1
kind: Secret
metadata:
  name: github-auth
  annotations:
    tekton.dev/git-0: https://github.com
type: kubernetes.io/basic-auth
stringData:
  username: {username}
  password: {password}


3、PipelineResource 对象,定义输出的信息

apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: docker-registry-tekton-examples
  namespace: default
spec:
  type: image
  params:
    - name: url
      value: docker.io/prodan/tekton-examples


4、镜像仓库户密码在实际的环境项目应该都是私有需要验证

apiVersion: v1
kind: Secret
metadata:
  name: docker-registry-auth
  namespace: default
  annotations:
    tekton.dev/docker-0: https://index.docker.io/v1/
type: kubernetes.io/basic-auth
stringData:
  username: {docker-hub-uaser}
  password: {docker-hub-password}


5、创建 ServiceAccount

apiVersion: v1
kind: ServiceAccount
metadata:
  name: pipeline-sa
secrets:
  - name: docker-registry-auth
  - name: github-auth


6、创建 go 单元测试任务

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: go-test
  annotations:
    tekton.dev/tags: go-run-test
spec:
  resources:
    inputs:
      - name: source-repo
        type: git
  steps:
    - name: go-run-test
      image: golang:1.15-alpine
      workingDir: /workspace/source-repo
      env:
      - name: CGO_ENABLED
        value: "0"
      command: ["go"]
      args: ["test"]


7、创建 image tag 任务,获取 git 提交的 head 作为镜像的 tag。通过 results 把结果传递给其他 Task。当然,可以也可以把这步合并到其他 Task 。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: image-tag
  annotations:
    tekton.dev/tags: git-commit-head
spec:
  resources:
    inputs:
      - name: source-repo
        type: git
  results:
    - name: git-commit-head
      description: The precise commit SHA that was fetched by this Task
  steps:
    - name: git-commit-head
      image: gcr.io/tekton-releases/github.com/tektoncd/pipeline/cmd/git-init:v0.24.3
      script: |
        #!/usr/bin/env sh
        cd /workspace/source-repo/
        RESULT_SHA="$(git rev-parse --short HEAD | tr -d '\n')"
        echo -n "$RESULT_SHA" > $(results.git-commit-head.path)


8、编译、构建镜像和上传镜像。不推荐使用 docker 构建镜像。

apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push
  annotations:
    tekton.dev/tags: build-and-push
spec:
  params:
    - name: pathToDockerFile
      type: string
      description: The path to the dockerfile to build
      default: /workspace/source-repo/Dockerfile
    - name: imageTag
      description: Tag to apply to the built image
      type: string
    - name: pathToContext
      type: string
      description: |
        The build context used by Kaniko
        (https://github.com/GoogleContainerTools/kaniko#kaniko-build-contexts)
      default: $(resources.inputs.source-repo.path)
  resources:
    inputs:
      - name: source-repo
        type: git
    outputs:
      - name: builtImage
        type: image
  steps:
    - name: build-and-push
      image: gcr.io/kaniko-project/executor:latest
      env:
        - name: DOCKER_CONFIG
          value: /tekton/home/.docker
      args:
        - --context=$(params.pathToContext)
        - --dockerfile=$(params.pathToDockerFile)
        - --destination=$(resources.outputs.builtImage.url):$(params.imageTag)


9、创建流水线,把上面的任务连起来

---
apiVersion: tekton.dev/v1beta1
kind: Pipeline
metadata:
  name: go-pipeline
spec:
  resources:
    - name: source-repo
      type: git
    - name: builtImage
      type: image
  tasks:
    # 运行应用测试
    - name: go-test
      taskRef:
        name: go-test
      resources:
        inputs:
          - name: source-repo      # Task 输入名称
            resource: source-repo  # Pipeline 资源名称
    - name: image-tag
      taskRef:
        name: image-tag
      resources:
        inputs:
          - name: source-repo      # Task 输入名称
            resource: source-repo  # Pipeline 资源名称
      runAfter:
        - go-test                  # go-test 任务执行之后
    - name: build-and-push
      params:
        - name: imageTag
          value: $(tasks.image-tag.results.git-commit-head) # 注入参数
      taskRef:
        name: build-and-push
      resources:
        inputs:
          - name: source-repo      # Task 输入名称
            resource: source-repo  # Pipeline 资源名称
        outputs:
          - name: builtImage
            resource: builtImage
      runAfter:
        - image-tag                # image-tag 任务执行之后


10、运行流水线

apiVersion: tekton.dev/v1beta1
kind: PipelineRun
metadata:
  name: run-pipeline-go
spec:
  serviceAccountName: pipeline-sa
  pipelineRef:
    name: go-pipeline
  resources:
    - name: source-repo
      resourceRef:
        name: github-tekton-examples
    - name: builtImage
      resourceRef:
        name: docker-registry-tekton-examples



11、查看 docker 仓库



05

小结

最近一段时间在做 CI/CD 的选型,目前比较倾向的方案是 Tekton CI + Argo CD 。完整的 CI/CD 一般都是在开发测试环境中,在实际的生成环境中,大都是通过 CD 把通过测试的镜像更新到生产环境。Tekton trigger 等功能后续更新...


文中示例项目的地址:

https://github.com/prodanlabs/tekton-examples

文章转载自ProdanLabs,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。

评论