<?xml version="1.0" encoding="utf-8" standalone="yes" ?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>tekton | 伪架构师</title>
    <link>/tags/tekton/</link>
      <atom:link href="/tags/tekton/index.xml" rel="self" type="application/rss+xml" />
    <description>tekton</description>
    <generator>Source Themes Academic (https://sourcethemes.com/academic/)</generator><language>zh</language><lastBuildDate>Thu, 03 Oct 2019 20:37:11 +0800</lastBuildDate>
    <image>
      <url>/img/logo-wide.png</url>
      <title>tekton</title>
      <link>/tags/tekton/</link>
    </image>
    
    <item>
      <title>可能是最适合自定义的 Pipeline：Tekton</title>
      <link>/post/customizable-cicd-tekton/</link>
      <pubDate>Thu, 03 Oct 2019 20:37:11 +0800</pubDate>
      <guid>/post/customizable-cicd-tekton/</guid>
      <description>

&lt;p&gt;持续集成是云原生应用的支柱技术之一，因此在交付基于云原生的一些支撑产品的时候，CICD 是一个无法拒绝的需求。为了满足这种需要，自然而然会想到对 Jenkins(X) 或者 Gitlab 进行集成，然而这两个东西虽说功能强大，却也不是为了做螺丝钉而设计的，其中包含了大量的周边功能，并非我们产品的需要，并且其接口和 Pipeline 设计也不太容易复用和提供给用户进行定制，而 Tekton 这个东西就有趣多了：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Kubernetes 原生
Tekton 的所有配置都是使用 CRD 方式进行编写存储的，非常易于检索和使用。&lt;/li&gt;
&lt;li&gt;配置和流程分离
Tekton 的 Pipeline 和配置可以分开编写，使用名称进行引用。&lt;/li&gt;
&lt;li&gt;轻量级
核心的 Pipeline 非常轻便，适合作为组件进行集成，另外也有周边的 Dashboard、Trigger、CLI 等工具，能够进一步挖掘其潜力。&lt;/li&gt;
&lt;li&gt;可复用、组合的 Pipeline 构建方式
非常适合在集成过程中对 Pipeline 进行定制。&lt;/li&gt;
&lt;/ol&gt;

&lt;h2 id=&#34;安装&#34;&gt;安装&lt;/h2&gt;

&lt;p&gt;安装过程非常轻松：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl apply -f \
    https://storage.googleapis.com/tekton-releases/latest/release.yaml
namespace/tekton-pipelines created
podsecuritypolicy.policy/tekton-pipelines created
clusterrole.rbac.authorization.k8s.io/tekton-pipelines-admin created
...
$ kubectl get pods -n tekton-pipelines
NAME                                           READY   STATUS    RESTARTS   AGE
tekton-pipelines-controller-5888756f5c-t5kgx   1/1     Running   0          2m10s
tekton-pipelines-webhook-7494f6f84b-gm92g      1/1     Running   0          2m10s
&lt;/code&gt;&lt;/pre&gt;

&lt;h2 id=&#34;概念&#34;&gt;概念&lt;/h2&gt;

&lt;p&gt;今天的内容主要涉及几个 CRD：&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;p&gt;Task：任务环节。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;TaskRun：Task 对象的运行参数。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;Pipeline：Task 的组合。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;PipelineRun：Pipeline 的运行参数。&lt;/p&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&#34;hello-world&#34;&gt;Hello world&lt;/h2&gt;

&lt;p&gt;这里有个比 Hello world 稍稍复杂一点的小例子：&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;&lt;p&gt;下载一个文件。&lt;/p&gt;&lt;/li&gt;

&lt;li&gt;&lt;p&gt;传递给下一个环节。&lt;/p&gt;&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;为什么不用官方例子呢？我想糊弄过 CI/CD/DevOps 的同学们应该都清楚，能使用容器、能执行 Shell、能获得输出、能传递文件，这几个能力加起来，足够冒充工具链小能手了。循序渐进并不适合心急的朋友们。&lt;/p&gt;

&lt;h3 id=&#34;下载文件并显示内容&#34;&gt;下载文件并显示内容&lt;/h3&gt;

&lt;p&gt;首先引入的是 Task 对象：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: get-http-file
spec:
  steps:
    - name: show
      image: dustise/sleep
      command:
        - curl
      args:
        - &amp;quot;-s&amp;quot;
        - &amp;quot;https://httpbin.org/ip&amp;quot;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里定义了一个 Task CRD，使用 &lt;code&gt;kubectl apply -f&lt;/code&gt; 提交到集群，会看到 &lt;code&gt;task.tekton.dev/get-http-file created&lt;/code&gt; 的反馈信息。&lt;/p&gt;

&lt;p&gt;要运行这个环节，可以创建一个 TaskRun 对象：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
  name: get-http-file-run
spec:
  taskRef:
    name: get-http-file
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;提交之后，可以使用 &lt;code&gt;kubectl get taskrun get-http-file-run -o yaml&lt;/code&gt; 来查看任务执行状况：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: TaskRun
metadata:
...
status:
...
  conditions:
  - message: All Steps have completed executing
    reason: Succeeded
    status: &amp;quot;True&amp;quot;
    type: Succeeded
  podName: get-http-file-run-pod-51fddd
...
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里能看到很多任务执行信息，还能看到执行这个步骤的 Pod 名称，看看它的日志：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-shell&#34;&gt;$ kubectl logs -f get-http-file-run-pod-51fddd
{
  &amp;quot;origin&amp;quot;: &amp;quot;165.22.223.124, 165.22.223.124&amp;quot;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;看来 CICD 过程中的日志输出和命令执行基本是有保障的，那么如何完成工件的传递呢？&lt;/p&gt;

&lt;h3 id=&#34;文件传递&#34;&gt;文件传递&lt;/h3&gt;

&lt;p&gt;通常我们都会想到使用 PVC 来进行文件存储和共享，例如：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: trans
spec:
  accessModes:
    - ReadWriteOnce
  resources:
    requests:
      storage: 8Gi
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;首先把上面的步骤命令行改为：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;command:
- curl
args:
- &amp;quot;-s&amp;quot;
- &amp;quot;-o&amp;quot;
- &amp;quot;/share/share.json&amp;quot;
- &amp;quot;https://httpbin.org/ip&amp;quot;
volumeMounts:
- name: trans
  mountPath: /share
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;第二个步骤就更加简单，只要显示文件内容即可：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: Task
metadata:
  name: display
spec:
  steps:
    - name: showcontent
      image: alpine
      command: [&amp;quot;cat&amp;quot;]
      args: [&amp;quot;/share/share.json&amp;quot;]
      volumeMounts:
        - name: trans
          mountPath: /share
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里需要使用 Pipeline 对象把步骤连接起来。&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: Pipeline
metadata:
  name: pipeline1
spec:
  tasks:
  - name: step1
    taskRef:
      name: download
  - name: step2
    runAfter: [step1]
    taskRef:
      name: display
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;这里的定义，使用 Pipeline 对象把两个步骤串联起来，其中使用 &lt;code&gt;taskRef&lt;/code&gt; 对我们定义的 &lt;code&gt;download&lt;/code&gt; 和 &lt;code&gt;display&lt;/code&gt; 两个 Task 对象进行引用，并且使用 &lt;code&gt;runAfter&lt;/code&gt; 数组定义先后顺序。&lt;/p&gt;

&lt;p&gt;和 &lt;code&gt;TaskRun&lt;/code&gt; 类似，Pipeline 定义之后，还需要用 PipelineRun 对象来执行一次，上面的 Task 中只定义了 &lt;code&gt;volumeMounts&lt;/code&gt;，具体的 Volume 就要在 PipelineRun 中定义：&lt;/p&gt;

&lt;pre&gt;&lt;code class=&#34;language-yaml&#34;&gt;apiVersion: tekton.dev/v1alpha1
kind: PipelineRun
metadata:
  name: pprun1
spec:
  pipelineRef:
    name: pipeline1
  podTemplate:
    volumes:
      - name: trans
        persistentVolumeClaim:
          claimName: trans
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;把 PipelineRun 提交到集群之后，就可以看到，Pipeline 开始运行，可以使用 &lt;code&gt;kubectl get&lt;/code&gt; 和 &lt;code&gt;kubectl logs&lt;/code&gt; 来查看运行情况。&lt;/p&gt;

&lt;h2 id=&#34;结果&#34;&gt;结果&lt;/h2&gt;

&lt;p&gt;这个项目还是很符合它的名字的描述的，真的只有 Pipeline 而已，它的最重要职责就是用 CRD 进行解耦，用 Step-&amp;gt;Task-&amp;gt;Pipeline 的三级形式对 CICD 中的动作进行抽象和分离；用 Task/TaskRun 以及 Pipeline/PipelineRun/Resource 的组合，把运行环节和输入输出内容进行分离。这样一来，就提供了一个稳定、可重构和组合的过程引擎，以及可定制的执行能力。&lt;/p&gt;

&lt;p&gt;Tekton 还提供了一些其它周边项目，例如 Dashboard、Trigger 等，能给 Pipeline 项目提供一定的帮助。&lt;/p&gt;
</description>
    </item>
    
  </channel>
</rss>
