kubernetes的DevOps业务(三):Jenkins,GitLab,Harbor,Tekton,GitOps


上面的资源清单文件安装后,会创建一个名为 tekton-pipelines 的命名空间,在该命名空间下面会有大量和 tekton 相关的资源对象,我们可以通过在该命名空间中查看 Pod 并确保它们处于 Running 状态来检查安装是否成功:


Tekton 安装完成后,我们还可以选择是否安装 CLI 工具,有时候可能 Tekton 提供的命令行工具比 kubectl 管理这些资源更加方便,当然这并不是强制的

tekton将全部用到的组建的相关内容都放在github官网上了https://github.com/tektoncd
在这里插入图片描述
在这里插入图片描述

安装完成后可以通过如下命令验证 CLI 是否安装成功:

[root@master1 tmp]# wget https://github.com/tektoncd/cli/releases/download/v0.23.1/tkn_0.23.1_Linux_x86_64.tar.gz
[root@master1 tmp]# tar -xf tkn_0.23.1_Linux_x86_64.tar.gz -C /usr/local/bin
[root@master1 tmp]# tkn version
Client version: 0.23.1
Pipeline version: v0.12.0

此外,还可以安装一个 Tekton 提供的一个 Dashboard,我们可以通过 Dashboard 查看 Tekton 整个任务的构建过程,直接执行下面的命令直接安装即可:

kubectl apply -f https://www.qikqiak.com/k8strain2/devops/manifests/tekton/dashboard.yaml
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: extensions.dashboard.tekton.dev
spec:
  group: dashboard.tekton.dev
  names:
    categories:
    - tekton
    - tekton-dashboard
    kind: Extension
    plural: extensions
  scope: Namespaced
  subresources:
    status: {
    
    }
  version: v1alpha1
---
apiVersion: v1
kind: ServiceAccount
metadata:
  labels:
    app: tekton-dashboard
  name: tekton-dashboard
  namespace: tekton-pipelines
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRole
metadata:
  name: tekton-dashboard-minimal
  namespace: tekton-pipelines
rules:
- apiGroups:
  - ""
  resources:
  - serviceaccounts
  verbs:
  - update
  - patch
- apiGroups:
  - ""
  resources:
  - pods
  - services
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - create
  - update
  - delete
- apiGroups:
  - extensions
  - apps
  resources:
  - deployments
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - tekton.dev
  resources:
  - tasks
  - clustertasks
  - taskruns
  - pipelines
  - pipelineruns
  - pipelineresources
  - conditions
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - tekton.dev
  resources:
  - taskruns/finalizers
  - pipelineruns/finalizers
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - tekton.dev
  resources:
  - tasks/status
  - clustertasks/status
  - taskruns/status
  - pipelines/status
  - pipelineruns/status
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - dashboard.tekton.dev
  resources:
  - extensions
  verbs:
  - create
  - update
  - delete
  - patch
- apiGroups:
  - triggers.tekton.dev
  resources:
  - clustertriggerbindings
  - eventlisteners
  - triggerbindings
  - triggertemplates
  verbs:
  - create
  - update
  - delete
  - patch
  - add
- apiGroups:
  - ""
  resources:
  - secrets
  verbs:
  - get
  - list
  - watch
  - create
  - update
  - delete
- apiGroups:
  - apiextensions.k8s.io
  resources:
  - customresourcedefinitions
  verbs:
  - get
  - list
- apiGroups:
  - security.openshift.io
  resources:
  - securitycontextconstraints
  verbs:
  - use
- apiGroups:
  - route.openshift.io
  resources:
  - routes
  verbs:
  - get
  - list
