初めて学ぶ kubernetes

# kubernetesとは	
コンテナ・オーケストレーションツールです。
	
読み方は"クーべネティス"、"クーバネティス"など定まっていいないみたいです。
略して"k8s"と呼ばれたりします。"kubernetes"の"k"と"s"の間に8文字あるからです。
	
ちなみに**Dockerとは別のソフトウェア**です。

Docker は単一のコンテナ化プラットフォームであり、kubernetes は複数のコンテナ制御するためのオーケストレーションツールです。

kubernetes 自体はコンテナを作成することはできないので、Docker または別の他のコンテナランタイムが必要になります。

# コンテナ・オーケストレーションとは	
複数のサーバー(コンテナを有するホスト)を束ねたり、その中にあるコンテナを制御するツールです。
	
メリットとしては、コンテナの管理、デプロイ、スケール、監視などを統合的に管理することが可能になります。

Nodeやその中にあるコンテナを制御するツールはオーケストレーターと呼ばれます。

# 構成について
以下構成について、コンポーネントごとに説明します。
![k8s_構成.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/5d20260b-8d8e-9bdc-bd4d-50033c1b4790.png)


# Node とは
物理または仮想のマシンを指します。

※Nodeには役割によって2種類に分かれます。
* Master Node
* Node(Woker Node)

**Master Node**
* オーケストレーションを行うNodeです。
* 監視やインフラ(APP,DB,内部DNS,NW)を提供します。
* コンテナはありません。
* コントロールプレーンであり、以下で構成されています。

![master_node.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/cd6bbeab-87b6-fe41-fafd-2e2da47c985e.png)

**Node(Woker Node)**
* アプリケーションなどのコンテナが動作するNodeです。
* クラスター内の計算リソースを提供し、アプリケーションコンテナの実行環境を提供します。
* kubelet、kube-proxyが入っています。

![node.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/22147eee-5e08-829a-20d7-b6f9d45e3a9a.png)


**Pod**
* kubernetes上でのコンテナです。
* Podは1つ以上のコンテナで構成されており、共有ネットワーク + ボリュームのセットを指します。
* 1対1でPod:コンテナの構成が多いが、複数のコンテナがある場合でもIPアドレスは1つです(Pod単位で割り当てられる)。
![Pod.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/e773808a-fa45-2ffe-d8d0-3ca660c73fd8.png)

**kubectl**
* Master NodeへのAPIで制御します。	
⇒コマンドやスクリプトを指します。	
	
**Cluster**
* Kubernetes全体の環境を指します。	
* Nodeの集まりです。	
 ※ClusterとしてNodeをまとめることで、以下のようなメリットがあります。	
	  ・スケーラビリティ : Cluster内の Node は、アプリケーションの負荷に合わせて自動的にスケーリングできます
	  ・フェイルオーバーと冗長性 : Cluster 内の Node が障害を起こした場合、他のノードにワークロードを自動的に移行させることができます。
	  ・ロードバランシング :  Cluster 内の複数の Node が負荷を分散するため、トラフィックの均等な分散が可能です。

# リソース	
クラスター内でデプロイおよび管理されるコンピュータリソースやアプリケーションの抽象的な表現を指します。
Kubernetes の構成要素を指しているくらいの理解でいいのではないでしょうか。

各リソースはKubernetes APIを介して定義され、KubectlやManifest（YAML形式 or JSON形式）を使用して操作および管理できます。

以下がリソースの例です。
* NameSpace
* Deployment
* ReplicaSet
* Service
* Volume

**NameSpace**
* Cluster内のリソース（Pod、Service）を論理的に分離する仮想的なセグメントです。
* クラスター内のリソース管理のための論理的なコンテナを指します。
* リソースの隔離、セキュリティ、リソース管理、プロジェクトの分離などの目的で使用されます。

**Deployment**
* デプロイ管理の仕組みを提供するリソースです。
* 主な機能としては、ローリングアップデート、ロールバックなどです。
⇒あるべき姿の定義することで、自動的にコンテナ化されたアプリケーションの管理します。

**ReplicaSet**
* 指定された数のpodを維持するリソースです。
* Deploymentによって生成および管理されることで上記を実現します。


![構成_01.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/6f63fac2-8b06-a2a3-295b-3687e08da741.png)


**Service**
* 永続的なIPアドレスを持たないNode,Podへの通信を提供するリソースです。
* アプリケーションの可用性、ロードバランシング、セキュリティ、名前解決などのネットワーキング関連の機能を提供します。
→用途によっていくつかのServiceType(後述)があります。

![構成_02.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/86b7fe94-eb9d-c55c-020c-d552a6e1f58c.png)

※ServiceType(ここでは以下のタイプを説明します)
* ClusterIP
* NodePort
* LoadBalancer

まず前提的な説明として、k8sのネットワークには以下があります。
* External Network
→Kubernetesクラスターとその**外部環境（通常はクラウドプロバイダーのネットワークまたは企業のデータセンターなど）のネットワーク**です。
* Internal Network
→Kubernetesクラスターにあるノード内に構成される**Pod間を通信するためのネットワーク**です。

