Skip to content

第3章-k8s原生CI-CD管理工具

本章所讲内容:

3.1 Jenkins 实现 k8s 应用按照指定版本回滚

3.2 什么是 Tekton?

3.3 为什么要用 k8s 原生的 CI-CD 工具 Tekton?

3.4 使用 Tekton 自动化发布应用流程

3.5 安装 Tekton

3.6 Tekton 概念

3.7 测试 Tekton 构建CI/CD 流水线

3.8 自定义 CRD 资源

3.9 通过自定义 CRD 部署 mongodb 集群

安装k8s-1.20(1.20及以前支持tekton)

kubeadm init --kubernetes-version=1.20.4 \
--apiserver-advertise-address=192.168.20.201 \
--image-repository registry.aliyuncs.com/google_containers  \
--service-cidr=10.10.0.0/16 --pod-network-cidr=10.122.0.0/16  --ignore-preflight-errors=SystemVerification | tee kubeadm-init.log

3.1 Jenkins 实现k8s 应用按照指定版本回滚

需要修改 gitee 源码:

https://gitee.com/podchaolucky66/jenkins-sample/blob/master/static/index.html

image-20230830233001642

改完之后:

重新构建刚才的 jenkins-variable-test-deploy,然后看看 qatest、devlopment、production 这个名称空间下是否有两个 rs,有的情况下就是说明镜像更新了

https://gitee.com/podchaolucky66/jenkins-rollout

getVersion.sh

kubectl rollout history deploy/jenkins-demo -n <namespace> | grep -v "deployment" | grep -v "REVISION" | awk '{print $1}' > version.csv

rollout.sh

kubectl rollout undo deployment jenkins-demo  --to-revision=<version> -n <namespace>

回到首页:

新建一个任务------>输入一个任务名称处输入 jenkins-variable-test-deploy-rollout---- >流水

线------>确定------- >在 Pipeline script 处输入如下内容

node('testhan') {
  stage('git clone') {
    git url: "https://gitee.com/qingcaihub/jenkins-rollout/blob/master/getVersion.sh##"
    sh "ls -al"
    sh "pwd"
}
  stage('select env') {
    def envInput = input(
      id: 'envInput',
      message: 'Choose a deploy environment',
      parameters: [
         [
             $class: 'ChoiceParameterDefinition',
             choices: "devlopment\nqatest\nproduction",
             name: 'Env'
         ]
     ]
)
echo "This is a deploy step to ${envInput}"
sh "sed -i 's/<namespace>/${envInput}/' getVersion.sh"
sh "sed -i 's/<namespace>/${envInput}/' rollout.sh"
sh "bash getVersion.sh"
// env.WORKSPACE = pwd()
// def version = readFile "${env.WORKSPACE}/version.csv"
// println version
}
  stage('select version') {
     env.WORKSPACE = pwd()
  def version = readFile "${env.WORKSPACE}/version.csv"
  println version
      def userInput = input(id: 'userInput',
                                        message: '选择回滚版本',
                                        parameters: [
            [
                 $class: 'ChoiceParameterDefinition',
                 choices: "$version\n",
                 name: 'Version'
       ]
      ]
)
       sh "sed -i 's/<version>/${userInput}/' rollout.sh"
}
  stage('rollout deploy') {
      sh "bash rollout.sh"
}
}

image-20230830233031552

image-20230830233036744

点击保存-立即构建

image-20230830233043332

image-20230830233049542

3.2 什么是 Tekton?

3.3 为什么要用 k8s 原生的CI-CD 工具 Tekton?

持续集成是云原生应用的支柱技术之一,因此在交付基于云原生的一些支撑产品的时候,CICD 是非常好的方案。为了满足这种需要,自然而然会想到对 Jenkins(X)或者 Gitlab 进行集成,也有创业公司出来的一些小工具比如 Argo Rollout。Tekton 是一款 k8s 原生的应用发布框架,主要用来构建 CI/CD 系统。它原本是 knative 项目里面一个叫做 build-pipeline 的子项目,用来作为 knative- build 的下一代引擎。然而,随着 k8s 社区里各种各样的需求涌入,这个子项目慢慢成长为一个通用的框架,能够提供灵活强大的能力去做基于 k8s 的构建发布。Tekton 其实只提供 Pipeline 这个一个功能,Pipeline 会被直接映射成 K8s Pod 等 API 资源。而比如应用发布过程的控制,灰度和上线策