- apiGroups:
  - extensions
  - apps
  resources:
  - ingresses
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - serviceaccounts
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods
  - services
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - pods/log
  - namespaces
  - events
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - ""
  resources:
  - configmaps
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - extensions
  - apps
  resources:
  - deployments
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - tekton.dev
  resources:
  - tasks
  - clustertasks
  - taskruns
  - pipelines
  - pipelineruns
  - pipelineresources
  - conditions
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - tekton.dev
  resources:
  - taskruns/finalizers
  - pipelineruns/finalizers
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - tekton.dev
  resources:
  - tasks/status
  - clustertasks/status
  - taskruns/status
  - pipelines/status
  - pipelineruns/status
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - dashboard.tekton.dev
  resources:
  - extensions
  verbs:
  - get
  - list
  - watch
- apiGroups:
  - triggers.tekton.dev
  resources:
  - clustertriggerbindings
  - eventlisteners
  - triggerbindings
  - triggertemplates
  verbs:
  - get
  - list
  - watch
---
apiVersion: rbac.authorization.k8s.io/v1
kind: ClusterRoleBinding
metadata:
  name: tekton-dashboard-minimal
roleRef:
  apiGroup: rbac.authorization.k8s.io
  kind: ClusterRole
  name: tekton-dashboard-minimal
subjects:
- kind: ServiceAccount
  name: tekton-dashboard
  namespace: tekton-pipelines
---
apiVersion: v1
kind: Service
metadata:
  labels:
    app: tekton-dashboard
    dashboard.tekton.dev/release: v0.6.1.4
    version: v0.6.1.4
  name: tekton-dashboard
  namespace: tekton-pipelines
spec:
  ports:
  - name: http
    port: 9097
    protocol: TCP
    targetPort: 9097
  type: NodePort
  selector:
    app: tekton-dashboard
---
apiVersion: apps/v1
kind: Deployment
metadata:
  labels:
    app: tekton-dashboard
    dashboard.tekton.dev/release: v0.6.1.4
    version: v0.6.1.4
  name: tekton-dashboard
  namespace: tekton-pipelines
spec:
  replicas: 1
  selector:
    matchLabels:
      app: tekton-dashboard
  template:
    metadata:
      labels:
        app: tekton-dashboard
      name: tekton-dashboard
    spec:
      containers:
      - env:
        - name: PORT
          value: "9097"
        - name: READ_ONLY
          value: "false"
        - name: WEB_RESOURCES_DIR
          value: /var/run/ko/web
        - name: CSRF_SECURE_COOKIE
          value: "true"
        - name: TRIGGERS_NAMESPACE
          value: tekton-pipelines
        - name: PIPELINE_NAMESPACE
          value: tekton-pipelines
        - name: INSTALLED_NAMESPACE
          valueFrom:
            fieldRef:
              fieldPath: metadata.namespace
        image: cnych/tekton-dashboard:v0.6.1.4
        livenessProbe:
          httpGet:
            path: /health
            port: 9097
        name: tekton-dashboard
        ports:
        - containerPort: 9097
        readinessProbe:
          httpGet:
            path: /readiness
            port: 9097
      serviceAccountName: tekton-dashboard
---

安装完成后我们可以通过 Dashboard 的 Service 的 NodePort 来访问应用。

[root@master1 tmp]# kubectl get pod -n tekton-pipelines
NAME                                           READY   STATUS    RESTARTS   AGE
tekton-dashboard-85fbcbdcdd-gvvs5              1/1     Running   0          62s
tekton-pipelines-controller-6fd67c849f-x7725   1/1     Running   0          3h5m
tekton-pipelines-webhook-7dc48bc5f7-8qhwq      1/1     Running   0          3h5m
[root@master1 tmp]# kubectl get svc -n tekton-pipelines
NAME                          TYPE        CLUSTER-IP      EXTERNAL-IP   PORT(S)                     AGE
tekton-dashboard              NodePort    10.99.246.65    <none>        9097:31311/TCP              77s
tekton-pipelines-controller   ClusterIP   10.97.88.210    <none>        9090/TCP                    3h6m
tekton-pipelines-webhook      ClusterIP   10.108.239.36   <none>        9090/TCP,8008/TCP,443/TCP   3h6m
[root@master1 tmp]# tkn version
Client version: 0.23.1
Pipeline version: v0.12.0
Dashboard version: v0.6.1.4

