乐趣区

小试-cdk8s

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 中的示例。

先决条件

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

退出移动版