kubernetesアーキテクチャまとめ

## はじめに
記事で挙げているkubernetesアーキテクチャ（Master構成）は、k8sを利用する上で必ず必要という訳ではないですが、筆者はCKA(Certificate Kubernetes Administorator)資格をきっかけにk8sの仕組みを知り、k8sを使うことに対する怖さが全くなくなりました。
CKAに無事合格できたので、kubernetesアーキテクチャの概要をまとめてみました。

## kubernetesアーキテクチャ概観

![kubernetes_arch_re_reshape.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667320/dbfaacab-3189-9504-d9bb-bb32672d99c6.png)

k8sは**Master**と**Worker Node**の２つに分けることができます。**Master**は、４つのコアコンポーネントで構成され、k8sの各種機能を実現しています。**Worker Node**は、主にpodをデプロイするために使用されるノードです。

## API Server
API Serverは、多くの場合staticPodとしてkube-systemネームスペースに存在します。API Serverの役割は各コンポーネントとのやり取りで、HUBとして機能をします。クライアントとのkubectlコマンドも、API Serverが受け付けます。

###API Server～クライアント
クライアントとAPI Serveの通信はTSLによって暗号化されています。この暗号化情報や、クライアントが接続するクラスター（API Server）の情報は、KubeConfigで設定します。

![kubeConfig_reshape.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/667320/af4c5194-fc01-937e-9852-3063c22ffacf.png)


## Scheduler
Schedulerは、多くの場合staticPodとしてkube-systemネームスペースに存在します。Schedulerの役割は、podを実行するノードを決定することです（デプロイはkubeletが行います）。kubernetesでは、pod実行ノードに制約をかけることのできる機能が多く存在します。

###podが実行されるノードに対する制約

| 機能              |説明|
|:-----------------|:-------------------------|
| taint            |taintは、tolerationを持たないpodのデプロイを防ぎます|
| affinity         |affinityをpodに設定することで、特定のnodeにデプロイさせることができます|
| drain            |drainにより、特定のノードへのデプロイを防ぎます|
| required resource|podデプロイ時にノードに要求するCPUやメモリを指定できます|

## etcd
etcdは、Key-Valueベースのデータベースで、クラスター情報を管理します。etcdの実体は、多くの場合kube-systemネームスペースのDeploymentです。このetcdのスナップショットを取っておくことで、クラスターのリストアが可能です。このように、etcdはクラスターにとって最も大切なコンポーネントであり、単一障害点にならないように冗長化されることも多いです。

```
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot save snapshotdb // etcdのsnapshotを取得
ETCDCTL_API=3 etcdctl --endpoints $ENDPOINT snapshot restore snapshotdb // etcdのrestoreが可能
```
※ etcdはAPI Serverと異なるTLSサーバ証明書を持つことが一般的です。
　 上記コマンド実行の際は、オプションでetcdのTLS証明書の指定が必要な場合が多いです。

## controller manager
controller managerは、多くの場合staticPodとしてkube-systemネームスペースに存在し、各種kubernetesリソースのコントローラーの役割をします。例えば、controller managerに含まれるdeployment-controllerは、
「kubernetesリソースのdeploymentで定義されれているreplica数」と「実際にRunning状態の対象Pod数」を比較して、スケールイン/スケールアウトの司令をだします。controller managerが正常に動作していないと、「kubectl scaleコマンド実行したのに、pod数が変わらない」スケールされないなどの事象が起きます。

## kubelet
kubeletは、各ノードのデーモンサービスとして動作します。
kubeletの主な役割は、
　・API Serverの司令によるpodデプロイ
　・ノード指定フォルダ配下のpodデプロイ（staticPodとしてデプロイされます）
　・メトリクスをAPI Serverに送信
です。

## kube proxy
kubeletは、daemonSetとしてkube-systemネームスペースに存在します（daemonSetは、任意のpodを各ノードに１つずつデプロイすることを可能にします）。kube proxyはトラフィック管理を行います。

### Serviceの実体からみる、kube proxyの役割
kubernetesは、Dockerのオーケストレーションサービスです。つまり、kubernetesが行うのはDockerの"管理"で、全てのコンポーネントはDocker上で動作します。Kubernetesリソースは、Docker上でどのように存在しているのでしょうか？？
例えば、Podであれば、Pod内の各コンテナはDockerコンテナとしてデプロイされます。Serviceはどうでしょうか？ServiceのようなDockerリソースは存在しません。Serviceの実体は、iptableのようなネットワーク設定です。kube proxyがkubernetesリソースであるServiceを検知して、Serviceをネットワーク設定に変換します。


## kubectlデプロイまでの流れ
kubectlでPod作成コマンド実行～Podデプロイまでの一連の流れです。
以下、コマンド例です。

```
kubectl run --generator=run-pod/v1 hoge --image=nginx
```

1. **kubectl → API Server**
kubectlコマンドは、API Serverが受け付けます。
クライアントへのレスポンスは、2 のetcd更新後に返却します。

2. **API Server → etcd**
API Serverは、etcdに作成するpod情報を記録します。
この時点で、podはPending状態になります。

3. **Scheduler → API Server**
Schedulerは、etcdからデプロイされていないpodを検知し、
CPU・メモリ要求に応じてデプロイするノードを決定し、API Serverに教えます。

4. **API Server → kubelet**
API Serverは、Schedulerが決定したノードのkubeletにpod作成要求を出し、
kubeletがPodデプロイをします。
デプロイ完了をすると、podはRunning状態になります。
  

  
**【参考】**
https://github.com/kubernetes/kubedash