略,都是我们自己编写 K8s Controller 来实现的,也就意味着 Tekton 不会在 K8s 上盖一个”大帽子 “,比如我们想看发布状态、日志等是直接通过 K8s 查看这个 Pipeline 对应的 Pod 的状态和日志,不需要再面对另外一个 API。

Tekton 功能:

1. Kubernetes 原生的 Tekton 的所有配置都是使用 CRD 方式进行编写存储的,非常易于检索和使

用。

2. 配置和流程分离: Tekton 的 Pipeline 和配置可以分开编写,使用名称进行引用。

3. 轻量级核心的 Pipeline 非常轻便:适合作为组件进行集成,另外也有周边的 Dashboard、 Trigger、CLI 等工具,能够进一步挖掘其潜力。

4. 可复用、组合的 Pipeline 构建方式:非常适合在集成过程中对 Pipeline 进行定制。

3.4 使用 Tekton 自动化发布应用流程

image-20230830233102819

这里的流程大致是:

1、用户把需要部署的应用先按照一套标准的应用定义写成 YAML 文件(类似 Helm Chart);

2、用户把应用定义 YAML 推送到 Git 仓库里;

3、Tekton CD (一个 K8s Operator) 会监听到相应的改动,根据不同条件生成不同的 Tekton Pipelines;

Tekton CD 的操作具体分为以下几种情况:

1、如果 Git 改动里有一个应用 YAML 且该应用不存在,那么将渲染和生成 Tekton Pipelines

用来创建应用。

2、如果 Git 改动里有一个应用 YAML 且该应用存在,那么将渲染和生成 Tekton Pipelines 用来升级应用。这里我们会根据应用定义 YAML 里的策略来做升级,比如做金丝雀发布、灰度升级。

3、如果 Git 改动里有一个应用 YAML 且该应用存在且标记了“被删除”,那么将渲染和生成

Tekton Pipelines 用来删除应用。确认应用被删除后,我们才从 Git 里删除这个应用的 YAML。

Tekton 相关的资源:

Tekton 为 Kubernetes 提供了多种 CRD 资源对象,可用于定义我们的流水线,主要有以下几个

CRD 资源对象:

1) Task:表示执行命令的一系列步骤,task 里可以定义一系列的 steps,例如编译代码、构建镜像、推送镜像等,每个 step 实际由一个 Pod 里的容器执行。

2) TaskRun:task 只是定义了一个模版,taskRun 才真正代表了一次实际的运行,当然你也可以自己手动创建一个 taskRun,taskRun 创建出来之后,就会自动触发 task 描述的构建任务。

3) Pipeline:一组任务,表示一个或多个 task、PipelineResource 以及各种定义参数的集合。

4) PipelineRun:类似 task 和 taskRun 的关系,pipelineRun 也表示某一次实际运行的 pipeline,下发一个 pipelineRun CRD 实例到 Kubernetes 后,同样也会触发一次 pipeline 的构建。

5) PipelineResource:表示 pipeline 输入资源,比如 github 上的源码,或者 pipeline 输出资源,例如一个容器镜像或者构建生成的 jar 包等。

Crd 官方文档:

https://kubernetes.io/zh/docs/tasks/extend-kubernetes/custom-resources/custom- resource-definitions/

3.5 安装 Tekton

##把 tekton-0-12-0.tar.gz 和 busybox-1-0.tar.gz 上传到k8s-node01, k8s-node02机器上,手动解压:

[root@k8s-node01 ~]## docker load -i busybox-1-0.tar.gz 
[root@k8s-node01 ~]## docker load -i xuegod-tekton-0-12-0.tar.gz

[root@k8s-node02 ~]## docker load -i busybox-1-0.tar.gz 
[root@k8s-node02 ~]## docker load -i xuegod-tekton-0-12-0.tar.gz

##编写安装 tekton 资源清单文件(上传)

[root@k8s-master01 tekton]## kubectl apply -f release.yaml

验证 pod 是否创建成功

[root@k8s-master01 tekton]## kubectl get pod -n tekton-pipelines
NAME                                          READY   STATUS    RESTARTS   AGE
tekton-pipelines-controller-df779b44b-zrbrz   1/1     Running   0          41s
tekton-pipelines-webhook-6bb6b45fd4-tq49t     1/1     Running   0          41s
[root@k8s-master01 tekton]## kubectl get crd |egrep "pipeline|task"