![構成図_05.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/08f39cd5-11b4-035f-db7c-fc7afb1e1f39.png)

**ClusterIP**
* Internal Network用のロードバランサーを提供するリソースです。
* クラスター内部用の仮想IPを提供します。

![cluster_ip.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/f0376e39-3283-86f3-a64d-03a0642c3ca8.png)


**NodePort**
* Kubernetesクラスター内のポッドに外部からアクセスするためのリソースです。
* クラスター内の各ノード上の指定されたポートでリッスンし、そのポートを介して外部トラフィックをポッドに転送します。
※InternalNetworkに外部用のPortを作るイメージです。

![ndoe_port.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/840ea9e0-58e6-3caa-6fd9-4de7e1e49fd3.png)

**LoadBalancer**
* クラスタ外からトラフィックを受け取るリソースです。
* クラウドサービス(AWS,Azure,GCPなど)の利用します。
* Serviceの公開、外部トラフィックの負荷分散(L4)、冗長化を行います。
※"LoadBalancer"という名前から負荷分散や冗長化はもちろんですが、ここではクラスタ外から通信を可能にする機能もあります。

![loadbalncer.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/e27580c3-327b-f175-37fe-59e4ce10a8d9.png)


以下が全体像(外部通信を行う場合)です。

![service_全体.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/845c92c4-927a-0a0c-235d-b8e3a923ce3e.png)


**Ingress**
* L7のロードバランシングを提供するリソースです。
* 主な機能としては、外部疎通可能なURL、URL負荷分散、SSL端末、名前ベースの仮想ホスティングがあります。
* 前述した **LoadBalancer は L4 であるのに対して、Ingress は L7 のロードバランシングを行います。**

※Ingress Controller
* 実際に Kubernetes クラスター内の HTTP および HTTPS トラフィックをルーティングし、サービスへ転送するためのリソースおよびコンポーネントです。
* 下記の公式ドキュメントのように様々な Ingress Controller があります。
https://kubernetes.io/ja/docs/concepts/services-networking/ingress-controllers/

下記は Nginx Ingress を利用した場合の構成です。
Nginx Ingress では、Pod として実際にロードバランサーの処理を行います。

![Ingress.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/6681d958-ea9a-1fcc-5fb7-1eaf8e164a0a.png)


**Volume**
* コンテナのデータを永続的に保存するリソースです。
* コンテナの制約として、終了時にコンテナ内のデータが消えてしまいます。そのためデータを保存するためには永続化する必要があります。

※永続化とは
コンテナ化されたアプリケーション内のデータをコンテナのライフサイクルとは独立して永続的に保存および管理するプロセスを指します。

kubernetesのVolumeの種類は以下です。
* pod内のディスクを利用...データは永続化は不可です。
* Nodeのディスクを利用...Nodeのディスク領域をPodにマウント。データの永続化が可能だが、Pod が別ノードで動作した場合にはデータの再利用不可です。
* 外部ストレージを利用...iSCSIやNFS、クラウドプロバイダーの外部ストレージを利用する方法。データの永続化が可能。再利用可能です。

kubernetesで指定できる外部ボリューム例
(1). Volume
(2). Persistent Volume (PV)
(3). Persistent Volume Claim (PVC)
(4). Storage Class (SC)

(1).**Volume**
* emptyDir...Nodeのディスクを一時的に利用する仕組みです(単一のpodのコンテナ間のみ共有可能)。
* hostPath...Nodeのディスクを一時的に利用する仕組みです(異なるpodのコンテナ間のみ共有可能)。

![構成図_03.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/e07983a7-2db7-576e-89c1-5f79ddf7efda.png)


(2). **Persistent Volume (PV)**
* 永続化領域として確保される外部のボリュームを抽象化するリソースです。
* PersistentVolumeClaim(後述)経由で利用します。
⇒欲しいVolume情報を事前に登録するイメージです。
⇒クラスタにボリュームを登録するだけのオブジェクトのため、これだけではVolumeとして利用不可です(後述のPVCが必要)。

(3). **Persistent Volume Claim (PVC)**
* 作成された PV から利用要求するためのリソースです
⇒PVC が利用要求をして、PVから実際のVolumeを作成します。

(4). **Storage Class (SC)**
→ダイナミックプロビジョニングに使用されます。

※ダイナミックプロビジョニング
事前にPVを手動で作成せず、PVCを作成すると必要な条件に基づいてPVが自動的に生成されることを言います。
この際、StorageClassがプロビジョニングルールを提供し、適切なPVを生成します。

※少しわかりにくいので、イラストで説明します。
* 手動で行う場合、Persistent Volume Claim リソースの条件に従ったものが PV から適した Volume を割り当てられます。
* Dynamic Provisioning を利用する場合、Persistent Volume Claimを作成した時点で、Persistent Volume が自動的に作成されて割り当てられます。

![構成図_04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/3513259/3e9accab-aa4d-c896-2586-6c8d0ff568cb.png)

以上、kubernetes基本のについての記載でした。

この記事に関して間違いなどありましたら、ご指摘いただけるとうれしいです。