Kubernetes完全ガイド第二版とこの二年間

Hodagi
15 min readAug 2, 2020

--

Kubernetesに関わる技術者で、Kubernetes完全ガイドの名前を聞いたことがない方はいらっしゃらないだろう。Kubernetesのアーキテクチャから、リソースの種類、オペレーション方法、運用監視、Kubernetes上で動作するアプリケーションサービスの設計に至るまで幅広く網羅した”完全”ガイドは、Kubernetesって何?という技術者の疑問に答え続けてきた※1。

そのKubernetes完全ガイド第二版が8/7に出る予定である。だがしかし、秋葉原の書泉ブックタワーで早刷り版が売られているという情報を著者のTwitter経由で伺い、たまたま購入することができた。

自分はKubernetes完全ガイド(無印)も持っている。だが、Kubernetesはインフラのプラットフォームでありながら、三ヶ月おきにマイナーバージョンが更新されていく巨大なプロダクトである。前著が出たのが2018/9/21、そこから二年経っていることを考えるとその間にマイナーバージョンが8つは上がったわけだ。

読み直してみると、実際にえ、こんなAPIあったっけというのがチラホラある。AKS上でウェブサービスを運用していても、このリソースAPIを使ってリファクタリングしてもいいかなと見当も考えだすなど、Kubernetesがますます便利になるのを感じた。

せっかくなので第二版の加筆修正部分で、個人的に気になったことについて比較してみることにした。

※1: 巻末の「よくある質問とその答え」が良い証左である。

細かい修正を拾い上げていくのではなく、あくまでここ二年で自分も三十路という境界線をまたいでしまったなーとしみじみする内容なのでご承知おきください。

Dockerコンテナイメージ周りについて

第一章にDockerイメージ、レイヤーコンテンツを探索し、Docker / OCIイメージのサイズを縮小する方法を発見するためのツールであるdiveについての説明が追加されていた。

2018年から比較するとコンテナイメージ周りはまた大きく変わったと思う。

例えば、以前はDockerデーモンによるセキュリティの脆弱性が盛んに危惧されていて、本著の初版が出た2018年は、Dockerデーモンからの脱却を目指してRed HatさんがPodmanを含めた新しいエコシステムを作っていた真っ最中だった。1.0、つまりGAになったのが2019年の1月。自分も多分そのあたりで遅ればせながらCentOS経由でPodmanに触れてDocker以外を初めて意識するようになったと思う。NTTの須田さん※2を中心とした、Dockerのルートレスモードも順調に開発が進んで、ちょうど去年ぐらいに無事にリリースされたのは記憶に新しい。

DevSecOpsの文脈でコンテナイメージのセキュリティがより意識されてバズワードになったのも、本著(無印)が出た後だと思う。

CIの中でコンテナイメージをスキャニングしてセキュリティの脆弱性を洗い出すTrivyDockleなんてツールも気軽に使えるOSSとして出てきて、前者は開発者ごとイスラエルのAquaSystemに買われてスゲーと思った。このあたりは手段はどうあれ、チェックすることが普通になったと言っていいだろう。

コンテナイメージやKubernetesのセキュリティ周りに関しては、先に触れた須田さんらによって今年の2月に出版されたDocker/Kubernetes開発・運用のためのセキュリティ実践ガイドがここ数年は鉄板本になるかと思う。Kubernetes完全ガイドと合わせて読まれることをお勧めする。

コンテナ周りで忘れてならないのはKubernetesのコンテナを動かすランタイム環境、CRIの存在である。直近ではクラウドプロバイダーなどk8sのディストリビューターによるコンテナランタイムのDockerEngine離れがより加速している印象。よりはっきり言えばcontainerdに置き換えが進んでいるようだ。AKSでは標準のランタイムをcontainerdにする計画中、AWSのFargateやEKSもproduction readyなoptionらしい…OpenShiftはCRI-Oだっけ。

Java界隈から来た人間なので
・開発環境としてのコンテナ環境
・実行環境としてのコンテナ環境
・CI環境としてのコンテナ環境
このあたりがユースケースに応じてプロダクトとして分かれるのはわりと感覚として納得がいく。Docker/mobyが及ぼした影響はあまりにも大きかったが、その行く先についても10年後ぐらいになにかしらの事象名がついてそうだ。

※2: コンテナ界隈には二人の須田さんがいらっしゃいます。自分は勉強会でご尊顔を拝見するまで、PFN(元Zラボ)の須田さんと勘違いしておりました…

第2章のまとめの最後に追加された一文とGitOps

まとめの最後に追加された「また、独自に作っていたリリース用のスクリプトなどを、Kubernetesやそのエコシステムなど共通した手段に置き換えることができるのも大きなメリットの一つでしょう」という一文。

これを追加した背景にGitOpsが念頭にあったことは間違いないだろう。

