Kubernetesで実践するクラウドネイティブDevOps -3章-

# 経緯
[Kubernetesで実践するクラウドネイティブDevOps](https://www.oreilly.co.jp/books/9784873119014/)という本を買ったので、実際に手を動かして学んでいきたいと思います。

コンテナとかKubernetesを全然知らないわけではないのですが、雰囲気でやってる部分が多いので再確認する意味でもしっかりやっていきたいと思います。

今回はKubernete環境の比較を行う3章です。

#  Kubernete環境の選択

Kubernetesを導入する際の選択肢

* オンプレで自前構築
* クラウドインスタンスやベアメタルサーバ上に構築
* マネージドKubernetesを使用
* Kubernetesを基盤にしたマネージドプラットフォーム

それぞれの特徴や主なーサービス/プロダクトを紹介していきます。

## クラスタのアーキテクチャ

その前にKubernetesのおさらい。

Kubernetesは複数のサーバをまとめて、クラスタとして扱う。そのクラスタはどのようなつくりになっているのか。

### コントロールプレーン

![クラスタ概要図.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151399/3496f40c-8466-d93e-48c8-29fafb213441.png)

* コントロールプレーンはクラスタの頭脳にあたる。Kubernetesがコンテナのスケジューリング、サービスの管理、APIリクエストの処理などの機能を実行するたに必要

以下のコンポーネントから構成され、クラスタを構成するノードのうち、コントロールプレーンのコンポーネントを実行するものをマスタノードと呼ぶ。

* kube-apiserver
    * コントロールプレーンのフロントエンドサーバ。APIリクエストを処理
* etcd
    * ノードの詳細やクラスタに存在するリソースの詳細など、あらゆる情報を保存
* kube-scheduler
    * 新たに作成するPodを実行する場所を決定する
* kube-controller-manager
    * Deploymentなどのリソースコントローラの実行を管理
* kube-controller-manager
    * クラウドプロバイダと情報をやり取りして、ロードバランサやボリュームなどのリソースを管理

### ワーカノードのコンポーネント

ユーザのワークロードを実行するクラスタのメンバをワーカノードと呼び、以下のコンポーネントから構成される

* kubelete
    * ノードにスケジューリングされているワークロードを起動するコンテナランタイムの運用とステータス監視
* kube-proxy
    * バックエンドのPodのグループに対してトラフィックをルーティングするIPアドレスを提供する
* コンテナランタイム
    * 実際にコンテナを起動終了し、必要な通信を処理する。DockerだけでなくrktやCRI-Oなどもサポートする

マスタノードをワーカノードは役割が違うが本質的な違いはない。小規模なクラスタではますたのをーワーカノード両方の役割を担うノードもある（Docker DesktopやMinukubeなど）。

### 高可用性

![k8sコンポーネント.jpg](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/151399/1ac59d25-cc44-46a2-8005-e25610984b53.jpeg)

* 高可用性のためには複数のマスタノードが必要で、個別のノードやコンポーネントの障害があっても正常に機能しなければならない
* ノード間の通信障害でもetcdレプリカの過半数が利用可能であれば個別のノードに障害が発生しても稼働する事が出来る

#### コントロールプレーンの障害

* アプリケーションがダウンすることはないが、誤動作する可能性はある
* すべてのマスタノードが停止してもアプリケーションは動くだろうが、Deploymentなどのコントローラは機能しなくなる
* コントロールプレーンの可用性は極めて重要であり、クォーラム（定足数）を維持できるように設計しなければならない
* 本番クラスタの場合は最低でも3つのマスタノードが必要

#### ワーカノードの障害

* ワーカノードの障害はマスタノードに比べれば影響が少ない
* コントロールプレーンがPodを再配置する
* しかしワーカノードの数が少ないと個々のワーカノードのクラスタ全体への影響は大きくなる
* 複数のアベイラビリティゾーンやリージョンでの運用が望ましい

#### 検証が大事

以下のようなテストをして確認するのが重要

* ワーカノードをリブートしてみる
* マスターノードをリブート

## セルフホスティング型Kubernetesのコスト

メリット
* 最大の柔軟性とコントロール

デメリット

人員、スキル、作業工数が膨大になる

* コントロールプレーン、ワーカノードの可用性担保
* 通信の暗号化や、ユーザの権限といったセキュリティ
* 認証、認可といった権限周り
* 各ノードのバージョン管理
* データのバックアップ戦略
* その環境の監視
* 頻繁なアップデートへの対応
* Chaos Monkey などを使った継続的なテスト

導入後もKubernetesの更新の仕方やリソースの拡張計画など、作業は永続的に続く。
（Openstackなどのプライベートクラウド導入時にも似たような話があったなあ）

実験やよほど変わった使い方をしない限りはセルフホスティングは薦めません。
GKEやEKSといったマネージドなら1日数ドル程度で動かせるので、まず試してはどうか。

## ターンキー方式のKubernetesソリューション

* 納品後に直ちに稼働できる状態で引き渡される方式をターンキー方式という
* WebUIで数クリックするだけで本番グレードのKubernetes
* [stackpoint.io](https://blog.netapp.com/netapp-acquires-stackpoint-io/)や、[ContainerShip](https://containership.io/)が有名

##  Kubernetesインストーラ

* マネージドでもターンキー方式でもない場合は、Kubernetesインストーラを使うことになる
* [kops](https://github.com/kubernetes/kops),[kubeadm](https://github.com/kubernetes/kops),[RKE](https://rancher.com/docs/rke/latest/en/)等々


##  購入か構築か：本書の推奨事項

選択の際のポイント

* 実行するソフトウェアを減らす
    * 標準のテクノロジを選ぶ
    * 差別化につながらない面倒な作業はアウトソーシングする
    * 長続きする競争優位性を生み出す
* 可能ならマネージドKubernetes
    * クラスタの保守作業は **差別化につながらない面倒な作業** とみなす
    * 競争優位性を生み出せるところに注力すべき
* ベンダロックインの問題
    * KubernetesはOSSなので、むしろ標準のプラットフォームに乗せる事が出来たと考えていい
    * マネージドKubernetesよりも(例えばEC2などに)セルフホスティングしたKubernetesの方が、そのクラウドに依存してしまう
* どうしてもセルフホスティングするのであれば、なるべく標準的なツールを使った方がいい
    * kopsや[Kubespray](https://github.com/kubernetes-sigs/kubespray)がおススメ。成熟していてAWSやGoogle Cloudで本番グレードのKubernetesを構築できる

## クラスタレスのコンテナサービス

コンテナのワークロードのオーバーヘッドを最小限にまで抑えられる方法。ユーザはkubectlのようなツール不要でコンテナをオンデマンドで実行できる。

### Amazon Fargate

* EC2に似ているが、VMの代わりにコンテナを動かす
* クラスタノードやコントロールプレーンを意識する必要なし
* EKS on Fargate という構成も可能

### ACI(Azure Container Instances)

* Fargateに似ているが、AKSとの統合機能が魅力
    * AKSクラスタの設定を介してACIにPod作成をしてスパイクしのぎなどができる
* バッチジョブの実行も可能

## 感想

**「よほどの事情がない限りはマネージドKubernetesを使え」**という、非常に強い意志を感じる章でした。「大規模なKubernetes環境を構築して運用」て、エンジニア冥利に尽きるとか思いがちですけど、それは**差別化につながらない面倒な作業**です。

Kubernetes自体は、Docker Desktopなんかでサンプルアプリを動かすだけならそんなに苦労しなくなってきたのかな？というのが僕自身の感想です。

ただ、本番グレードとなると上述したように可用性やセキュリティ、頻繁なアップデートへの追従など**差別化につながらない面倒な作業**がとても多く運用担当者の疲弊に繋がるでしょう。

とはいえ、何も知らずにマネージドKubernetesを使うと設計やトラブルシューティング時に苦労するので、やはり勉強は必要ですね。

なので次回の4章では、「Kubernetesオブジェクトの基本操作」を学んでいきます。


最後までお読みいただきありがとうございました。