発展途上のデファクト・スタンダードが辛い

Docker・Kubernetes・Terraform あたりに対する、素人利用者が覚える印象の話。あるいは進歩が早い界隈への苦手意識と個人的な限界。

Docker は Docker 社が開発しているコンテナ化のためのツール。技術的には安定してきたものの、最近は Docker Hub の Pull 制限、企業における Docker Desktop 利用の有償化などの話が湧いており、企業として収益化するために色々と変化がある。

Kubernetes は Google が開発し、CNCF がメンテしている。Docker 等のコンテナを管理するためのツールだ。以前は Service の API 形式がちょくちょく変わったりしていたが、最近はベース部分は安定している。しかし未だ安定しないのは、クラウドベンダごとの LoadBalancer、Ingress 回りのお作法。クラウドベンダごとに似て非なる書き方をする必要があり、固有のバグを踏んではワークアラウンドで対処する。半年ごとのアップデートへの追従もあり、「リリースしたらできるだけ触りたくない」と考える企業にとっては面倒である。Secret の秘匿化に SealedSecret や Vault を使うとか、Git 連携との兼ね合いで面倒臭さもある。

Terraform は、Vagrant や Vault を開発している HashiCorp が開発している、クラウドインフラをコードで構築するためのツール。この中では一番「発展途上」感が強い印象。Terraform 自体のバージョンアップにより記法が変わったり、クラウドベンダごとの「Provider」と呼ばれる実装部分のバージョンアップの影響も受けたり、Provider にもバグが多くて「Terraform だと正常に作れないので AWS CLI を組み合わせてバグを回避する」みたいなワークアラウンドが生まれがち。


これらの技術は、「コンテナ化といったら Docker、他は知らない」「時代は Kubernetes でしょ」「Pulumi とかいうのも聞くけど主流は Terraform だよね」といった具合で、デファクトスタンダードと化している。

まぁまぁ確かに、コレ以外のツールの台頭は聞かないし、競合ツールもさほど発展していなくて、「安定したモノを使いたい」と考えている人にとっては飛びつく理由がなかったりする。

ただ、じゃあ Docker・Kubernetes・Terraform が安定して使えるツールなのかというと、前述のとおりバグはちょくちょく残ってるし、開発・運用時の制約やしがらみによって、使いづらさが残る部分も多くある。

オンプレで、お手製のスクリプトで、コンテナ化もせずアプリケーションをデプロイした方が楽だとは思わない。これらの仮想化・抽象化技術によってそうした前時代のつらみをだいぶ軽減できているとは思う。だけど、今発生しているこのつらみも中々のもんだよな、という気持ち。

他に Docker・Kubernetes・Terraform に代わるツールがないから仕方なくデファクトスタンダードとして使っているけど、本当にこんな発展途上のツールを使わないといけないのかしらん?という気持ちにはなる。


それぞれのツールやクラウドベンダが、我先にと必死に開発を進め、新しい機能をリリースしている。「アジャイル開発」の考え方が浸透しているのか、迅速にリリースし、バグは後から直し、フィードバックを聞きながら機能改善を繰り返していくスタイル。

このリリース方式は当然ながら、利用者にも継続した変化への対応を求めることになる。「その API はなくなりました、利用しているコードは修正してください」「この機能は○○機能と統合されて使い方が変わります」なんて言われて、しかも「古いバージョンは脆弱性が含まれるので必ずアップデートしてください」と言われ、新しいバージョンの学習を必修化させられている。


ニホンノエスイーが受託開発するような案件では、大きな機能改修なんて1年に数回程度しかリリースしないのに、どこかで聞きかじったのか「コンテナ化されてないと困るなぁ」とか「IaC に CI/CD してください」とか言い出したりする。よく知らない人は「Docker さえ使えば簡単になる」「Terraform さえ使えば自動化される」のように思っているらしい。IaC も CI/CD も発注側が自分達でやる気などないので、「Kubernetes は半年に1回程度はバージョンアップ作業が発生しますよ」と知らせると「何とかやらずに回避できない?」とか言い出して、何を望んでいるんだろうという感じ。

ただ、そうした素人目に感じる「面倒臭さ」は、自分も理解はできる。

大概のシステムは「1度作ったら終わり」で後から手を加えることがほとんどないので、Terraform を頑張って書く労力に効果が見合わないのだ。1年後に機能追加の案件が発生して、Terraform のコードを引っ張り出してみたら、Provider のバージョンを上げる必要が出てきて、そしたら既存コードの修正も必要になって、あれやこれやしてたら Remote State との整合性が取れなくなって手作業で回避、とかいう事態が発生する。

システムのリリースもそう頻繁ではないのに、Secret を秘匿化して Git Push するとそれをトリガーに CI/CD サービスが起動して Kubernetes クラスタにデプロイされる…なんていう抽象化層が入ると、ただただ作業が面倒臭くなるだけで、便利になった気がしない。いつの間にか CI/CD サービスが上手く動かなくなっていて、Git の状態と相違が発生するようになって、でももう最初に k8s クラスタを作った開発者はいなくなっていて、残された人々は k8s のスキルがないので何をどうしたら修正できるのか分からなくなり、起動中の Pod に直接接続してデータ書き換えを試みたりする。