找到下面这些东西,说明创建 crd 成功了:

clustertasks.tekton.dev                               2023-08-24T13:03:03Z
pipelineresources.tekton.dev                          2023-08-24T13:03:03Z
pipelineruns.tekton.dev                               2023-08-24T13:03:03Z
pipelines.tekton.dev                                  2023-08-24T13:03:03Z
taskruns.tekton.dev                                   2023-08-24T13:03:03Z
tasks.tekton.dev                                      2023-08-24T13:03:03Z
[root@k8s-master01 tekton]## kubectl api-versions |grep tekton

看到下面说明 apiversion 创建成功了

tekton.dev/v1alpha1
tekton.dev/v1beta1

3.6 Tekton 概念

Tekton 为 Kubernetes 提供了多种 CRD 资源对象,可用于定义我们的流水线,主要有以下几个

CRD 资源对象:

1) Task:表示执行命令的一系列步骤,task 里可以定义一系列的 steps,例如编译代码、构建镜像、推送镜像等,每个 step 实际由一个 Pod 里的容器执行。

2) TaskRun:task 只是定义了一个模版,taskRun 才真正代表了一次实际的运行,当然你也可以自己手动创建一个 taskRun,taskRun 创建出来之后,就会自动触发 task 描述的构建任务。

3) Pipeline:一组任务,表示一个或多个 task、PipelineResource 以及各种定义参数的集合。

4) PipelineRun:类似 task 和 taskRun 的关系,pipelineRun 也表示某一次实际运行的 pipeline,下发一个 pipelineRun CRD 实例到 Kubernetes 后,同样也会触发一次 pipeline 的构建。

5) PipelineResource:表示 pipeline 输入资源,比如 github 上的源码,或者 pipeline 输出资源,例如一个容器镜像或者构建生成的 jar 包等。

Crd 官方文档:

https://kubernetes.io/zh/docs/tasks/extend-kubernetes/custom-resources/custom- resource-definitions/

3.7 测试 Tekton 构建CI/CD 流水线

我们测试一个简单的 golang 程序。应用程序代码,测试及 dockerfile 文件可在如下地址获取:

https://github.com/xuegod66/tekton-demo

https://gitee.com/podchaolucky66/tekton-demo

3.7.1 clone 应用程序代码进行测试,创建一个 task 任务

[root@k8s-master01 tekton]## cat 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
    imagePullPolicy: IfNotPresent
    workingDir: /workspace/repo
    command: ["go"]
    args: ["test"]

更新资源清单文件

[root@k8s-master01 tekton]## kubectl apply -f task-test.yaml

##查看 Task 资源

[root@k8s-master01 tekton]## kubectl get task
NAME   AGE
test   15s

##上面内容解释说明:

resources 定义了我们的任务中定义的步骤中需要输入的内容,这里我们的步骤需要 Clone 一个 Git 仓库作为 go test 命令的输入。Tekton 内置了一种 git 资源类型,它会自动将代码仓库 Clone到 /workspace/$input_name 目录中,由于我们这里输入被命名成 repo,所以代码会被 Clone到 /workspace/repo 目录下面。然后下面的 steps 就是来定义执行运行测试命令的步骤,这里我们直接在代码的根目录中运行 go test 命令即可,需要注意的是命令和参数需要分别定义

3.7.2 创建 pipelineresource 资源对象

通过上面步骤我们定义了一个 Task 任务,但是该任务并不会立即执行,我们必须创建一个 TaskRun 引用它并提供所有必需输入的数据才行。这里我们就需要将 git 代码库作为输入,我们必须先创建一个 PipelineResource 对象来定义输入信息,创建一个名为 pipelineresource.yaml 的资源清 单文件,内容如下所示:

[root@k8s-master01 tekton]## cat pipelineresource.yaml 
apiVersion: tekton.dev/v1alpha1
kind: PipelineResource
metadata:
  name: xuegod-tekton-example
spec:
  type: git
  params:
    - name: url
      value: https://gitee.com/qingcaihub/tekton-demo
    - name: revision
      value: master

##更新资源清单文件

[root@k8s-master01 tekton]## kubectl apply -f pipelineresource.yaml

3.7.3 创建 taskrun 任务

[root@k8s-master01 tekton]## cat taskrun.yaml 
apiVersion: tekton.dev/v1beta1
kind: TaskRun
metadata:
  name: testrun
