选用 Go 表述您的 Kubernetes 插件

七爪源标识符:将您的Unity虚拟化撰写为Get标识符-Cdk8s进阶插图

基础建设即标识符 (IaC) 是一类成形的实例,是指用与插件标识符完全相同的形式处置基础建设(互联网、硬盘、储存、资料库、最新消息堆栈等)并应用领域主要包括源标识符其中的通常计算机科学课堂教学的国际标准课堂教学 掌控管理工具、试验等。 比如,Terraform 和 AWS CloudFormation 是广为选用的控制技术,它选用命令行/模版来则表示基础建设模块。

Infrastructure-IS-Code – 一类相同的思索形式

想像呵呵,您有两个插件,该插件包涵两个以 API 交换机为后端无伺服器机能和做为后端 NoSQL 资料库。 与以动态形式(选用 JSON、YAML 等)表述它,比不上选用国际标准C语言内部结构(捷伊、方式等)来则表示那些模块。这是两个伪标识符实例:

DBTable table =newDBTable(“demo-table”); table.addPrimaryKey(“email”, Type.String);Functionfunction=newFunction(“demo-func”);function.addEnvVars(“TABLE_NAME”, table.Name());APIGateway apigw =newAPIGateway(); apigw.addFunctionIntegration(function);

特别注意(假定的)类 DBTable、Function 和 APIGateway 和它的选用形式。比如两个表达式能提及表第一类并赢得它的中文名称——大部份那些都在程序代码时再次出现,并由下层架构/互联网平台的同时实现控制技术细节处置。

但您无须为制造基础建设撰写伪标识符!

…非常感谢原有的软件系统,比如 cdk8s、AWS CDK、Pulumi、CDK for Terraform (cdktf) 等。基本上大部份那些软件系统都遵从类似的方式 – 撰写标识符来表述基础建设,然后将其转换为配置,比如Kubernetes 清单 (YAML)、AWS CloudFormation 模版、HCL 配置等,然后能选用国际标准工具进行应用领域。

当我们谈到这个话题时,很难不提到 Go C语言及其在云服务和基础建设领域无处不在的存在。它结合了编译语言的安全性和解释语言(如 Python)的速度,拥有强大的国际标准库并编译为单个二进制文件。那些和更多的品质导致了许多用 Go 撰写的云原生软件(IaC、监控、可观察性等),比如 Prometheus、Terraform、Grafana、Jaeger 等。

事实上,云原生计算基金会中超过 75% 的项目都是用 Go 撰写的。

将Infra-Is-Code口号应用领域于 Kubernetes

在多篇博文中,我将介绍 Go 开发人员如何选用 cdk8s(Kubernetes 的云开发工具包)项目来表述 Kubernetes 资源。它是两个开源架构(也是 CNCF 的一部分),提供高级抽象,能组合成更大的 Kubernetes 插件。 cdk8s 没有选用 YAML 或其他配置/模版驱动的方式,而是支持多种C语言,这意味着您能选用熟悉的概念(比捷伊、方式等)来选用 Kubernetes 资源。终,cdk8s 会生成您能选用 kubectl 应用领域的 Kubernetes 清单- 照常营业!

在撰写本文时,cdk8s 支持 Go、Typescript、Python 和 Java

这篇博文将开始并提供对 cdk8s 的温和而实用的介绍。到后,您将熟悉关键概念并了解如何选用 cdk8s Go API 表述 Kubernetes 插件、部署(选用 kubectl)和试验它。

在你开始之前…

确保您已安装 Go(v1.16 或更高版本)和 cdk8s CLI。此外,您需要有权访问 Kubernetes 集群。对于学习和实验,我建议选用本地运行的单节点集群——比如 minikube、kind 等。

我通常用minikube,所以搭建集群像minikube start一样简单

安装 cdk8s CLI。

您能从以下选项中进行选择:

homebrewbrewinstallcdk8snpmnpminstall-g cdk8s-cliyarnyarnglobaladdcdk8s-cli

好吧,让我们开始吧!