在这里插入图片描述
在这里插入图片描述

概念

Tekton 为 Kubernetes 提供了多种 CRD 资源对象,可用于定义我们的流水线。
在这里插入图片描述
主要有以下几个资源对象:

1.Task:表示执行命令的一系列有序的步骤,task 里可以定义一系列的 steps,例如编译代码、构建镜像、推送镜像等,每个 task 实际由一个 Pod 执行。
2.Pipeline:一组有序的 Task,Pipeline 中的 Task 可以使用之前执行过的 Task 的输出作为它的输入。表示一个或多个 Task、PipelineResource 以及各种定义参数的集合。
3.TaskRun:Task 只是定义了一个模版,TaskRun 才真正代表了一次实际的运行,当然你也可以自己手动创建一个 TaskRun,TaskRun 创建出来之后,就会自动触发 Task 描述的构建任务。
4.PipelineRun:类似 Task 和 TaskRun 的关系,PipelineRun 也表示某一次实际运行的 pipeline,下发一个 PipelineRun CRD 实例到 Kubernetes 后,同样也会触发一次 pipeline 的构建。
5.ClusterTask:覆盖整个集群的任务,而不是单一的某一个命名空间,这是和 Task 最大的区别,其他基本上一致的。
PipelineResource:表示 pipeline 输入资源,比如 github 上的源码,或者 pipeline 输出资源,例如一个容器镜像或者构建生成的 jar 包等。

每个任务都在自己的 Kubernetes Pod 中执行,因此,默认情况下,管道内的任务不共享数据。要在 Tasks 之间共享数据,你必须明确配置每个 Task 以使其输出可用于下一个 Task 并获取先前执行的 Task 的输出作为其输入。

Task任务

使用 Tekton 后你的 CI/CD 工作流中的每个操作都变成了一个 Step,使用指定的容器镜像来执行。Steps 然后组织在 Tasks 中,它在集群中作为 Kubernetes Pod 运行(就是一个pod中多个容器),还可以进一步组织 Tasks 变成成 Pipelines,还可以控制几个 Tasks 的执行顺序。
在这里插入图片描述
在这里我们使用一个简单的 Golang 应用,可以在仓库 https://github.com/cnych/tekton-demo 下面获取应用程序代码,测试以及 Dockerfile 文件。
在这里插入图片描述

Dockerfile:
FROM golang:1.14-alpine

WORKDIR /go/src/app
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]

main.go:
package main

import "fmt"

func sum(a, b int) int {
    
    
	return a + b
}

func main() {
    
    
	fmt.Println("Sum: ", sum(1, 2))
}

main_test.go:
package main

import "testing"

func TestSum(t *testing.T) {
    
    
	total := sum(10, 10)
	if total != 20 {
    
    
		t.Errorf("Sum was incorrect, got: %d, want: %d.", total, 20)
	}
}

golang:x.xx-alpine这种景象很常用,提供一个基础的go环境

首先第一个任务就是 Clone 应用程序代码进行测试,要创建一个 Task 任务,就需要使用到 Kubernetes 中定义的 Task 这个 CRD 对象,这里我们创建一个如下所示的资源文件,内容如下所示:

# task-test.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: test
spec:
  resources:
    inputs:
      - name: repo
        type: git
  steps:
    - name: run-test
      image: golang:1.14-alpine
      workingDir: /workspace/repo
      command: ['go']
      args: ['test']

其中 resources 定义了我们的任务中定义的 Step 所需的输入内容,这里我们的步骤需要 Clone 一个 Git 仓库作为 go test 命令的输入,目前支持 git、pullRequest、image、cluster、storage、cloudevent 等资源。

Tekton 内置的 git 资源类型,它会自动将代码仓库 Clone 到 /workspace/$input_name 目录中,由于我们这里输入被命名成 repo,所以代码会被 Clone 到 /workspace/repo 目录下面。

然后下面的 steps 就是来定义执行运行测试命令的步骤,这里我们直接在代码的根目录中运行 go test 命令即可,需要注意的是命令和参数需要分别定义。