spec:
  taskRef:
    name: test
  resources:
    inputs:
    - name: repo
      resourceRef:
        name: xuegod-tekton-example

##更新资源清单文件

[root@k8s-master01 tekton]## kubectl apply -f taskrun.yaml

上面资源清单文件解释说明

这里通过 taskRef 引用上面定义的 Task 和 git 仓库作为输入,resourceRef 也是引用上面定义的PipelineResource 资源对象。

##创建后,我们可以通过查看 TaskRun 资源对象的状态来查看构建状态

[root@k8s-master01 tekton]## kubectl get taskrun
NAME      SUCCEEDED   REASON      STARTTIME   COMPLETIONTIME
testrun   True        Succeeded   46s         37s
[root@k8s-master01 tekton]## kubectl get pod 
NAME                READY   STATUS      RESTARTS   AGE
testrun-pod-z97ds    2/2    Running     0           9s

当任务执行完成后, Pod 就会变成 Completed 状态了:

[root@k8s-master01 tekton]## kubectl get pod 
NAME                READY   STATUS      RESTARTS   AGE
testrun-pod-z97ds   0/2     Completed   0          61s

我们可以通过 kubectl describe 命令来查看任务运行的过程,首先就是通过 initContainer 中的一个 busybox 镜像将代码 Clone 下来,然后使用任务中定义的镜像来执行命令。当任务执行完成后, Pod 就会变成 Completed 状态了,我们可以查看容器的日志信息来了解任务的执行结果信息:

[root@k8s-master01 tekton]## kubectl logs testrun-pod-z97ds --all-containers
{"level":"info","ts":1692882679.338511,"caller":"git/git.go:136","msg":"Successfully cloned https://gitee.com/qingcaihub/tekton-demo @ c6c2a85091d538a13c44f85bcee9e861c362b0d3 (grafted, HEAD, origin/master) in path /workspace/repo"}
{"level":"info","ts":1692882679.3569958,"caller":"git/git.go:177","msg":"Successfully initialized and updated submodules in path /workspace/repo"}
PASS
ok      _/workspace/repo    0.001s

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

总结:我们已经在 Kubernetes 集群上成功安装了 Tekton,定义了一个 Task,并通过 YAML 清单和创建 TaskRun 对其进行了测试。

3.8 自定义CRD 资源

3.8.1 通过 **crd 资源创建自定义资源,即自定义一个 Restful API: **

[root@k8s-master01 tekton]## cat crontab-crd.yaml 
apiVersion: apiextensions.k8s.io/v1
kind: CustomResourceDefinition
metadata:
  name: crontabs.stable.example.com
spec:
  group: stable.example.com
  versions:
    - name: v1
      served: true
      storage: true
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer
  scope: Namespaced
  names:
    plural: crontabs
    singular: crontab
    kind: CronTab
    shortNames:
    - ct

Yaml 文件注解:

metadata.name** 是用户自定义资源中自己自定义的一个名字。一般我们建议使用“顶级域名.xxx.APIGroup”这样的格式,名称必须与下面的 spec.Group 字段匹配,格式为:

<plural>.<group>



spec 用于指定该 CRD 的 group、version。比如在创建 Pod 或者 Deployment 时,它的group 可能为 apps/v1 或者 apps/v1beta1 之类,这里我们也同样需要去定义 CRD 的 group。


  group: stable.example.com##组名称 
  versions:
    - name: v1 ##指定组下的版本
      served: true ##每个版本都可以通过服务标志启用/禁用
      storage: true ##必须将一个且只有一个版本标记为存储版本。
      schema:
        openAPIV3Schema:
          type: object
          properties:
            spec:
              type: object
              properties:
                cronSpec:
                  type: string
                image:
                  type: string
                replicas:
                  type: integer


  scope: Namespaced ##指定 crd 资源作用范围在命名空间或集群
  names:  ##指的是它的 kind 是什么,比如 Deployment 的 kind 就是 Deployment,Pod 的kind 就是 Pod,这里的 kind 被定义为了 CronTab
    plural: crontabs ##字段就是一个昵称,比如当一些字段或者一些资源的名字比较长时,可以用该字段自定义一些昵称来简化它的长度;
    singular: crontab  ## 在 CLI(shell 界面输入的参数)上用作别名并用于显示的单数名称
    kind: CronTab
    shortNames:
    - ct   ## 短名称允许短字符串匹配 CLI 上的资源,就是能通过 kubectl 在查看资源的时候使用该资源的简名称来获取。

