本記事について
・自分の整理を兼ねて今更ながら概要をまとめてみたものです。

Kubernetes(K8s)とは?
・ギリシャ語で航海長の意味、略称はK8s。
・K8sはコンテナ化されたアプリケーションのデプロイ、スケーリングなどの管理を自動化するためのOSSプラットフォーム。
・Dockerコンテナにより、コンテナの利活用が進み、大規模でもコンテナを活用したいというニーズが高まり、コンテナを管理する仕組みとして登場。
・K8sはDocker以外のコンテナ環境(containerd,cri-o)も利用できる。
・Googleが開発したコンテナクラスタマネージャの「Borg」を元に2014年に公開され、2016年以降はCNCF(Cloud Native Computing Foundation)が管理。
・1年に3回(4ヶ月毎)のマイナーバージョンアップがリリースされる。
できること
以下のようなコンテナ運用を、自動化された簡単なオペレーションに移行できる。
・スケーリング/オートスケーリング
・リソース管理
・セルフヒーリング
・コンテナの負荷分散 ・
・データ管理
・管理を宣言的なコードで実現(Infrastructure as Code)
K8sアーキテクチャ
MasterとWorkerのノードで構成されたクラスター。全ての操作はAPIを通じて行われる。
各コンポーネントの役割
Client(kubectl)
・kubernetes MasterのAPIを直接叩かずに、操作するためのコマンドラインツール。
Control Plane
・コントロールプレーンコンポーネントはK8sの中核となり、全体的な決定(スケジューリングなど)を行う。
Controller Manager
・様々なコントローラーをまとめて実行するコンポーネント。
※DeploymentやReplicasetの状態を監視しながら、必要に応じてReplicaSetやPodを作成する等
API Server
・Kubernetes APIを外部に提供するKubernetesコントロールプレーンのコンポーネント。
Scheduler
・新しく作られたPodにノードが割り当てられているか監視し、割り当てられていなかった場合にそのPodを実行するノードを選択。
etcd
・クラスタ情報を永続化して格納するためのKVS。
Worker Node
・実際にPodを動作させるためのノード。Podとノードコンポーネントでできている。
Node Components
・すべてのノードで実行され、稼働中のPodの管理やKubernetesの実行環境を指す。
Kubelet
・ノード上で動作し、コンテナの管理を行うエージェント機能。
Kube Proxy
・ネットワーキングと負荷分散をサポートするコンポーネント。各ノードで実行され、内部的にはLinuxカーネルのiptablesを利用する。
コンテナランタイム
・ノード上でコンテナを実行するコンポーネント。kubeletから受けた指示を元にコンテナのイメージ取得から実行までを行う。
Pod
・K8sが管理するコンテナの単位、コンテナを複数まとめて1つのPodにする場合もある。
Kubernetes APIの利用方法
・Kubernetes APIを使用すると、Kubernetes API内のオブジェクトの状態をクエリで操作する。
・基本的にはkubectl CLIを用いてAPI操作する。
・kubectl CLIを利用してK8sクラスターの各種リソースをマニュフェストを用いて宣言的に設定する。
K8sとDockerの関係
・Dockerはアプリをコンテナの中で管理し、実行できるようにするコンテナ型の仮想環境であり、K8sはDocker(Docker以外も可)と連携して利用できるデプロイ/オーケストレーションツールとなる。K8sのPod内でコンテナ(Docker)を利用する。

K8sを利用できる環境
・クラウドやオンプレで利用でき、様々なサービスがある。マネージドサービスの品質を担保するため、CNCFのCertified Kubernetes Conformance Programがあり、一定レベルでKubernetes APIに対応しているディストリビューションの認定を行っている。
マネージド(クラウド)
・Amazon EKS
・Azure Kubernetes Grid
・Google Kubernetes Engine
オンプレ/IaaS
・Red Hat OpenShift Container Platform
・VMware Tanzu Kubernetes Grid
・kind
アプリ開発の流れ
・K8sはコンテナのオーケストレーションツールでコンテナの運用に利用するため、コンテナの開発(イメージビルド)は別の場所で行うのが一般的である。そのため、開発はDockerやComposeを利用し、運用をk8s上で行うケースが多い。

アプリ展開
・K8sではマニュフェストと呼ばれる構成ファイルを使ってアプリを展開/運用することが一般的。
・以下の図ではPodとそれを外部に公開するサービスのマニュフェストの2つを利用してNginxを展開する。

