😸

ソケットとは?

に公開

はじめに

Dockerでインテグレーションテストを実施する際、コードからDockerコンテナを立てる必要がありましたが、開発環境をDevcontainerで立てているため、どうやらホストOSのソケットを開発環境コンテナにマウントしないとホストOSにアクセスができないらしい。

ひょんなことから出てきたソケットという概念について、曖昧な理解だったので体系的に勉強します。(TCPやらプロトコルやらでガッツリ勉強になってしまった)

ソケットとは?

  • 【広義の意味】データの交換を受け持つOSの機能のこと
  • 【狭義の意味】実態として、OSカーネルにあるデータのこと。通信を管理するための情報を持つ。どのように(インターネットソケット・Unixドメインソケット、UDP/TCP)、どんな接続状態(リッスン/接続確立済み/クローズ、)、送受信バッファ(受け渡しデータの一時保存先)を持つ。
  • 超解釈した例)
    ソケットとは、郵便局と言ってよく、様々な配送方法(宅配便、定形外、はがき、チルドゆうパック)に応じて、適切な方法で荷物を届けてくれるサービスのこと。(プロトコル)
    ただし、配送前に本当にその住所が受取を許可しているか確認してから届けるオプションもある。(TCP)
    逆に、確認せずに送ることもできる(UDP)
    上記の配送システムは、住所という前提のルールがあって成り立っている(IP[Internet Protocol])
  • IT用語でちゃんと説明した例)
    ソケットとは、様々なプロトコル(HTTP、SCP、SMTP、SSH、DNS)(アプリケーション層)にしたがって、データを相手ホストに届けてくれる機能。(なんのデータをどの形式で送るか)
    TCP(トランスポート層)を利用して接続を確認してから送る方法、UDP(トランスポート層)を利用して確認せずに送るオプションが選べる。(データ送り方を決める。信頼性や送る順序や再送のオプションを決める)
    前提として、IP(インターネット層)の上に成り立っている。(どこに送るか)
  • 主な利用タイミング
    • Web通信 (HTTP/HTTPS):TCP/IPのネットワークソケット。ポートは80,443
    • ファイル転送 (FTP, SFTP, SCP):TCP/IPのネットワークソケット。ポートは22
    • メール送受信 (SMTP, POP3, IMAP):TCP/IPのネットワークソケット。ポートは25,110,143
    • リモートログインとコマンド実行 (SSH, Telnet):TCP/IPのネットワークソケット。ポートは22,23
    • データベースアクセス:
      • 異なるホスト間の場合:TCP/IPネットワークソケット。MySQLなら3306。Postgreなら5432
      • 同一ホスト間の場合:UnixドメインソケットもしくはTCP/IPネットワークソケット(localhostで接続)

ソケットのライフサイクル(長いので飛ばすこと推奨)

  • ソケット作成とリッスン
    1. サーバー(デーモン)がOSに対しソケット作成要求(socket() システムコール)し、OSがカーネルにソケットを作成する。
    2. デーモンはソケット実態とエンドポイント(ネットワークソケット、Unixドメインソケット)を紐づける。(bind()システムをコール)
      ※Unixドメインソケットの場合は、引数としてパス名を渡し、この際にソケットファイルという特殊なファイルが作成され、これがエンドポイントとなる。
      ※ネットワークソケットの場合は、引数としてIPアドレス+ポートを渡し、紐づけされる。
    3. デーモンはソケットに対して、リッスンをするように要求。(listen()システムコール)
  • 通信
    1. クライアントがOSにソケット作成要求を行い、OSがカーネルにソケットを作成
    2. クライアントがエンドポイントに接続要求(connect()システムコール)
    3. サーバーが接続要求を受け入れる(accept()システムコール)※ここで通信を行うためのソケットがクライアント・サーバーに作成される(チャネルが確立される)
    4. クライアントが通信用ソケットに対し、データ(APIリクエストなど)を書き込む(send()またはwrite()システムコール)
      ※データは通信用ソケットにコピーされる(クライアントのプロセスメモリからOSカーネル内の送信バッファ)
    5. クライアントのカーネルが、指定されたプロトコル(TCP/IP、Unixドメインソケットの内部メカニズム)に従って、サーバー側のソケットに転送する
    6. サーバーのOSカーネルは、受信したデータを通信用ソケットの受信バッファに格納する。
    7. サーバーのOSカーネルは、通信用ソケットからデータを読み出す(recv()またはread())
      ※データは通信用ソケットにコピーされる(OSカーネル内の受信バッファからサーバーのプロセスメモリ)
    8. サーバーがデータを返却
    9. クライアント・サーバのどちらかがソケットを閉じる(close()システムコール)

ネットワークソケット (Network Sockets)

  • ネットワークを介した異なるマシン上のプロセス間、または同一マシン上のプロセス間での通信をするためのエンドポイント
  • プロトコル
    • TCP (Transmission Control Protocol) :コネクションを確立した通信を行う。(HTTP, HTTPS, FTP, SMTPなどがTCP)
    • UDP (User Datagram Protocol) :信頼性の低い(データが届く保証がない、順序も保証されない)、コネクションレスの通信を行う。(DNS, DHCP, VoIPなどがUDP)
  • エンドポイントの指定方法
    • IPアドレス+ポート番号
  • カーネル内のソケット実態はbind()操作によって、IPアドレス+ポート番号と紐づけられる
  • メリットは汎用的(同一ホストでもループバックアドレスを使った通信が可能だし、ほかホストとの通信も可能)だが、デメリットとしてオーバーヘッドが大きい(処理が遅い)ため、インターネットを利用する場合(Webサーバー、APIサーバー)や、標準化されたプロトコル(HTTP、FTP)を利用する場合はこちらを利用する。