创建自定义 contab 资源

[root@k8s-master01 tekton]## kubectl apply -f crontab-crd.yaml

查看

$ kubectl get crd

查看自定义 crontab 资源的信息

$ kubectl get crontab$ kubectl get crontab

3.8.2 创建自定义资源的对象

根据 crd 对象资源创建出来的RESTful API,来创建 crontab 类型资源对象

[root@k8s-master01 tekton]## cat my-crontab.yaml 
apiVersion: "stable.example.com/v1"
kind: CronTab
metadata:
  name: my-new-cron-object
spec:
  cronSpec: "* * * * * *"
  image: busybox
[root@k8s-master01 tekton]## kubectl apply -f my-crontab.yaml

##查看资源

[root@k8s-master01 tekton]## kubectl get crontab
NAME                 AGE
my-new-cron-object   13s

提示:可以看到对应类型资源已经创建成功;以上示例只是单纯的 crd 的使用示例,没有任何实质的作用。

3.9 、通过自定义 CRD 部署mongodb 集群

示例:部署 mongodb-aperator

1、项目地址

https://github.com/mongodb/mongodb-kubernetes-operator.git

找到 0.5.0,看这个版本对应使用

把课件里的压缩包传到 k8s 控制节点上,手动解压

[root@k8s-master01 tekton]## unzip mongodb-kubernetes-operator-0.5.0.zip

2、创建名称空间 mongodb,并进入到 mongodb-kubernetes-operator 目录应用 crd 资源,创建自定义资源类型

