OS
オペレーティングシステム
ハードウェアを抽象化し、アプリケーションに実行環境を提供する基盤ソフトウェア。
概要
OS(オペレーティングシステム)は、コンピュータのハードウェア資源——CPU・メモリ・ディスク・ネットワーク——を一手に管理し、アプリケーションに「使いやすい形」で貸し出す基盤ソフトウェアです。私たちが書くプログラムは、CPUに直接命令を並べているように見えて、実際にはOSが用意した窓口(システムコール)を通してハードウェアを間接的に使っています。代表例はLinux、Windows、macOSで、サーバの世界ではLinuxが圧倒的多数を占めます。
普段の開発でOSを意識する場面は多くないかもしれません。しかし「ファイルを開く」「ネットワークに接続する」「メモリを確保する」といった当たり前の操作はすべてOSの機能ですし、プロセスやスレッド、ソケットといった語彙はどれもOSが提供する抽象の名前です。パフォーマンス問題や障害の調査を突き詰めていくと、最終的にこの層に行き着きます。
なぜ生まれたか
初期のコンピュータには OS がなく、プログラムはハードウェアを直接操作していました。プログラムを1本動かすたびに機械を占有し、ディスクやプリンタの制御コードも各プログラムが自前で書く必要がありました。つまり「ハードウェアの細部を知る仕事」と「解きたい問題を解く仕事」が分離されておらず、機種が変わればプログラムも書き直しでした。
さらに、当時のコンピュータは非常に高価だったため、1つのプログラムがI/O待ちをしている間もCPUを遊ばせておくのは大きな無駄でした。そこで「複数のプログラムを切り替えながら同時に走らせ、ハードウェアの違いは共通の窓口で吸収する」仕組みが求められ、資源管理と抽象化を専門に担うソフトウェア——OS——が生まれました。1969年に誕生したUNIXの設計(すべてをファイルとして扱う、プロセスという実行単位など)は、現代のLinuxやmacOSにまで受け継がれています。
詳細
カーネルとシステムコール
OSの中核は「カーネル」と呼ばれる部分です。カーネルはCPUの特権モードで動作し、ハードウェアを直接触れる唯一の存在です。一方、アプリケーションはユーザーモードという制限された環境で動き、ファイルの読み書きやネットワーク通信が必要になると「システムコール」という決まった窓口を通してカーネルに依頼します。この二層構造のおかげで、行儀の悪いプログラムがハードウェアを壊したり、他のプログラムのメモリを勝手に読んだりすることを防げます。
OSが担う4つの資源管理
OSの仕事は大きく4つに整理できます。第一にCPU管理。多数のプロセスやスレッドを短い時間で切り替えて(スケジューリング)、1つしかないCPUコアをあたかも複数あるように見せます。第二にメモリ管理。仮想メモリという仕組みで、各プロセスに「自分だけがメモリ全体を使っている」ように見える独立した空間を与えます。第三にファイルシステム。ディスク上のただのビット列を、ディレクトリ階層とファイルという扱いやすい形に抽象化します。第四にネットワークと入出力。TCP/IPのプロトコルスタックはOSの中に実装されており、アプリケーションはソケットというインターフェースを通じてそれを利用します。
全体の構成を図にすると、アプリケーションとハードウェアの間にカーネルが挟まり、4つの資源管理がその中に収まっている姿が見えてきます。
サーバ運用と現代のインフラでの位置づけ
Webサービスを運用するうえで、OSの知識は「異常時に効く」知識です。CPU使用率・メモリ使用量・ディスクI/O・開いているファイルディスクリプタ数といったOSレベルの指標は監視の基本項目ですし、top や ps、ログの調査といった障害対応の道具はすべてOSの機能に根ざしています。「メモリが足りずプロセスがOOM Killerに殺された」「ファイルディスクリプタ上限に達して接続を受けられない」といった障害は、OSを知らないと原因にたどり着けません。
また、現代のインフラ技術はOSの機能の応用として理解できます。仮想マシンはハードウェアごと仮想化して複数のOSを1台の物理マシンに同居させる技術であり、コンテナはLinuxカーネルの隔離機能(namespace、cgroup)を使って「OSは共有しつつプロセスを隔離する」技術です。サーバレスやクラウドコンピューティングはOSの管理を事業者側に委ねる仕組みですが、その裏側では必ずLinuxが動いています。抽象化が進むほどOSは見えなくなりますが、消えたわけではなく、誰かが代わりに面倒を見ているだけ——この視点を持っておくと、レイヤをまたいだトラブルシューティングに強くなります。