改めて説明するまでもないが、weaveworks社が提唱したGitOpsの考えはCI/CDの元祖としてHudson、改めJenkinsが世に出て以来、CI/CDは一緒のツールで自動化するものだという概念を打ち破り、なおかつKubernetesをよりエンタープライズな現場で安全に運用するためのニーズを満たすという意味で革新的であったと思う。

コンテナレジストリというアーティファクトに関するわかりやすい共通仕様によって、CI/CDを別々のツールできれいに繋げることができたわけだが、実際に触ってみた最初の所感でビューティフォーとつぶやかずにはいられなかった。

第二版の17章でKubernetes環境におけるCI/CDについてより詳しく説明されている。初版で漠然とOSSを羅列していた項目について大幅に書き直されており、わかりやすい。

ところで気になったことがある。この章で取り扱っているツールはどういう基準で取り上げられたのだろう。Kubernetesの隆盛に伴い、同じ目的を果たしたり、機能が重複する幾多のツールが出てきている。17章のツールでないと同じ事が実現できないかといえば、そんなことはないのだ。

そこでヒントとなるのが勉強会である。サイバーエージェントの技術者によるKubernetesの勉強会でセッションやLTでどれも目にしたツールなのだ。つまり、実際に現場で運用し、洗練した結果がこうやって取りまとめられているのだろう。

もちろん、サイバーエージェントによるビジネス、技術運用要件を満たすツールなので、これから導入しようという現場はこれに限らず様々なツールを、PoCを回した上で検証を重ねるべきだと思うが、事例として大いに参考になるし心強いと思う。

話はそれるが、最近読んだ悩みに悩んだ Kubernetes Secrets の管理方法、External Secrets を選んだ理由は、GitHubのREADMEだけではわかりづらい現場の運用要件とのギャップや技術課題について、検証の過程を丁寧に説明して非常に参考になり、面白かったのでここで推しておく。

3章: kindいいよね

Kubernetes環境に関して試しにやってみたい場合や開発環境として持っていたい本について紹介したこの章、青山さんとしてはkindの追加が最も大きいはずだ。contributeもされているくらいだし。

Kubernetes in Docker…Dockerコンテナイメージをノードとしてkubernetesを構築するツールは、Minikubeが対応した※遥か前からマルチノードをサポートしていた。コンテナでノードを構築している以上、Dockerの制約に引っ張られる形でネットワークに取り回しの難を抱えていたこともあった(例えばかつてはnginx-ingressで二つのポートを公開したいときに踏み台コンテナを作る必要があった)が、改善され続けた今、とても良きツールである。

WindowsユーザーとしてはWSL2のDockerサポートによりWindowsからLinuxコマンドとdockerコマンドを一貫して使えるようになったのも見逃せない。WSL1でも工夫すれば使えないことはなかったが、時々バグるし、挙動はあてにならなかった。「docker rm 全部」というワードでググりxargsとawkという古き良きパイプラインでつなぐLinuxリファレンスの事例しか出てこなくてフラストレーションを感じていた時代は終わりを告げたのだ!!…今はpruneコマンドがあるからそんな心配もないのだけ…Windowsが所管しているTerminalでPOSIX準拠のシェルコマンドを入力できる日が来たのは素直にうれしい。

WSL2のアーキテクチャ周りといえば、WSLのアーキテクチャの解説記事が非常にわかりやすかったのでここで推しておく。

6章: Topology-Awareな世界とマルチクラウド

ここ二年はマルチクラウド、クラウドとオンプレミス、マルチリージョンでのKubernetesの構築を行って冗長性を確保することが(営業トークとして)盛んに言われていた気がする。

それを象徴するものとして、CoreDNSコンポーネントの歴史とTopology-Awareというワードに触れていきたい。

Kubernetes内のPod間の疎通を行うためにDNSによる名前解決、サービスディスカバリー機能が仕様として入っている。Kubenetes上のネットワーク環境を支えるために必要な機能でありつつも、そのコア機能であるDNSサーバーはkubeDNSというkubernetesの開発者が合間に開発していたアプリケーションが使用されており、性能が悪かった。そこで代わりにCoreDNSが完全ガイド(無印)が出版された後で、デフォルトで採用されるようになった。

CoreDNSとは今はRedHatの一部であるCoreOS社が開発に着手し、現在はコミュニティでサポートされている高性能のDNSサーバーだ。最近も、Service Discovery With Hybrid and Multi-Cloud: Introduction to CoreDNS という2019年のKubeConNAがCoreDNSのセッションが示すようにマルチクラウド、より巨大なクラスタ構築での冗長性確保に向けた改善が行われている。それと強調するように、KubernetesのService API側での開発が進んでいる。その一つがEndpointSlicesだ。

Endpointリソースを改善したのがEndpointSlicesリソースなのでEndpointSlicesのまえにEndpointについて説明せねばならない。試しに手元のk8sにつながるコンソール画面を叩いてみるとわかりやすいだろう。

