はじめに
業務に邁進する中でネットワークの知見が足りていないことに気づき、ネットワークの基礎固めに精進することにしました。最終的にはDockerおよびKubernetesで利用されるネットワーク技術を解説できるようになること、を目標とし、シリーズ記事として記載する予定です。
参考にする書籍
Docker・Kubernetesで利用されるネットワーク技術に関する本
ネットワークの基礎を理解するための本
本記事で理解すること
- TCP/IPとはなにか
- プロトコルが階層化されていることの意味
- TCP/IP4階層モデルのそれぞれの階層での役割
シリーズ(予定)
- (基礎)TCP/IP4階層モデル ←今回はこれ
- VXLAN(Virtual eXtensible Local Area Network)←今回はこれ
- Network Namespce
- iptables
そもそもTCP/IPってなに
インターネット上の通信相手まで情報を届けるためのプロトコルがIP、さらにその通信の信憑性を高めるためのプロトコルがTCPとなります。通信を実現するためには、いくつかのプロトコルが組み合わさる必要があります。その組み合わせを階層的にまとめたものがTCP/IP4階層モデル、となります。
プロトコルが階層化されていることの意味
そもそもわざわざ階層にしたことに何の意味があるのか?を調べてみました。理由は主に4つあります。
- 複雑すぎる問題を分割して単純化するため
- 「知らなくていいこと」を増やすため
- 技術を簡単に入れ替えられるようにするため
- 障害を特定しやすくするため
1. 複雑すぎる問題を分割して単純化する
まずは、AさんのスマホからBさんのスマホに画像付きメッセージを送る、というだけでも複雑な問題になる、ということを認識しないといけません。
- 電気信号?
- 無線?
- IPアドレス?
- 暗号化?
- メッセージを形式?
これらをひとつのプロトコルですべて解決しようとすると地獄です。
そこで、電気信号や電波に関してはこの層が、宛先や経路についてはこの層が、メッセージの形式はこの層が、というように責務を分けると比較的簡単に考えられるようになります。
2. 知らなくていいことを増やすため
例えば、アプリケーションを作成する人が、どのルータを通るのか、パケットは光にするのか電波にするのかとかは考えません。すべての層を考慮していると開発に膨大な時間がかかるからです。それぞれの層の詳細を知らずとも、抽象化された概念だけで開発が可能となるようになっています。
3. 技術を簡単に入れ替えられるようにするため
階層化されていないと、ネットワークケーブルを変更しただけでアプリが動かなくなる、無線方式変えたらプロトコルを書き直さないといけない、など。実際は、有線 → Wi-Fi → LTE...というように、アプリケーションの変更がなくても下の層は進化してきました。
4. 障害を特定しやすくするため
通信トラブルが起きたときに、
- ケーブルが抜けていない?
- IP開いている?
- アプリケーションが落ちていない?
など、どこが原因であるのかを層で分けているとデバックしやすくなります。
TCP/IP4階層モデル
さて、メインのTCP/IP4階層モデルのお話に入ります。TCP/IP4階層モデルは、アプリケーション層、トランスポート層、インターネット層、ネットワークインターフェース層のわずか4つの層で成り立つモデルです。
※ 画像は以下から引用
https://shinmeisha.co.jp/newsroom/2020/01/20/tcp-ip%E3%81%A8%E3%81%AF/
通信ケーブルに出るまでの流れ(ざっくり)
各レイヤの役割を説明する前に、レイヤ間の連携をざっくりと図にしてみました。役割を持つレイヤーが順番にプロトコルヘッダを付与します。最終的にEhternetヘッダまで付与されると、NIC(ネットワークインターフェースカード)に転送され、通信ケーブルを通じて通信先のマシンに送られます。
次からは各レイヤの役割を説明します。
アプリケーション層
利用者の意図やアプリケーションの仕様などを定義する役割を担います。例えば、「example.com というサーバに対して、/index.html というリソースを、HTTP/1.1 のルールで取得(GET)したい」というクライアントの指示とアプリケーションの仕様に対しては、以下のようなデータを作成します。
GET /index.html HTTP/1.1
Host: example.com
トランスポート層ではこれはバイナリデータとして扱われ、意味を理解せず処理されていきます。
トランスポート層
インターネット層が提供するコンピュータ同士の通信機能を利用し、目的に応じたプロトコルを利用し機能を付加する役割があります。主に信頼性を高める目的、とにかく素早く通信を行うようにする目的、に分かれます。
TCP
信頼性を高める目的で利用されるプロトコルがTCPです。TCPは事前に十分な接続確認(3-wayハンドシェイクと呼ばれます)を行う処理を行います。パケットの消滅やパケットの内容の間違い、パケットの順序の入れ替わりなど、不具合を見つけたときに、その解消を図ります。Web、メールなど誤りのない通信が求められる用途で利用されます。
UDP
素早く通信を行うようにする目的で利用されるプロトコルがUDPです。TCPはコネクションレスのプロトコルであるため、いきなりデータを送信することができます。信憑性ではなくとにかくリアルタイム性が求められる用途で利用されます。
インターネット層
インターネット層は、別々のネットワークに属するコンピュータ同士が相互に通信できるようにする役割があります。インターネット層の下にあるネットワークインターフェース層では、同じネットワークに属するコンピュータ同士がネットワークできるようになっており、その機能を利用しつつ直接的に繋がっていないコンピュータ同士でも相互に通信できるようにします。
ネットワークインターフェース層
インターネット層でも触れましたが、同一ネットワーク内の機器間でデータを適切に転送する役割を持ちます。代表的なプロトコルはEthernetです。EhternetはMACアドレスを利用してデータの送信先を決定します。
おわりに
今回は、TCP/IP4階層モデルを題材に、ネットワーク通信の全体像をざっくり整理してみました。
普段は「なんとなく通っている」通信も、層ごとに役割を分けて見てみると、
- アプリケーション層は「何をしたいか」を決める
- トランスポート層は「ちゃんと/速く届ける」を担当する
- インターネット層以下は「どこへどう運ぶか」を考える
と、それぞれがかなり割り切った仕事をしていることが分かります。
次回は「ネットワークを分ける」という概念に進み、IPアドレスやサブネット、ルーティングといった考え方がDockerやKubernetesのネットワークとどう繋がっているのかを整理していく予定です。
ネットワークは一度つまずくと難しく感じがちですが、一つひとつの役割を分解していけば、ちゃんと理解できる分野だと思っています。同じように基礎から見直したい方の参考になれば嬉しいです。

