階層モデル — それぞれの層が何を決めるのか
一言でいうと
階層は、各層が下の層のサービスだけを使い、上の層にはインターフェースだけを公開するように分けた設計であり、障害を診断するときは、「どの層まで成功したか」を問うための道具になります。
なぜ必要なのか
ネットワークは、1人で作るものではありません。光ケーブルを敷く会社、ルーターを作る会社、ブラウザーを作る会社は、すべて違います。これらが互いの実装を知らなくても一緒に動作するには、境界と契約が必要です。
階層化が、その契約です。下の層は上の層にサービスを提供し、上の層は、下の層がそのサービスをどう実装したのかを知らなくてもかまいません。TCPは、自分のセグメントが光ケーブルで行くのかWi-Fiで行くのかを気にしません。
どう動くのか
教科書のOSI 7階層と、実際のインターネットのTCP/IPモデルは、次のように対応します。
| OSI | TCP/IP | この層が決めるもの | データ単位 |
|---|---|---|---|
| アプリケーション、プレゼンテーション、セッション | アプリケーション | 何をやり取りするのか(HTTP、DNS) | メッセージ |
| トランスポート | トランスポート | どのプロセスに、信頼性をもって送るのか | セグメント / データグラム |
| ネットワーク | インターネット | どのホストへ、どの経路で送るのか | パケット |
| データリンク | リンク | 同じネットワーク内の次の機器まで、どう送るのか | フレーム |
| 物理 | リンク | ビットをどんな信号に変えるのか | ビット |
カプセル化は、上の層のデータに、下の層のヘッダーを付け足す過程です。HTTPリクエストにTCPヘッダーが付いてセグメントになり、IPヘッダーが付いてパケットになり、イーサネットヘッダーが付いてフレームになります。受け取る側は、逆の順序で剥がします。
ここで、よく誤解される点を押さえておく必要があります。OSI 7階層は教育用のモデルであり、インターネットの実装ではありません。プレゼンテーション層とセッション層に正確に対応するインターネットのプロトコルはありません。「TLSは何層か」のような質問に、ぴたりと当てはまる答えがない理由です。TLSはTCPの上で動作してアプリケーションデータを暗号化するので、どこに置いても違和感があります。モデルは理解を助ける道具であり、実体ではありません。
現場での姿
階層モデルの実戦での価値は、診断の順序にあります。接続できないとき、次の順序で問うと、範囲が素早く絞られます。
- 名前が解決されるか:
getent hosts api.example.com(アプリケーション層より下の名前解決) - そのアドレスにTCP接続ができるか:
curl -v --connect-timeout 3 http://주소:포트/(プレースホルダーは、アドレスとポートです) - 接続はできるのに、応答がないか: トランスポート層は通過しており、アプリケーション層の問題です
この順序を守れば、「ネットワークがつながりません」という報告を、「ステップ3で止まります」に変えられます。ちなみに、ラボ環境のように、pingやtcpdumpを使えない場所でも、ss、curl、dig、getent、/proc/net/*だけで、上の3段階はすべて確認できます。
症状で層を探す表
階層モデルの実用的な価値は、症状を見て、どの層を見るかを決めることです。
| 症状 | 疑う層 | 確認コマンド |
|---|---|---|
| リンクが上がらない | L1(物理) | ip link、ケーブル・SFP |
| 同じサブネットなのにつながらない | L2 | ip neigh、ARP応答 |
| 別のアドレス帯につながらない | L3 | ip route get、traceroute |
| ポートだけが開かない | L4 | nc -zv、ファイアウォール |
| 名前が解決されない | アプリケーション(DNS) | getent hosts、dig |
| TLSエラー | プレゼンテーション(TLS) | openssl s_client -connect |
| 404・500 | アプリケーション | アプリケーションのログ |
下から上に上がっていくのが基本ですが、実務では、真ん中(L3/L4)から見るほうが速いです。物理の問題はまれで、アプリケーションの問題はログが教えてくれるからです。
カプセル化が生むオーバーヘッド
各層がヘッダーを付けるので、実際のデータは、その分だけ減ります。
이더넷 프레임 1518 바이트 (MTU 1500)
− IP 헤더 20
− TCP 헤더 20
= 1460 바이트가 실제 데이터 (MSS)
VPNやオーバーレイネットワークを使うと、ここにさらにヘッダーが付きます。VXLANは50バイトを足すので、実際のMSSは1410になります。MTUを合わせないと、大きなパケットが断片化されたり、破棄されたりします。
これが、Kubernetesで「小さなリクエストは通るのに、大きなレスポンスが止まる」症状の原因です。パスMTUディスカバリー(PMTUD)はICMPを使いますが、そのICMPがファイアウォールにブロックされると、送信者が大きなパケットを送り続け、何の応答も受け取れなくなります(PMTUブラックホール)。
# 조각내지 않고 보낼 수 있는 최대 크기 찾기
ping -M do -s 1472 <대상> # 1472 + 28(ICMP+IP) = 1500
なぜTCPとUDPを分けるのか
| TCP | UDP | |
|---|---|---|
| 接続 | 3-wayハンドシェイク | なし |
| 順序・再送 | 保証 | なし(アプリが行う) |
| フロー制御 | あり | なし |
| 最初のバイトまで | 最低でも1 RTT追加 | 即座 |
DNSがUDPを使う理由は、問い合わせ1つにハンドシェイク3回は無駄だからです。応答が512バイトを超えると、TCPで問い合わせ直します。
QUICは、UDPの上に信頼性と暗号化を作り直したものです。TCPの問題(ヘッドオブラインブロッキング、カーネルに組み込まれた実装)を避けながら、信頼性を得ようとする設計です。
続くクイズで確認すること
各層が何を決めるのか、カプセル化の順序がどうなっているのか、そしてOSIモデルをどこまで信じるべきかを確認します。