定义完成后直接使用 kubectl 创建该任务:

[root@master1 tmp]# kubectl apply -f task_test.yaml
task.tekton.dev/test created
[root@master1 tmp]# kubectl get task
NAME   AGE
test   44s

现在我们定义完成了一个新建的 Task 任务,但是该任务并不会立即执行,我们必须创建一个 TaskRun 引用它并提供所有必需输入的数据才行。当然我们也可以直接使用 tkn 命令来启动这个 Task 任务,我们可以通过如下所示的命令来获取启动 Task 所需的资源对象:

tkn task start --help
--dry-run                   preview TaskRun without running it

[root@master1 tmp]# tkn task start test --dry-run
no pipeline resource of type "git" found in namespace: default
Please create a new "git" resource for pipeline resource "repo"
? Enter a name for a pipeline resource : demo-git
? Enter a value for url :  https://github.com/cnych/tekton-demo
? Enter a value for revision :  master
New git resource "demo-git" has been created
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  creationTimestamp: null
  generateName: test-run-
  namespace: default
spec:
  resources:
    inputs:
    - name: repo
      resourceRef:
        name: demo-git
  serviceAccountName: ""
  taskRef:
    name: test
status:
  podName: ""

在这里插入图片描述
由于我们这里的 Task 任务需要一个 git 代码仓库作为输入,所以需要一个 Pipeline Resource 对象来定义输入信息,上面的命令会自动创建一个名为 demo-git 的 PipelineResource 资源对象,如下所示:

[root@master1 tmp]# kubectl get pipelineresource
NAME       AGE
demo-git   4m55s
[root@master1 tmp]# kubectl get pipelineresource demo-git -o yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  creationTimestamp: "2022-05-23T09:55:16Z"
  generation: 1
  managedFields:
  - apiVersion: tekton.dev/v1alpha1
    fieldsType: FieldsV1
    fieldsV1:
      f:spec:
        .: {
    
    }
        f:params: {
    
    }
        f:type: {
    
    }
    manager: tkn
    operation: Update
    time: "2022-05-23T09:55:16Z"
  name: demo-git
  namespace: default
  resourceVersion: "621648"
  uid: 9090e4d3-b75a-48e0-a517-4770958d4673
spec:
  params:
  - name: url
    value: https://github.com/cnych/tekton-demo
  - name: revision
    value: master
  type: git

(revision修订)
当我们不知道如何创建 PipelineResource 的时候我们就可以参考上面的方式来创建,当然最后还需要创建 TaskRun 对象才可以真正执行这个 Task 任务,上面的 tkn task start 命令也为我们打印出对应的 TaskRun 资源,将其内容添加到 taskrun.yaml 文件中(根据自己的习惯进行一些修改):

apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  #creationTimestamp: null
  #generateName: test-run-
  #namespace: default
  name: testrun
spec:
  resources:
    inputs:
    - name: repo
      resourceRef:
        name: demo-git
  #serviceAccountName: ""
  taskRef:
    name: test
#status:
  #podName: ""

这里的 taskRef 引用上面定义的 Task 和 git 仓库作为输入,resourceRef 也是引用上面定义的 PipelineResource 资源对象。现在我们创建这个资源对象过后,就会开始运行了:

[root@master1 tmp]# kubectl apply -f taskrun.yaml
taskrun.tekton.dev/testrun created

Tekton 现在将开始运行您的 Task

我们可以通过 kubectl describe 命令来查看任务运行的过程,首先会通过 tekton-git-init 拉取代码,然后会使用我们定义的 Task 任务中的 Steps 镜像来执行任务。当任务执行完成后, Pod 就会变成 Completed 状态了:

