天天看点

带你读《云原生应用开发 Operator原理与实践》第一章引言1.2Operator 介绍(三)

1.2.2       Operator 应用案例

前面介绍了基于 CR 和相应的自定义资源控制器,我们可以自定义扩展Kubernetes原生的模型元素,这样的自定义模型可以加入到原生KubernetesAPI管理;同时Operator开发者可以像使用原生 API 进行应用管理一样,通过声明式的方式定义一组业务应用的期状态,并且根据业务应用的自身特点编写相应控制器逻辑,以此完成对应用运行时刻生命周期的管理,并持续维护与期望状态的一致性。

在本节我们将介绍如何使用 Kubebuilder工具,快速构建一个 KubernetesOperator,通过创建 CRD完成一个简单的 Web应用部署,通过编写控制器相关业务逻辑,完成对CRD的自动化管理。

1. Kubebuilder介绍

Kubebuilder是一个用 Go语言构建 KubernetesAPI控制器和CRD的脚手架工具,通过使用 Kubebuilder,用户可以遵循一套简单的编程框架,编写 Operator 应用实例。

(1)依赖条件

① goversionv1.13+。

② dockerversion17.03+。

③ kubectlversionv1.11.3+。

④ AccesstoaKubernetesv1.11.3+ cluster。

(2)安装 Kubebuilder

在安装 Kubebuilder前,首先需要安装 Go 语言环境,针对不同的操作系统,安装方法可参考 Go语言官方文档。

安装完成后,我们通过如下命令验证是否安装完成:

$goversion

查看命令是否正确回显当前安装的 Go语言版本,输入如下命令查看Go 语言环境变量:

$goenv

我们可以看到 GOOS及 GOARCH等常用环境变量配置  ,然后安装Kubebuilder,具体 shell命令见代码清单 1-2。

os=$(goenvGOOS)arch=$(goenvGOARCH)

#downloadkubebuilderandextractittotmp

curl-Lhttps://go.kubebuilder.io/dl/2.3.1/${os}/${arch}|tar-xz-C/tmp/

#movetoalong-termlocationandputitonyourpath

#(you'llneedtosettheKUBEBUILDER_ASSETSenvvarifyouputitsomewhereelse)sudomv/tmp/kubebuilder_2.3.1_${os}_${arch}/usr/local/kubebuilder

exportPATH=$PATH:/usr/local/kubebuilder/bin

执行完成后,输入如下命令检查是否正确:

$kubebuilderversion

至此 Kubebuilder已安装完成,使用 kubebuilder-h可以查看帮助文档。

2. Welcome案例介绍

Welcome案例主要实现使用 Operator和 CRD 部署一套完整的应用环境,可以实现根据自定义类型创建资源,通过创建一个 Welcome 类型的资源,后台自动创建 Deployment和 Service,通过 Web页面访问 Service 呈现应用部署,通过自定义控制器方式进行控制管理,整体流程如图 1-10所示。

带你读《云原生应用开发 Operator原理与实践》第一章引言1.2Operator 介绍(三)

图 1—10 案例应用交互流程

本案例中,我们需要创建Welcome自定义资源及对应的 Controllers,最终我们可以通过类似代码清单 1-3的 Yaml文件部署简单的 Web应用。

apiVersion:webapp.demo.welcome.domain/v1kind:Welcome

metadata:

name:welcome-samplespec:

name:myfriends

(1)Web应用介绍

本案例中,我们使用 Go语言 http模块创建了一个 Web服务,用户访问页面后会自动加载 NAME及 PORT环境变量并渲染 index.html静态文件,代码逻辑见代码清单1-4。

funcmain(){

name:=os.Getenv("NAME")

hello:=fmt.Sprintf("Hello%s",name)

http.Handle("/hello/",http.StripPrefix("/hello/",http.FileServer(http.

Dir("static"))))

f,err:=os.OpenFile("./static/index.html",os.O_APPEND|os.O_

WRONLY|os.O_CREATE,0600)

iferr!=nil{

panic(err)

}

deferf.Close()

if_,err=f.WriteString(hello);err!=nil{panic(err)

port:=os.Getenv("PORT")ifport==""{

port="8080"

其中,NAME环境变量通过我们在 Welcome中定义的name 字段获取,我们在下面的控制器编写中会详细介绍获取字段的详细方法。我们将index.html放在Static文件夹下, 并将工程文件打包为 Docker镜像,Dockerfile见代码清单 1-5。

FROMgolang:1.12asbuilder

#Copylocalcodetothecontainerimage.WORKDIR/

COPY..

COPYstatic

#Buildthecommandinsidethecontainer.

RUNCGO_ENABLED=0GOOS=linuxgobuild-v-omain

#UseaDockermulti-stagebuildtocreatealeanproductionimage.

FROMalpine

RUNapkadd--no-cacheca-certificates

#Copythebinarytotheproductionimagefromthebuilderstage.COPY--from=builder/main/usr/local/main

COPY--from=builderstatic/static

#Runthewebserviceoncontainerstartup.CMD["/usr/local/main"]

本案例中 Docker镜像文件已上传至dockerhub,可以通过 dockerpullsdfcdwefe/welcomedemo:v1进行下载。