[root@k8s-master01 tekton]## kubectl create ns mongodb
[root@k8s-master01 tekton]## cd mongodb-kubernetes-operator-0.5.0
[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl apply -f deploy/crds/mongodb.com_mongodbcommunity_crd.yaml

##查看 mongodb 是否创建成功

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl get crd/mongodbcommunity.mongodb.com
NAME                           CREATED AT
mongodbcommunity.mongodb.com   2023-08-24T13:31:15Z

3、安装 operator

[root@k8s-node01 ~]## docker load -i mongodb-kubernetes-operator.tar.gz
[root@k8s-node02 ~]## docker load -i mongodb-kubernetes-operator.tar.gz

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl apply -f deploy/operator/ -n mongodb

提示:mongodb-kubernetes-operator 这个项目是将自定义控制器和自定义资源类型分开实现的;其 operator 只负责创建和监听对应资源类型的变化,在资源有变化时,实例化为对应资源对象,并保持对应资源对象状态吻合用户期望状态;上述四个清单中主要是创建了一个 sa 账户,并对对应的 sa 用户授权;

验证:查看 operator 是否正常运行

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl get pods -n mongodb
NAME                                           READY   STATUS    RESTARTS   AGE
mongodb-kubernetes-operator-694855ccf5-8hfht   1/1     Running   0          17s

验证:使用自定义资源类型创建一个 mongodb 副本集集群

[root@k8s-node01 ~]## docker load -i mongo4.2.6.tar.gz
[root@k8s-node02 ~]## docker load -i mongo4.2.6.tar.gz

[root@k8s-node01 ~]## docker load -i mongodb-k8s-hook.tar
[root@k8s-node02 ~]## docker load -i mongodb-k8s-hook.tar
[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## cat deploy/crds/mongodb.com_v1_mongodbcommunity_cr.yaml
---
apiVersion: mongodb.com/v1
kind: MongoDBCommunity
metadata:
  name: example-mongodb
spec:
  members: 3
  type: ReplicaSet
  version: "4.2.6"
  security:
    authentication:
      modes: ["SCRAM"]
  users:
    - name: my-user
      db: admin
      passwordSecretRef: ## a reference to the secret that will be used to generate the user's password
        name: my-user-password
      roles:
        - name: clusterAdmin
          db: admin
        - name: userAdminAnyDatabase
          db: admin
      scramCredentialsSecretName: my-scram

## the user credentials will be generated from this secret
## once the credentials are generated, this secret is no longer required
---
apiVersion: v1
kind: Secret
metadata:
  name: my-user-password
type: Opaque
stringData:
  password: 58LObjiMpxcjP1sMDW
[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl apply -f deploy/crds/mongodb.com_v1_mongodbcommunity_cr.yaml -n mongodb
[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl get pods -n mongodb
NAME                                           READY   STATUS    RESTARTS   AGE
example-mongodb-0                              0/2     Pending   0          60s
mongodb-kubernetes-operator-694855ccf5-8hfht   1/1     Running   0          3m51s

提示:这里可以看到对应 pod 处于 pending 状态;查看 pod 详细信息

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl describe pod -n mongodb example-mongodb-0 |grep -A 10 "Events"
Events:
  Type     Reason            Age    From               Message
  ----     ------            ----   ----               -------
  Warning  FailedScheduling  2m14s  default-scheduler  0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.
  Warning  FailedScheduling  2m14s  default-scheduler  0/3 nodes are available: 3 pod has unbound immediate PersistentVolumeClaims.

提示:这里提示没有可以用的 pvc;删除 mongodb 名称空间下 pvc

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl get pvc -n mongodb
NAME                            STATUS    VOLUME   CAPACITY   ACCESS MODES   STORAGECLASS   AGE
data-volume-example-mongodb-0   Pending                                                     3m16s
[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl delete pvc --all -n mongodb

创建 pv 和 pvc

[root@k8s-master01 tekton]## cat pv-demo.yaml 
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  nfs-pv-v1
  labels:
    app: example-mongodb-svc 
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]
  persistentVolumeReclaimPolicy: Retain
  mountOptions:
  - hard
  - nfsvers=4.1
  nfs:
    path: /data/p1
    server: 192.168.20.201
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  nfs-pv-v2
  labels:
    app: example-mongodb-svc 
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]
  persistentVolumeReclaimPolicy: Retain
  mountOptions:
  - hard
  - nfsvers=4.1
  nfs:
    path: /data/p2
    server: 192.168.20.201
---
apiVersion: v1
kind: PersistentVolume
metadata:
  name:  nfs-pv-v3
  labels:
    app: example-mongodb-svc 
spec:
  capacity:
    storage: 1Gi
  volumeMode: Filesystem
  accessModes: ["ReadWriteOnce","ReadWriteMany","ReadOnlyMany"]
  persistentVolumeReclaimPolicy: Retain
  mountOptions:
  - hard
  - nfsvers=4.1
  nfs:
    path: /data/p3
    server: 192.168.20.201
[root@k8s-master01 tekton]## mkdir /data/p1
[root@k8s-master01 tekton]## mkdir /data/p2
[root@k8s-master01 tekton]## mkdir /data/p3
[root@k8s-master01 tekton]## vim /etc/exports
[root@k8s-master01 tekton]## cat /etc/exports
/data/v1 *(rw,no_root_squash)
/data/p1 *(rw,no_root_squash)
/data/p2 *(rw,no_root_squash)
/data/p3 *(rw,no_root_squash)

[root@k8s-master01 tekton]## exportfs -arv
[root@k8s-master01 tekton]## kubectl apply -f pv-demo.yaml 

创建 pvc 资源

[root@k8s-master01 tekton]## cat pvc-demo.yaml 
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-volume-example-mongodb-0
  namespace: mongodb
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 500Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-volume-example-mongodb-1
  namespace: mongodb
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 500Mi
---
apiVersion: v1
kind: PersistentVolumeClaim
metadata:
  name: data-volume-example-mongodb-2
  namespace: mongodb
spec:
  accessModes:
    - ReadWriteMany
  volumeMode: Filesystem
  resources:
    requests:
      storage: 500Mi
[root@k8s-master01 tekton]## kubectl apply -f pvc-demo.yaml

如果再出现镜像拉取失败,请关闭科学

[root@k8s-master01 mongodb-kubernetes-operator-0.5.0]## kubectl get pod -n mongodb
NAME                                           READY   STATUS    RESTARTS   AGE
example-mongodb-0                              2/2     Running   2          8m10s
example-mongodb-1                              2/2     Running   0          2m
example-mongodb-2                              2/2     Running   0          89s
mongodb-kubernetes-operator-694855ccf5-qvghv   1/1     Running   4          9h

总结:

3.1 Jenkins 实现 k8s 应用按照指定版本回滚

3.2 什么是 Tekton?

3.3 为什么要用 k8s 原生的 CI-CD 工具 Tekton?

3.4 使用 Tekton 自动化发布应用流程

3.5 安装 Tekton

3.6 Tekton 概念

3.7 测试 Tekton 构建CI/CD 流水线

3.8 自定义 CRD 资源

3.9 通过自定义 CRD 部署 mongodb 集群