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资源,例如PodServiceDeploymentReplicaSet等。

构造是cdk8的基本构建块。它们是通过普通的面向对象的类来构成和创建更高级别的抽象的工具。

如果您来自Kubernetes世界,则可以将构造视为以编程方式定义的Helm Charts。关于“以编程方式定义”构造的好处是,我们可以使用它们来利用面向对象编程的全部功能。例如:

  • 您可以使用强类型数据类型来表达抽象的API
  • 您可以表达与方法和属性的丰富交互
  • 您可以通过接口和基类创建多态编程模型
  • 通过常规软件包管理器共享它们
  • 使用我们熟悉的测试工具和技术对其进行测试
  • 版本管理

cdk8s应用程序仅定义Kubernetes应用程序,实际上并未将其应用于集群。执行某个应用程序时,它会将应用程序中定义的所有图表综合到dist目录中,然后可以使用kubectl apply -f dist/chart.k8s.yaml或GitOps工具(如Flux)将这些图表应用于任何Kubernetes集群。

示例

让我们来看一个简单的"Hello,World!" TypeScript中的示例。

先决条件

个人比较喜欢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
+ cdk8s-cli@0.23.0

创建工程

现在,我们将使用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项目启发的ServiceDeployment资源。

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流程结合起来。


iyacontrol
1.4k 声望2.7k 粉丝

专注kubernetes,devops,aiops,service mesh。