『プロのためのLinuxシステム構築・運用技術』読書ノート

プロのための Linuxシステム構築・運用技術』を読んだので、学んだ点をまとめる。

1 Linuxサーバの構築

1.1 サーバ・ハードウェア

Linuxの起動

電源投入
→システムBIOSがハードウェア・コンポーネントの状態確認
→システムBIOSがブートストラップローダをメモリに読み込む
→ブートストラップローダがブートローダ(GRUB)をメモリに読み込む
→GRUBがカーネル本体と初期RAMディスクのファイルをメモリに読み込む

GRUB

設定ファイル:/boot/grub/grub.conf

オプション 意味
timeout 起動エントリを選択するまでのタイムアウト秒
default タイムアウト時に使用されるエントリ(0から始まる通し番号)

次のようなコマンドを打って、カーネルをアップデート(-U)するのではなく複数バージョンのカーネルをインストール(-i)している場合、最新のカーネルを起動したければdefault=0で、一個前のカーネルを起動したければdefault=1としてから再起動すればいい。

1.2 Linuxの導入作業

パーティション

ルート・パーティションは10GBもあれば十分。アプリケーションのデータ領域に外部ストレージを利用する場合は、通常データ用パーティションに充てる容量をルート・パーティションに充ててもOK。
RHELの「デフォルトのレイアウト」を用いるとルート・パーティションもLVMになるが、バックアップが複雑になったりするため、LVMにしないようにするのがいい。

データ領域はLVMを用いて拡張可能なようにするのがいい。

swap領域は2GB上限。

2 Linuxサーバ運用の基礎

2.1 システム監視

システム監視の3種類
  • 監視エージェント
    • ログファイル監視(logmonなど)
    • プロセス監視
    • リソース監視(sysstatなど)
  • ネットワーク監視
    • ping監視
    • ポート監視
    • SNMP監視
  • システム管理プロセッサ(ハードウェアの監視)

2.2 バックアップ

レスキューブートによるシステムバックアップ

インストールメディアからサーバを起動することで行う。
起動時に表示されるboot:プロンプトに対して、linux rescueと入力する。

レスキューモードでは、サーバのハードディスク内のファイルを使用しないため、安全にバックアップできる。
バックアップサーバをNFSマウントして、そこに書きだすことも可能。

システム領域を書きだすには、dump(←→restore)コマンドを使う。
ddコマンドでディスクパーティション全体を1つのイメージファイルに書き出すのは、サイズが大きい問題とリストア時に同じサイズのパーティションが必要になる問題でお勧めできない。

バックアップ手順

/bootファイルシステムがsda1で、ルートファイルシステムがsda2である場合、次のようになる。

リストア手順

2.4 構成管理・変更管理・問題管理

構成管理
  • サーバ・ハードウェアの物理構成とシステムBIOSやファームウェアのバージョン
  • ネットワーク機器や外部ストレージ装置との物理接続図
  • ディスク装置の論理構成
  • OSの基本設定情報(RHELではあれば、sosreportコマンドで出力)
  • ネットワーク構成情報(ホストネーム、IP)
  • 導入したRPMや設定変更した箇所

3 Linuxのストレージ管理

3.1 ストレージエリア・ネットワークの基礎

ストレージエリア・ネットワーク(SAN)は、サーバとストレージ装置の間に、物理的な接続は独立した論理的な接続を実現する技術。
複数のサーバとストレージ装置をSANスイッチを介して、FCケーブルで接続する。そのうえでSANスイッチのゾーニング機能を用いて、サーバとストレージの間の論理的な接続を決定する。

3.2 LVMの構成・管理

LVMの基礎
  • 物理ボリューム(PV)
  • ボリュームグループ(VG)
  • 論理ボリューム(LV)
LVMの作成

LVMの確認

物理ボリュームの追加

論理ボリュームの拡張

LVMの削除

構成情報のバックアップ

vg_data01.cfgにはvg_data01に含まれる物理ボリュームと論理ボリュームの情報がテキスト形式で記載される。構成情報のバックアップとして保存しておく。

再構成するとき、vg_data01.cfgのphysical_volumesに書かれた物理ボリュームのUUIDを使ってpvcreateする。

3.3 iSCSIとFCoE

iSCSIの基礎

IPネットワークによる接続環境で、Linuxがリモートストレージを使用する方法
→NFS
NFSによるファイル共有機能を提供する専用のアプライアンス製品
→NAS

