【K8s】Kubernetesのネットワークを理解するまで


# Kubernetesのネットワークを理解するまで
※ Kubernetesのネットワークを理解するまでに調べたことを書いていっています。

## 内容
- 基礎知識の復習
- Dockerのネットワーク
- Kubernetesのネットワーク

## 基礎知識の復習
### OSI参照モデル
下記がOSI参照モデルになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/ede78ca7-b706-819d-7fac-8144c8559c9f.png)

詳細は下記を参考にすれば問題ないと思います。
[OSI参照モデルまとめ](https://qiita.com/tatsuya4150/items/474b60beed0c04d5d999#osi%E5%8F%82%E7%85%A7%E3%83%A2%E3%83%87%E3%83%AB%E3%81%A8%E3%81%AF)
[OSI reference model](https://www.infraexpert.com/study/networking3.html)

### TCP/IPモデル
上記のOSI参照モデルを実運用で使いやすくしたモデルをTCP/IPモデルと呼びます。
[TCP/IP 4階層モデルとは？](https://thinkit.co.jp/story/2015/04/30/5800)
[「OSI参照モデル」と「TCP/IPモデル」の違い](https://wa3.i-3-i.info/diff322model.html)

下記の右側がTCP/IPモデルになります。
OSI参照モデルを**よりシンプルにしている**ことがわかります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/5adb3f08-0e28-191e-94c3-b837e000ccbc.png)

### インターネット通信の流れ
PCからPCにアクセスする流れは、上記のアプリケーション層から順に降っていき、第1層になったタイミングで電気信号になり、送り先のPCに送られます。この電気信号を受信したPCは、物理層から順に上がっていき、アプリケーション層に到達することができます。
この時の電気信号は、ルーターを経由することによって、目的地まで運ぶことが可能になっています。

>1. 運搬に必要な情報をデータに付与する
2. そのデータを目的地まで運ぶ
3. 到着したら、付与された情報を紐解きつつ、データを指定アプリケーションまで届ける


データの流れは下記のようになります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/852e62cd-721c-ae82-314b-ffbb286089ec.png)

#### 各層での役割
- マシンがある(物理層)
- イーサネット(ネットワークインターフェース層)
- IPアドレスを元に通信(インターネット層)
- TCPでアプリケーションプログラムの通信を実現(トランスポート層)
- クライアント、サーバーモデルが動作(アプリケーション層)

[インターネット通信の流れ](https://qiita.com/naoki_mochizuki/items/7ee0e01db61e1e7abd62)
[通信周りに疎いエンジニアがTCP/IPの要点を頑張って教えます](https://qiita.com/genre/items/05186691fbf8c10a4a48)


### 基礎用語の確認
#### イーサネット
>LANに採用されている通信規格のこと
>LANのこと

[イーサネット (Ethernet)とは](https://wa3.i-3-i.info/word1539.html)

##### Wifi
>イーサネットの無線版となる存在が「WiFi」です。
[イーサネットとは？用途別のケーブルの選び方まですべて解説！](https://wifi-style.com/basics-of-wifi/ethernet/)

#### TCP
通信データが受信側に確実に届くことを保証するプロトコルです。
信頼性を重視します。

#### UDP
信頼性のないデータグラム型のプロトコルです。
DNSで主に使用されています。

#### ART
>IPアドレスからEthernetのMACアドレスの情報を得られるプロトコルです。LANに接続されたコンピュータ間で通信するためには、IPパケットは下位のレイヤでL2ヘッダが付加された上で伝送されることからMACアドレスの情報が必要となります。しかしこれらのIPアドレスとMACアドレスは自動的な関連づけがないので、ARPでMACアドレスを得る必要があります。

[TCP/IP - ARP](https://www.infraexpert.com/study/tcpip2.html)
[ARPとは](https://wa3.i-3-i.info/word174.html)

#### ルーター
IPアドレスが付与され、経路制御を行う機器のことを指します。
ルーターをホップしていくことで目的のIPアドレスに到達することができます。
ルーターの中身は、ルーティングテーブルという情報を持っており、この情報に次にどのルーターへ送れば良いかが記載されています。

#### NAT
>プライベートIPアドレスをグローバルIPアドレスに変換する技術です。

[NATに関して可能な限り分かりやすくまとめて見た](https://qiita.com/tasakii/items/60a3696ec7b86111884d)


#### MACアドレスとIPアドレス
MACアドレスが人で、IPアドレスが住所(変わることがある)という例が非常にわかりやすいです。
[MACアドレスとIPアドレスの違い](https://qiita.com/cironaga/items/6a0c909e31f986c9f825)

#### IPアドレス種類
IPアドレスには、プライベートとグローバルの2種類が存在し、それぞれに静的、動的IPアドレスが存在しています。
[用語集　「IPアドレスとは？」](https://www.cman.jp/network/term/ip/)

##### プライベートIPアドレスとグローバルIPアドレス
プライベートIPアドレスとは、**インターネットに接続しないタイプのIPアドレス**

>プライベートIPアドレスとは、LANなどの企業内ネットワークに存在する端末が、自由に使用できるIPアドレスのこと。自ネットワーク内でのみ一意であるため、ほかのネットワークでは同じプライベートアドレスが利用されている可能性がある

[プライベートIPアドレス](https://www.atmarkit.co.jp/aig/06network/privateip.html)

グローバルIPアドレスとは、**インターネットに接続するタイプのIPアドレス**

>グローバルIPアドレスとは、インターネットで相手と通信するために持つ、ほかのアドレスと重複しない一意のIPアドレスのこと。TCP/IPでは、通信相手を特定してIPパケットを送信したり、ルーティングするために必要となる。

[グローバルIPアドレス](https://www.atmarkit.co.jp/aig/06network/globalip.html)

##### 静的IPアドレス(固定IPアドレス)
>機器や人に対して固定で割り当てられたIPアドレスのこと

[静的IPアドレスとは](https://wa3.i-3-i.info/word14985.html)

##### 動的IPアドレス
>IPアドレスの割り当て方のひとつで、ネットワークを使うときに一時的に割り当て、使わなくなると回収されるので、使う度にIPアドレスが変わる（可能性のある）割り当て方のこと

[動的IPアドレス (dynamic IP address)とは](https://wa3.i-3-i.info/word14983.html)
[固定IPアドレスと動的IPアドレス](https://www.cman.jp/network/term/ip/p3/)

#### NIC
ネットワークとPCのインターフェースになります。
LANケーブルは、インターネットとパソコンをつなぐ役割をしてくれます。
LANケーブルのさしたところに、ネットワークカード(LANケーブルを挿す穴がくっついた部品)が存在します。
[ネットワークカード (NIC)とは](https://wa3.i-3-i.info/word12498.html)

イーサネットなどが該当します。
Macの場合は、イーサネットがデフォルトで入っていることで、インターネットに接続することができます。

下記コマンドで自分のMACアドレスを確認することができます。
下記の場合、etherがイーサネットを指し、a4:83:e7:93:20:85がMACアドレスを指しています。

```
$ ifconfig en0 ether
en0: flags=8863<UP,BROADCAST,SMART,RUNNING,SIMPLEX,MULTICAST> mtu 1500
	ether a4:83:e7:93:20:85
```

#### ホスト
IPアドレスが付与された機器

##### ホップ
区間ごとにルーターがIPパケットの転送処理を行います。


## Dockerのネットワーク
次はDockerを掘り下げていきます。

### Linux bridge機能
Linuxがハブになって、Dockerに接続する機能を指す。
下記が全体像になります。

>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/251bdbab-57f2-5ffa-ff09-392a0809a799.png)
下記記事より引用
[Docker の基本学習 ~ Docker のネットワーク](https://qiita.com/Arturias/items/b538e6bbf05dd3364397)

### 仮想ブリッジ
`docker0`という名称の仮想ブリッジを使用します。
docker0　→　veth　→　eth0 と言う順序で接続されます。
インターネット層で使用されます。

### veth
仮想的なネットワークインターフェース(仮想NIC)をさします。
1つはコンテナ側（eth0）、もう1つはホスト側(veth)に別れ、ペアで設置されます。
またvethは、仮想ブリッジ(docker0)に接続することができるようになります。

#### eth0
IPアドレスが付与されます。
コンテナの場合、docker側が勝手にIPを付与してくれる。

[Docker network 概論](https://qiita.com/TsutomuNakamura/items/ed046ee21caca4a2ffd9)
[Docker の基本学習 ~ Docker のネットワーク](https://qiita.com/Arturias/items/b538e6bbf05dd3364397)
[Virtualization - Part2](https://www.infraexpert.com/study/virtual2.html)

## Kubernetesのネットワーク
まず、Kubernetesのネットワークを理解するためには、下記を認識しておく必要があります。

>Kubernetes では、ホストや VM がどのように接続されているかを考えるのではなく、ポッド、サービス、外部クライアントがどのように通信するかを考えます。


### Node
Nodeは、Virtual Private Cloud(VPC)から割り当てらてたIPアドレスを使用します。
ノードは仮想マシンであり、GCEインスタンスとして実行されています。
下記が全体図になっており、構成はLinux bridge機能のところで紹介した構成図とほぼ同じになっていることがわかります。
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/c3e3de87-d4f5-8a6f-aa2a-eb4f64ea912d.png)
[ネットワークの概要から引用](https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview#terminology_related_to_ip_addresses_in_kubernetes)

### Pod
同じPod内のコンテナに対しては、localhostでアクセスすることができます。
異なるPodでの通信では、PodのIP宛に通信する必要があります。
ただし、Podは作成されたり、削除されたりするので、毎回異なるIPアドレスが付与されます。
これでは、毎回指定するIPを変更する必要があり非常に面倒です。
この場合に有効なのが、**Service**になります。

Pod間通信は、sevice経由で通信が可能になります。
例えば、フロントからバックエンドに対してリクエストを送る場合は、
バックエンドのService(例えば、ClusterIP)の名前を指定してあげることで、リクエストを送信することができます。

#### コンテナから見たPod
>コンテナの視点からは、ポッドはネットワーク インターフェースを 1 つ備えた物理マシンのように見えます。

Podからコンテナへの通信に関しても、Linux bridge機能を備えているのであれば、Linux bridge機能が2重になっているということになるのかな。
ここあんまり自信ないです.....

>ポッド内のすべてのコンテナは、この同じネットワーク インターフェースを参照します。各コンテナの localhost は、ポッドを介して、ノードの物理ネットワーク インターフェース（eth0 など）に接続されます。

これが同じPod内のコンテナ間通信は、`localhost`でできる理由ですね。


#### クラスタ外DNS、クラスタ内DNS
クラスタ外に関しては、一般的なDNSサーバー(AWS Route53など)に問い合わせる
クラスタ内に関しては、クラスタ内DNSを利用して名前解決を行います。
[ServiceとPodに対するDNS](https://kubernetes.io/ja/docs/concepts/services-networking/dns-pod-service/)

>Kubernetesのbarというネームスペース内でfooという名前のServiceがあると仮定します。barネームスペース内で稼働しているPodは、fooに対してDNSクエリを実行するだけでこのServiceを探すことができます。barとは別のquuxネームスペース内で稼働しているPodは、foo.barに対してDNSクエリを実行するだけでこのServiceを探すことができます。

イメージとして、上記のように名前解決をしてくれます。
この時に使用されるのが、`kube-dns(Core DNS)`です。

### Service
>一連のポッド エンドポイントを 1 つのリソースにグループ化したものです

サービスの定義は、上記で定義されています。

サービスを定義する理由としては、固定の IP アドレスを取得し、Podを動かすためだと考えています。
Podは、停止し、再起動すると、IPアドレスが変わってしまいます。
そのため、Serviceを通して動かす必要があります。

>ポッドが Service のメンバーとして識別されるには、セレクタで指定されたすべてのラベルがポッドに設定されている必要があります

ServiceはPodのラベルを識別し、リクエストをPodにルーティングしてくれます。

[Service](https://cloud.google.com/kubernetes-engine/docs/concepts/service)
[Kubernetes NodePort vs LoadBalancer vs Ingress? When should I use what? (Kubernetes NodePort と LoadBalancer と Ingress のどれを使うべきか) を訳した](http://chidakiyo.hatenablog.com/entry/2018/09/10/Kubernetes_NodePort_vs_LoadBalancer_vs_Ingress%3F_When_should_I_use_what%3F_%28Kubernetes_NodePort_%E3%81%A8_LoadBalancer_%E3%81%A8_Ingress_%E3%81%AE%E3%81%A9%E3%82%8C%E3%82%92%E4%BD%BF%E3%81%86)

### ラベル
クラスタの整理に役立つKey-Valueペアのことを指します。
Kubernetesでは、このラベルを使用して、サービスがどのPodにアクセスを分散させるか確認しています。

[ラベルの作成と管理](https://cloud.google.com/kubernetes-engine/docs/how-to/creating-managing-labels)
[kubernetesにおけるHTTP/2のロードバランシング](https://qiita.com/shoichiimamura/items/be2e57767bde69b65425#service%E3%81%AE%E4%BB%95%E7%B5%84%E3%81%BF)
[GKE/Kubernetes でなぜ Pod と通信できるのか](https://qiita.com/apstndb/items/9d13230c666db80e74d0)

#### トラフィック
>![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/148392/34652fef-d2ce-b0d2-ec07-bb387ef0bf12.png)
[ネットワークの概要から引用](https://cloud.google.com/kubernetes-engine/docs/concepts/network-overview#terminology_related_to_ip_addresses_in_kubernetes)

トラフィックに関しては、`kube-proxy`によって管理されています。
iptablesがルーターの役割をしていると考えています。

1. kube-proxyがiptablesを設定
2. Podにトラフィックを送信する

[マルチホストでのDocker Container間通信 第3回: Kubernetesのネットワーク(CNI, kube-proxy, kube-dns)](https://tech.uzabase.com/entry/2017/09/12/164756)


## 感想
Linuxについてもっと知らなければ