Kubernetes概要
Kubernetesを学ぶ前に、まずDockerについて知っておく必要がある。Dockerについて知らない場合は、先にDockerについて学んでほしい。
Kubernetesとは?
Kubernetes(略称k8s)の公式ドキュメントによると、Kubernetesはオープンソースシステムであり、「コンテナを管理するための基盤ツール」である。
複数のホストでコンテナを扱う場合に便利で、アプリケーションの開発および管理を簡単かつ安全にしてくれる。
Googleが2014年6月に開始した、Goで作られたオープンソースソフトウェア(OSS)である。
docker runとdocker-composeの違いは、同じホスト上で複数コンテナを管理するか、単一コンテナを管理するかという違いである。この構成では、ホストが停止するとコンテナも一緒に停止してしまう。そのため、ホストを複数作成し、複数のコンテナをそれらのホストグループに割り当てるものが「コンテナオーケストレーション(Container Orchestration)ツール」である。この種のツールとしてKubernetesが最も広く使われている。
Kubernetesの特徴
k8sとも呼ばれるKubernetesの基本機能には、コンテナ化されたアプリケーションのデプロイ、拡張、ロードバランシング、ロギング、モニタリングなどがある。
また、アプリケーション運用では、高負荷などで異常が発生したときの対応、スケールアウト、自動フェイルオーバーなど、気を配るべき問題が多い。
VMを使用する構成では、結局のところ管理はVM単位で行う必要があり、スケールアウトや自動フェイルオーバーの設定もVM単位でしか行えない。
Kubernetesを使用すると、コンテナ単位またはアプリケーション単位で管理でき、スケールアウトやフェイルオーバーもアプリケーション単位で設定できる。
なぜKubernetesを使うのか?
マイクロサービスアーキテクチャを実現するにはKubernetesが必要である。

Figure 1: Monoliths and Microservices - https://martinfowler.com/articles/microservices.html
もう少し具体的に、システムが変化する構造を見ていこう。
以前は、多くのシステムが多機能なプロセスで構成されたモノリシックアーキテクチャで構成されていた。

その後、以下のようなマイクロサービスアーキテクチャが導入された。

そして再び、マイクロサービスはコンテナアーキテクチャへと変化した。

これにより、デプロイ単位が細分化され、更新や機能追加が容易になった。

これだけ見ると利点ばかりに見えるが、一方で構造は複雑になり、管理はより難しくなった。
- コンテナの起動が面倒である。
- コンテナ間通信の制御が複雑である。
- コンテナのデータ永続性はどのように管理すべきか。
- コンテナで障害が発生したり停止したりしたとき、どのように復旧すべきか。
こうした不便な点を解決してくれるのがKubernetesである。このようなマイクロサービスアーキテクチャでKubernetesを使う利点は次のとおりである。
- 複数ホスト上の複数コンテナにロードバランシングし、ワークロードを分散できる。
- 1つのPod、つまりコンテナが停止した場合でも自動的に回復できる。
- 無停止更新、つまりローリングアップデートができる。
- アプリケーション稼働中にScale-up、Scale-downができる。
Kubernetesの機能
Kubernetesの機能は次のとおりである。
-
クラスタリング(Clustering)
- 複数のシステムをクラスタリングし、リソースをプーリングできる。
- クラスタを構成するマシンをNodeという。
-
マニフェスト(manifest)による宣言的リソース管理
- アプリケーションに関連するさまざまな要素をリソースとして管理する。
- リソースの定義をYAMLで記述する。
- これをマニフェストという。
- リソースの操作ではなく、定義だけを記述する。そのため宣言的という。
-
リソース種類
- コンテナ: 単一コンテナ。直接定義することはできない。
- Pod: コンテナを統合管理するもの。VMのような概念。デプロイの最小単位。
- Deployment: Podのスケーリングを行うもの。
- Service: 仮想ルーターおよびロードバランサーのようなもの。
- ConfigMap、Secret: コンテナ内の設定ファイルなどを表すもの。Secretは暗号化される。
- PersistentVolume: 永続ボリューム。ホストディレクトリやNFS共有など。
-
宣言的リソース管理
- リソース定義が登録されると、Kubernetesは実際のリソース状態を定義どおりに動作させる。
- Podのコンテナイメージを変更したい場合:
- 古いコンテナを削除し、新しいコンテナの起動を指示する。
- それが難しければ、コンテナイメージ名を書き換えたPod定義で上書きする。
-
仮想フラットネットワーク
- 各Podは複数ノードに分散してデプロイされるが、すべてのPodは仮想ネットワークの同一セグメントにある。
- Kubernetesの仮想ネットワークでコンテナ間通信を行うインターフェースはCNI(Container Network Interface)として標準化されている。
- さまざまな種類のプラグインが存在する。
- Weave Net: VXLAN
- Calico: BGP
- Flannel
-
仮想ネットワーク内DNS
- ロードバランサーの機能を持つServiceにはDNS名が付く。
- このDNS名は仮想ネットワーク内のDNSでIPアドレスに解決できる。
- つまり、PodをServiceの背後に置くことで、PodにDNS名でアクセスできる。
- PodのIPアドレスは動的に変わるため、Service経由のアクセスが基本である。
-
リソースの論理的分割、つまりグループ化
- Namespaceというリソースで、PodやServiceなどのリソースをグループ化できる。
- Namespaceごとにアクセスを隔離するものではないため、管理目的で使用する。
-
コンテナ死活監視およびオートヒーリング
- コンテナの死活監視を定義できる。
- 次のいずれかを定期的に実行し、その結果で死活を確認する。
- HTTPポーリング
- TCP ping
- 任意のコマンド
- コンテナが停止したと判断されると、Kubernetesが再起動してくれる。
-
その他
- Pod複製
- Podローリングアップデート
- ワンショット作業(Job)
- 定期実行タスク(CronJob)
- Pod単位、Namespace単位のリソース(CPU、メモリ)制限
- 仮想ネットワークアクセスポリシー(NetworkPolicy)