経緯
私はインフラエンジニアとしてAWSを用いたコンテナ基盤などの案件に携わってきました。
この前、同僚のアプリケーションエンジニアとコンテナ開発について会話したときに、「コンテナは基盤の持ち物でしょ!」と力説されました。
確かに、コンテナ自体は非機能か機能かで言われたら非機能要件を解決するツールと言えなくもないので、チームをアプリと基盤に分断するのであれば、基盤に近しい存在なのかと思います。
ただ、個人的なイメージではやはりアプリ資材をまとめている存在になりますので、アプリを開発している側の人間が詳しく管理出来たほうがいいのでは・・・?と思い議論に発展しました。
目的
前提として、自社開発においてアジャイル方式で、機能ごとのマイクロコンテナを開発する場合は、1人のエンジニアが一気通貫で面倒を見れたほうが良いと考えています。
しかし、SI企業など請負ビジネスで開発をする場合、基盤やアプリケーションの開発をチームで分担し、ウォーターフォールを取ることが多いです。
そのため、コンテナはどちらのチームでどのように分担するべきなのか考えてみました。
インフラエンジニアの視点
私自身はインフラ畑の人間なので、例えばAWSを用いて開発をする場合、以下のように考えます。
- データプレーンの設定: EC2やFargateなど。
- コントロールプレーンの設定: ECSやEKS、Kubernetesなど。
- これらを取り巻くネットワーク等の周辺基盤環境: VPC, Route53, ALB, CloudWatchなど。
これらは基盤担当のものとして請け負いたいと思います。
ただし、コンテナの中身を決めるようなDockerfileなどのファイルはアプリを作る人間にお願いしたいと思っています。
また、CI/CDにおいても、どういったサービスを使いたいかは、ある程度アプリ側の人間の意見を聞きたいと考えています。
具体的には、以下のような選定があります。
- Gitサービスは何を使うのか
- Gitのパイプライン機能を使うのか
- Kubernetesの機能を使うのか
- ECSであればCodeBuild/CodeDeploy/CodePipelineを使うのか
選定が終わった後のそれらのサービスを使う土壌は基盤チームで請け負うべきです(パイプラインが動くようなネットワーク環境、サーバーの設定、AWSサービスであればIAMロールなど)。
その上で、CodeBuildのBuildSpecやCodeDeployのAppSpecなど、資材のインストールやビルド、テストなどのコード部分はアプリケーション作成者にお願いしたい気持ちが強いです。
アプリエンジニアの視点
しかし、同僚のアプリエンジニアの話を聞くと異なる見解が出てきます。
Dockerの中のミドルウェアの設定やCI/CDなどは全般的に動くところまでお願いして、基本的にはお客様の求める機能要件だけを追求していきたいという意見です。
確かに、コンテナは基盤としての面も強く、コンテナの中にOSやミドルウェアがある場合には、基盤側で設定することも多いです。
しかし、基盤とチームを分けた場合、アプリがどんな資材構成を取りたいかというのは正確にはわからない部分もあり、ある程度のコンテナコーディングはお願いしたいところです。
役割案:コンテナの2重ビルド
コンテナ基盤を基盤とアプリに分断する場合、コンテナイメージを2回ビルドする方式を提案してみます。
まずイメージ図。
これはGitサービスをGitLabに勝手に定義したものとなり、任意に変更いただいてよいです。
-
基盤チームの役割:
- Dockerfileを作成し、基盤側での設定を完了させる。
例えば、OS、ミドルウェアのインストール、証明書の設定、プロキシの設定などを行う。 - これらのDockerfileで作成されたイメージはプライベートリポジトリ(ECRなど)に格納し、ベースイメージとする。
- Dockerfileを作成し、基盤側での設定を完了させる。
-
アプリチームの役割:
- ベースイメージをFROMとして、アプリ資材用のDockerfileを作成し、ビルドを行う。
- CI/CDのための設定ファイルなどの作成を行う。
これにより、CI/CDパイプラインは2つ必要としますが、1つは基盤チームが自分たち用にすべてを定義します。
2つ目はアプリチームにお願いする形ですが、共通する仕組みは基盤チームのものと同じにし、IaCツールなどで複製する方式です。これにより、アプリチームには多少のCI/CD関連のソースコードをお願いするだけで済みます。
また、コンテナ監視用のコンテナ(Jaegerなど)を用いる場合、それはオンラインアプリケーションとは別枠の非機能要件としてのコンテナになるので、基盤側で請け負うのもよいのかなと思います。
その他のメリット
これらの方式をとることで、脆弱性パッチや製品のアップデートを行いたいとき、ベースイメージ側を基盤独自に行ってしまえることです。
アプリチームとしては基盤の変更を、DockerfileのFROM部分を変更するだけで完了できるため、基盤が設定を変更するからと言って面倒なリリース手順を踏まなくても、同じ手順でリリースできるメリットがあると思います。
まとめ
コンテナは基盤にもアプリにも関わりの深いサービスだと思います。
結局チームをわけたとてやるべきことはお互いの認識合わせのための会話と歩み寄りがなにより大切だと思っています。
今回の提案内容は下記にまとめておきます。ここの観点にない話や、それだと問題があるなど意見いただければと思います。
基盤チームの役割
- コンテナオーケストレーションツールの選定
- コントロールプレーンの設計
- データプレーンの設計
- コンテナベースイメージの設計・作成
- ベースイメージ用のCI/CDの作成
- コンテナ監視系ツールの導入
アプリチームの役割
- CI/CDツールの選定
- アプリケーションリリースのためのCI/CD関連ファイルおよびDockerfileの作成