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マニフェストとして生成されます。
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
結果として以下のようなファイルが生成されます。
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の指定だけです。
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作ってなかったです。
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+でも今後、起こっていくのか、
期待したいところですね。