世界のトップ企業が開発した OSS を使おうというのだから、そのリリースサイクルや運営思想まで含めて、利用者が受け入れないといけない。…と言われればそれまでなのだが、それにしても辛い。

自分達は Kubernetes を使うことで、既存のどういう問題を解消したいのか。Kubernetes を使うことで発生する手間や労力、バグ対応などを覚悟できるか。自分達がやりたいことに対し、Terraform は本当に必要なのだろうか。

そういうことを熟考して、「自分達はやっぱり EC2 に Docker-Compose で動かせば十分じゃない?」だったり、「Kubernetes は使うけど Terraform は止めて、クラウドベンダが提供する CLI ツールを使って、構築スクリプトと手順書を作るに留めよう」とかいった技術選定をちゃんとやらないと、ただただしんどくなるだけで全然便利になった気がしないだろうなーと思う。

IT 素人の発注者方には、こういう泥臭いところが理解できないし、この泥臭い作業をやるにも開発ベンダが勝手に上手くやるワケにはいかず、何をどうしたいかという発注側の意思がないことにはどの選択肢も選べないのだ、というところが、分かっていないというか、伝わらないことが多い。しまいには「Kubernetes 全然便利じゃないじゃん、なんでこんなの使うって話に合意したの?」なんて言われて開発ベンダの責任に転嫁されたりする。

インフラだけじゃない。フロントエンドの SPA フレームワークなんかでも同じようなことが起きてる。「Vue は簡単らしい」「React は流行っているらしい」その程度の認識で選んで、どのフレームワークも上手く実装できなくて詰むという。元々 JS を知らないまま、jQuery が都合よくバグを握り潰してくれていたから何とか誤魔化し誤魔化しでシステムが作れていた程度の人材では、SPA なんて無理なんよ。JSON ってなんですかとか言う人間が発注側にいたら、SPA とか「フロントエンドとバックエンドの分離」とか言わない方が良いのよ。勉強して頭をアップデートしてからじゃないとマジで「作れない」よ。


技術者としてその技術を追っていて、上っ面じゃないドッグフーディングや小規模な実利用もしてみて、「コレは本当に楽になるのだろうか」と疑わしく思うけど、コレを使わない選択肢が選びづらかったり、競合ツールもなくて事実上それを選択するしかないかのような場合が、まぁまぁある。でも、選ぶとやっぱり辛くなる。

世界のトップエンジニア達がこぞって開発を進めて頻繁に最新版がリリースされるツールを、複数併用しようというのだから、利用者としては学習コストは高い。組み合わせ方は自分達で編み出さないといけないし、バグは引くし、新しいモノなのでナレッジも少ない。多少の不具合は自分達で直せるスキルが求められる。ココまで追従できて、出来るのは「維持保守」作業だけ。

そうしたツールを使った新規開発や、改修案件をやろうと思うと、維持保守ができるだけのスキルの上に、無理のないアーキテクチャ構成を乗せる設計思想がしっかりしていないと詰む。ネットワークに関する知識は当たり前に求められるし、各ツールの実装を覗ける程度に Go 言語などの知識が必要になる。「英語できないんですよねー」なんて言うレベルの人は GitHub Issues が読めないワケで話にならない。…なんていう感じで、エンジニアに対する要求水準はココ数年でメチャクチャ上がっているのでは、という気がする。

発注側が呑気に「流行りの新しいアレを使いたい」と言うのに対して、その面倒臭さ、何と何がトレードオフになるのかっていう説明が適切にできないといけないし、「ていうか発注者のお前らも理解して運用するつもりでいるか?」って問えるだけの材料を揃えて折衝しないといけない。そのためにも、「使ったことはないんですけど、使いたくないです」では通用しないので、やっぱり継続した勉強が必要になって、とにかくエンジニア辛い。


元々「面倒臭いことを簡単に済ましたい」という欲から、エンジニア業が性に合うだろうなーと思って就職したのに、こんなに継続してあれもこれも勉強しないといけないのって、大変よね。今のところ自分の中だけでは、積み重ねてきたモノもあるし地頭も足りてるし、拒絶まで行ってないから何とかついて行けているけど、「このままついて行って何になるんだろう」「本当に楽になるんかな」という疑いが段々強まっているので、時間の問題かもしれない。

一度作ったらキチンと放置して運用できる。作った当時の環境を後になってまるっと復元できる。頻繁なバージョンアップや追従作業が要らない。そういう「枯れた技術」にどんどん憧れるようになってきた。


大抵のシステム開発って、GAE にフルスタック Web アプリを載せれば十分だったりしません?GAE の構築も Terraform なんて使わず、gcloud コマンドをメモしておけば良くないですか?SPA とか FaaS とか Kubernetes とか、本当に運用コストまで天秤にかけて使う決断してるかな?CI/CD サービスを連携した GitOps を構築する必要性ががどれだけあるの?「担当者がお手製のスクリプトを流す」では本当に回らないのか?

流行りの新しいモノに追従するの、メチャクチャ大変だぞ。何も知らずには使えないし、全ての繋ぎ込みや既知の不具合など全部込みで面倒見る必要があるぞ。労力は減らないと思った方が良いぞ。みんな慎重に考えような。新しいことやろうとするんだから勉強しないといけないんだぞ。その覚悟あるか?