cdk8s是一个由aws开源的软件开发框架,用于使用熟悉的编程语言和丰富的面向对象的API定义Kubernetes应用程序和可重用的抽象。 cdk8s生成纯Kubernetes YAML--您可以使用cdk8s为在任何地方运行的任何Kubernetes集群定义应用程序。
特性
- 与Kubernetes一起使用:您可以使用cdk8s为在任何地方运行的任何Kubernetes集群(包括任何云或本地)定义应用程序。 cdk8s在您的开发环境中本地运行,并生成可应用于任何集群的标准Kubernetes YAML。
- 多语言支持:目前将支持TypeScript,JavaScript,Python,Java和.NET,将来还会有更多支持。它可以与Kubernetes的任何上游版本一起使用。
- 支持核心Kubernetes对象和自定义资源:您可以从任何Kubernetes API版本和自定义资源定义导入对象以与cdk8s一起使用。这使得使用cdk8s轻松编写整个Kubernetes应用程序变得容易,并在应用程序更改时使它们保持最新。
- 与GitOps工作流程完美配合,使您在修改配置时以及在API版本之间轻松查看更改。只需使用cdk8来合成新的YAML配置文件并将它们提交到git repo。
- 社区驱动。
设计原理
cdk8s应用程序是使用一种受支持的编程语言编写的程序。它们被构造为构造树。
树的根是一个App
构造。在应用程序中,用户可以定义任意数量的图表(扩展了Chart
类的类)。每个图表都被合成到一个单独的Kubernetes清单文件中。图表依次由任意数量的构造组成,最终由资源组成,这些资源代表任何Kubernetes资源,例如Pod
,Service
,Deployment
,ReplicaSet
等。
构造是cdk8的基本构建块。它们是通过普通的面向对象的类来构成和创建更高级别的抽象的工具。
如果您来自Kubernetes世界,则可以将构造视为以编程方式定义的Helm Charts。关于“以编程方式定义”构造的好处是,我们可以使用它们来利用面向对象编程的全部功能。例如:
- 您可以使用强类型数据类型来表达抽象的API
- 您可以表达与方法和属性的丰富交互
- 您可以通过接口和基类创建多态编程模型
- 通过常规软件包管理器共享它们
- 使用我们熟悉的测试工具和技术对其进行测试
- 版本管理
cdk8s应用程序仅定义Kubernetes应用程序,实际上并未将其应用于集群。执行某个应用程序时,它会将应用程序中定义的所有图表综合到dist目录中,然后可以使用kubectl apply -f dist/chart.k8s.yaml
或GitOps工具(如Flux)将这些图表应用于任何Kubernetes集群。
示例
让我们来看一个简单的"Hello,World!" TypeScript中的示例。
先决条件
- Node.js >= 10.x
- 你最喜欢的 editor/IDE
- yarn (可选)
个人比较喜欢vscode,vscode 对cdk8s支持非常好。
安装CLI
cdk8s有一个CLI,其中包含一些有用的命令。让我们从全局安装cdk8s CLI开始:
$ npm install -g cdk8s-cli
安装成功有类似输出:
usr/local/bin/cdk8s -> /usr/local/lib/node_modules/cdk8s-cli/bin/cdk8s
+ [email protected]
创建工程
现在,我们将使用cdk8s init
命令创建一个新的TypeScript cdk8s应用程序:
$ mkdir hello
$ cd hello
$ cdk8s init typescript-app
creating a new project from template: typescript-app
...
这将执行以下操作:
- 创建一个新的项目目录
- 安装cdk8s作为依赖项
- 导入所有Kubernetes API对象
- 将TypeScript编译为JavaScript
最终我们可以看到如下输出:
========================================================================================================
Your cdk8s typescript project is ready!
cat help Print this message
Compile:
npm run compile Compile typescript code to javascript (or "yarn watch")
npm run watch Watch for changes and compile typescript in the background
npm run build Compile + synth
Synthesize:
npm run synth Synthesize k8s manifests from charts to dist/ (ready for 'kubectl apply -f')
Deploy:
kubectl apply -f dist/*.k8s.yaml
Upgrades:
npm run import Import/update k8s apis (you should check-in this directory)
npm run upgrade Upgrade cdk8s modules to latest version
npm run upgrade:next Upgrade cdk8s modules to latest "@next" version (last commit)
========================================================================================================
watch
由于TypeScript是一种编译语言,因此我们需要将.ts文件编译为.js才能执行CDK应用程序。您可以像这样在后台连续进行操作:
$ npm run watch
应用和图表
打开 main.ts
文件,可以看到如下内容:
应用程序以结构树的形式构成,结构是抽象的可组合单元。我们将很快了解有关构造的更多信息。
cdk8s init
创建的初始代码定义了一个具有单个空图表的应用程序。
当您运行npm run synth
时,将为您应用中的每个Chart合成一个Kubernetes清单YAML,并将其写入dist
目录。
引入Kubernetes API 的构造
好的,现在让我们在图表中定义一些Kubernetes API对象。
与图表和应用程序类似,Kubernetes API对象在cdk8s中也表示为构造。使用命令cdk8s import
将这些结构“导入”到您的项目中,然后可以在项目目录中的imports/k8s.ts
文件下找到它们。
cdk8s初始化创建项目时,它已经为您执行了cdk8s import
,因此您应该已经在其中看到了imports目录。您可以将该目录提交到源代码管理中,也可以在构建过程中生成它。
现在,让我们使用这些构造来定义一个简单的Kubernetes应用程序,其中包含受hello-kubernetes项目启发的Service
和Deployment
资源。
import { Construct } from 'constructs';
import { App, Chart } from 'cdk8s';
// imported constructs
import { Deployment, Service, IntOrString } from './imports/k8s';
class MyChart extends Chart {
constructor(scope: Construct, name: string) {
super(scope, name);
const label = { app: 'hello-k8s' };
new Service(this, 'service', {
spec: {
type: 'LoadBalancer',
ports: [ { port: 80, targetPort: IntOrString.fromNumber(8080) } ],
selector: label
}
});
new Deployment(this, 'deployment', {
spec: {
replicas: 2,
selector: {
matchLabels: label
},
template: {
metadata: { labels: label },
spec: {
containers: [
{
name: 'hello-kubernetes',
image: 'paulbouwer/hello-kubernetes:1.7',
ports: [ { containerPort: 8080 } ]
}
]
}
}
}
});
}
}
const app = new App();
new MyChart(app, 'hello');
app.synth();
现在,在执行npm run synth
之后,下面是hello.k8s.yaml
的内容:
apiVersion: v1
kind: Service
metadata:
name: hello-service-9878228b
spec:
ports:
- port: 80
targetPort: 8080
selector:
app: hello-k8s
type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
name: hello-deployment-c51e9e6b
spec:
replicas: 2
selector:
matchLabels:
app: hello-k8s
template:
metadata:
labels:
app: hello-k8s
spec:
containers:
- image: paulbouwer/hello-kubernetes:1.7
name: hello-kubernetes
ports:
- containerPort: 8080
应用程序合成的清单可以使用诸如kubectl apply之类的标准工具应用于任何Kubernetes集群:
$ kubectl apply -f dist/hello.k8s.yaml
总结
随着Kubernetes的使用量增加,并且管理应用程序和集群的繁琐工作从运维团队转移到开发团队,管理扩展的工作不是很直观。OAM和cdk8s 通过不同的思考维度,来简化k8s应用的管理。
使用cdk8s,避免了yaml的诸多不足。可以使用强类型数据类型来表达抽象的API,加入丰富的测试和代码版本管理。而且非常容易和整个CICD流程结合起来。