16.实践篇:让我们聊一聊运维利器(三):Operator控制器

16.实践篇:让我们聊一聊运维利器(三):Operator控制器

2020-02-07 15:25:56

1.为什么还需要Operator?

        我们前面讲了很多很多基础的资源对象和控制器,如pod、deployment、service、deployment等等,仿佛已经满足了我们大多数情况的场景和需求了,那我们为什么还需要operator呢?


        我们再来回顾一下,无状态应用(如nginx)的扩容是最方便的,我们只要使用deployment控制器中的ReplicaSet字段申明,我们需要几个数量的nginx节点即可。

那对于有状态应用呢?

此时你可能想到,StatefulSet控制器,没错!他的确能够帮助我们解决有状态应用基础的扩缩容动作和行为逻辑,但是还有大多数场景,他是完成不了的。

如mysql主从集群、多主集群的扩缩容、备份、数据迁移等包含一系列传统架构中,需要运维人员介入,并通过脚本处理的复杂操作。

另外,在Kubernetes上运维人员通常喜欢使用自动化来处理重复的任务。

Operator控制器就是将运维人员的知识、操作和预期翻译成代码片段,如果你了解jenkins,就好比jenkins file、DSL和groovy。
这是我一直坚信和推崇的一个理念:“基础设施即代码”(Infrastructure as Code)

        正是如此,他们每个节点具有不同的角色配置文件、启动顺序、依赖性和自动化操作。此时,StatefulSet控制器已经胜任不了了,Operator就此诞生!

2.What is Operator?

        Operator由CoreOS开发的,通过软件的方式进行扩展kubernetes。Operator通过使用CRD(自定义资源)来管理他们各有应用和基础组件。

CRD(CustomResourceDefinition):通过扩展kubernetesAPI,从而满足用户的定制化需求。我们后面会具体讲解

同时,Operator也遵循了kubernetes的原理、尤其是控制循环。

注意:Operator的开发和维护工作,并不属于kubernetes本身,而是在于各产品线(mysql、jenkins、prometheus等等)。他们才是致力于维护各自Operator的主角,并帮助用户快速在kubernetes集群上搭建、维护和高效使用自己的产品。

3.Operator原理

operator.png

        Operator通过扩展Kubernetes定义Custom Controller,观察应用并根据实际状态执行自定义任务。应用被定义为Kubernetes对象:Custom Resource (CR),它包含yaml spec和被API服务接受的对象类型。如图所示,Operator控制器的调度逻辑和以往原生控制器调度的逻辑有以下的不同点:

1.Operator通过Custom Controller协调应用的spec属性,原生控制器则通过kubelet;
2.Operator可以独立运行在集群内部或外部,原生控制器则必须运行于集群内部。

Operator控制器真正价值来自于你对应用失败状态处理的最佳实践,以及Operator如何协同人工干预的期望逻辑。

4.Operator应用场景

如果有以下涉及的工作内容刚需,你可以选择operator来帮助你:

1>按需部署应用程序
2>获取并恢复应用程序状态的备份数据
3>处理应用程序升级相关的变更需求,如数据库库表,或者是额外事项的配置
4>发布一个服务,使得原本kubernetes API原生不支持的应用可以发现它
5>模拟整个或部分集群中的故障以测试其弹性
6>在没有内部成员选举程序的情况下,为分布式应用程序选择一位领导者

5.如何部署Operator

我们部署Operator最常见也是最通用的方法就是,在我们的kubernetes集群中,新增相应的CRD资源,以及和他相关联的控制器。