kubectl describe pod testrun-pod-mz76l
Events:
  Type    Reason     Age    From               Message
  ----    ------     ----   ----               -------
  Normal  Scheduled  2m27s  default-scheduler  Successfully assigned default/testrun-pod-mz76l to node2
  Normal  Pulling    2m25s  kubelet            Pulling image "busybox@sha256:a2490cec4484ee6c1068ba3a05f89934010c85242f736280b35343483b2264b6"
  Normal  Pulled     2m23s  kubelet            Successfully pulled image "busybox@sha256:a2490cec4484ee6c1068ba3a05f89934010c85242f736280b35343483b2264b6" in 1.668181441s
  Normal  Created    2m23s  kubelet            Created container working-dir-initializer
  Normal  Started    2m23s  kubelet            Started container working-dir-initializer
  Normal  Pulling    2m22s  kubelet            Pulling image "cnych/tekton-entrypoint:v0.12.0"
  Normal  Pulled     108s   kubelet            Successfully pulled image "cnych/tekton-entrypoint:v0.12.0" in 34.24577358s
  Normal  Created    108s   kubelet            Created container place-tools
  Normal  Started    108s   kubelet            Started container place-tools
  Normal  Pulling    107s   kubelet            Pulling image "cnych/tekton-git-init:v0.12.0"
  Normal  Pulled     76s    kubelet            Successfully pulled image "cnych/tekton-git-init:v0.12.0" in 31.106212702s
  Normal  Created    76s    kubelet            Created container step-git-source-demo-git-w7zfg
  Normal  Started    75s    kubelet            Started container step-git-source-demo-git-w7zfg
  Normal  Pulling    75s    kubelet            Pulling image "golang:1.14-alpine"
  Normal  Pulled     5s     kubelet            Successfully pulled image "golang:1.14-alpine" in 1m10.131057675s
  Normal  Created    3s     kubelet            Created container step-run-test
  Normal  Started    2s     kubelet            Started container step-run-test


[root@master1 tmp]# kubectl get pod
NAME                READY   STATUS    RESTARTS   AGE
testrun-pod-mz76l   2/2     Running   0          2m30s
[root@master1 tmp]# kubectl get taskrun
NAME      SUCCEEDED   REASON    STARTTIME   COMPLETIONTIME
testrun   Unknown     Running   2m38s
[root@master1 tmp]# kubectl get pod
NAME                READY   STATUS      RESTARTS   AGE
testrun-pod-x98wc   0/2     Completed   0          89s

要查看最后一个 TaskRun 的日志,可以使用以下 tkn 命令:

tkn taskrun logs --last -f
[git-source-demo-git-kg45h] {
    
    "level":"info","ts":1653302345.2074475,"caller":"git/git.go:136","msg":"Successfully cloned https://github.com/cnych/tekton-demo @ 5e1e3a1d0f167b9b639df5b802a0f0f81064d21e (grafted, HEAD, origin/master) in path /workspace/repo"}
