DevOpsチーム、k8sやめるってよ

# 人はなぜk8sを始め、そしてやめるのか

Mediumをみていたら、Kubernetes(以下、k8s)をやめたらDevOpsチームが幸せになった、という記事をみつけました。

https://medium.com/stackademic/i-stopped-using-kubernetes-our-devops-team-is-happier-than-ever-a5519f916ec0

有料記事なので詳細には触れませんが、記事を読む限りはk8sというインフラがチームに合っていなかったことは明らかだと思いました。

一般的にK8sは開発者の視点ではオーバースペックに感じることが多いと思います。

もし開発者自身に決定権があれば、CI/CDを考慮しても、本番サービスはECSやApp Runnerなどで提供した方が楽になるでしょう。

しかしK8sを喜んで利用する人達はそういう次元では考えていないと思います。

# K8sの利点

K8sはフルスタック・インフラエンジニアにとっては魅力的で実際に便利なツールですが、その観点では次のような特徴が魅力的に映ると思います。

* 物理サーバーの統合
* アプケーションの集約
* ネットワークの統合

物理サーバーにはOSの管理コストやストレージ装置を含みます。

アプリケーションの集約には、複数のアプリケーションの共通部分をマイクロサービスのような形で実装・利用するといった変更を含みます。

最後のネットワークの統合というのはL2やL3レベルの機器統合だけではなく、ロードバランサーやL7レベルのFirewall/WAFやnamespaceによる通信の制御といった点を含みます。

ロールベースの権限管理によって1つのクラスターに複数のアプリケーションを混在させても、プロセスやネットワークなどの資源を安全に隔離できることが大きな利点だと思います。

この記事のきっかけになったMediumの記事では、K8sクラスターを1つの仮想マシンのようにアプリケーション毎に1クラスターといった運用を行っていた形跡があって、K8sの利点を生かせていないと思いました。

このような運用であればコンテナツール(docker/podman)の延長線上にあるECSのようなサービスを選択する余地があるのであれば、ほとんどの場合はそれが最適になるでしょう。

あるいはオンプレミスk8sクラスターをまったく持たずにEKSやGKSといったクラウドのK8sクラスターを利用するのであれば、ECSのようなコンテナサービスでほとんどのニーズは満たせるように思えます。

## K8sが向かない用途

具体的に次のような利用方法では問題になるでしょう。

* アプリケーション単体を動かすプラットフォームとしてk8sを利用する
* 部署やチーム毎にK8sクラスターが存在する
* スケールアウトしないからベアメタルサーバーを使うべきなのに、k8sに全てを集約してしまう
* ミッション・クリティカルな業務アプリケーションの稼動

私はDevOpsという言葉は開発チームを主体に捉えているイメージを与えかねないので好きではありません。

そしてこの種の問題はそんな開発チームの存在感が大きいか、デリバリー・チームに発言力がないことに起因すると思っています。

セキュリティの観点からドメインを分離したい気持ちは理解できますが、顧客やアプリを別々のクラスターに分散させてしまったことで、統合・集約というk8sのメリットを十分に引き出せなかったのではないでしょうか。

またミッション・クリティカルな業務向けのアプリケーションであれば、不確定要素を削除することも大切で、抽象度の高いインフラの選択にはリスクを詳細に分析することが必要になります。この観点ではECSなども同様に不適かもしれません。

しかしHigh-Availability(HA)構成で十分な用途であれば、k8sは最適なインフラになるでしょう。

## k8sをやめてしまう理由

始める理由はそれほど深刻ではないのだと思います。流行っているということもあるでしょうし、GoogleのBorgが元になっていることなど、k8sへの関心が高いことは間違いありません。

コンテナ・オーケストレーションという概念が、DevOps開発において重要であるかのように喧伝されていることも大いに影響していると思います。

関心の高さや、CI/CDとの関連からk8sに手を出してしまうのだと思いますが、やめてしまう背景には開発チームがk8sの運用面に手を出してしまうこともあると思います。

Mediumの記事を書いたチームが幸せになった理由には、k8sをやめた事ではなく、本番環境のインフラを1つに統一した事が本当の理由ではないでしょうか。