这个控制器通常运行于控制平面(https://kubernetes.io/docs/reference/glossary/?all=true#term-control-plane)之外

这里我还整理了两个市面上主流的Operator资源社区,供你实践时参考使用:
operatorhub.io(https://operatorhub.io/)
awesome-operators(https://github.com/operator-framework/awesome-operators)

6.如何使用Operator

通过上面我提供的2个地址,你可以找到自己所需的Operator资源。你可以通过一系列的帮助和文档,可能会经历一些坎坷,完成你的第一个Operator的部署工作。一旦你部署完成,你就可以像使用原生kubernetes控制器的方法来操作他了,如:get、delete等方法。不同的是,每个Operator都有各自特有的类型(kind),如下所示:

#mysql operator的常用操作
kuberctl get mysql
kuberctl edit mysql/mysql-1

7.实战:部署一个Jenkins Operator(v0.3.x)

jenkins_operator.png

操作之前,你需要make sure确保以下两点:
1.access to a Kubernetes cluster version 1.11+
2.kubectl version 1.11+

7.1.What's the Jenkins Operator?

        jenkins operator是kubernetes平台上原生的,可以全面管理jenkins的控制器,以代码既配置的思想为基础,目前提供了以下几点功能:

1>与kubernetes集成
2>pipelines as code
3>通过groovy脚本配置进行扩展
4>安全和配置增强

7.2.功能现状

但operator也有不少问题待解决,一些是本身的缺陷,还有一些则是传统架构下jenkins遗留的不足之处:

1>安装具有不兼容版本或安全漏洞的插件
2>更好的配置作为代码思想
3>安全和开箱即用的特性
4>使错误对终端用户更明显
5>备份和还原作业历史记录
6>优雅关闭的处理
7>生命周期内端到端的测试

7.3.环境安装

1)首先,我们来部署专有的CRD资源

kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/crds/jenkins_v1alpha2_jenkins_crd.yaml

你可以不难发现,Jenkins Operator有特有的kind名称:jenkins.jenkins.io,并且是名称空间级别的资源。

apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
  name: jenkins.jenkins.io
spec:
  group: jenkins.io
  names:
    kind: Jenkins
    listKind: JenkinsList
    plural: jenkins
    singular: jenkins
  scope: Namespaced
  versions:
    - name : v1alpha2
      served: true
      storage: true
    - name : v1alpha1
      served: true
      storage: false

2)接下来,我们要创建名为jenkins-operator的ServiceAccount、role名为jenkins-operator的RBAC策略、镜像为virtuslab/jenkins-operator:v0.3.1、并且运行在default名称空间中。

kubectl apply -f https://raw.githubusercontent.com/jenkinsci/kubernetes-operator/master/deploy/all-in-one-v1alpha2.yaml

如果碰到镜像拉取失败的情况,你可以在Jenkins_docker_hub(https://hub.docker.com/r/virtuslab/jenkins-operator)获取相关镜像

3)此时,你可以通过命令kubectl get pods -w观察pod资源的生成情况了。

jenkins-operator-7768f7c484-rhnhz   0/1   Pending   0     0s
jenkins-operator-7768f7c484-rhnhz   0/1   Pending   0     0s
jenkins-operator-7768f7c484-rhnhz   0/1   ContainerCreating   0     0s
jenkins-operator-7768f7c484-rhnhz   1/1   Running   2     76s

7.4.部署Jenkins

1)Jenkins Operator我们已经部署并运行起来了,接下来我们要运行一个实际的本地jenkins实例。

apiVersion: jenkins.io/v1alpha2
kind: Jenkins
metadata:
  name: example
spec:
  master:
    containers:
    - name: jenkins-master
      image: jenkins/jenkins:lts
      imagePullPolicy: Always
      livenessProbe:
        failureThreshold: 12
        httpGet:
          path: /login
          port: http
          scheme: HTTP
        initialDelaySeconds: 80
        periodSeconds: 10
        successThreshold: 1
        timeoutSeconds: 5
      readinessProbe:
        failureThreshold: 3
        httpGet:
          path: /login
          port: http
          scheme: HTTP
        initialDelaySeconds: 30
        periodSeconds: 10
        successThreshold: 1
        timeoutSeconds: 1
      resources:
        limits:
          cpu: 1500m
          memory: 3Gi
        requests:
          cpu: "1"
          memory: 500Mi
  seedJobs:
  - id: jenkins-operator
    targets: "cicd/jobs/*.jenkins"
    description: "Jenkins Operator repository"
    repositoryBranch: master
    repositoryUrl: https://github.com/jenkinsci/kubernetes-operator.git

jenkins_operator_issue.png

这里有个坑:pod初始化的时候会去下载很多插件,探针的初始检查时间为80秒;你要视本身网络情况调整initialDelaySeconds字段的值;或者通过squid等代理的方式进行规避。

2)你可以通过以下命令申明,并观察相关资源的生成。

#声明我们的配置文件
kubectl apply -f jenkins_instance.yaml

#观察pod情况
kubectl get pods -w

3)你可以通过以下命令获取登录所需的用户名和密码信息。

kubectl get secret jenkins-operator-credentials-example -o 'jsonpath={.data.user}' | base64 -d
kubectl get secret jenkins-operator-credentials-example -o 'jsonpath={.data.password}' | base64 -d

4)接下来我们连上jenkins就可以了,此时你就可以在本地的localhost:8080访问jenkins的登录页面了。

minikube:

minikube service jenkins-operator-http-<cr_name> --url

kubelet:

kubectl port-forward jenkins-<cr_name> 8080:8080

jenkins.operator.png

其他具体的配置功能,你可以参考configuration

@版权声明:51CTO独家出品,未经允许不能转载,否则追究法律责任


版权声明:
作者:WaterBear
链接:https://l-t.top/2052.html
来源:雷霆运维
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
< <上一篇
下一篇>>
文章目录
关闭
目 录