はじめに
Kubernetesを運用していると、デプロイメントやサービス、イングリスポーティングなど、数多くのYAMLファイルを管理することになります。これらのYAMLファイルは、コピペで増殖しがちで、少しの変更でも全体を把握するのが困難になる「YAML地獄」に陥ることも少なくありません。そんな課題を解決してくれるのが、今回ご紹介するCDK8s (Cloud Development Kit for Kubernetes)です。CDK8sを使えば、TypeScriptやPythonといった馴染みのあるプログラミング言語でKubernetesマニフェストを生成できるため、コードの再利用性や保守性を劇的に向上させることができます。
CDK8sの基礎知識
CDK8sは、AWS CDK (Cloud Development Kit) の思想をKubernetes向けに展開したツールです。AWS CDKと同様に、プログラミング言語の表現力を活用してインフラストラクチャを定義します。
- 抽象化: 関数、クラス、ループ、条件分岐といったプログラミング言語の強力な機能を使って、繰り返し登場するマニフェストのパターンを抽象化できます。これにより、コードの重複を減らし、管理が容易になります。
- 型安全: TypeScriptなどの静的型付け言語を使用することで、コンパイル時にマニフェストの誤りを検出できます。これにより、「No more YAML」とも言われるように、YAMLの構文エラーやフィールド名のtypoによるデプロイ失敗を防ぎ、より安全なインフラ管理を実現します。
- 再利用性: 定義したコンポーネントをライブラリとして共有したり、他のプロジェクトで再利用したりすることが容易になります。
CDK8sの実装・解決策
CDK8sでは、まずCDK8sプロジェクトを作成し、その中でTypeScriptなどの言語を使ってKubernetesリソースを定義していきます。定義されたコードは、`cdk8s synth` コマンドによって最終的にKubernetesが解釈できるYAMLマニフェストに変換されます。
基本的な流れは以下のようになります。
- CDK8sプロジェクトの作成:
npm install -g cdk8s-cliでCLIをインストールし、cdk8s init app --language typescriptなどでプロジェクトを初期化します。 - リソースの定義: プロジェクト内のTypeScriptファイル(例: `main.ts`)で、CDK8sが提供するクラスを使ってKubernetesリソースを定義します。
- マニフェストの合成:
cdk8s synthコマンドを実行すると、定義したコードがYAMLファイルとして出力されます。 - デプロイ: 生成されたYAMLファイルを `kubectl apply -f
` などでKubernetesクラスターに適用します。
サンプルプログラム (TypeScript)
ここでは、簡単なNginx DeploymentとServiceをCDK8sで定義する例を見てみましょう。
// main.ts
import { Construct } from ‘constructs’;
import { App, Chart, ChartProps } from ‘cdk8s’;
import as k8s from ‘cdk8s-plus-27’; // Kubernetes v1.27 のAPIを使用
// customChartクラスを定義し、Chartクラスを継承します
interface MyChartProps extends ChartProps {
// 必要に応じてカスタムプロパティを追加できます
}
export class MyChart extends Chart {
constructor(scope: Construct, id: string, props: MyChartProps) {
super(scope, id, props);
// Nginx Deploymentを定義します
const deployment = new k8s.Deployment(this, ‘nginx-deployment’, {
metadata: {
name: ‘nginx-deployment’
},
spec: {
replicas: 2, // レプリカ数を2に設定
selector: {
matchLabels: { app: ‘nginx’ } // ラベルセレクター
},
template: {
metadata: {
labels: { app: ‘nginx’ } // Podのラベル
},
spec: {
containers: [{
name: ‘nginx’, // コンテナ名
image: ‘nginx:latest’, // 使用するDockerイメージ
ports: [{ containerPort: 80 }] // コンテナのポート
}]
}
}
}
});
// Nginx Serviceを定義します
const service = new k8s.Service(this, ‘nginx-service’, {
metadata: {
name: ‘nginx-service’
},
spec: {
type: k8s.ServiceType.CLUSTER_IP, // ServiceタイプをClusterIPに設定
ports: [{ port: 80, targetPort: 80 }], // Serviceのポートとターゲットポート
selector: { app: ‘nginx’ } // Deploymentのラベルセレクターと一致させる
}
});
// DeploymentとServiceを関連付けます (cdk8s-plus では自動で関連付けられますが、明示的に依存関係を示すことも可能です)
// deployment.expose(80, { serviceType: k8s.ServiceType.CLUSTER_IP }); // cdk8s-plus の簡易的な方法
}
}
// アプリケーションを作成します
const app = new App();
// MyChartインスタンスを作成し、’nginx-chart’ というIDで追加します
new MyChart(app, ‘nginx-chart’, {
// Chartに渡したいプロパティがあればここに記述します
// 例: namespace: ‘default’,
});
// アプリケーションを合成します (cdk8s synth コマンドで実行されます)
app.synth();
このコードを `main.ts` として保存し、プロジェクトのルートディレクトリで `cdk8s synth` を実行すると、`dist/` ディレクトリに `nginx-chart.k8s.yaml` のような名前でYAMLファイルが生成されます。
応用・注意点
- コンポーネント化による再利用: よく使うDeploymentのテンプレートや、特定のNamespaceにリソースをデプロイする関数などを共通化し、ライブラリとして管理することで、チーム内での開発効率を向上させることができます。
- GitOpsとの連携: CDK8sで生成されたYAMLをGitリポジトリにコミットし、Argo CDやFlux CDのようなGitOpsツールと連携させることで、インフラのコード化と自動デプロイをより強力に推進できます。
- バージョン管理: CDK8sのバージョンアップによって、依存するKubernetes APIのバージョンが変わることがあります。`cdk8s-plus-XX` の `XX` の部分(例: `cdk8s-plus-27`)は、使用したいKubernetesのバージョンに合わせて選択してください。
- デバッグ: 型安全とはいえ、ロジックの間違いによる意図しないマニフェストが生成されることもあります。`cdk8s synth –dry-run` で生成されるYAMLを確認したり、`kubectl explain` コマンドでフィールドの型や意味を確認しながら開発を進めると良いでしょう。
CDK8sを活用することで、Kubernetesマニフェストの管理はより効率的で、安全なものになります。ぜひ、あなたのプロジェクトでもCDK8sを試してみてください。

コメント