本来は規模の大きなk8sクラスターの中に、自分たちが強みを持っているビジネスロジックを共通コンポーネントとしてデプロイし、それらを利用する個別アプリケーションを別々のnamespaceにデプロイするべきだったのだろうと思います。

共通部分のほとんどないアプリケーションを分散したk8sクラスターにデプロイしたとしても、管理コストが増えて幸せにはならないだろうなと記事を読みながら感じたところです。

# 開発チームが主体となってK8sクラスターを管理することは問題か？

一般的にK8sは複雑なシステムだといわれています。そう感じる理由には開発者が「アプリケーションを安定稼動させる」目的からは過剰に思えるような選択肢が用意されていることがあると思います。

## K8sを導入して幸せになる組織

まず組織のインフラ基盤として自社のためにk8sクラスターを整備することには多くのメリットがあります。

デリバリー・チームがk8s環境を整備し、利用できるMiddlewareやストレージ基盤、他のサービスを整理して開発チームに提供することで管理コストを下げることが可能になります。

開発チームが使いたいミドルウェアを全て提供するようなことをするべきではありません。

従業員の認証基盤をk8sのサービスとして共通利用するといった統合化はセキュリティ上だけでなく、全体最適を促すため経営的な観点でも理想的といえます。他のサービスについても同様にデリバリー・チームが中心となって提供するべきです。

開発チームはミドルウェアレイヤー以下について自由な選択肢を失いますが、本来あるべき姿とはそういうものです。

## K8sを導入しても幸せを感じられない組織

反対に必要に応じてアプリケーション・サービスを様々な会社から購入するような組織であれば、k8sを整備しても購入先の選択肢が狭まってしまいメリットがないでしょう。

SIerのような受託開発を行うチームや組織がK8sを利用することにも、CI/CDの恩恵はあると思いますが、コンテナ化には意味があっても、本番環境をk8sにするまでのメリットはあまりないと思います。

いずれも完全仮想化の方が幅広いニーズに素早く答えられるはずです。

K8sをやめたくなる組織はDevOps, CI/CDを実践しているといっても、実際には受託開発をメインとするような業態ではなかったのかなと思われます。

認証基盤やストレージ装置の統合といったニーズがなく、もしセキュリティ上の理由で環境を分割するように求められるのであれば、サーバーの統合といった本来のメリットはそのままデメリットになってしまいます。

# さいごに

K8sはとても便利なインフラ環境ですが、とはいえ同時に難しさも感じています。

例えばLAMP環境での動作を前提としているようなWebアプリケーションや、フレームワークはスタンドアロン型での動作に最適化されていて、マルチテナント型システムでの動作に対応していない場合があります。

:::note
ホスト名やURLパス(context-root)の専有を必要とするWebアプリケーションは有名、無名を問わず多く存在します。
:::

またJavaは総合的にすばらしいエコ・システムを提供していますが、コンテナにはJavaランタイムを含めなければいけないため、イメージに数十MBのオーバーヘッドが存在します。

1サーバーで複数JVMを起動する時のメモリコストが問題だった時に、ライブラリの共有化が行われた時の状況に似ているかもしれません。

またDevOpsという言葉があまり好きではない理由は、Dev"→"Ops というフローを感じるからです。

オペレーションの最適化のために開発チームが力を発揮するべきだと思うのですが、工程の上流側にあることで運用チームが開発チームの決定を受け入れなければいけない場合がまだ多いのではないでしょうか。

これはある種の文化ですが、O'Reillyから出版されている「SREの探求 (Seeking SRE)」ではSREチームへの権限の委譲、運用メンバーのエンジニアリングチームへの参画など、運用重視による全体の見直しがキーであることは繰り返し述べられています。運用チームの最適化がSREやDevOpsのポイントでは決してありません。

開発者のk8sに対するネガティブな反応は、本能的に自分達の活動に制約が導入されることに気がついているからかもしれません。

いっそk8sの運用に最適化した形で組織体制を刷新できれば良いのですが、それは革命であって感情面も含めてチームがバラバラになってしまいます。

メンバーの協力を得て穏かな体制の転換を徐々に図るようなk8sの導入や浸透を模索していって、開発者が喜んでk8sを導入する道を模索していきましょう。

:::note warn
TODO: Qiitaに投稿するならコードをきちんと含めること
:::