IPネットワークを通じて、疑似的なSCSI接続を実現する方法
→iSCSI
※SCSI接続:物理的なディスク装置をサーバに接続するもの
iSCSIは、Linuxサーバ側で/dev/sdXの形式でアクセスする物理デバイスとして認識され、ファイルシステムを作成する必要がある。

4 Linuxのネットワーク管理

4.1 IPネットワーク

ルーティングの仕組み

L2スイッチ:ルータの機能を持たない→同一サブネットの機器同士を接続する
L3スイッチ:ルータの機能を持つ→隣接するサブネットにパケット転送できる

L3スイッチで異なるサブネットとの通信をする仕組みを理解するには、ルーティングテーブルを理解する必要がある。

宛先のネットワークが、ルーティングテーブルに書かれたDestination/Genmaskにマッチする行を見る。
Gatewayが0.0.0.0であれば、同一サブネットなので、ルータを介さずパケットを送るという意味になる。
Destinationが0.0.0.0の行は、デフォルトのエントリとなり、どの行にもマッチしなかった場合に適用される。この行のGatewayが、いわゆる「デフォルトゲートウェイ」。

デフォルトゲートウェイ

/etc/sysconfig/network-scripts/ifcfg-ethXのGATEWAYで設定する。
デバイスごとに設定するものではないが、慣習的にデフォルトゲートウェイと同じサブネットのデバイスの設定ファイルで指定する。

スタティックルート

サーバにNICが2枚(例えばサービス提供用と管理用)あり、eth0とeth1のデフォルトゲートウェイを個別に設定したい場合。デフォルトゲートウェイを二つ設定することは不可能なため、片方のサブネットに対してゲートウェイをスタティックルートで指定して、もう片方のゲートウェイをデフォルトゲートウェイにする。

この例だと、192.168.12.10に送信するときに使われるゲートウェイは192.168.11.1になり、192.168.2.10に送信するときに使われるゲートウェイはデフォルトゲートウェイ192.168.1.1になる。

スタティックルートは/etc/sysconfig/network-scripts/route-ethXで指定する。

4.2 Linuxのネットワーク設定

IPエイリアス

1つのNICに複数のIPアドレスをアサインする。
/etc/sysconfig/network-scripts/ifcfg-eth0:0のように、ethX:エイリアス番号のファイルを作成する。
エイリアスデバイスethX:エイリアス番号には、ethXとDEVICE, ONBOOT, IPADDRなど同様の項目を書くが、HWADDRだけは書かない。

4.3 高度なネットワーク設定

Well-knownポート

0-65535まであるポートのうち、0-1023までをWell-knownポートと呼ぶ。
apache(80ポート)などWell-knownポートで接続を待つプロセスはroot権限でないといけない。

クライアントアプリが使用するポート

1024-65535の中から選択する。
カーネルパラメータnet.ipv4.ip_local_port_rangeで実際に使用する範囲が設定されており、デフォルトでは32768-61000が指定されている。

TCPセッションの状態遷移
  • TCPセッションの確立
    1. SYN→
    2. ←SYN/ACK
    3. ACK→
  • TCPデータの転送
    1. DATA→
    2. ←ACK/DATA
    3. ACK→
  • TCPセッションの切断
    1. FIN→
    2. ←ACK
    3. ←FIN
    4. ACK→

TCPセッションの切断では、切断したい方(はじめにFINを送った方)が、ソケットをクローズする前に一定時間TIME-WAIT状態になる。理由は、相手が最後のACKを受信できずに再度FINを送る可能性があるため。
TIME-WAITについてはこちらも参照→高トラフィックに対応するWEBサーバのネットワーク設定

TCPセッションのタイムアウト時間

パケットの再送するための待ち時間は、RTO(Retransmission timeout)と呼ばれる。
RTOはダイナミックに変化する。※初期から最大値120秒まで再送ごとに2倍ずつ増加するなど。

セッションの確立を行うSYNについてはSYN/ACKが返ってこない場合net.ipv4.tcp_syn_retriesで定義された回数を最大回数としてSYNの再送を行い、同様にSYN/ACKについてはACKが返るまでnet.ipv4.tcp_synack_retriesで定義された回数を最大回数としてSYN/ACKの再送を行う。
net.ipv4.tcp_syn_retriesを少なくすると、早く接続失敗が確定する。

