自分用: インフラとネットワークのメモ

## はじめに
ネットワークは前にやったきりで時間も経ってるため、だいぶ忘れてしまいました.
久しぶりにネットワークの復習と追加学習をしました.
その内容をここにメモします.
間違ってたりアドバイスあったら優しく教えてくれると助かります〜

## TCP
L3までのおかげでパケットを相手に送信する事ができるようになったが、実際に届いたかどうかはわからない.
なので、相手はパケットが届いたら届いたよ！と、教えたりするルールを設けたのがTCP.(詳しくは省く

パケットを送る時はPORT番号を指定する必要がある.
TCPの場合、相手からのパケットも受け取る必要があるので、依頼元も今回の通信で使うPORT番号を指定する.
送信元PORT番号は[動的・プライベート ポート番号 (49152–65535)]から選ばれる.
つまり、このout用のport番号を超えた65535-49152=16383を超える同時な外部へのTCPでの接続は工夫しないと、基本的にできない.
UDPの場合も送信元PORTが必要.

## ARP
http://www5e.biglobe.ne.jp/aji/3min/26.html

ARPはL3のプロトコルで、ARP Requestをブロードキャストすることにより、ARP Requestに含まれている ARP Replyを頂ける.
ARP ReplyにリクエストされたMACアドレスが含まれた状態で届く.
これを利用することにより、ARP tableに宛先mac addressがない場合でもパケットを届けられるようになる.

### ARPのusecaseその4ぐらい
手動でnic設定したstatic ip addressで一度も外部通信していない場合、bridgeやRouterのARP tableにmac addressが記録されていない.
その様な状態の時に、Routerは受け取った宛先 IPのMac AddressをARPを使って調べる.

## firewall
firewallでよく80番ポートだけ開放するとかやります.
その場合、80番ポート以外のポートが記載されたパケットを全てロスする設定になっていると、動的ポート番号のパケットまで捨てられてしまいます.
そうした場合、TCPを利用したやりとりができなくなってしまいます.
なので、当たり前ですが、基本的にinとout用でセキュリティで考慮することや設定は変わります.
ちなみにUDPの場合は、response用のポートを動的ポート番号で確保する必要ないので、UDPリクエストしかしないと保証されているようなクライアントがいた場合、全てのportを閉じてもデータを外部に送れます.

## NIC
eh0はnic0枚目、eth1はnic1枚目って事
ethN == nicって認識で基本大丈夫
物理レイヤーにパケットを送る場合はethに送信パケットを投げて、ethがそれをethのpeerに対して送る. (nicは基本イーサネットケーブル等を通じて、bridgeやrouter等、対となるnicと繋がっている.その対のことをpeerと呼ぶ.

## Router作成の概念
http://redhatlinux.kt.fc2.com/cont/router.htm
このサイトが詳しい.
`route -n`の見方がわからない場合、このサイトを見るといい.
https://xtech.nikkei.com/it/article/COLUMN/20080520/303086/
http://linux.kororo.jp/cont/intro/dgate.php

コンバージェンスとか一旦置いといた、一番シンプルなRouterはNICから受け取ったパケットを別のNICに飛ばす技術であるip forwardだけで実現が可能.
linuxでip forwardを有効化するには、`/etc/sysctl.conf`に`net.ipv4.ip_forward=1`を追記し、ネットワークを再起動すると、ip forwardの機能が有効化される.

## ifconfig vs ip command
ifconfigはnet-toolsパッケージに含まれているコマンド.
その他にもよく使うroute, netstat, arpなどもnet-toolsパッケージに入っているコマンド.
net-toolsパッケージは現在非推奨になっている.

## 仮想bridgeの作り方
bridgeは以下のいずれからでも作成できる

* bridge-utils
* iproute2
* netctl
* systemd-networkd
* NetworkManager

bridgeにはeth0等の実デバイスとveth等の仮想デバイスを接続することができます

## 仮想networkの作り方
仮想nicを作りまくって、仮想bridgeに繋げば、仮想プライベートネットワークは作れる.

しかし、このままだとプライベートネットワークがインターネットとやりとりできない.
直接eth0と繋ぐと、今度はeth0が専有されて、プライベートネットワークに所属していない奴らがインターネットに接続できなくなる.
なので、iptablesを使い、ipマスカレードする事によって、できる.
なので、docker等のbridgeのipマスカレードの設定を消すと、完全にネットワークから切り離せる.

## ipマスカレード(NAPT
iptablesを使う事により、ipマスカレードを使える.
ipマスカレードを使うと、NAPTの機能はもちろん、port forwardや、securityとかも行える.

## port forward
https://qiita.com/Ayaka14/items/449e2236af4b8c2beb81
こんな感じ
iptablesでもできる
特定のportに届いたパケットを特定のip addressのportに転送できる.
L2のproxyとして使える.
また、ネットワークセグメント同士を繋ぐのにも使える.
ネットワークセグメント同士を繋げば、VXLANが構築できる.

## VXLAN
https://tech.uzabase.com/entry/2017/08/23/175813
このサイトが詳しい.

## 冗長化
基本的に対障害の為、単一のマイクロサービスを複数ホストに配置したいので、１マイクロサービスは複数ネットワークセグメント上に展開する.

## VXLANの感想
結局はroutingの設定って感じがした.
routingの特定項目の設定とかにport forwardとか色んな特別な名前をつけてる感じ.

## VRRP
アプリケーションをスケールアウトさせるとき、ロードバランサを前段に立てて、そいつに後に振り分けてもらう.
しかし、ロードバランサが1つしかないとそこが単一障害点になる.
なので、ロードバランサを冗長化させるために、VRRPを実装したkeepalived等を使う.
これを使うと、複数のホストに同一の仮想IPと仮想MACアドレス(仮想IPから導出される)を与えられて、プライオリティの高いホストから3秒間連絡なかったら、次にプライオリティが高い待機していたホストがそのIPとMACの保持者になり、リクエストをさばく.
VRRPプロトコルの詳しい仕組みについては、[この記事](https://www.infraexpert.com/study/fhrpz06.html)か、適当にググると沢山でてくる.

## MySQLのMaster Slave構成の場合のメモ
Master Slave構成の場合、Queryの内容を見て、master or slaveへロードバランシングするProxyはHAProxyがメジャーぽい.
または、クライアントロードバランシングで、updateを含む一連のQueryを発行する場合は、Masterに発行し、Readだけの場合はSlaveにQueryを渡すようにしている構成も見る.
その場合、Slaveのロードバランシングの手法は色々見受けられるが、NGINXのTCP Loadbalancer + keepaliveでのLoadbalancerの冗長化構成が良さそう. (Nginxの設定ファイル以外はWeb Serverのクラスターのロードバランサーと同じ様な設定にできるし、シンプルに済みそう.

### 参考文献
* [3分間ネットワーキング](http://www5e.biglobe.ne.jp/aji/3min/)
* [IPフォワード](https://linuc.org/study/knowledge/422/)
* [IPルーティング](https://www.atmarkit.co.jp/ait/articles/0302/21/news002_3.html)
* [【図解】初心者にも分かる PPP の仕組み, フォーマット](https://milestone-of-se.nesuke.com/nw-basic/ppppppoe/ppp-summary/)
* [Linuxルーターから、PPPoEによるインターネット接続を行う](https://qiita.com/developer-kikikaikai/items/3275f52c3e9549d8152f)
* [チュートリアル：WAN設定：PPPoEを使用したWAN-IPアドレス取得の設定](https://support.onewan.cloud/hc/ja/articles/360016162972-%E3%83%81%E3%83%A5%E3%83%BC%E3%83%88%E3%83%AA%E3%82%A2%E3%83%AB-WAN%E8%A8%AD%E5%AE%9A-PPPoE%E3%82%92%E4%BD%BF%E7%94%A8%E3%81%97%E3%81%9FWAN-IP%E3%82%A2%E3%83%89%E3%83%AC%E3%82%B9%E5%8F%96%E5%BE%97%E3%81%AE%E8%A8%AD%E5%AE%9A-)
* [スーパーネット化](https://wa3.i-3-i.info/word11985.html)
* [ネットワーク ゲームにおけるTCPとUDPの使い分け](https://www.slideshare.net/yhonjo/tcpudp-81497235)
* [ＤＨＣＰとは](https://www.ccjc-net.or.jp/~kouza/199805/dhcp1.html)
* [VXLANとは](https://www.nic.ad.jp/ja/basics/terms/vxlan.html)
* [Docker/Kubernetesを扱う上で必要なネットワークの基礎知識（その1）](http://sagantaf.hatenablog.com/entry/2019/12/08/015317)
* [Docker/Kubernetesを扱う上で必要なネットワークの基礎知識（その２）](http://sagantaf.hatenablog.com/entry/2019/12/14/000948)
* [Dockerのネットワークの仕組み](http://sagantaf.hatenablog.com/entry/2019/12/18/234553)
* [TCPやUDPにおけるポート番号の一覧](https://ja.wikipedia.org/wiki/TCP%E3%82%84UDP%E3%81%AB%E3%81%8A%E3%81%91%E3%82%8B%E3%83%9D%E3%83%BC%E3%83%88%E7%95%AA%E5%8F%B7%E3%81%AE%E4%B8%80%E8%A6%A7)
* [TCP ソケットバッファーを調整する](https://access.redhat.com/ja/solutions/504383)
* https://qiita.com/zembutsu/items/9e9d80e05e36e882caaa
* [Linuxマシンをルータにする方法](http://redhatlinux.kt.fc2.com/cont/router.htm)
* [第13回　IPとルーティング](https://xtech.nikkei.com/it/article/COLUMN/20080520/303086/)
* [デフォルトゲートウェイの設定 - コロのLinuxサーバー構築](http://linux.kororo.jp/cont/intro/dgate.php)
* [マルチホストでのDocker Container間通信 第1回: Dockerネットワークの基礎](https://tech.uzabase.com/entry/2017/08/07/172411)
* [マルチホストでのDocker Container間通信 第2回 Port Forwarding と Overlay Network](https://tech.uzabase.com/entry/2017/08/23/175813)
* [マルチホストでのDocker Container間通信 第3回: Kubernetesのネットワーク(CNI, kube-proxy, kube-dns)](https://tech.uzabase.com/entry/2017/09/12/164756)
* [iproute2](https://wiki.linuxfoundation.org/networking/iproute2)
* [iproute2 wiki](https://ja.wikipedia.org/wiki/Iproute2)
* [[netns] 秒速でネットワーク作成 [veth peer]](http://blog.serverworks.co.jp/tech/2019/08/05/post-70460/)
* [LinuxのNetns/veth/Bridge/NATで仮想ネットワーク構築](https://blog.kamijin-fanta.info/2018/12/netns/)
* [ネットワークブリッジ](https://wiki.archlinux.jp/index.php/%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF%E3%83%96%E3%83%AA%E3%83%83%E3%82%B8)
* [カテゴリ:ネットワーク](https://wiki.archlinux.jp/index.php/%E3%82%AB%E3%83%86%E3%82%B4%E3%83%AA:%E3%83%8D%E3%83%83%E3%83%88%E3%83%AF%E3%83%BC%E3%82%AF)
* [VRRP](https://www.infraexpert.com/study/fhrpz06.html)
* [Keepalived](https://www.keepalived.org)
* [haproxyをkeepalivedで冗長化して高可用性ロードバランサを構築する](https://bbrfkr.hatenablog.jp/entry/2018/03/15/094536)
* [MySQL入門　レプリケーション編](https://qiita.com/Tocyuki/items/c224cef57493f536a941#73-mysql%E3%81%AE%E9%AB%98%E5%8F%AF%E7%94%A8%E6%80%A7%E6%A7%8B%E6%88%90)
* [MySQLでMaster-Slave構成のレプリケーション設定](https://qiita.com/ksugawara61/items/fdd5ae9b78931540887f)
* [MySQL負荷分散の方法](https://www.slideshare.net/xshsaku/mysql-14066617)
* [nginxのTCPロードバランシングを試す(MySQLの複数のSlaveへのロードバランシング等に使える)](https://kazuhira-r.hatenablog.com/entry/20161106/1478427551)
* [5. Read/Write Splitting with HAProxy](https://severalnines.com/resources/database-management-tutorials/mysql-load-balancing-haproxy-tutorial)
* [severalnines/proxysql](https://hub.docker.com/r/severalnines/proxysql)
* [proxysql](https://proxysql.com/)
* [Introduction to YAML: Creating a Kubernetes deployment](https://www.mirantis.com/blog/introduction-to-yaml-creating-a-kubernetes-deployment)
* [vethとか仮想ネットワークカード、TAPインターフェイスって言うらしい](https://ja.wikipedia.org/wiki/TUN/TAP)
* [フォーラム資料(2018/01/19) Calico検証PJ CalicoとBGP](https://www.slideshare.net/okinawaopenlabs/20180119-calicopj-calicobgp)