見出し画像

コンテナ/k8s化は必要?ちょっと考えてみよう

■目的

Dockerを中心としたコンテナ技術、Kubernetesを主流としたコンテナオーケストレーション技術、それぞれが本当に必要なのかという部分を改めて整理する。

■注意

ここではコンテナ技術=Docker, コンテナオーケストレーション技術=Kubernetesと仮置きして気定義するので注意してください。

■コンテナ・コンテナオーケストレーションが目指すもの

Dockerが初期の頃から掲げているスローガン?としてBuild, Ship, Runがあります。ビルド(Build)したイメージをどこかに運び(Ship)、実行(Run)するだけでアプリケーションが動作するというイメージです。このようにアプリケーションの可搬性を限界まで高めることを目的としたのがDockerです。

さらに複数台のDockerのインストールされたサーバ(Dockerホスト)を統合運用するための仕組みがコンテナオーケストレーションです。コンテナオーケストレーションツールとはDockerホストを意識させないように抽象化を図るための仕組みです。具体的にはコンテナの可用性の確保、コンテナ間のネットワーキング、サービスディスカバリなどの各種非機能要件をDockerホストを可能な限り意識させることなしに実現します。

代表的なコンテナオーケストレーションツールであるKubernetes*1はこれらの満たすもので最も広く利用されています。

このようなことからDockerとKubernetesを用いることが、アプリケーションの可搬性を高め、各種非機能要件を実現するための手段となりえます。

*1ただし、最近はKubernetes自身、徐々に"コンテナ"のオーケストレーションツールの域を超えつつあるようです。

■Docker・Kubernetesの”現時点での”課題

ではこのような前提のもとでDocker・Kubernetesの課題を考えてみましょう。

Docker・Kubernetesが容易に能力を発揮できるのは以下のような場合です。おそらく他にも多々あると思います。

・頻繁にデプロイを実施するもの
・水平スケール可能なもの
・可能な限りステートレスに作られているもの

コンテナイメージを作成するためのDockerfileでシステムを構成するコンポーネント(≒アプリケーションバイナリ)が起動するための環境を順します。次にKubernetesのリソースマニフェストファイルにおいてそれらの個々のコンポーネント間をつなぎ合わせます。*2。このようにビルドからデプロイをコードベースで定義できるようにすることで頻繁にデプロイすることを可能にします*3

*2ただし一部Dockerfile側で実現するかKubernetesのリソースで実現するのかの判断が必要なものもあります。

*3 実際にはコード化しなくても手順書ベースで頻繁にデプロイすることは可能ではありますが、チームメンバーのメンタル面での疲弊につながることの理解は必要です。

しかしここで注意すべき事柄が発生します。Dockerfileがいつまでもは信用できない点です。Dockerfileは内部の手順については可能な限り動作が変わらない様努力をしてくれますが、外部環境の変化については脆弱です。例えばパッケージリポジトリなどを利用している場合は対象となるパッケージのバージョンなどが変わる可能性があり、必ずしも再現性を保証してくれるものではありません。

では、コンテナイメージはどうか?となりますが、これについても保証の限りではありません。

一般的にDockerにおけるコンテナ仮想化はOSカーネルはDockerホストのものを利用するためカーネルのバージョンが大幅に変更になっている場合は必ずしも正しく動作することが保証されません。(OSカーネル自身はほとんどの場合、後方互換性を保持できるよう配慮されていますが、必ずこれが守られるとは限りません。)

従って、OSのバージョンアップなどを伴う場合は動作が保証できないため詳細な検証が必要になってきます。

Kubernetesの場合の注意点についても考えてみましょう。まず最初に思い浮かぶのがアプリケーションそのものの要件が大きく響きます。Kubernetes自身がBorgをベースとして作られているため思想面でもBorgの影響を強く受けています。例えばコンテナが何らかの理由不意に停止し、他のホストで再起動してもシステム全体が致命的なダメージを受けないように設計しなければなりません。つまり、単一の処理のリトライが容易に実行できるような仕組みになっていなければなりません。Kubernetesが基本的にコントロールできる範囲はアプリケーションコンポーネントの動作の管理と起動停止までであり、例えばそれぞれのコンポーネント内部のデータ管理については範疇外であるためです。(作り込み次第では不可能ではありませんが。)

ここまでに挙げたようにDocker・Kubernetes自身も銀の弾丸ではなく苦手としている領域が明確に存在することがわかります。

■あなたのシステム、コンテナ化・Kubernetes化必要?

では、あなたの周りにあるシステムがコンテナ化、k8s化すべきかという部分が見えてきます。

いわゆるDocker・Kubernetesがフィットするシステムは以下のような特性を備えています。

・頻繁にデプロイする
・不意の再起動でも致命的な影響は出づらい

Docker、Kubernetesともにビルドとデプロイを容易にするための仕組みなので、頻繁にデプロイを実施するシステムほどフィットします。

また、処理が何かしらの理由で途中で止まった場合でも容易にリトライできる仕組みを備えているか、そもそもそのような仕組みが必要ないくらい単純にりとらいできるようになっているものです。

後者については作り込み次第では影響が出ますが前者についてはビジネス的な理由が殆どを占めると思います。例えばビジネスの競争力の源泉となっているものかつ、競合との熾烈な競争に晒されているものなどが考えられます。具体的にはB2Cのサービスで仮説検証サイクルを高頻度で回して機能の追加、改善を行う必要がある場合などです。

では、あなたの身の回りにあるシステムを考えてみましょう。プライベートではなく、職場にあるシステムで考えてみます。

例えば勤怠管理システム、給与計算システムです。これらは”利用者側としては”*4熾烈な競争に晒されているものではありません。むしろ、頻繁な変更は避けたく、特別な理由(OSのEOSLなど)がない限りは塩漬けにしておきたいはずです。従って、頻繁にビルド、デプロイを行うモチベーションが存在しないため、コンテナ化のメリットは得づらいものになります。

*4 "利用者側としては"という部分が重要です。あなたが勤怠管理システムや給与計算システムの提供側(ベンダー)であれば頻繁にリリースを行って仮説検証を行いたいはずです。特にSaaS形式などであればなおさらです。

では、翻ってあなたの会社の競争力の源泉となるシステムを考えてみましょう。B2Cであればなお良いです。大抵の場合は熾烈な競争に晒されており、ユーザ体験をより良いものとするための仮説検証を頻繁に行いたいはずです。結果としてビルド・デプロイは高頻度で行うようになります。このような場合は、Docker・Kubernetesは高い効果を発揮してくれるはずです。

■まとめ

普段はコンテナ・k8sまわりに関わることが多いためあえてそれらがフィットしない状況というものも考えてみました。あくまで一個人の考えなのでご参考までにお願いします。

この記事が気に入ったらサポートをしてみませんか?