DockerfileとKubernetesHelmChartを入れる

今回は社内の別プロジェクトで採用している手法ですが、「プロジェクトリポジトリに Dockerfile と kubernetes helm chart を入れておくと幸せになれる(かもしれない)話」をご紹介したいと思います
(SEROKU ではプロジェクトリポジトリに Dockerfile は含めていますが、helm chart を同梱するまでには至っていません)

サンプル

早速実例で紹介します

具体的には以下のようなディレクトリ構成になっています

.
├── docker
│   ├── Dockerfile
│   ├── Dockerfile.helm.jenkins
│   ├── Dockerfile.jenkins
│   └── Dockerfile.nginx
├── kubernetes
│   └── charts
│       └── (プロジェクト名)
│           ├── Chart.yaml
│           ├── templates
│           │   ├── configmap.yaml
│           │   ├── deployment.yaml
│           │   ├── _helpers.tpl
│           │   ├── ingress.yaml
│           │   ├── NOTES.txt
│           │   ├── secret.yaml
│           │   ├── serviceaccount.yaml
│           │   └── service.yaml
│           └── values.yaml
├── package.json
├── README.md
├── values.yaml
└── yarn.lock

package.json や README.md, values.yaml ... などが含まれているのは JavaScript を使ったプロジェクトだからです

docker ディレクトリに Dockerfile 関連を格納して、kubernetes ディレクトリ以下に helm chart やプロジェクトに関する他の yaml を格納する形式を取っています

docker ディレクトリの中で様々な Dockerfile を作成している理由は「用途によって使い分ける」ためです

例えば Dockerfile.jenkins では jenkins ビルド時に必要なコマンドをインストールしています

また、Dockerfile.nginx は本番デプロイ時にフロントエンド用のファイル配信サーバとして動作させるために、ある程度カスタマイズした nginx イメージを作るために用意しています

Dockerfile と kubernetes helm chart をプロジェクトリポジトリに格納しておくメリット

以下のようなメリットを感じています

  1. デプロイ関係のファイル群をバージョン管理できる

    • 大抵はプロジェクトに関するコードとデプロイ用のコードは分けて考えられることもありますが、プロジェクト自体に特化した Dockerfile を書くならば、chart 自体も分離しない方が管理しやすいように思います
  2. Dockerfile を kubernetes helm chart を同じリポジトリに置いておくことで、デプロイ時の手順を確認しやすい

    • 以前ではプロジェクトリポジトリに Dockerfile のみ格納し、helm chart や kubernetes 用の deployment.yaml などは別リポジトリで管理していました
    • しかし、リポジトリ間の移動がどうしても発生してしまうため、作業内容を同期する場合には若干の心理的負担になっていました
    • そこから改善し Dockerfile と helm chart を横断的に見られるようになったことで、現在どんな状況でデプロイされているかが把握しやすくなりました
  3. helm chart 前提になったことでプロジェクト自身の改善点が出しやすくなった

    • 副次的な効果ではありますが、kubernetes helm chart を利用する前提になると、スケールするためのデプロイ戦略や設定の持たせ方を考えるようになりました
    • Dockerfile のみで完結しようとすると、どうしても環境変数を乱用しがちで設定の管理が複雑になっていました
    • helm chart を利用する前提ならば、 ConfigMap や Secret などの情報も利用でき、更に設定ファイルをイメージデプロイ時に配置することができるようになるため、柔軟な設定管理を行うことができるようになりました

プロジェクトの helm chart の作り方と使い方

helm chart の作り方

以下のコマンドを打つことで、シンプルに helm chart の作成を始めることができます

$ helm create (プロジェクト名)

これで以下のようなディレクトリ構成を作ってくれるため、あとは公開されている helm chart (github の helm/charts ) などから適宜実装していきます

.
├── charts
├── Chart.yaml
├── templates
│   ├── deployment.yaml
│   ├── _helpers.tpl
│   ├── ingress.yaml
│   ├── NOTES.txt
│   └── service.yaml
└── values.yaml

公式ドキュメント も参考になりますが、Bitnami でも helm chart の作り方が公開されています

How to Create Your First Helm Chart | docs.bitnami.com

helm chart の使い方

現在の主流になっている helm chart の使い方は、大抵公式の helm/charts の stable を利用している方が多いのではないのでしょうか。

wordpress の helm chart を利用してリリースする場合には、以下のようなコマンドを打つことになります

$ helm install -f values.yaml stable/wordpress 

ですが、helm chart 自体はリポジトリからだけでなく、ローカルのディレクトリを指定することでデプロイをすることができます

先述した「サンプル」の箇所に書いたプロジェクトディレクトリ配下で実行する場合には、以下のようなコマンドで実行することができます

$ helm install -f values.yaml kubernetes/(プロジェクト名)

通常の helm install 時と遜色なくデプロイできるため、構築手順がシンプルに抑えられるのではないでしょうか。

最後に

最新の技術を利用したり、CI 技術を全力で活用することも大切ですが、プロジェクトをチームで開発するにあたって、プロジェクト自身のディレクトリ構成を工夫することは侮れません。

ルール自体はシンプルですが、重要な一つの開発ポリシーだと思います。

しかし、実環境で動作しているプロジェクトのディレクト構成や開発ポリシーなどは意外と検索しても出てこないケースが多いと感じています。

弊社では先述したディレクトリ構成を採用したことで、プロジェクト自体のコード品質を上げていくと共に、デプロイ関係のファイルも併せて改善できるようになってきました

皆さまの開発の参考になれば幸いです

関連記事

CircleCI 2.1とkubernetesで動作するアプリケーションの CI/CD 事始め

Kubernetes時代のCI/CD Jenkins Xとは?-前編