目录
自定义资源定义
创建和部署自定义资源定义
定制控制器
Operator开发
Kubernetes示例控制器
Operator Framework
创建和部署Kubernetes Operator
Kubernetes已经拥有丰富的资源集,从作为构建块的Pod到有状态集和部署等高级资源。可以根据Kubernetes资源及其高级配置选项来部署现代云原生应用程序。但是,当需要人员专业知识和操作时,这些功能还不够。
本文摘录自OnurYılmaz撰写的Packt Publishing的《Kubernetes设计模式和扩展》一书。本书涵盖了Kubernetes的最佳实践,设计模式,Kubernetes扩展点的基础知识,Kubernetes的网络模型等等。
在本文中,您将学习有关扩展Kubernetes API,创建和部署自定义资源定义,自定义控制器等的知识。
Kubernetes支持使用新资源扩展其自己的API并将其作为具有以下功能的Kubernetes本地对象进行操作:
扩展Kubernetes API涉及两个主要步骤:
在Kubernetes中,所有资源在Kubernetes API服务器中都有其REST端点。REST端点通过使用 /api/v1/namespaces/default/pods对特定对象(例如Pod)启用操作。自定义资源是Kubernetes API的扩展,可以在运行时动态添加或删除。它们使群集的用户可以在扩展资源上运行。
定制资源在“定制资源定义”(CRD)对象中定义。使用内置的Kubernetes资源(即CRD),可以使用Kubernetes API本身添加新的Kubernetes API端点。
考虑到客户希望在Kubernetes中以可扩展的云原生方式观看天气报告。我们预计将扩展Kubernetes API,以便客户端和其他将来的原生应用程序使用天气报告资源。我们想要创建CustomResourceDefinitions并将其部署到集群中以检查其效果,并使用新定义的资源来创建扩展对象。
让我们开始执行以下步骤:
1、使以下命令,使用kubectl部署自定义资源定义:
kubectl apply -f k8s-operator-example/deploy/crd.yaml
自定义资源定义是Kubernetes资源,可动态注册新的自定义资源。可以在 k8s-operator-example/deploy/crd.yaml文件中定义WeatherReport的示例自定义资源,如下所示:
apiVersion: apiextensions.k8s.io/v1beta1
kind: CustomResourceDefinition
metadata:
name: weatherreports.k8s.packt.com
spec:
group: k8s.packt.com
names:
kind: WeatherReport
listKind: WeatherReportList
plural: weatherreports
singular: weatherreport
scope: Namespaced
version: v1
像所有其他Kubernetes资源一样,CRD具有API版本,种类,元数据和规范组。此外,CRD的规范还包括新定制资源的定义。对于WeatherReport,将在k8s.packt.com下以v1的版本创建REST端点,并且将在客户端中使用其复数形式和单数形式。
2、使用以下命令检查部署到集群的自定义资源:
kubectl get crd
您将获得以下输出:
如上面的屏幕快照所示,天气报告CRD由复数名称和组名称定义。
3、检查API服务器的REST端点是否有新的自定义资源:
kubectl proxy &
curl -s localhost:8001 |grep packt
您将获得以下输出:
创建了新的端点,这表明Kubernetes API服务器已经扩展为可以与我们的新自定义资源weatherreports一起使用。
4、检查来自Kubernetes客户端的天气报告实例,例如kubectl:
kubectl get weatherreports
您将获得以下输出:
尽管“找不到资源”的输出看起来像是一个错误的指示,但它向我们显示了没有预期的weatherreports资源的实时实例。它向我们显示,除了创建CustomResourceDefinition之外,无需任何其他配置,Kubernetes API服务器将扩展为新的端点,并且客户端已准备好使用新的自定义资源。
定义自定义资源后,现在可以使用WeatherReport创建、更新和删除资源。可以定义WeatherReport的示例,如k8s-operator-example/deploy/cr.yaml文件中所示:
apiVersion: "k8s.packt.com/v1"
kind: WeatherReport
metadata:
name: amsterdam-daily
spec:
city: Amsterdam
days: 1
WeatherReport资源具有相同的结构,带有内置资源,并且由API版本,种类,元数据和规范组成。在此示例中,说明指示此资源用于阿姆斯特丹市以及最近1天的天气预报。
5、使用以下命令部署天气报告示例:
kubectl apply -f k8s-operator-example/deploy/cr.yaml
6、使用以下命令检查新创建的天气报告:
kubectl get weatherreports
您将看到以下输出:
7、使用以下命令进行清理:
kubectl delete -f k8s-operator-example/deploy/cr.yaml
kubectl delete -f k8s-operator-example/deploy/crd.yaml
定制控制器(也称为运算符)是一种将领域知识和专业知识转换为代码的应用程序。operator使用自定义资源,并在创建,更新或删除自定义资源时采取必要的措施。operator的主要任务可以分为三个部分,Observe,Analyze和Act,如下图所示:
这些阶段解释如下:
对于天气报告示例,operator模式应按以下方式工作:
Kubernetes环境中已经使用了operator,因为它们使复杂的应用程序能够以最少的人工交互在云上运行。存储提供商(Rook),数据库应用程序(MySQL,CouchDB,PostgreSQL),大数据解决方案(Spark),分布式键/值存储库(Consul等)以及更多现代云原生应用程序由其官方operator安装在Kubernetes上。
Operator是本地Kubernetes应用程序,它们与Kubernetes API进行广泛的交互。因此,遵守Kubernetes API并通过简单的方法将领域专业知识转换为软件对于operator开发至关重要。考虑到这些因素,开发operator有两条途径,如以下各节所述。
在正式的Kubernetes存储库中,维护了一个实现监视自定义资源的示例控制器。该存储库演示了如何注册新的自定义资源以及如何对新资源执行基本操作,例如创建、更新或列出。此外,还实现了控制器逻辑以显示如何采取措施。存储库以及与Kubernetes API的交互是一种完整的方法,它向您展示了如何创建类似自定义控制器的Kubernetes。
在KubeCon 2018上宣布了Operator Framework,它是一个用于管理Kubernetes本机应用程序的开源工具包。Operator SDK是此框架的一部分,它通过提供更高级别的API抽象和代码生成来简化operator开发。Operator Framework及其环境工具集是开源的,并由CoreOS控制维护社区。
以下主要步骤涵盖了operator开发的整个生命周期:
客户希望自动化天气报告收集的操作。他们当前正在连接到第三方数据提供者并检索结果。此外,他们希望在集群中使用云原生的Kubernetes解决方案。我们预计将通过实现Kubernetes operator来自动化天气报告数据收集的操作。我们将通过使用Operator Framework SDK来创建Kubernetes operator,并通过创建自定义资源,自定义控制器逻辑并最终将其部署到集群中来利用它。让我们开始执行以下步骤:
1、通过以下命令使用Operator Framework SDK工具创建operator项目:
operator-sdk new k8s-operator-example --api-version=k8s.
packt.com/v1 --kind=WeatherReport
该命令创建一个名称为k8s-operator-example的全新Kubernetes operator项目,并监视WeatherReport自定义资源的更改,该资源在k8s.packt.com/v1下定义。生成的operator项目位于k8s-operator-example文件夹下。
2、在deploy/crd.yaml文件中已经生成了自定义资源定义。但是,自定义资源的规范保留为空,以便开发人员可以填充它。自定义资源的规范和状态在Go中编码,如pkg/apis/k8s/v1/types.go中所示:
type WeatherReport struct {
metav1.TypeMeta 'json:",inline"'
metav1.ObjectMeta 'json:"metadata"'
Spec WeatherReportSpec
'json:"spec"'
Status WeatherReportStatus
'json:"status,omitempty"'
}
type WeatherReportSpec struct {
City string 'json:"city"'
Days int 'json:"days"'
}
在前面的代码段中,WeatherReport由元数据、规范和状态组成,就像任何内置的Kubernetes资源一样。WeatherReportSpec包括配置,在我们的示例中为City和Days。WeatherReportStatus包括State和Pod(用于跟踪状态)以及为天气报告集合创建的Pod。
注意:您可以在Github上参考完整的代码。
3、在此示例中,WeatherReport创建新对象时,我们将发布一个查询天气服务的pod,并将结果写入控制台输出。所有这些步骤都在pkg/stub/handler.go文件中进行了编码,如下所示:
func (h *Handler) Handle(ctx types.Context, event types.Event) error {
switch o := event.Object.(type) {
case *apiv1.WeatherReport:
if o.Status.State == "" {
weatherPod := weatherReportPod(o)
err := action.Create(weatherPod)
if err != nil && !errors.IsAlreadyExists(err) {
logrus.Errorf("Failed to create weather report pod : %v", err)
注意:您可以在Github上参考完整的代码。
4、使用Operator SDK和工具集将整个项目构建为Docker容器:
operator-sdk build
将生成的Docker容器作为onuryilmaz/k8s-operator-example推送到Docker Hub,以在集群中进一步使用。
5、使用以下命令将operator部署到集群中:
kubectl create -f deploy/crd.yaml
kubectl create -f deploy/operator.yaml
成功部署operator后,可以按以下方式检查日志:
kubectl logs -l name=k8s-operator-example
输出如下:
6、部署自定义资源定义和自定义控制器之后,就该创建一些资源并收集结果了。创建一个新WeatherReport实例,如下所示:
kubectl create -f deploy/cr.yaml
成功创建后,WeatherReport可以检查的状态:
kubectl describe weatherreport amsterdam-daily
您将看到以下输出:
7、由于operator为新的天气报告创建了一个天气报告,因此我们应该查看它的运行并收集结果:
kubectl get pods
您将看到以下结果:
8、使用以下命令获取天气报告的结果:
kubectl logs $(kubectl get weatherreport amsterdam-daily -o jsonpath={.status.pod})
您将看到以下输出:
9、使用以下命令清理:
kubectl delete -f deploy/cr.yaml
kubectl delete -f deploy/operator.yaml
kubectl delete -f deploy/crd.yaml
总而言之,在本文中,我们学习了有关扩展Kubernetes API,创建和部署自定义资源定义,自定义控制器等的知识。要阅读有关具有设计模式的Kubernetes的更多信息并了解Kubernetes扩展点的基础知识,请阅读Packt Publishing出版的《Kubernetes设计模式和扩展》一书。