cdk8s 让您能非常轻松地开始和引导您的插件。 您无需猜测和弄清楚如何构建项目、设置依赖项等,因为 cdk8s init 命令会为您完成!

cdk8s init go-appoutput…. Your cdk8s Go project is ready! cathelpPrints this message cdk8s synth Synthesize k8s manifeststodist/ cdk8simportImports k8s API objectsto“imports/k8s”Deploy: kubectlapply-f dist/

完成后,您将赢得如下目录内部结构:

. ├──cdk8s.yaml├──dist│ └──test.k8s.yaml├──go.mod├──go.sum├──help├──imports│ └──k8s│ ├──internal│ │ └──types.go│ ├──jsii│ │ ├──jsii.go│ │ └──k8s-0.0.0.tgz│ ├──k8s.go│ ├──k8s.init.go│ └──version└──main.go

更新生成 go.mod 文件,并将其替换为以下内容 – 这是为了让您更简单。

如果需要,请随意选用新版本的模块。

module getting-started-with-cdk8s-gogo1.16require ( github.com/aws/constructs-go/constructs/v10 v10.1.42github.com/aws/jsii-runtime-gov1.60.1github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2 v2.3.29)

你们都准备好写一些 Go 标识符了!

规范的 Kubernetes hello world是让 nginx 伺服器启动并运行。 简单的选择是简单地选用 kubectl run 比如 kubectl 运行 nginx –image=nginx。 但,由于这是必须的,我们切换到声明式形式,在其中表述我们想要的状态(在 yaml 文件中)并要求 Kubernetes 解决问题。

比如 我们能撰写两个部署清单并选用 kubectl apply -f 将其提交给 Kubernetes。

apiVersion:apps/v1kind:Deploymentmetadata:name:nginx-deploymentspec:replicas:1selector:matchLabels:app:hello-nginxtemplate:metadata:labels:app:hello-nginxspec:containers:image:nginxname:nginx-containerports:containerPort:8080

但我们在这里是为了尽量减少 yaml……

因此,打开 main.go 文件并复制以下 Go 标识符。 别着急,小编带你一探究竟!

packagemainimport (“getting-started-with-cdk8s-go/imports/k8s”“github.com/aws/constructs-go/constructs/v10”“github.com/aws/jsii-runtime-go”“github.com/cdk8s-team/cdk8s-core-go/cdk8s/v2”)typeNginxChartPropsstruct{ cdk8s.ChartProps }funcNewNginxChart(scope constructs.Construct, idstring, props *NginxChartProps)cdk8s.Chart{varcprops cdk8s.ChartPropsifprops !=nil{ cprops = props.ChartProps } chart := cdk8s.NewChart(scope, jsii.String(id), &cprops) selector := &k8s.LabelSelector{MatchLabels: &map[string]*string{“app”: jsii.String(“hello-nginx”)}} labels := &k8s.ObjectMeta{Labels: &map[string]*string{“app”: jsii.String(“hello-nginx”)}} nginxContainer := &k8s.Container{Name: jsii.String(“nginx-container”), Image: jsii.String(“nginx”), Ports: &[]*k8s.ContainerPort{{ContainerPort: jsii.Number(80)}}} k8s.NewKubeDeployment(chart, jsii.String(“deployment”), &k8s.KubeDeploymentProps{ Spec: &k8s.DeploymentSpec{ Replicas: jsii.Number(1), Selector: selector, Template: &k8s.PodTemplateSpec{ Metadata: labels, Spec: &k8s.PodSpec{ Containers: &[]*k8s.Container{nginxContainer}}}}})returnchart }funcmain(){ app := cdk8s.NewApp(nil) NewNginxChart(app,“nginx”,nil) app.Synth() }

在用任何语言撰写基于 cdk8s 的标识符时,您都会遇到一组常见的概念/术语——主要包括 Construct、App 和 Chart。我将在我们浏览标识符时解释那些。

稍微绕道(标识符演练和概念)

首先从main表达式开始——我们选用cdk8s.NewApp来创建两个App。