[git-source-demo-git-kg45h] {
    
    "level":"info","ts":1653302345.2768123,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/repo"}

[run-test] PASS
[run-test] ok   _/workspace/repo        0.003s

我们可以查看容器的日志信息来了解任务的执行结果信息:
(-c 可以指定某个特定的容器)

[root@master1 tmp]# kubectl logs testrun-pod-x98wc --all-containers
{
    
    "level":"info","ts":1653302345.2074475,"caller":"git/git.go:136","msg":"Successfully cloned https://github.com/cnych/tekton-demo @ 5e1e3a1d0f167b9b639df5b802a0f0f81064d21e (grafted, HEAD, origin/master) in path /workspace/repo"}
{
    
    "level":"info","ts":1653302345.2768123,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/repo"}
PASS
ok      _/workspace/repo        0.003s

我们可以看到我们的测试已经通过了。

Docker Hub 配置

为了能够构建 Docker 镜像,一般来说我们需要使用 Docker 来进行,我们这里是容器,所以可以使用docker in docker模式,这种模式安全性不高,除了这种方式之外,我们还可以使用 Google 推出的 Kaniko 工具来进行构建(docker镜像),该工具可以在 Kubernetes 集群中构建 Docker 镜像而无需依赖 Docker 守护进程,之前我们已经介绍过 kaniko 这种形式,这里我们就介绍 DIND 这种模式。登录凭证可以保存到 Kubernetes 的 Secret 资源对象中,创建一个名为 harbor-auth.yaml 的文件,内容如下所示:
(实际用来跑任务的即做ci/cd的是容器,要部署的应用服务提供方式也是容器化,这里在完成任务的容器中使用docker技术构建docker镜像)

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

记得将 username 和 password 替换成你的 Harbor 仓库登录凭证。
我们这里在 Secret 对象中添加了一个 tekton.dev/docker-0 的 annotation,该注解信息是用来告诉 Tekton 这些认证信息所属的 Docker 镜像仓库

然后创建一个 ServiceAccount 对象来使用上面的 docker-auth 这个 Secret 对象,创建一个名为 sa.yaml 的文件,内容如下所示:

# sa.yaml
apiVersion: v1
kind: ServiceAccount
metadata:
  name: build-sa
secrets:
  - name: harbor-auth

然后直接创建上面两个资源对象即可:

$ kubectl apply -f harbor-auth.yaml
secret/harbor-auth created
$ kubectl apply -f sa.yaml
serviceaccount/build-sa created

创建完成后,我们就可以在运行 Tekton 的任务或者流水线的时候使用上面的 build-sa 这个 ServiceAccount 对象来进行 Docker Hub 的登录认证了。

创建镜像任务

现在我们创建一个 Task 任务来构建并推送 Docker 镜像

这里使用的示例应用根目录下面已经包含了一个 Dockerfile 文件了,所以我们直接 Clone 代码就可以获得:


FROM golang:1.14-alpine

WORKDIR /go/src/app
COPY . .

RUN go get -d -v ./...
RUN go install -v ./...

CMD ["app"]
[root@master1 ~]# cat task-build-push.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push
spec:
  resources:
    inputs: # 定义输入资源
    - name: repo  #输入资源,就是github的那个仓库
      type: git
    outputs: # 定义输出资源
    - name: builtImage # 输出镜像名字
      type: image
  params:
  - name: pathToDockerfile #指明 dockerfile 在仓库中的哪个位置
    type: string
    default: $(resources.inputs.repo.path)/Dockerfile # repo资源的路径
    description: The path to the dockerfile to build
  - name: pathToContext #指明构建上下文的路径
    type: string
    default: $(resources.inputs.repo.path)  # repo资源的路径
    description: the build context used by docker daemon
  steps:
    - name: build-and-push
      image: docker:stable
      script: |
        #!/usr/bin/env sh
        docker login harbor.k8s.local
        docker build -t $(resources.outputs.builtImage.url) -f $(params.pathToDockerfile) $(params.pathToContext)
        docker push $(resources.outputs.builtImage.url)  # 这边的参数都是在 input 和 output 中定义的
      volumeMounts:
        - name: dockersock #将docker.sock文件挂载进来,使用宿主机docker daemon 构建镜像
          mountPath: /var/run/docker.sock
  volumes:
    - name: dockersock
      hostPath:
        path: /var/run/docker.sock


[root@master1 ~]# cat task-build-push.yaml

将 git 作为输入资源,此外还定义了 pathToDockerfile 与 pathToContext 参数,用来指定 Dockerfile 和构建上下文的路径,此外还定义了一个名为 builtImage 的镜像输出资源,用来定义 Docker 镜像的相关参数。然后定义了一个名为 build-and-push 的步骤,这里我们使用 DIND 的方式,将宿主机的 /var/run/docker.sock 文件挂载到 docker:stable 的容器中,然后执行 script 下面的 Docker 镜像构建推送的操作
创建了 Task 任务过后,要想真正去执行这个任务,创建一个对应的 TaskRun 资源对象。

执行任务

和前面一样,现在我们来创建一个 TaskRun 对象来触发任务,不同之处在于我们需要指定 Task 时需要的 ServiceAccount 对象

[root@master1 ~]# cat task-build-push.yaml
apiVersion: tekton.dev/v1beta1
kind: Task
metadata:
  name: build-and-push
spec:
  resources:
    inputs: # 定义输入资源
    - name: repo  #输入资源,就是github的那个仓库
      type: git
    outputs: # 定义输出资源
    - name: builtImage # 输出镜像名字
      type: image
  params:
  - name: pathToDockerfile #指明 dockerfile 在仓库中的哪个位置
    type: string
    default: $(resources.inputs.repo.path)/Dockerfile # repo资源的路径
    description: The path to the dockerfile to build
  - name: pathToContext #指明构建上下文的路径
    type: string
    default: $(resources.inputs.repo.path)  # repo资源的路径
    description: the build context used by docker daemon
  steps:
    - name: build-and-push
      image: docker:stable
      script: |
        #!/usr/bin/env sh
        docker login harbor.k8s.local
        docker build -t $(resources.outputs.builtImage.url) -f $(params.pathToDockerfile) $(params.pathToContext)
        docker push $(resources.outputs.builtImage.url)  # 这边的参数都是在 input 和 output 中定义的
      volumeMounts:
        - name: dockersock #将docker.sock文件挂载进来,使用宿主机docker daemon 构建镜像
          mountPath: /var/run/docker.sock
  volumes:
    - name: dockersock
      hostPath:
        path: /var/run/docker.sock
[root@master1 ~]# cat taskrun-build-push.yaml
# taskrun-build-push.yaml
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: build-and-push
spec:
  serviceAccountName: build-sa   # 关联具有harbor认证信息的serviceaccount
  taskRef:
    name: build-and-push  # 关联定义好的task
  resources:
    inputs:
      - name: repo  # 指定输入的仓库资源
        resourceRef:
          name: demo-git
    outputs:  # 指定输出的镜像资源
      - name: builtImage
        resourceRef:
          name: harbor-image
  params:
  - name: pathToDockerfile #指明 dockerfile 在仓库中的哪个位置
    value: $(resources.inputs.repo.path)/Dockerfile # repo资源的路径
  - name: pathToContext # 指定构建上下文
    value: $(resources.inputs.repo.path)  # repo资源的路径

注意这里我们通过 serviceAccountName 属性指定了 Docker 认证信息的 ServiceAccount 对象,然后通过 taskRef 引用我们的任务,以及下面的 resourceRef 关联第一部分我们声明的输入资源,此外还需要定义一个关于输出镜像的 PipelineResource 资源

[root@master1 ~]# cat harbor-image-res.yaml
# harbor-image-res.yaml
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: harbor-image
spec:
  type: image
  params:
    - name: url
      value: harbor.k8s.local/course/tekton-demo:v0.1.0 #构建完的镜像名称

kubectl apply -f harbor-image-res.yaml
kubectl apply -f taskrun-build-push.yaml

[root@master1 ~]# kubectl get pod,taskrun
NAME                           READY   STATUS            RESTARTS   AGE
pod/build-and-push-pod-crbfd   0/4     PodInitializing   0          51s
pod/testrun-pod-p4zpp          0/2     Completed         0          26m

NAME                                SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
taskrun.tekton.dev/build-and-push   Unknown     Pending     51s
taskrun.tekton.dev/testrun          True        Succeeded   26m         16m

tkn taskrun logs build-and-push

TaskRun 任务已经执行成功了。 这个时候其实我们可以在 Harbor 上找到我们的镜像了,当然也可以直接使用这个镜像进行测试

[root@master1 ~]# kubectl get pod --watch
NAME                       READY   STATUS      RESTARTS   AGE
build-and-push-pod-v88fw   0/4     Completed   0          112s
testrun-pod-p4zpp          0/2     Completed   0          65m

[root@master1 ~]#
[root@master1 ~]# kubectl get taskrun
NAME             SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
build-and-push   True        Succeeded   2m9s        18s
testrun          True        Succeeded   65m         55m

如果报错,注意得让他能访问harbor,比如docker那里设置insecure,还有准备好course项目,用好日志信息
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/weixin_45843419/article/details/124919418
今日推荐