[bastion-user@bastion-host ~]$ kubectl get ep
NAME ENDPOINTS AGE
sonarqube 10.128.6.106:9000,10.128.6.106:9000 25h

Endpointリソースが割り振られていることがわかる。これはなんだろうか?平たく言えばPodがKubernetes の Serviceリソースに公開するときのIPアドレスやポート番号である。これらをEndPointリソースとしてPodと共にetcdで管理し、Podのライフサイクルに合わせてこれらの値も書き換わる。

問題はこのEndPoints群が一つのオブジェクトとして論理的に管理されていることだ。Podが1万個あった時、そのうちの一つを更新するとすべてに影響を及ぼすことになる。特に影響を受けるのがkube-proxyだ。kube-proxyは各ノードに常駐し、podへのネットワークの橋渡しをする。こいつが各自、同じEndpointsを保持しているのだ。一つ更新しただけで各ノードのkube-proxyが一斉に更新を始めるのだ。障害につながりやすいことが容易に想像つくであろう。

そこでEndPointSlicesが出てきた。KEPをみると大規模なノードとPod数を念頭に置いた仕様、機能開発が進んでいることがわかる。このKubernetesのEndPointSlicesは、Kubenetesのネットワーク機能の根幹にあたるのでまだGA機能となるには時間がかかりそうだが、一足先にマージされた機能がある。Service Topologyである。

クラウドネイティブにおけるトポロジーといえば、個人的には冗長性を担保するためのクラスタの大きさというのが文脈上理解しやすい。その場合、冗長性の確保と通信遅延が対立要素になる。

http://ilikesqldata.com/wp-content/uploads/2019/10/azurecomcdn.azureedge.net3ea59a64-bd5b-4eef-bf86-0-18971bff75a7125008cd7a190f7afc17d0433d9f.png より抜粋

上記図を例に説明する。一般にリージョン間にまたいだKubernetes環境を構築したほうが冗長性を確保した状態で、より大型のKubernetesクラスタに向いている。一方で、もしもリージョンにまたいで通信を行うサービスを配置した場合、リージョン間での通信遅延は無視できないものになってくる。俗にいうEast-Westトラフィック問題だ。これを解決するために用意されたのがService Topology、Topology-aware Service Rourtingである。技術的な詳細説明は完全ガイドに譲り、ここではこの二年間の潮流として、Kubernetesの大規模化について触れたい。

あえていうまでもないが、Kubernetesはある程度大きなシステムに向いている。が、その中でさらに巨大化、冗長性を確保しようというユースケースに対しても対応すべく機能を拡張を続けている現況がある。

Scaling Kubernetes to Thousands of Nodes Across Multiple Clusters

Airbnbの人が去年KubeConNAで行ったセッションだ。
正直値が大きすぎてめまいがしそうだが、目指すはこの世界らしい。

そのためのEndpointSlicesであり、Topology-aware Servicesという潮流を抑えると今後も変わっていくKubernetesの機能を追いやすいであろう。

20章: 2年前これからとされていたknativeは当たり前になっていた

knativeがここ二年でserverlessでは当たり前のプロダクトになっていた。書籍が出た当時はまだリリースほやほや感が伺えて、二度、感慨深かった。

kubernetesのv1.16~1.18のKubernetesリソースについて大きく機能拡張されているのでいつかその辺取り上げたい(本当はこちらが趣旨だったが、いつか振り返りたいと存じます)。

kubectlのpluginをちょっといい感じに導入しやすくしてくれるkrewは便利だが、初版だとギリ最初のバージョンが出た頃だから記述なかったことに気づく。(Kubernetes Podcastに詳しい経緯が説明されているが、krewはGoogleのインターン生が開発を始めた) 今では考えられない。

kustomizeが下剋上果たしているw
かわりにksonnetは…()

ephemeral container/storage の存在を2版で思い出した。デバッグに非常に便利ですでに懐かしい機能ではあるが、入ったのは昨年でした。

コンテナのヘルスチェック周りはサイドカー周りに限ってはまだAPIの再編が必要かと存じます。StartupProbesはよい。

ConfigMapの変更をできなくする Immutable フィールドの改善点がよい。明示することには意味があるのだ。

Immutablehttps://github.com/kubernetes/enhancements/issues/1412

https://github.com/kubernetes/kubernetes/pull/86377

本著のスコープには入らないが、kubectlなどのライブラリとして使用されているclient-goライブラリとそれをラップしたKubebuilderOperator-SDK周りはこの二年で非常に洗練されて開発しやすくなった、とは聞く。

著者の青山さんには、KubernetesのSlackで度々お世話になっているので、ダイレクトお布施できたらと思って購入しましたが、思っていたよりも初版と第二版で多くの違いがあり、自分がKubernetesを知った時にすでに円熟した製品だったとの思い違い…大きなムーブに取り残されてしまっていた寂寥感を打ち破り、非常に勉強になりました。

--

--