把你的Kubernetes写成Go代码--用自定义结构扩展cdk8s
构建一个Wordpress部署作为cdk8s结构。
构造是cdk8s(Cloud Development Kit for Kubernetes)的基本构件,这是一个开源框架(CNCF的一部分),你可以用常规的编程语言(而不是yaml )来定义你的Kubernetes应用程序。在开始使用cdk8s时,你看到了如何使用核心的cdk8s 库。
你也可以使用cdk8s-plus 库(在之前的博客中也有涉及),以减少你需要编写的模板代码的数量。通过cdk8s-plus ,创建一个KubernetesDeployment ,指定它的容器(和其他属性)并通过Service ,只需三个函数调用就可以了?
例如,要设置和访问Nginx ,你只需要这样:
Nginx
//...
deployment := cdk8splus22.NewDeployment(chart, jsii.String("deployment"), &cdk8splus22.DeploymentProps{Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String("nginx-deployment-cdk8s-plus")}})
deployment.AddContainer(&cdk8splus22.ContainerProps{
Name: jsii.String("nginx-container"),
Image: jsii.String("nginx"),
Port: jsii.Number(80)})
deployment.ExposeViaService(&cdk8splus22.DeploymentExposeViaServiceOptions{
Name: jsii.String("nginx-container-service"),
ServiceType: cdk8splus22.ServiceType_LOAD_BALANCER,
Ports: &[]*cdk8splus22.ServicePort{{Port: jsii.Number(9090), TargetPort: jsii.Number(80)}}})
//...
但事情可以变得更好
你可以把它打包成一个可重用的组件,就像其他内置的cdk8s 函数(如NewDeployment、NewService 等)一样,而不是重复编写相同的逻辑。尽管对于简单的应用程序来说,这种方法可能听起来不那么有用,但对于想要扩展其工程努力的大型项目、团队或组织来说,这种方法是非常宝贵的。事实上,在constructs.dev网站上已经有了一个可供使用的组件库。这些组件包括由社区、AWS和其他机构贡献的、跨越多种编程语言的构造。
为了更好地理解实践中可能出现的情况
......让我们看一下代码。我将继续使用Wordpress 作为例子,就像我在上一篇博文中做的那样。这里有一个代码片段,显示了所有的东西是如何连接在一起的(在下一节有一个实现的演练)。
你可以参考Github上的完整代码
Nginx
//...
func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {
//....
NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{//....)
return chart
}
func main() {
app := cdk8s.NewApp(nil)
NewMyChart(app, "wordpress-custom-stack", nil)
app.Synth()
}
NewWordpressStack给了我们一个结构,代表了整个 的安装(单行代码!)。Wordpress- 我们只需按照我们的要求来配置它(用
WordpressProps)。 - 将其作为cdk8s.Chart的一部分,然后将其包含在cdk8s.App中(与其他
cdk8s的应用程序一样)
根据你的要求,在你想建立一个自定义结构方面有很大的灵活性。但是,就其核心而言,其基本概念是定义一种方法来创建一个新的construct.Construct。你会希望提供一种方法来添加元数据,以进一步配置/完善你的Construct - 通常,这是通过属性(cdk8s.ChartProps)来完成。
首先,我们定义WordpressProps - 这封装了/外化了WordPress安装的属性。由于这只是一个例子,我提供了有限的属性,如MySQL/WordPress Docker图像、MySQL密码和所需的存储空间。
Nginx
type WordpressProps struct {
MySQLImage *string
MySQLPassword *string
MySQLStorage *float64
WordpressImage *string
WordpressStorage *float64
然后我们有一个函数,将允许其他图表/结构实例化WordPress。这就是整个实现的地方:
Nginx
func NewWordpressStack(scope constructs.Construct, id *string, props *WordpressProps) constructs.Construct {
...
}
props *WordpressProps 参数允许其他结构体影响WordPress栈的创建,例如,你可以定义你需要多少存储空间,也许为WordPress/MySQL使用不同的Docker镜像。这个函数的实际代码与你在这里看到的类似(有必要的调整),所以在这里没有必要重复它。我将简单地强调重要的部分--特别是使用props 来配置所需组件的部分:
这个样本结构使用了
cdk8splus22库。之所以采用这种命名方式,是因为每个cdk8s-plus库都是单独针对特定的Kubernetes版本进行销售的--后面的22标志着这个依赖将与Kubernetes1.22。你可以使用与你的Kubernetes版本相对应的库,并参考常见问题以了解更多信息。
我们使用来自props 的MySQL密码,并使用它来创建Secret 。
Nginx
//...
password := props.MySQLPassword
mysqlSecret := cdk8splus22.NewSecret(wordpressConstruct, jsii.String("mysql-secret"),
&cdk8splus22.SecretProps{
Metadata: &cdk8s.ApiObjectMetadata{Name: jsii.String(secretName)}})
secretKey := "password"
mysqlSecret.AddStringData(jsii.String(secretKey), password)
//...
MySQL和WordPress的容器镜像是通过各自的Deployment来引用的:
Nginx
//...
containerImage := props.MySQLImage
mysqlContainer := dep.AddContainer(&cdk8splus22.ContainerProps{
Name: jsii.String("mysql-container"),
Image: containerImage,
Port: jsii.Number(3306),
})
//...
wordpressContainer := wordPressDeployment.AddContainer(&cdk8splus22.ContainerProps{
Name: jsii.String("wordpress-container"),
Image: props.WordpressImage,
Port: jsii.Number(80),
})
我们也使用传入的存储 - 这是用来配置PersistentVolumeClaim 请求的:
Nginx
...
mysqlPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("mysql-pvc"), &cdk8splus22.PersistentVolumeClaimProps{
AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},
Storage: cdk8s.Size_Gibibytes(props.MySQLStorage)})
...
wordpressPVC := cdk8splus22.NewPersistentVolumeClaim(wordpressConstruct, jsii.String("wordpress-pvc"), &cdk8splus22.PersistentVolumeClaimProps{
AccessModes: &[]cdk8splus22.PersistentVolumeAccessMode{cdk8splus22.PersistentVolumeAccessMode_READ_WRITE_ONCE},
Storage: cdk8s.Size_Gibibytes(props.WordpressStorage)})
最后,我们从另一个cdk8s.Chart ,并传入我们要配置的属性,调用NewWordpressStack :
Nginx
func NewMyChart(scope constructs.Construct, id string, props *MyChartProps) cdk8s.Chart {
var cprops cdk8s.ChartProps
if props != nil {
cprops = props.ChartProps
}
chart := cdk8s.NewChart(scope, jsii.String(id), &cprops)
NewWordpressStack(chart, jsii.String("wordpress-stack"), &WordpressProps{
MySQLImage: jsii.String("mysql"),
MySQLPassword: jsii.String("Password123"),
MySQLStorage: jsii.Number(3),
WordpressImage: jsii.String("wordpress:4.8-apache"),
WordpressStorage: jsii.Number(2)})
return chart
}
用这个来安装WordPress
要在本地测试它...
Shell
# make sure cluster is running
minikube start
git clone https://github.com/abhirockzz/cdk8s-for-go-developers
cd part4-custom-construct
创建清单并检查所有资源(见dist 目录):
Shell
cdk8s synth
部署它们:
Shell
kubectl apply -f dist/
# output (might differ in your case)
secret/mysql-pass created
deployment.apps/mysql-mysql-deployment-cdk8splus-c83762d9 created
persistentvolumeclaim/mysql-mysql-pvc-c8799bba created
service/mysql-service created
deployment.apps/wordpress-wordpress-deployment-cdk8splus-c8252da7 created
service/wordpress-service created
persistentvolumeclaim/wordpress-wordpress-pvc-c8334a29 created
检查 KubernetesService (称为wordpress-service ),它暴露了 WordPressDeployment :
Shell
kubectl get svc wordpress-service
如果你使用minikube ,在不同的终端运行(如果尚未运行)。
Shell
minikube tunnel
使用你的浏览器导航到http://localhost:80。你应该看到熟悉的WordPress安装屏幕。
继续,完成安装并登录到你的WordPress实例。随意地试验一下吧。
总结
cdk8s 是一个强大的工具本身,但它也为你提供了在它上面扩展和建立其他抽象的能力。你看到了如何编写一个自定义的构造Go ,并使用它来在Kubernetes上部署WordPress。这可以进一步作为其他可重用组件的基础。
编码愉快!