Unixドメインソケット (Unix Domain Sockets, UDS / IPC Sockets)

  • 同一ホストマシン上で動作するプロセス間の通信をするためのエンドポイントのファイル。
  • エンドポイントの指定方法
    • ファイルシステムのパス名(サービス毎にリッスンするパスがデフォルトで決まっている ※もちろん変更は可能だが普通しない)
      • Docker: /var/run/docker.sock
      • MySQL: /tmp/mysql.sock や /var/run/mysqld/mysqld.sock
      • PostgreSQL: /tmp/.s.PGSQL.5432 や /var/run/postgresql/.s.PGSQL.5432
  • ファイルは特別なソケットファイルとして認識され、パーミンションを用いることで認可を実現している
  • ソケットファイルはサーバーの受け口のため、ユーザが直接参照したりすることはない。クライアントアプリケーション(dockerクライアント、MySQLクライアント)や、コマンドラインツールがソケットにアクセスしてデーモンと通信している
  • メリットはひじょーに早く、低遅延だが、同一ホストでしか使えないので、同一ホストのDB通信に利用されることがある。

APIとは?

  • システムの機能を利用するため、外部に公開している操作方法のこと。(この操作を実行すれば目的の機能が利用できる)

  • システムを外部から操作するためのインターフェースの一つ。他の種類として、CLI、API(REST API)、API(SDK)、GUIがある。

  • API別整理

    特徴/要素 CLI (コマンドラインインターフェース) API (アプリケーションプログラミングインターフェース) - Web API/REST APIなど API (アプリケーションプログラミングインターフェース) - ライブラリ/SDKなど GUI (グラフィカルユーザーインターフェース)
    主な対象者 人間 (開発者、システム管理者)、スクリプト プログラム (他のアプリケーション、サービス) プログラム (開発者が書くコード) 人間 (エンドユーザー、開発者)
    操作方法 テキストベースのコマンド入力 HTTPリクエスト (GET, POSTなど) 関数呼び出し、メソッド呼び出し マウス操作、キーボード入力 (ボタンクリック、フォーム入力など)
    データの形式 テキスト (人間が読みやすい)、終了コード、標準出力/エラー出力 構造化データ (JSON, XMLなど)、HTTPステータスコード、ヘッダー プログラミング言語のデータ型 (引数、戻り値)、例外 視覚的表現 (テキスト、画像、アイコンなど)、ユーザーへのフィードバック
    対話の仕方 同期的 (コマンド実行 → 結果待機)、パイプやリダイレクトで連携 同期的/非同期 (リクエスト → レスポンス)、ステートレスが基本 同期的 (関数呼び出し → 戻り値)、オブジェクト指向の原則に従うことが多い イベント駆動 (ユーザー操作 → アプリケーション応答)
    主な用途 システム管理、バッチ処理、スクリプトによる自動化、開発時の簡易操作 Webサービス連携、マイクロサービス間通信、モバイルアプリのバックエンド連携 特定の機能やプラットフォームの機能をプログラムに組み込む、再利用可能なコンポーネント開発 アプリケーションの直接操作、データの可視化、直感的なタスク実行
    ドキュメント manページ、ヘルプコマンド (--help) APIドキュメント (Swagger/OpenAPIなど)、SDK APIリファレンスドキュメント (Javadoc, Godocなど)、チュートリアル、IDEのコード補完 直感的な操作、ツールチップ、ヘルプメニュー
    状態管理 各コマンドは独立、セッションはシェルが管理 ステートレスが推奨 (状態はクライアントまたはサーバー側で別途管理) オブジェクトが状態を持つことがある、ライブラリの初期化/終了処理がある場合も アプリケーションがユーザーセッションやUIの状態を管理
    エラー処理 終了コード、標準エラー出力 HTTPステータスコード、エラーレスポンスボディ (構造化データ) 例外、エラーコード、特定の戻り値 エラーダイアログ、メッセージ表示、入力フィールドのハイライトなど
    セキュリティ OSのユーザー権限、sudo APIキー、OAuth、JWT、TLS/SSL、IP制限など ライブラリが提供する認証・認可機能、OSのセキュリティ機能に依存することも ユーザー認証 (ID/パスワード)、アクセス制御、OSのセキュリティ機能
    ls, grep, docker run, git commit Twitter API, Google Maps API, 決済API Javaの java.util.ArrayList, Goの net/http パッケージ, AWS SDK Webブラウザ、テキストエディタ、OSのデスクトップ環境

まとめ

  • ソケットはデータの交換を受け持つOSの機能。あくまでデータをやり取りするだけの機能で、これを利用してAPIのデータ受け渡し、DBのクライアントとサーバーのデータの受け渡しなどを行っている。他ホストとやり取りするためのネットワークソケット(REST APIなど)、同ホストでやり取りするためのパスのソケット(同一ホストのDBのクライアント、サーバ)の2つがある。
  • APIはシステムの機能を利用するため、外部に公開している操作方法のこと。CLI、API(REST API)、API(SDK)、GUIがある。

Discussion