LoginSignup
2
2

More than 1 year has passed since last update.

cdk8sとcdk8s+を使ってkubernetesマニフェストを生成する

Last updated at Posted at 2022-01-18

cdk8sとは

CDKでCloudFormationテンプレートファイルを生成するのと同様に、
cdk8sでKubernetesマニフェストファイルを生成する、というもの。

生成するのはあくまでyamlであって、
kubectl applyでファイルの内容をリソースに適用するので、
Kubernetesの宣言的な自律性はそのまま。

cdk8s+とは

cdk8sに比べてより抽象度の高いライブラリを使える。
具体的にはcdk8sはLow Level API(Constructs)で、cdk8s+はHigh Level API(Constructs)

Constructsとは

公式のドキュメントにはKubernetesの世界に例えた場合、
Helmのようなもの、という記載があった。
https://cdk8s.io/docs/latest/concepts/constructs/
ちなみにですがHelm Constructsもあるみたいです。
https://cdk8s.io/docs/latest/reference/cdk8s/typescript/#helm

また、それに加えてプログラマブルに記述できることのメリットとして、
例えば以下などのメリットがあるとのこと。

  • 型があることによる抽象化やポリモーフィズムの導入
  • メソッドやプロパティによる相互運用性

cdk8sの実践

公式のGetting Startedに沿って実践していきます。
https://cdk8s.io/docs/latest/getting-started/

CLIのインストール

$ npm install -g cdk8s-cli

確認

$ cdk8s --version
1.0.78

プロジェクトの作成

$ cdk8s init typescript-app

一通りのKubernetesAPIがインポートされます。

コードの作成

サービスとデプロイメントで構成されるリソースを作成します。
Chartが単一のKubernetesマニフェストとして生成されます。

main.js
import { Construct } from 'constructs';
import { App, Chart, ChartProps } from 'cdk8s';

import { KubeDeployment, KubeService, IntOrString } from './imports/k8s';

export class MyChart extends Chart {
  constructor(scope: Construct, id: string, props: ChartProps = { }) {
    super(scope, id, props);

    const label = { app: 'hello-k8s' };

    new KubeService(this, 'service', {
      spec: {
        type: 'LoadBalancer',
        ports: [ { port: 80, targetPort: IntOrString.fromNumber(8080) } ],
        selector: label
      }
    });

    new KubeDeployment(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();

マニフェストを生成する

以下コマンドでsynthします。

$ npm run compile && cdk8s synth

結果として以下のようなファイルが生成されます。

dist/hello.k8s.yaml
apiVersion: v1
kind: Service
metadata:
  name: hello-service-c8c17160
spec:
  ports:
    - port: 80
      targetPort: 8080
  selector:
    app: hello-k8s
  type: LoadBalancer
---
apiVersion: apps/v1
kind: Deployment
metadata:
  name: hello-deployment-c8c7fda7
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

実際にKubernetes環境に適用する

$ kubectl apply -f dist/hello.k8s.yaml 
service/hello-service-c8c17160 created
deployment.apps/hello-deployment-c8c7fda7 created

deployment

$ kubectl get deployment
NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
hello-deployment-c8c7fda7   2/2     2            2           2m

pod

$ kubectl get pod
NAME                                         READY   STATUS    RESTARTS   AGE
hello-deployment-c8c7fda7-5474f75f59-plhjf   1/1     Running   0          2m8s
hello-deployment-c8c7fda7-5474f75f59-rzj2n   1/1     Running   0          2m8s

service

$ kubectl get svc -o=jsonpath='{range .items[]}{.metadata.name}{"\t"}{.spec.type}{"\n"}{end}'
hello-service-c8c17160	LoadBalancer

cdk8s+の実践

こちらも公式に沿ってやっていきます。
https://cdk8s.io/docs/latest/plus/

コードの作成

replicasとimageの指定だけです。

main.ts
import * as kplus from 'cdk8s-plus-22';
import * as cdk8s from 'cdk8s';

const app = new cdk8s.App();
const chart = new cdk8s.Chart(app, 'Chart');

new kplus.Deployment(chart, 'Deployment', {
  replicas: 3,
  containers: [{
    image: 'paulbouwer/hello-kubernetes:1.7',
  }],
});

app.synth();

マニフェストを生成する

こちらも以下コマンドで生成します。

$ npm run compile && cdk8s synth

以下が生成されました。
こっちはservice作ってなかったです。

dist/chart-c86185a7.k8s.yaml
apiVersion: apps/v1
kind: Deployment
metadata:
  name: chart-deployment-c8a3b439
spec:
  replicas: 3
  selector:
    matchLabels:
      cdk8s.deployment: Chart-Deployment-c822d80c
  template:
    metadata:
      labels:
        cdk8s.deployment: Chart-Deployment-c822d80c
    spec:
      containers:
        - env: []
          image: paulbouwer/hello-kubernetes:1.7
          imagePullPolicy: Always
          name: main
          ports: []
          volumeMounts: []
      volumes: []

実際にKubernetes環境に適用する

こちらもやってみます。

$ kubectl apply -f dist/chart-c86185a7.k8s.yaml
deployment.apps/chart-deployment-c8a3b439 created

deployment

$ kubectl get deployment
NAME                        READY   UP-TO-DATE   AVAILABLE   AGE
chart-deployment-c8a3b439   3/3     3            3           2m4s

pod

$ kubectl get pods
NAME                                         READY   STATUS    RESTARTS   AGE
chart-deployment-c8a3b439-5f646b8489-48svk   1/1     Running   0          2m
chart-deployment-c8a3b439-5f646b8489-d6pdz   1/1     Running   0          119s
chart-deployment-c8a3b439-5f646b8489-z2gfn   1/1     Running   0          119s

最後に

cdk8s/cdk8s+でマニフェスト生成する流れをやってみました。

マニフェストをプログラミング言語で記述できることで、
処理を共通化できたり、IDEのエコシステムに乗っかることができるなどメリットがあるかな、
といったところでしょうか。

AWSではCloudFormationを直接書くよりもCDKのほうが主流なのかと思いますが、
これと同じようなことがcdk8s/cdk8s+でも今後、起こっていくのか、
期待したいところですね。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2