超ざっくり！Kubernetesの主要コンポーネントとpodが立ち上がるまで

# 普段何気なく使用しているKubernetesって何してるんだろう？
普段業務などで使用しているKubernetesって、デプロイの時に役立っててオートスケジューリングとかコンテナ管理してくれて超便利ってイメージしかなく。

実際どんな仕組みで動いているのかわかってないので、調べてわかった事をつらつら書いてみようと思います。

## Kubernetesについて
その中でも今回は、最も基本的なkubernetesでクラスターを作成してpodが立ち上がるまでのプロセスを説明しようと思います。しかしその説明をする上で必要な言葉がいくつかあるため、先にそちらの説明を行います。
**間違っていること言ってたらごめんなさい！！**

### kubernetesの主要コンポーネントについて
簡単にいうとサーバーの構成についてです。

だいたいこんな感じだと思います。
<img width="1012" alt="853733fc-eb0e-749d-f95d-d47db317e597.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545198/05a6e917-b1c5-83e1-4d69-719ea804b7ef.png">




#### Masterコンポーネント
##### API Server
kubernetesのリソース情報を管理するためのフロントエンドのREST API。
各コンポーネントから情報を受け取ってetcdに格納する役目があります。

kubectlコマンドで開発者はAPI Serverにアクセスします。

##### Scheduler
podをどのNodeで動かすかを制御するためのバックエンドコンポーネント。
ノードに割り当てられていないpodに対して、kubernetesクラスターの状態を確認し、空きスペースを持つNodeを探してpodを実行させるスケジューリングを行います。

##### Congroller Manager
定義ファイルで指定したものと、実際のNodeやコンテナで動作している状態を管理します。

##### etcd
kubernetesクラスターの構成を保持する分散KVS。
key-Value型でデータを管理します。どのようなpodをどう配置するかなどの情報を持ち、api serverから参照されます。


マニフェストの内容が保存されると考えていいと思います。

#### Nodeコンポーネント
##### kubelet
Nodeではkubeletと呼ばれるエージェントが動作しています。
これはpodに定義ファイルにしたがってコンテナを実行したり、ストレージをマウントしたりする機能があります。
他にも、Nodeのステータスを定期的に監視する機能もあり、定期的にAPI Serverに通知します。

kube-proxy
様々な中継、変換を行うネットワークプロキシです。
cloud sql proxyなんかもこの一種です。

### 実際にpodが作成されるまでのプロセス
※既にクラスターは作成されているものとします

上のコンポーネントを大体把握したら、これからの説明はわかりやすいと思います。
処理の流れは大体こんな感じ。
<img width="966" alt="d0548b75-9d25-cb52-8f63-c3812d332830.png" src="https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/545198/22570ccd-d39f-6d0a-240e-ec4565253a71.png">


#### kubectl createによるReplication Controllerの作成

```
kubectl create -f hogehoge.yaml
```

でReplication Controllerの作成を実行すると、API Serverに対してReplication Controllerの情報をPOSTします。
API ServerでReplication Controllerのリソースが作成された段階で完了が表示されます。
実際にはまだコンテナは動いてません。

#### API Serverの動き
各コンポーネントからリソースの情報を受け取ってetcdに保存します。
各コンポーネントはAPI Serverのリソースを監視しているので、非同期にイベントが通知されます。

#### controllerの動き
Controller Managerが立ち上げるコントローラの１つに、Replication Controllerを管理するReplication Managerがあります。

このマネージャーは、APIサーバを用いてReplication Controllerとpodのリソースの変更を監視しています。
そのため、新規でReplication Controllerが作成されると指定されたreplica数分、APIサーバを用いてpodを生成します。**この時点ではあくまでリソースとしてpodが生成されるだけなので、まだどのノードにも割り当てられてません。**

#### Schedulerの動き
スケジューラは、APIサーバを用いてノードに未割り当てのpodを監視しています。
未割り当てのpodはetcdが管理している情報を参考に優先度を見て、Nodeに割り当てられます。

#### Kubeletの動き
kubeletはAPIを用いて自Nodeに割り当てられたPodを監視しています。
そしてPodに定義されたコンテナを起動します。

この段階を経てpodが生成されて各Nodeに割り当てられ、開発者が実際に使用できるようになります。

#### 補足

```
kubectl create -f hogehoge.yaml
```

このコマンドで複数台のpodが同時に起動します。
また、起動や削除する際に同時に落とせる理由としてyamlファイルで設定しているLabelが関係しています。

```
spec:
  replicas: 5
  selector:
    matchLabels:
      app: photo-view

  template:
    metadata:
      labels:
        app: photo-view
        env: stage
```

このyamlファイルではlabelsで

```
app: photo-view
env: stage
```

を設定しています。

LabelはKubernetes 上のオブジェクト(Podなど)に付けることができる Key/Value ペアの文字列です。Pod が複数ある場合にそれぞれにラベルを付けることにより、Pod をグループ化したり、特定の Pod を抽出することができるようになります。

なので、podの起動や削除もこのラベルを指定することで、**同時に処理を行うことができています**。

ラベルを用いて上手にグループ分けを行うことは、kubernetesでは必須だし大きなメリットだと感じます。

## 終わりに
今回超ざっくりと起動までのプロセスと、それに関係するコンポーネントを紹介しました。
もしかしたら今後もっと詳しくコンテナが立ち上がるまでの流れを説明するかもしれませんし、Kubernetesに関するもっと別のことを書くかもしれません。

その際はまた見て頂けると嬉しいです！

では、この辺りで。
最後まで読んで頂きありがとうございます。