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所示。
图 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进行下载。