データ転送についての最大回数を定義しているのは、net.ipv4.tcp_retries2

セッション切断についての最大回数を定義しているのは、net.ipv4.tcp_orphan_retries

ソケット数の上限
プロセスごとに決められる上限

ファイルディスクリプタ数の上限が、プロセスが同時にオープンできるファイルの数の上限となる。
ulimitコマンドで変更でき、最大値は1048576である。

ulimitにはソフトリミットとハードリミットがあり、ソフトリミットは実際の上限で、ハードリミットが変更可能な値の上限となる。ハードリミットはrootしか増やせない。

ログインシェルに対して設定する場合は、/etc/security/limits.confで設定する。
自動起動されるプロセスに対して設定する場合は、/etc/initscript内でulimitコマンドを実行する。

nオプションは「ファイル数」を指すオプションで、H, Sがそれぞれハードリミット、ソフトリミットを指す。

ulimitで設定できるのはファイル数だけでなく、ファイルサイズやコアダンプのファイルサイズ等が設定できる。aオプションでログイン中のユーザに対する現在の設定が確認できる。

サーバ前提で決められる上限

ファイルオブジェクト数の上限が、システム全体で同時にオープンできるファイルの数の上限となる。
カーネルパラメータfs.file-maxで設定する。

5 Linuxの内部構造

5.1 プロセス管理

Linuxの主なプロセスシグナル
シグナル名 シグナル番号 処理内容
HUP 1 プロセスのリスタート
INT 2 プロセスの通常終了(Ctrl+C、割り込み(Interrupt)の略)
KILL 9 プロセスの強制終了
QUIT 3 プロセスの終了(coreダンプ)
TERM 15 プロセスの通常終了(killコマンドデフォルトシグナル)
STOP 19 プロセスの一時停止
CONT 18 プロセスの一時停止からの復帰
CHLD 17 子プロセスの終了通知
プロセスの状態遷移

プロセスは必ずある親プロセスからフォークした子プロセスとして生成される。ログインシェルから実行したコマンドのプロセスはログインシェルのプロセスからフォークする。
親プロセスを持たない唯一のプロセスは、プロセスIDが1のinitプロセスであり、Linux起動後、カーネルが最初に立ち上げる。その他のプロセスはinitからフォークして起動していく。子プロセスが終了する前に親プロセスが終了した場合は、initが新しい親プロセスとして設定される。

プロセスの状態
記号 意味 説明
R 実行可能状態/実行状態 CPUを使用中
D 割り込み不能な待機状態 ディスクIOの完了待ち
S 割り込み可能な待機状態 プログラムの指示によるスリープ
T 停止状態 STOPシグナルで一時停止中
Z ゾンビ状態 実行を終了して、親プロセスによる終了確認を待っている
Niceレベル

プロセスの優先度を調整できる。
-20 ~ 19まで設定でき、デフォルトは0。値が小さいほど優先度が高い。
プロセスの起動時にniceコマンドでNiceレベルを指定することができ、またreniceコマンドで指定したプロセスIDをもつ稼働中のプロセスのNiceレベルを変更することができる。

5.2 メモリ管理

メモリのオーバーコミット

プログラムが実際にメモリ内の領域にデータを書き込もうとしても、割り当て可能な物理メモリが確保できなくなると、OOM Killerが動作する。
カーネルパラメータvm.overcommit_memory, vm.overcommit_ratioでオーバーコミットの動作を変更できる。
OOM Killerとカーネルパラメータの変更についてはこちらも参照→PostgreSQLを作るときはOOM Killer対策が必要

ディスクキャッシュ

freeコマンドでメモリの使用状況を確認したとき、buffersとcachedの合計がディスクキャッシュとして使用されているメモリの容量である。2行目の-/+ buffers/cache:は、ディスクキャッシュを空き容量としてみなした、物理メモリの使用量と空き容量。

ディスクキャッシュを強制的に解放するには、echo 3 > /proc/sys/vm/drop_cachesを実行する。
しかしプロセス間共有メモリの領域等に使われるtmpfs(メモリを利用したRAMディスク機能)は解放されない。tmpfsはdfコマンドで現在の使用量が確認できる。

5.3 ファイルシステム管理

fsck