那么,App 中到底有什么?它是两个构造,您能将构造视为则表示状态的更高级别的构建块。需要特别注意的关键是那些构造是可组合的。这意味着您能表述那些构造的级别(每个级别提供/公开相同的抽象层)并将它组合起来以创建您想要的终状态——在这种情况下,它恰好是两个带有诸如 Deployment 之类的第一类的 Kubernetes 清单,但它可能是别的东西。

比如两个 AWS CloudFormation 模版(如果您要选用 AWS CDK,请不要与 cdk8s 混淆)

回到 App – 所以,App 也是两个构造。实际上,您能将其视为构造树(层次内部结构)中的根。那么,那棵树上还有什么?查看主表达式中的第二行 – NewNginxChart(app, “getting-started”, nil) – 这会调用两个表达式 NewNginxChart,该表达式返回两个 cdk8s.Chart,它是层次内部结构中的下两个模块。 AA cdk8s 插件能包涵多个图表,并且每个图表都能转换(或用精确的 cdk8s 术语 – 合成)为单独的 Kubernetes 清单文件(您很快会看到此操作)。

后,请特别注意 NewNginxChart 表达式。它有很多东西,但请特别注意对 k8s.NewKubeDeployment 表达式的调用。这是我们在标识符中实际表述 Kubernetes 部署的地方(在下一节中,我们还将向图表添加两个服务。)

您能在两个图表中表述多个 Kubernetes 模块,比如 Pod、Service、Ingress、Job 等——您的插件在 Kubernetes 上运行所需的一切。

总而言之,这是我刚才解释的直观则表示——记住一切都是构造(插件、图表等)

七爪源标识符:将您的Unity虚拟化撰写为Get标识符-Cdk8s进阶插图1

等等,Kubernetes API 依赖项呢?

如果您花时间以编程形式访问 Kubernetes,那么这是两个显而易见(而且很棒!)的问题。如果您要选用 go 处置 k8s 第一类,那么您至少需要 Kubernetes client-go、API 机器等。猜猜看,cdk8s 也能满足您的需求!

您实际上不需要引入那些依赖项,因为 cdk8s 允许您将那些 Kubernetes API 第一类视为构造 – 请记住,一切都是构造!当您运行 cdk8s init 命令时,它会自动导入到您的项目中,但您也能选用 cdk8s import 显式执行此操作。生成的 API 可做为导入文件夹的一部分选用(是的,继续检查一遍!)。在 main.go 顶部,检查导入的包 – 它只是指导入文件夹。

不过,cdk8s 导入还有更多内容。但您必须等待其他博客文章才能看到这一点 – 我们才刚刚开始!

好吧,让我们回到正轨……

..并继续实际操作。是时候生成一些 yaml 了——你无法消除它,但至少你无须手动撰写它!为此,只需运行:

cdk8ssynth

一旦完成(应该很快!),检查 dist 目录以检查 cdk8s 生成了什么。

为了更容易理解,这里有两个图表,它在 cdk8s 标识符第一类/属性与它在 yaml 中的对应第一类之间具有一对一映射(特别注意标签 1、2、3 等?),比如spec.replicas、spec.selector、template.spec 等。

七爪源标识符:将您的Unity虚拟化撰写为Get标识符-Cdk8s进阶插图2

您现在能选用旧的 kubectl 将其部署到 Kubernetes,因为 cdk8s 不会为您这样做,至少现在还不会;)

kubectlapply -f dist/kubectlget pods -w

一旦 Deployment 准备绪,Pod 应该处于 Running 状态。 只需选用 port-forward 在本地访问 nginx 容器端口:

kubectlport-forward<enternginxpodname> 8080:80

要访问 nginx 主页,请选用浏览器导航到 http://localhost:8080

您还能选用 CLI 工具,比如 卷曲本地主机:8080。

那不是全部!

代替端口转发,让我们通过表述两个 Service 资源来选用国际标准 Kubernetes 访问插件的形式,该资源通常表述如下:

apiVersion:v1kind:Servicemetadata:name:nginx-servicespec:ports:port:9090targetPort:8080selector:app:hello-nginxtype:LoadBalancer

但你知道规则 – 不要手动撰写 yaml! 因此,在 main.go 文件的 NewNginxChart 表达式中,在表述 Deployment 的部分之后添加这段标识符:

k8s.NewKubeService(chart, jsii.String(“service”), &k8s.KubeServiceProps{ Spec: &k8s.ServiceSpec{ Type: jsii.String(“LoadBalancer”), Ports: &[]*k8s.ServicePort{{Port: jsii.Number(9090), TargetPort: k8s.IntOrString_FromNumber(jsii.Number(80))}}, Selector: &map[string]*string{“app”: jsii.String(“hello-nginx”)}}})

首先,删除原有的 Deployment – kubectl delete -f dist/。 然后,再次运行 cdk8s synth 以在 dist 文件夹中创建新的清单。

服务和部署都在同两个文件中 – 这是因为它是同两个图表的一部分。

您如何访问该服务将取决于 Kubernetes 集群。 如果您选用的是云提供商,它可能会提供该云原生的负载均衡器服务,比如 AWS 中的插件负载均衡器。 请根据您的设置进行调整。

在终端中,运行以下命令(它做为单独的进程运行):

minikubetunnel

在另两个终端中,删除原有的 Deployment,然后应用领域新的清单:

kubectlapply -f dist/kubectlget pods -w

检查服务:

kubectlgetsvc

要访问 nginx 伺服器,请导航到外部 IP(根据服务)。 对于 minikube,您能简单地选用 localhost:9090 或 127.0.0.0:9090

请记住选用端口 9090,因为这是我们在标识符的服务配置中指定的外部端口

在结束之前…

.. 我想强调 cdk8s 中的其他一些有用的东西。

提及和重用原有清单和 Helm 图表

假定您已经在 service.yaml 文件中表述了两个服务。 您能将它做为您可能拥有的更大插件/图表的一部分包涵在您的 cdk8s 中。 这是两个例子:

cdk8s.NewInclude(chart,jsii.String(“existingservice“), &cdk8s.IncludeProps{Url: jsii.String(“service.yaml”)})

同样,您也能包涵 Helm 图表。 假定你想添加 bitnami/nginx:

cdk8s.NewHelm(chart, jsii.String(“bitnami nginx helm chart”), &cdk8s.HelmProps{ Chart: jsii.String(“bitnami/nginx”), Values: &map[string]interface{}{“service.type”:“ClusterIP”}})

另两个方便的机能是……

… 声明任何两个 cdk8s 内部结构之间的依赖关系的能力。 比如,在前面的实例中,我们有两个部署和两个服务。 您能这样创建依赖项:

deployment := k8s.NewKubeDeployment(…) service := k8s.NewKubeService(…)deployment.AddDependency(service)

多亏了 AddDependency,生成的清单将使得 Service 被放置在 Deployment 第一类之前。

依赖性不限于图表中的单个构造。 如果您有多个图表做为 cdk8s 插件的一部分,您也能建立跨图表的依赖关系。

结论

惊人的。 因此,您能通过编码解决问题并忽略 YAML。 希望你喜欢它! 为简单起见,我演示了两个部署和服务,但您能从其他 Kubernetes 模块中进行选择,比如 Ingress、Job 等。它都选用类似的模式(比如 NewKube)公开。 NewKubeJob、NewKubeIngress 等。

但在表述 Kubernetes 模块时仍然涉及到很多样板标识符。 撰写 Go 标识符听起来比 YAML 工程好得多(至少对我而言),似乎我们正在将原有的 YAML 转换为 Go 内部结构(和字段)。 在随后的博客文章中,我们将探讨如何进一步改进这一点。

快乐编码!

关注七爪网,获取更多APP/小程序/网站源代码资源!

作者 nasiapp

在线客服
官方客服
我们将24小时内回复。
12:01
您好,有任何疑问请与我们联系!

选择聊天工具: