はじめに
Linuxなんも分からん。
第1章 Linuxの入門
- OSの役割はハードウェアの抽象化してプロセス、メモリ、ファイル、ネットワーク管理などの基本機能をAPIとして提供するこも
- LinuxはPOSIX及びSVIDに準拠するよう作られている
第2章 Linuxカーネル
- カーネルが全てのコア機能を提供するが、それ自体がOSではない
- シェルやssh、grepなどはユーザ空間であり、カーネルにあるわけではない
- カーネルモードは少ない抽象化による高速な実行、ユーザモードは低速だが安全で便利な抽象化を意味する
- コンピュータアーキテクチャ = CPUファミリ
- OS起動時にBIOSが使われる。最近はUEFIに置き換わったらしいが、BIOSという言葉がまだ使われている
- BIOSからハードウェアの情報を取得するコマンドはdmidecodeまたはlscpu
- x86アーキテクチャは広く利用されているがエネルギー効率はよくない。ARMアーキテクチャは高速で安価、消費電力を最小限に抑えている。RISC-Vアーキテクチャは比較的新しめ
- プロセスの状態についての参考記事: Linux Process States
- モダンなCPUでは仮想アドレスと物理アドレスを変換するためのTLB(Translation Lookaside Buffer)という小さなキャッシュを使用して変換処理を高速化している
- カーネル層はソケット、TCP、UDP、インターネットプロトコル。ユーザ層はHTTPやSSHなど
- straceコマンドでシステムコールが実行された順番や引数を見ることができる
第3章 シェルとスクリプト
- stdin(FD 0)は標準入力、stdout(FD 1)は標準出力、stderr(FD 2)は標準エラー出力
1>
または>
で標準出力を、2>
で標準エラー出力を、&>
で両方をリダイレクトする- Unixの哲学についての再考 Revisiting the Unix philosophy in 2018
- whichコマンドはPOSIXで規定されていない外部プログラムのため、 whichコマンドではなく、command -vコマンドの使用が提案されている
- すでに実行中のコマンドでnohupがついていない場合、disownを使用するとnohupをつけて実行したときと同じ状態になる
- モダンなコマンド
- exa: Rust製でlsの代替として使える。gitステータス、ツリー表示もサポートなど
- bat: catの進化版。シンタックスハイライト、表示不可能な文字の表示、gitのサポートなど
- rg: Rust製でgrepの高速版。行番号も表示してくれるなど、grepより結果がわかりやすい
- さらにモダンなコマンドについて知りたい場合 moder-unix repo
- screenコマンドやtmuxコマンドでマルチプレクサ
- 気になるマルチプレクサ Zellij
第4章 アクセス制御
- ユーザ、プロセス、ファイルの関係の簡易図
graph TD ユーザ -->|起動| プロセス プロセス -->|使用| ファイル ユーザ -->|所有| ファイル
- rwx以外のファイルアクセスビット
- s: setuid/setgid。実行ファイルに設定し、実行すると実質ファイルのオーナーやグループ権限でプログラムが実行される
- t: このビットが設定されているディレクトリは、オーナーとrootユーザ以外はディレクトリ内のファイルを削除できなくなる
- プロセス実行時のパーミッションに関連するユーザIDいろいろある
- 実UID(Real UID): プロセスを起動したユーザのUID。あるプロセスの実UIDは
stat -c “%u /proc/$pid”
で確認できる - 実効UID(effective UID): 共有リソースにアクセスする際にプロセスが持つ権限を決めるために実効UIDを使う
- 保存set-user-ID(saved set-user-ID): setuidビットが設定されている場合に使う。プロセスが実UIDと保存set-user-IDの間で実効UIDを切り替えられる
- ファイルシステムUID: ファイルアクセスのパーミッションを決定するために使う
- 実UID(Real UID): プロセスを起動したユーザのUID。あるプロセスの実UIDは
- アクセス制御のよい実践方法は、最小権限化、setuidを避ける、監査
第5章 ファイルシステム
- Linuxではファイルは特定の構造を持たず、単なるバイトのストリーム
- inode
- サイズ、オーナー、データの場所、日付、パーミッションなど個々のファイルのメタデータを保存する
- ファイル名と実際のデータは保存しない。ファイル名はディレクトリに保存され、ディレクトリはinodeをファイル名にマッピングする
- 仮想ファイルシステム(VFS)はカーネル内の抽象化レイヤで、異なる種類のファイルシステムへのアクセスを抽象化する
- 仮想ファイルシステムいろいろある
- ローカルファイルシステム: ext3、XFS、FAT、NTFSなど。HDDやSSDなどブロックデバイスにアクセスするために使う
- インメモリファイルシステム: tmpfsなど。長期保存用のデバイスにバックアップされず、メインメモリに保存する
- 擬似ファイルシステム: procfsなど。カーネルとのやり取りや、デバイスの抽象化のために使う
- ネットワーク型ファイルシステム: NFS、Sambaなど。実際のデータはリモートマシンに存在する
- パーティションはハードディスクを直接分割したもので、OSが認識する最小のストレージ単位
- 論理ボリュームマネージャ(LVM)により、物理ボリューム、ボリュームグループ、論理ボリュームといった概念を用いて柔軟かつ高度なストレージ管理が可能
- macOSではAPFSという独自のファイルシステムが採用されており、LVMが提供する機能を包含しているため、LVMは使われていない
- ファイルシステムを使う手順: ファイルシステムの作成(フォーマット) → マウント
- マウントはフォーマットしたファイルシステムをファイルシステムツリーに挿入する操作
- FHS(Filesystem Hierarchy Standard): どこのディレクトリにどのようなファイルの配置が推奨されているかなどを標準化している
- man hierコマンドで自分の環境のファイルシステムツリーの構成を確認できる
+
- 擬似ファイルシステム
- procfs: カーネルからプロセス関連の情報を公開し、psやfreeコマンドで使用できるようにすることがもともとの目的。現在はマウント、ネットワーク、ttyドライバなどさまざまな情報が含まれている
- Linuxでは/proc/PID以下にあるが、macOSには存在していない。macOSでprocfsに該当する情報を取得したい場合はsysctlコマンドを使う
- sysfs: Linuxカーネルが標準化したレイアウトを用いて情報が構造化されている。/sysディレクトリ以下に様々なディレクトリが存在する
- devfs: ブロックデバイス、キャラクタデバイス、特殊デバイスなどを管理する
- procfs: カーネルからプロセス関連の情報を公開し、psやfreeコマンドで使用できるようにすることがもともとの目的。現在はマウント、ネットワーク、ttyドライバなどさまざまな情報が含まれている
第6章 アプリケーション、パッケージ管理、コンテナ
- initは初期化時はサービスを英数字順に起動するが、systemdは依存関係が解決しているサービスを並列で起動できる
- journalctlはsystemdのコンポーネントで、systemdが記録するログを一元管理する
- RPM(RedHat Package Manager)はもともとRed Hatによって開発されたが、現在はさまざまなディストリビューションで採用されている
- systemd-cgtopコマンドでリソースの使用状況が確認できる
第7章 ネットワーク
- TCP/IPスタックの4つの層
- リンク層: 物理デバイス間でのパケット送信を行う
- インターネット層: ネットワーク間のパケット送信をサポートする。ベストエフォート配信(性能の保証はない)
- トランスポート層: パケットの転送方法、ポートによるマシン上のサービスの識別、データの完全性の確認を行う(パケット順序、再送、配送保証など)
- アプリケーション層: ウェブ、SSH、メールなど、ユーザ向けのツールやアプリを扱う
- 最近はifconfigではなくipコマンドが推奨されている
- IPv4は、32bitをピリオドで4つの8bitセグメントに分割する(各セグメントはオクテットと呼ぶ)
- 例: 127.0.0.1 の場合、左から順に第1オクテット、第2オクテット、となる
- CIDR(Classless Inter-Domain Routing): IPアドレスの範囲を割り当てる適切な方法
- 例: 10.0.0.0/24 の場合、第1オクテットから第3オクテットまでがネットワーク部で、第4オクテットがホストが使用できるIPアドレスの範囲となる
- iwコマンドでワイヤレスデバイスの表示、設定、トラブルシューティングできる
- 特別な目的で予約されているIPアドレス
- 127.0.0.0: ローカルアドレス。127.0.0.1はループバックアドレス
- 169.254.0.0/16: リンクローカルアドレス。パケットをネットワーク内に留める
- 224.0.0.0/24: マルチキャスト用のアドレス
- RFC1918で定義されているプライベートIPの範囲
- 10.0.0.0/8
- 172.16.0.0/12
- 192.168.0.0/16
- gpingコマンドでpingをグラフィカルにできる
- ssコマンドでソケット関連の情報を取得できる
- DNSに関するオリジナルのRFC1034とRFC1035は実装ガイダンスとして今でも有用
- wireshark、tshark、tcpdumpコマンドでネットワークトラフィックのキャプチャができる
- socatコマンドでエンドポイント間でのデータ転送を可能にする
第8章 オブザーバビリティ
- 一般的なログフォーマット
- 共通イベントフォーマット: デバイス、セキュリティユースケースに使用
- 共通ログフォーマット: Webサーバ用
- Graylog拡張ログフォーマット: JSONを拡張したGraylog独自のフォーマット
- Syslog: OS、アプリ、デバイス向け
- 埋め込みメトリクスフォーマット: Amazonが開発
- logrotateやデータ温度によりディスク容量を節約する
- syslog: カーネルからデーモン、ユーザ空間、さまざまなソースのための標準的なロギング機能。テキスト形式
- journalctl: systemdのエコシステムの一部で、ログを管理するコンポーネント。バイナリ形式
- 監視に使えるコマンド例
- uptime: システムの稼働時間とロードアベレージ(平均負荷)を表示する
- free: メモリの使用量を表示する
- vmstat: メモリの使用状況を表示する
- time: ある操作にかかった時間を計測する
- iostat: I/Oデバイスを監視する
- ss: ソケットの統計情報を出力する
- lsof: ネットワーク接続の情報や、プロセスが使用しているファイルディスクリプタやI/Oなどを確認できる
- htop: topの改良版で、topよりも高速
- guider: さまざまなメトリクスを表示し、グラフ化できるアナライザ
- neoss: ssの進化版
- mtr: tracerouteの進化版
- トレース: 1台のLinuxマシンでプロセスの実行を時系列に沿ってキャプチャすること
第9章 高度なトピック
- プロセス間通信(IPC): Inter-Process Communication
- シグナル: カーネルがユーザ空間にイベントを通知する方法。
- 名前付きパイプ: ファイルとして表現される。単方向のデータ通信しかできない
- UNIXドメインソケット: 双方向通信が可能。ソケットのアドレスはファイルパスで表現される
付録A 便利なコマンド集
気になるものだけ抜粋した。
- gstack, pstack: ユーザ空間における、あるプロセスのスタックトレースを確認する。カーネル空間は cat /proc/<PID>/stack で確認できる
- stat: inodeのような情報を含んだファイルの詳細を確認できる
- which, type: シェルがコマンドをどのように解釈しているか、実行ファイルがどこにあるか確認できる
おわりに
各章、とても早足でLinuxで使用される概念について説明されている。詳しく知りたかったら参考文献を見てな!という勢い。後半になるに連れてそれが顕著になっていた気がした。