fsckコマンド(e2fsck)は、デフォルトではジャーナルを利用したメタデータの修復のみを行うが、以下の場合はメタデータ領域の全検索を行う。

  1. -fオプションを指定した場合
  2. Mount Countの値が、Maximum mount countに達した場合
  3. Last checkedの日時から、Checked intervalで指定された期間が経過した場合

突然、サーバの起動に長時間かかる場合は、ほとんどの場合、2か3の条件に合致してしまった場合。
Maximum mount countとChecked intervalには、運用ポリシーに合わせて、適切な値を設定するべきで、無効にしたければ0を設定する。

ジャーナリング・ファイルシステム

ファイルの書き込みは、Linuxのディスクキャッシュを経由して行われる。つまり、メモリ上のディスクキャッシュに書き込まれた内容が、定期的にまとめて物理ディスクに書き込まれる。
サーバの停止等によるデータ不整合を防ぐため、ジャーナルログを利用している。

  1. メタデータの変更内容(ジャーナルログ)を、物理ディスクのジャーナル領域に書き込む。
  2. 物理ディスクのメタデータを変更する。
  3. ジャーナルログを削除する。

2の途中でサーバが停止しても、ジャーナルログを利用してメタデータの変更を最後まで完了してくれる。1の途中だった場合は、ジャーナル領域のデータを単純に破棄する。

この仕組みはあくまでメタデータの不整合を防止するためのもので、実データ領域の破損は考慮していない。ext3ファイルシステムでは、mountのオプションdata=による指定で3つのジャーナリングモードを選択できる。

  • ordered(デフォルト) : メタデータのみジャーナリングを行う。メタデータの書き込みはデータブロックの書き込み完了後
  • writeback : メタデータのみジャーナリングを行う。メタデータの書き込みはデータブロックの書き込みのタイミングを考慮しない
  • journal : メタデータだけでなく実データに対してもジャーナリングを行う
NFS

NFSでの書き込みは次の通り行われる。

  1. クライアントのディスクキャッシュ
  2. サーバのディスクキャッシュ
  3. サーバの物理ディスク

クライアントのmountオプションでsyncを指定すると1→2の転送が即座に行われる。デフォルトはasync
サーバのexportオプションでsyncを指定すると2→3の転送が即座に行われる。デフォルトは先ほどとは逆でsync

6 Linuxサーバの問題判別

6.1 問題判別の基礎

syslogデーモン

syslogデーモンに送られるメッセージは、facilityとpriorityを持つ。
syslogデーモンがログを書き出す時は、サーバの停止等で停止に関わるログを失わないため、書き込んだ内容をディスクキャッシュから物理ディスクに強制的に書き出す。デフォルトの/etc/syslog.confではfacilityがmailの時、ログファイル名の先頭に-がついており(-/var/log/maillog)、この場合はディスクキャッシュの強制出力が行われない。

loggerコマンドを利用すると、facilityとpriorityを指定してsyslogデーモンにメッセージを送信できる。シェルスクリプト内でloggerでログ出力すると、ログファイルの管理をロギングシステムに任せることができる。

6.3 パフォーマンスの問題判別

CPU

us+syが、継続的に80~90%を越える場合は、CPUがボトルネックになっている可能性がある。
ユーザプロセス処理時間usが高い場合はアプリケーションに原因がある可能性があり、カーネル処理時間syが高い場合はディスクIOやネットワーク通信に伴うデバイスドライバの処理負荷が高い可能性がある。

vmstatで表示されるCPU使用率は全コアの平均値。対してmpstatでは各コアの使用率が確認できる。

ディスクIO

vmstatのwaが継続的に高い値で、IO待ちプロセス数(procs b)が多い場合、ディスクIOがボトルネックの可能性がある。
読み込みブロック数(io bi)と書き込みブロック数(io bo)からサーバ全体でのディスクIO量(KB)が確認できる。

iostatの使用率%utilが高いディスクに負荷がかかっている。
デバイスごとのIO量は、IOリクエスト数がr/s, w/s、セクタ数がrsec/s, wsec/sで確認できる。rsec/s ÷ r/sで平均リクエストサイズ(セクタ数/1リクエスト)が算出でき、小さなデータ処理が多いか大きなデータ処理が多いか判断できる。

メモリ

vmstatのswap si, swap soの発生状況を確認する。

プロセス情報の確認

各プロセスの実メモリの使用量は、ps auxで表示されるRSSの値。実際に使用している物理メモリ(KB)を表す。

-読書ノート