ネットワーク
・K8sクラスターには複数のノードが存在するが、各ノードで起動するPod間の通信をどのように実現するのかがポイントとなる。
・K8sのネットワークを実装するには、いくつかの要件がある。
・ノード上のポッドは、NATなしですべてのノード上のすべてのポッドと通信できます。
・ノード上のエージェント(システムデーモン、kubeletなど)は、そのノード上のすべてのポッドと通信できます。
・ノードのホストネットワーク内のポッドは、NATなしですべてのノード上のすべてのポッドと通信できます
※引用:Kubernetes/クラスターネットワーキング「Kubernetesネットワークモデル」
コンテナネットーワークの基本
・Pod内に複数のコンテナを内包でき、同じPod内であれば全てのコンテナは同じIPアドレスが割り当てられるため、同一Pod内のコンテナへ通信する場合はLocalhost宛に通信を行う。
・異なるPodのコンテナへの通信はPodのIP宛に通信する。通常は各個Podが独自のIPアドレスを持つ。このIPアドレスは外部と通信できない内部用となる。
ノード間通信
・Pod同士の通信が可能なのは同一ノード内のみであり、そのままのIPアドレスでノードを跨いでの通信はできない。
・Dockerではコンテナとホスト外部の通信にNATが利用されているが、K8sの場合、Pod毎にNATテーブルを実装すると管理上煩雑になるため、XVLAN技術等を用いた「オーバーレイネットワーク」を用いて実現している。

CNIの実装
・オーバーレイネットワークを採用するFlannelや、Calicoなど仕組みがあるが、これは元々K8s向けに作られた仕組みではなく、K8sプロダクト毎に対応していくのは非効率的となる。そこで、共通のインターフェイスであるCNI(Container Network Interface)を標準実装することで簡素化を実現している。
Service
・上記の仕組みを用いることで、ノード毎とのネットワークセグメントは自動的に分割して割り当てられるため、利用者が特別意識する必要はない。従って、PodはSericeを利用せずともPod間通信を行うことが可能となる。
・ただ、Serviceを利用することでアプリのサービスとして利用する上での恩恵、例えば
「Pod宛トラフィックのLB」、「サービスディスカバリとクラスタ内のDNS」を受けることができる。
・利用者が直接利用するものとしては、ServiceリソースのL4ロードバランサーとIngress(L7ロードバランサー)の2種類がある。
リソース | type | 内容 | 備考 |
---|---|---|---|
Service | Cluster IP | K8sクラスター内でPod同士が通信するのに利用 | |
Service | NodePort | クラスター外からクラスター内のPodに対してアクセスするのに利用する。NodeのIPアドレスとPort番号の組み合わせとなる。 | |
Service | LoadBalancer | K8sクラスター外のLBを利用して、クラスター内のPodに対してアクセスするのに利用する。 | |
Service | ExternalName | CNAMEレコードを返すことにより、externalNameフィールドに指定したコンテンツ(例: foo.bar.example.com)とServiceを紐づける。 | L4LBの機能 |
Ingress | - | K8sクラスター外のLBを利用して、クラスター内のPodに対してアクセスするのに利用する。負荷分散に加えて、SSL終端、名前ベースの仮想ホスティングを提供する。 | L7LBの機能 |
LBとDNSの使われ方
・DNS
・K8sクラウスター内部ではCoreDNSを起動する。K8sクラスター内で起動するPodはCoreDNSをリゾルバとして参照し、クラスター内で起動するPodの名前とIPアドレスや、サービス名やLBの仮想IPが自動的に登録・管理される。
・ロードバランサー
・受信したトラフィックを複数のPodにバランシング(負荷分散)する機能。Podは起動する毎にそれぞれ異なるIPアドレスが割り当てられるため、LBに対する仕組みを独自に実現しようとすると、各PodのIPを都度調べてバランシングの転送先設定を行う必要がある。Serviceを利用することで、自動的に構築することができるとともに、ロードバランサーの接続口となるエンドポイントも提供する。

ストレージ
・K8sでは、ボリュームを抽象化してPodと疎結合なリソースとなる。
・データを永続化するためのストレージモデルとして、3つのリソースがある。
モデル | 内容 | 権限 | 備考 |
---|---|---|---|
PersistentVolume | 永続化領域として確保されるボリューム。特定のPodに関連付けられなく、K8sによって管理される。 | 管理者 | ショートネーム:PV |
PersistnetVolumeClaim | 作成されたPVの中からアサインするためのリソースになる。実際にPodから利用するためにはPVCを定義して利用する必要がある。 | ユーザ | ショートネーム:PVC |
StorageClass | ボリュームの生成元となるストレージを示すリソース。AWSのEBS等を指す。 | 管理者 | ショートネーム:SC |
■参考URL
https://kubernetes.io/ja/docs/home/
https://www.mushroom-blog.com/177/
https://thinkit.co.jp/article/17453
https://www.nic.ad.jp/ja/materials/iw/2018/proceedings/h2/
■参考書籍
Kubernetes完全ガイド 第2版 impress top gearシリーズ by 青山真也
たった1日で基本が身に付く! Docker/Kubernetes超入門