云原生之Kubernetes:16、详解Operator控制器
详解Operator控制器!
文章目录
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、什么是Operator?
Operator由CoreOS开发的,通过软件的方式进行扩展kubernetes。
Operator通过使用CRD(自定义资源)来管理他们各有应用和基础组件。
CRD(CustomResourceDefinition):通过扩展kubernetesAPI,从而满足用户的定制化需求。
我们后面会具体讲解
同时,Operator也遵循了kubernetes的原理、尤其是控制循环。
注意:Operator的开发和维护工作,并不属于kubernetes本身,而是在于各产品线(mysql、jenkins、prometheus等等)。
他们才是致力于维护各自Operator的主角,并帮助用户快速在kubernetes集群上搭建、维护和高效使用自己的产品。
3、Operator原理
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)
操作之前,你需要make sure确保以下两点:
1、access to a Kubernetes cluster version 1.11+
2、kubectl version 1.11+
1、什么是Jenkins Operator?
jenkins operator是kubernetes平台上原生的,可以全面管理jenkins的控制器,以代码既配置的思想为基础,目前提供了以下几点功能:
1、与kubernetes集成
2、pipelines as code
3、通过groovy脚本配置进行扩展
4、安全和配置增强
2、功能现状
但operator也有不少问题待解决,一些是本身的缺陷,还有一些则是传统架构下jenkins遗留的不足之处:
1、安装具有不兼容版本或安全漏洞的插件
2、更好的配置作为代码思想
3、安全和开箱即用的特性
4、使错误对终端用户更明显
5、备份和还原作业历史记录
6、优雅关闭的处理
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
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
这里有个坑: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
其他具体的配置功能,你可以参考configuration。
更多推荐
所有评论(0)