-
-
Save yut148/f091b9d5c1a7a7be49a0164efe5c45a9 to your computer and use it in GitHub Desktop.
TCP/IPは下記の4層で構成されています。
TCP/IPモデル | 役割 | 例 | OSI参照モデル |
---|---|---|---|
アプリケーション層 | ソフトウェア同士のやりとり | HTTP, SSH, DNS | 7, 6, 5 |
トランスポート層 | データ転送の制御 | TCP, UDP | 4 |
インターネット層 | IPアドレスの割り当て、ルーティング | IP, ICMP, ARP | 3 |
インターフェース層 | 機器同士の通信 | Ethernet, PPP | 2 |
データを転送する際には各層でヘッダを付けて、下の層へデータを渡していきます。
ref. 詳説 TCP/IPプロトコル:第6回 イーサネット(その1) - イーサネットの規格とCSMA/CDアクセス制御方式 (1/5) - @IT
Ethernetフレームではフレームの最大サイズは1518バイトとなっています。 「ジャンボフレーム」という規格に対応したハブやEthernetカードを使うと最大サイズが拡張されるので、やりとりするパケット数を減らすことができます。
EthernetではMACアドレスを宛先としてデータを送信します。
Ethernetのデータ通信では、Ethernetフレームで付与される情報だけを扱うのでデータの中身のIPの情報は参照しません。
そのため「どのMACアドレスのホストがどのIPアドレスに対応するのか」という対応表が必要となるのですが、これを解決するのがARPです。 ARPはIPアドレスからMACアドレスを調べます。
「192.168.0.10」のIPアドレスにデータを送信する場合、最初に送信するときはこのIPアドレスがどのMACアドレスを持っているか分からないので、APR要求を行い、192.168.0.10のMACアドレスを取得して、ARPキャッシュに記録します。 移行の通信ではこのARPキャッシュを使ってMACアドレスを解決します。
ARP要求はルータまでしか届きません。 ルータを超えてデータを転送するときは、ルータがEthernetヘッダを付け替えてもう一方のネットワークへ転送します。
インターネットに向けて通信する場合、デフォルトゲートウェイが最寄りのルータとなります。
TCP/IPでの通信方法には"UDP"と"TCP"の2種類があります。
UDP | TCP |
---|---|
コネクションレス型 | コネクション型 |
高速 | 低速 |
パケットの順序は保証なし、再送なし | 順序制御、再送制御、ウィンドウ制御、フロー制御 |
DNS, NTP, DHCP, etc. | HTTP, FTP, SMTP, etc. |
TCP
では通信を開始する際に下図のやりとりを行います。
これを3ウェイハンドシェークといいます。

TCP
では送受信するデータにはシーケンス番号が付与されます。
ACKでは次に欲しいシーケンス番号を「応答番号」として返します。
受信側では順序が正しくなかったり欠落した場合には「再送してほしいシーケンス番号」を応答番号として返すことで、データを再送してもらえます。 送信側では応答番号を確認することでデータが相手に届いたかを判断できます。
データの再送はTCPが自動的に行うので、上位層では何も気にする必要はありません。
パケットを覗いてみよう。
local $ vagrant up
local $ vagrant ssh
ターミナル(1)で下記を実行。 後述のターミナル(3)からの接続が来たら"hello world"など適当に返す(レスポンスデータの終了はCtrl-D。プロセスの終了はCtrl-C)。
vagrant $ sudo /bin/sh -c 'while [ 1 ]; do nc -l 127.0.0.1 80; done'
別のターミナル(2)を開いて実行。次のいずれかのコマンドを実行(3ウェイハンドシェイクを確認する場合は最初のコマンドがおすすめ)。
vagrant $ sudo tcpdump -i lo port 80
vagrant $ sudo tcpdump -s0 -A -i lo port 80 # ASCIIで表示
vagrant $ sudo tcpdump -s0 -X -i lo port 80 # 16進とASCIIで表示
tcpdumpは内部でBerkeley Packet Filter(BPF)を利用する。BPFは下記リンクを参照。
別のターミナル(3)を開いて実行。
vagrant $ curl 127.0.0.1
パケットフィルタリングとNAT機能を提供するソフトウェアです。
大まかには テーブル x チェイン x (マッチ条件) x ターゲット を組み合わせて設定を行います。
iptablesには役割の違う4つのテーブルが存在します。 それぞれのテーブルの役割は下記の通りです。
テーブル | 役割 |
---|---|
filter | パケットの通過や遮断 |
nat | NAT(ネットワークアドレス変換機能) |
mangle | パケットの改変 |
raw | コネクション追跡を除外するマーク(NOTRACK)を付与する |
チェインはパケットの取り扱いルールのリストです。
図のようなタイミングで各チェインに登録されたルールが適用されます。 チェインはユーザー定義もできます。

各テーブルで利用できるチェインは次のようになっています。
チェイン | 説明 | filter | nat | mangle | raw |
---|---|---|---|---|---|
PREROUTING | ルーティング前に受信したパケットに対するチェイン(宛先を変換) | ✔ | ✔ | ✔ | |
INPUT | 受信したパケットに対するチェイン | ✔ | ✔ | ||
FORWARD | 受信したマシンを経由するパケットに対するチェイン | ✔ | ✔ | ||
OUTPUT | ローカルプロセスで生成されたパケットに対するチェイン(送信を制御) | ✔ | ✔ | ✔ | ✔ |
POSTROUTING | 送信するパケットに対するチェイン(送信元を変換) | ✔ | ✔ |
ターゲットは条件にマッチしたパケットの処理方法になります。 主要なターゲット次のとおりです。
ターゲット | 説明 |
---|---|
ACCEPT | パケットを通す |
DROP | パケットを捨てる |
REJECT | パケットを捨てる(ICMPエラーを返す) |
REDIRECT | 特定ポートにリダイレクトする |
SNAT | 送信元IPアドレスを変更する |
DNAT | 送信先IPアドレスを変更する |
MASQUERADE | SNATと同様。外部I/Fが固定IPではない場合などに利用 |
LOG | ログを出力する |
各ターゲットについての詳細はこのへんを参照。
おおまかな書式は次のとおりです。
iptables [-t テーブル] コマンド [チェイン] [パラメーター(オプション)...] [-j ターゲット]
-
ルールを確認する(
-t
によるテーブル指定を省略した場合はfilter
テーブルが対象となります)$ sudo iptables --list
-
チェインのルールをすべて削除し、各チェインのポリシー(デフォルトのターゲット)を設定する
$ sudo iptables --flush $ sudo iptables --policy INPUT DROP # !!!リモートから操作している場合はやっちゃダメ!!! $ sudo iptables --policy FORWARD ACCEPT $ sudo iptables --policy OUTPUT ACCEPT
-
ポート22への接続を許可する
$ sudo iptables --append INPUT --protocol tcp --dport 22 --jump ACCEPT
-
ホストからのSMTP接続を192.168.1.1のみに制限する
$ sudo iptables --append OUTPUT --protocol tcp --dport 25 --destination ! 192.168.1.1 --jump DROP
-
すべてのパケットを拒否する
$ sudo iptables --append INPUT --jump DROP
iptablesを設定します。
$ vagrant up
$ vagrant ssh
下記のポリシーを設定してみましょう。対象はすべてfilter
テーブルとなります。
- stateがRELATED, ESTABLISHEDのパケットの受信を許可する(stateモジュールを利用する)
- icmpパケット(pingなど)の受信を許可する
- ループバックインターフェース(lo)への接続を許可する
- ポート22への新しい接続(
stete NEW
)を許可する - それ以外の受信パケットは拒否する(REJECT)
- 転送パケットはすべて拒否する(REJECT)
- 送信パケットはすべて許可する
-A INPUT -m state --state RELATED,ESTABLISHED -j ACCEPT
-A INPUT -p icmp -j ACCEPT
-A INPUT -i lo -j ACCEPT
-A INPUT -p tcp -m state --state NEW --dport 22 -j ACCEPT
-A INPUT -j REJECT
-A FORWARD -j REJECT
トラブルシューティングを円滑に行うためには、ネットワーク全体のトポロジやパブリック、プライベートIPアドレス、ルーティング、それぞれのサーバの役割などの管理を適切に行なっていなければなりません。
これらの管理を怠っていた場合、障害への対応の遅れや余計な手間、トラブルを招いてしまいます。
PowerPointやVisio、Excel、専用管理ツール、または自作するなどして、これらのリソースをしっかりと管理しましょう。
兎にも角にも、まずはエラーメッセージを確認します。
/var/log
配下のログファイルやアプリケーションのログを確認し、エラーメッセージが出力されている場合はよく読んで次の行動に移りましょう。
ネットワークの状態を確認するにはping
、traceroute
、dig
などのコマンドを使用します。
対象のサーバと通信可能か確認します。
$ ping 172.16.33.10
PING 172.16.33.10 (172.16.33.10): 56 data bytes
64 bytes from 172.16.33.10: icmp_seq=0 ttl=64 time=1.241 ms
64 bytes from 172.16.33.10: icmp_seq=1 ttl=64 time=0.312 ms
64 bytes from 172.16.33.10: icmp_seq=2 ttl=64 time=0.312 ms
^C
--- 172.16.33.10 ping statistics ---
3 packets transmitted, 3 packets received, 0.0% packet loss
round-trip min/avg/max/stddev = 0.312/0.565/1.241/0.392 ms
各行にあるms
は応答時間です。
pingコマンドはICMPで通信しています。 対象のホストでICMPがフィルタされている場合はpingに失敗するので注意してください。
宛先のホストへのネットワーク上の経路を確認します。
$ traceroute yahoo.co.jp
traceroute: Warning: yahoo.co.jp has multiple addresses; using 183.79.135.206
traceroute to yahoo.co.jp (183.79.135.206), 64 hops max, 52 byte packets
1 192.168.0.1 (192.168.0.1) 2.059 ms 3.576 ms 1.074 ms
2 khp059134001129.ppp-bb.dion.ne.jp (59.134.1.129) 6.209 ms 3.523 ms 5.000 ms
3 oymbbar001-2.bb.kddi.ne.jp (106.162.212.30) 11.691 ms 12.472 ms 12.525 ms
4 tm4bbac02.bb.kddi.ne.jp (27.90.191.218) 15.936 ms 20.042 ms 14.786 ms
5 otejbb206.int-gw.kddi.ne.jp (118.152.254.65) 18.298 ms 18.146 ms 15.251 ms
6 jc-ote302.int-gw.kddi.ne.jp (118.155.197.179) 14.947 ms 54.521 ms 18.458 ms
7 106.187.28.202 (106.187.28.202) 18.407 ms 18.659 ms 19.823 ms
8 * * *
9 61.206.157.74 (61.206.157.74) 23.759 ms 22.868 ms 24.816 ms
10 124.83.252.242 (124.83.252.242) 29.696 ms 29.789 ms 30.318 ms
11 * * *
12 * * *
...
tracerouteはパケットが想定外のルーティングをされていないかを確認するときなどに使います。
tracerouteもICMPで通信します。
結果の一部で*
が表示されることがあります。これはICMPをフィルタしているネットワークになります。
DNSサーバに対して名前解決を行います。
$ dig yahoo.co.jp
; <<>> DiG 9.8.2rc1-RedHat-9.8.2-0.30.rc1.el6_6.3 <<>> yahoo.co.jp
;; global options: +cmd
;; Got answer:
;; ->>HEADER<<- opcode: QUERY, status: NOERROR, id: 35922
;; flags: qr rd ra; QUERY: 1, ANSWER: 2, AUTHORITY: 0, ADDITIONAL: 0
;; QUESTION SECTION:
;yahoo.co.jp. IN A
;; ANSWER SECTION:
yahoo.co.jp. 52 IN A 182.22.59.229
yahoo.co.jp. 52 IN A 183.79.135.206
;; Query time: 20 msec
;; SERVER: 10.0.2.3#53(10.0.2.3)
;; WHEN: Tue Jul 21 05:00:33 2015
;; MSG SIZE rcvd: 61
status
がNOERROR
なので正しく情報が取得できています。ドメインが存在しない場合はNXDOMAIN
と表示されます。flags
のqr rd ra
はQR(Query/Response)
,RD(Recursion Desired)
,RA(Recursion Available)
フラグが有効になっていることを表します。他にもAA(Authority Answer)
,TC(TrunCation)
があります。QUESTION SECTION
は問い合わせ内容です。yahoo.co.jpのAレコードを調べたことが分かります。ANSWER SECTION
は答えです。2件のアドレスが答えとして返ってきています。- この他にも権威サーバーを表す
AUTHORITY SECTION
や付随情報を表すADDITIONAL SECTION
があります。 - 問い合わせタイプには
A(Address Mapping: default)
,AAAA(IPv6 Address)
,CNAME(Canonical Name)
,NS(Name Server)
,MX(Mail Exchanger)
,SOA(Start of Authority)
,HINFO(Host Information)
,ISDN(Integrated Services Digital Network)
,PRT(Reverse-lookup Pointer)
,TXT(Text)
,ANY
があります。
DNSサーバを指定する場合は@SERVER
とします。
$ dig @SERVER yahoo.co.jp
また、逆引き(IPアドレスをドメイン名に変換)する場合は-x
を使用します。
$ dig -x 182.22.59.229
指定したポートで通信可能か確認します。 ファイアウォールなどで通信が妨げられていないか確認できます。
$ nc www.example.com 80
ちなみにncは-l
オプションで指定したポートをLISTENできます。
ネットワーククライアントの接続テストなどに利用できます。
$ sudo nc -l 80
システム全体やプロセスの状況を確認するにはtop
、dstat
、ps
などのコマンドを使用します。
システムの状況を確認します。
$ top -b -n 1 -a | head -n 20
top - 04:31:46 up 1:51, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 103 total, 1 running, 102 sleeping, 0 stopped, 0 zombie
Cpu(s): 0.1%us, 0.1%sy, 0.0%ni, 99.8%id, 0.0%wa, 0.0%hi, 0.0%si, 0.0%st
Mem: 1020000k total, 241936k used, 778064k free, 9596k buffers
Swap: 950268k total, 0k used, 950268k free, 134136k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
2681 root 20 0 94252 4268 3320 S 0.0 0.4 0:00.22 sshd
1210 postfix 20 0 81592 3868 2948 S 0.0 0.4 0:00.03 qmgr
1203 root 20 0 81328 3840 2900 S 0.0 0.4 0:00.09 master
2705 postfix 20 0 81408 3828 2912 S 0.0 0.4 0:00.03 pickup
1246 root 18 -2 12416 2624 556 S 0.0 0.3 0:00.01 udevd
1247 root 18 -2 12416 2612 544 S 0.0 0.3 0:00.00 udevd
2684 vagrant 20 0 94252 2228 1260 S 0.0 0.2 0:00.04 sshd
2685 vagrant 20 0 109m 1944 1560 S 0.0 0.2 0:00.04 bash
931 root 20 0 243m 1588 1040 S 0.0 0.2 0:00.07 rsyslogd
1105 root 20 0 328m 1504 880 S 0.0 0.1 0:02.39 VBoxService
1 root 20 0 19232 1496 1220 S 0.0 0.1 0:01.73 init
1215 root 20 0 114m 1400 768 S 0.0 0.1 0:02.13 crond
971 rpcuser 20 0 23348 1332 888 S 0.0 0.1 0:00.01 rpc.statd
注目するところはload average
, Tasks
, Cpu(s)
, Mem
, Swap
です。
ロードアベレージです。左から1分、5分、15分の平均になります。
CPUのコア数で割って1以下であればおよそ問題ありません。
プロセスの数が表示されます。
zombieが大量にないか確認してください。
CPU利用率が表示されます。
項目 | 解説 |
---|---|
%us | ユーザープロセス |
%sys | システムプロセス |
%ni | niceされたプロセス |
%id | アイドル |
%wa | I/O待ち |
%hi | ハードウェア割り込み |
%si | ソフトウェア割り込み |
%st | 仮想プロセス |
%id以外の値が大きい場合はなにか対処が必要かもしれません。
メモリの利用率が表示されます。
項目 | 解説 |
---|---|
total | メモリの合計 |
used | 利用中メモリ |
free | 空きメモリ |
buffers | 確保メモリ |
freeが少ない場合はメモリ不足の恐れがあります。
スワップの利用率が表示されます。
メモリのfreeが多いのにスワップのusedが高い場合はswappiness
の値を調整します。
値が大きいほどスワップしやすくなります。
$ cat /proc/sys/vm/swappiness
60
CPU、メモリの使用状況を確認します。
topで確認した時にCPUもメモリもスワップも大した数値ではないけどload averageが高いという場合はI/Oに問題があります。
$ vmstat 1
procs -----------memory---------- ---swap-- -----io---- --system-- -----cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
1 0 0 778064 9612 134156 0 0 5 3 9 7 0 0 100 0 0
0 0 0 778064 9612 134156 0 0 0 0 42 19 0 0 100 0 0
0 0 0 778056 9620 134152 0 0 0 12 23 32 0 0 100 0 0
0 0 0 778056 9620 134152 0 0 0 0 22 19 0 0 100 0 0
0 0 0 778056 9620 134156 0 0 0 0 16 23 0 0 100 0 0
注目するところはprocs
です。
r
が実待ちプロセス、b
がブロック中プロセスの数になります。
r
の値がCPU数の倍以上の場合は注意が必要です。
b
の値が高い場合は更に分析が必要ですが、SSDを採用したりディスクを分散する対策が必要になる場合があります。
システムの状況をより詳しく確認します。
$ dstat -tclmdn --top-io --top-bio
----system---- ----total-cpu-usage---- ---load-avg--- ------memory-usage----- -dsk/total- -net/total- ----most-expensive---- ----most-expensive----
date/time |usr sys idl wai hiq siq| 1m 5m 15m | used buff cach free| read writ| recv send| i/o process | block i/o process
22-07 08:29:11| 0 0 100 0 0 0| 0 0 0| 110M 12.3M 137M 737M|4738B 4178B| 0 0 |bash 334B 1B|
22-07 08:29:12| 0 0 100 0 0 0| 0 0 0| 110M 12.3M 137M 737M| 0 0 | 60B 166B| |
22-07 08:29:13| 0 0 100 0 0 0| 0 0 0| 110M 12.3M 137M 737M| 0 0 | 60B 118B| |
22-07 08:29:14| 0 0 99 0 0 0| 0 0 0| 110M 12.3M 137M 737M| 0 0 | 60B 102B| |
22-07 08:29:15| 0 0 100 0 0 0| 0 0 0| 110M 12.3M 137M 737M| 0 0 | 60B 102B| |
--list
でプラグインの一覧を確認できます。
システムで動作してるプロセスを確認します。
$ ps axlfww
F UID PID PPID PRI NI VSZ RSS WCHAN STAT TTY TIME COMMAND
1 0 2 0 20 0 0 0 kthrea S ? 0:00 [kthreadd]
1 0 3 2 -100 - 0 0 migrat S ? 0:00 \_ [migration/0]
1 0 4 2 20 0 0 0 ksofti S ? 0:00 \_ [ksoftirqd/0]
1 0 5 2 -100 - 0 0 cpu_st S ? 0:00 \_ [stopper/0]
5 0 6 2 -100 - 0 0 watchd S ? 0:00 \_ [watchdog/0]
1 0 7 2 -100 - 0 0 migrat S ? 0:00 \_ [migration/1]
...
1 0 2776 1 20 0 175748 3776 poll_s Ss ? 0:00 /usr/sbin/httpd
5 48 2778 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2779 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2780 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2781 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2782 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2783 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2784 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
5 48 2785 2776 20 0 175748 2420 inet_c S ? 0:00 \_ /usr/sbin/httpd
-
なしでBSDオプションで指定a
,x
は互いに指定するとすべてのプロセスをリストするl
は長いフォーマットで出力するf
はプロセスツリーを表示するw
は出力幅を広げる。2つ指定すると幅の制限がなくなる
項目 | 解説 |
---|---|
UID | 実行ユーザーID |
PID | プロセスID |
PPID | 親プロセスのプロセスID |
NI | nice値 |
VSZ | 仮想メモリサイズ |
RSS | スワップされていない物理メモリ(kB) |
STAT | プロセス状態 |
COMMAND | 実行コマンド |
プロセスのシステムコールを確認します。
$ sudo strace -p 2778
Process 2778 attached - interrupt to quit
accept4(4, {sa_family=AF_INET6, sin6_port=htons(54263), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28], SOCK_CLOEXEC) = 10
getsockname(10, {sa_family=AF_INET6, sin6_port=htons(80), inet_pton(AF_INET6, "::1", &sin6_addr), sin6_flowinfo=0, sin6_scope_id=0}, [28]) = 0
fcntl(10, F_GETFL) = 0x2 (flags O_RDWR)
fcntl(10, F_SETFL, O_RDWR|O_NONBLOCK) = 0
read(10, "GET / HTTP/1.1\r\nUser-Agent: curl"..., 8000) = 162
stat("/var/www/html/", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat("/var/www/html/index.html", 0x7ffffbdbbd50) = -1 ENOENT (No such file or directory)
...
プロセスが開いているファイルを確認します。
$ sudo lsof -p 2778
COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME
httpd 2778 apache cwd DIR 253,0 4096 2 /
httpd 2778 apache rtd DIR 253,0 4096 2 /
httpd 2778 apache txt REG 253,0 355232 2362037 /usr/sbin/httpd
httpd 2778 apache mem REG 253,0 9488 2361963 /usr/lib64/apr-util-1/apr_ldap-1.so
httpd 2778 apache mem REG 253,0 65928 2228254 /lib64/libnss_files-2.12.so
httpd 2778 apache mem REG 253,0 10416 2362033 /usr/lib64/httpd/modules/mod_version.so
httpd 2778 apache mem REG 253,0 27312 2361992 /usr/lib64/httpd/modules/mod_cgi.so
httpd 2778 apache mem REG 253,0 22992 2361999 /usr/lib64/httpd/modules/mod_disk_cache.so
...
MySQL, PostgreSQLで実行中のプロセスを確認します。
SHOW full processlist
SELECT * FROM pg_stat_activity
systemdはSysV initやUpstartに代わってLinuxの起動プロセスを管理する仕組みです。
主要なLinuxディストリビューションではすでに採用/段階的な導入が行われてきています。
systemdのSysV initとの違いは以下が挙げられます。
- 起動処理の並列化(起動時間短縮)
- サービス状態、ログ、PIDを監視(サービスプロセス管理)
- cgroupsを利用したプロセスのグルーピング(サービス実行環境管理)
- journaldによるログ管理(ログ管理)
ユニットとはsystemdが管理する処理の単位です。 SysV initでは"ランレベル"や"サービス"と呼ばれていたものに相当します。
主なユニットタイプは次のものがあります。
名前 | 概要 |
---|---|
service | サービスを起動 |
target | 複数のユニットをグループ化する(ランレベルに相当) |
mount | ファイルシステムのマウント |
swap | スワップ領域を有効化 |
device | ディスクデバイス |
socket | ソケット |
timer | タイマー。cron的なことができます |
ユニットの状況を確認するにはsystemctl (list-units)
を実行します。
$ systemctl
表示するユニットタイプを指定するには-t(--type)
オプションを指定します。
$ systemctl -t service
UNIT LOAD ACTIVE SUB DESCRIPTION
auditd.service loaded active running Security Auditing Service
crond.service loaded active running Command Scheduler
dbus.service loaded active running D-Bus System Message Bus
[email protected] loaded active running Getty on tty1
kdump.service loaded failed failed Crash recovery kernel arming
kmod-static-nodes.service loaded active exited Create list of required static device nodes for the current kernel
lvm2-lvmetad.service loaded active running LVM2 metadata daemon
lvm2-monitor.service loaded active exited Monitoring of LVM2 mirrors, snapshots etc. using dmeventd or progress polling
lvm2-pvscan@8:2.service loaded active exited LVM2 PV scan on device 8:2
network.service loaded active exited LSB: Bring up/down networking
NetworkManager.service loaded active running Network Manager
polkit.service loaded active running Authorization Manager
postfix.service loaded active running Postfix Mail Transport Agent
...
各項目の意味は次の通りです。
項目 | 意味 |
---|---|
UNIT | ユニット名 |
LOAD | 設定の読み込み状況 |
ACTIVE | 実行状態の概要 |
SUB | 実行状態の詳細 |
DESCRIPTION | ユニット説明 |
$ systemctl list-unit-files
chkconfig --list
に相当するコマンドはsystemctl list-unitfiles -t service
になります。
$ systemctl list-unit-files -t service
UNIT FILE STATE
arp-ethers.service disabled
auditd.service enabled
auth-rpcgss-module.service static
[email protected] disabled
blk-availability.service disabled
brandbot.service static
console-getty.service disabled
console-shell.service disabled
cpupower.service disabled
crond.service enabled
dbus-org.freedesktop.hostname1.service static
...
STATEの意味は次の通りです。
STATE | 意味 |
---|---|
enabled | システム起動時に実行されます |
disabled | システム起動時に実行されません |
static | システム起動時の実行の有無は設定できません |
デバイス一覧は-t device
です。
$ systemctl -t device
UNIT LOAD ACTIVE SUB DESCRIPTION
sys-devices-pci0000:00-0000:00:03.0-net-enp0s3.device loaded active plugged PRO/1000 MT Desktop Adapter
sys-devices-pci0000:00-00...1-host0-target0:0:0-0:0:0:0-block-sda-sda1.device loaded active plugged VBOX_HARDDISK
sys-devices-pci0000:00-00...1-host0-target0:0:0-0:0:0:0-block-sda-sda2.device loaded active plugged LVM PV t2Hvum-FrN8-FITs-xw9B-1aXt-3We2-mEexIg on /dev/sda2
sys-devices-pci0000:00-00...0-ata1-host0-target0:0:0-0:0:0:0-block-sda.device loaded active plugged VBOX_HARDDISK
sys-devices-platform-serial8250-tty-ttyS0.device loaded active plugged /sys/devices/platform/serial8250/tty/ttyS0
...
マウント状況一覧は-t mount
です。
$ systemctl -t mount
UNIT LOAD ACTIVE SUB DESCRIPTION
-.mount loaded active mounted /
boot.mount loaded active mounted /boot
dev-hugepages.mount loaded active mounted Huge Pages File System
dev-mqueue.mount loaded active mounted POSIX Message Queue File System
home.mount loaded active mounted /home
sys-kernel-config.mount loaded active mounted Configuration File System
...
スワップ状況一覧は-t swap
です。
$ systemctl -t swap
UNIT LOAD ACTIVE SUB DESCRIPTION
dev-dm\x2d1.swap loaded active active /dev/dm-1
...
サービスの起動や停止を行うのにもsystemctl
を使用します(serivce
コマンドに相当)。
-
サービスの起動
$ sudo systemctl start httpd
-
サービスのステータス確認
$ sudo systemctl status httpd httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled) Active: active (running) since 火 2015-07-28 13:45:41 UTC; 4s ago Main PID: 12683 (httpd) Status: "Processing requests..." CGroup: /system.slice/httpd.service ├─12683 /usr/sbin/httpd -DFOREGROUND ├─12684 /usr/sbin/httpd -DFOREGROUND ├─12685 /usr/sbin/httpd -DFOREGROUND ├─12686 /usr/sbin/httpd -DFOREGROUND ├─12687 /usr/sbin/httpd -DFOREGROUND └─12688 /usr/sbin/httpd -DFOREGROUND 7月 28 13:45:41 localhost.localdomain httpd[12683]: AH00558: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdom...is message 7月 28 13:45:41 localhost.localdomain systemd[1]: Started The Apache HTTP Server. Hint: Some lines were ellipsized, use -l to show in full.
-
サービスの再起動
$ sudo systemctl restart httpd
-
サービスの停止
$ sudo systemctl stop httpd
システム起動時にサービスを自動起動させるにはsystemctl eneble
を実行します(chkconfig
相当)。
$ sudo systemctl enable httpd
ln -s '/usr/lib/systemd/system/httpd.service' '/etc/systemd/system/multi-user.target.wants/httpd.service'
実行すると/usr/lib/systemd/system/
配下にある、該当のユニットファイルのシンボリックリンクが/etc/systemd/system/multi-user.target.wants
に作成されます。
これはSysV initにおける/etc/init.d
のサービス起動スクリプトと/etc/rc.d
のランレベルごとに作成されるシンボリックリンクに相当します。
自動起動をやめるにはsystemctl disable
を実行します。
$ sudo systemctl disable httpd
rm '/etc/systemd/system/multi-user.target.wants/httpd.service'
サービスの自動起動設定を確認するにはsystemctl is-enabled
を実行します。
$ systemctl is-enabled httpd
disabled
また、systemctl mask
を実行するとサービスがsystemdの管理から除外されます。
$ sudo systemctl mask httpd
ln -s '/dev/null' '/etc/systemd/system/httpd.service'
除外されたサービスは手動でも起動できません。
$ sudo systemctl start httpd
Failed to issue method call: Unit httpd.service is masked.
systemctl unmask
を実行するとサービスをsystemdの管理に戻すことができます。
$ sudo systemctl unmask httpd
rm '/etc/systemd/system/httpd.service'
/etc/systemd/system/myapp.service
を下記の内容で準備します。
$ cat /etc/systemd/system/myapp.service
[Unit]
Description=Mojolicious App
After=local-fs.target network.target
[Install]
WantedBy=multi-user.target
[Service]
Type=simple
User=vagrant
Group=vagrant
ExecStart=/usr/local/bin/hypnotoad -f /home/vagrant/myapp.pl
ExecReload=/usr/local/bin/hypnotoad -f /home/vagrant/myapp.pl
ExecStop=/usr/local/bin/hypnotoad -s /home/vagrant/myapp.pl
Restart=on-failure
myapp.serviceを有効化し、起動します。
$ sudo systemctl enable myapp
$ sudo systemctl start myapp
$ systemctl status myapp
myapp.service - Mojolicious App
Loaded: loaded (/etc/systemd/system/myapp.service; enabled)
Active: active (running) since 水 2015-07-29 02:33:06 UTC; 6s ago
Process: 19074 ExecStop=/usr/local/bin/hypnotoad -s /home/vagrant/myapp.pl (code=exited, status=0/SUCCESS)
Main PID: 19077 (/home/vagrant/m)
CGroup: /system.slice/myapp.service
├─19077 /home/vagrant/myapp.pl
├─19078 /home/vagrant/myapp.pl
├─19079 /home/vagrant/myapp.pl
├─19080 /home/vagrant/myapp.pl
└─19081 /home/vagrant/myapp.pl
8080ポートにアクセスして動作を確認しましょう。
$ curl localhost:8080
ユニットファイルを編集した時はreenable
を実行してください。
$ sudo systemctl reenable myapp
ユニットファイルは[Unit]
, [Service]
, [Install]
などのセクションに分けて記述します。
ユニットに依存しないオプションの設定を行うセクションです。
主なオプションは次の通りです。
オプション | 説明 |
---|---|
Description | ユニットの説明 |
Documentation | ユニットのドキュメントのURI |
Requires/Wants | ユニットと同時に有効化が必要なユニット |
Before | このユニットより後に起動するべきユニット(ここで挙げるユニットより先に起動します) |
After | このユニットより先に起動するべきユニット(ここで挙げるユニットより後に起動します) |
After=local-fs.target network.target
では、local-fsターゲットとnetworkターゲットが起動した後に、このユニットを起動します。
詳しくは systemd.unit(5) を参照してください。
ユニットの自動起動に関するオプションの設定を行うセクションです。
主なオプションは次の通りです。
オプション | 説明 |
---|---|
WantedBy/RequiredBy | このユニットのシンボリックリンクを指定したユニットの.wants/.requiresに作成 |
WantedBy=multi-user.target
では/etc/systemd/system/multi-user.target.wants
にこのユニットのシンボリックリンクが作成されます。
詳しくは systemd.unit(5) を参照してください。
serviceタイプのユニット固有のオプションの設定を行うセクションです。
主なオプションは次の通りです。
オプション | 説明 |
---|---|
Type | サービスプロセスの起動完了の判定方法 |
User | サービスプロセスの実行ユーザー |
Group | サービスプロセスの実行グループ |
ExecStart | サービス起動コマンド |
ExecReload | サービスリロードコマンド |
ExecStop | サービス停止コマンド |
Restart | サービスプロセス停止時の再起動条件 |
Type
のデフォルト値はsimple
です。他にもoneshot
, forking
, notify
, dbus
などがあります。
simple
はフォアグラウンドで実行するプロセス、oneshot
は一度だけ実行するプロセス、forking
はデーモン型のプロセス、notify
, dbus
はsystemdもしくはD-BuxのAPIを通じて起動完了を通知するプロセスに対応します。
Restart=on-failure
ではプロセスが異常終了(exitステータスが0以外)、特定のシグナル(SIGHUP, SIGTERM, SIGINT, SIGPIPE)以外を受け取った、もしくはSuccessExitStatus=
で指定したステータスコードやシグナル以外の場合に自動的に再起動する設定です。
デフォルト値はno
となっており、自動的に再起動を行いません。
この他にもalways
, on-success
, on-abnormal
, on-abort
, on-watchdog
がサポートされています。
詳しくは systemd.service(5) を参照してください。
systemdは/etc/systemd/system
以下のサブディレクトリに作成された、ユニットファイルへのシンボリックリンクを順次実行して、サービスを起動します。
サービスの起動は並列に行われ、起動順はユニットファイルに記載された依存関係を元に、systemd側で自動的に制御してくれます。
ユニットファイルのシンボリックリンク元ファイルは/usr/lib/systemd/system
です。シンボリックリンク先ディレクトリとの関係を下記に示します。
ディレクトリ | 説明 |
---|---|
/usr/lib/systemd/system | サービス起動のためのユニットファイルが格納されています。/etc/rc.d/init.d 相当。 |
/etc/systemd/system | サービス起動のためのユニットファイルに対するシンボリックリンクが配置されます。/etc/rc.d/ 相当。 |
サブディレクトリはターゲットユニットごとに作成されており、主なディレクトリの役割は次の通りです。
ディレクトリ | 役割 |
---|---|
sysinit.target.wants | 起動初期に実行されるターゲットです。rc.sysinit 相当。 |
basic.target.wants | システム共通に実行されターゲットです。 |
multi-user.target.wants | ランレベル3に相当するターゲットです。 |
graphical.target.wants | ランレベル5に相当するターゲットです。 |
現在のデフォルトターゲットを確認するにはsystemctl get-default
を実行します。
$ systemctl get-default
multi-user.target
デフォルトターゲットを変更するにはsystemctl set-default
を実行します。
$ sudo systemctl set-default graphical.target
$ sudo reboot
一時的にターゲットを変更するにはsystemctl isolate
を実行します(telinit
相当)。
$ sudo systemctl isolate graphical.target
systemctl
ではサービスを制御するコマンドとして下記のものが用意されています。
- start
- stop
- restart
- reload
従来のSysV initの起動スクリプトでは自由にコマンドを定義できましたが、systemctl
では上記のコマンド以外の制御コマンドはありません。
例えばSysV initのhttpd起動スクリプトでは上記の他に
- condrestart
- try-restart
- force-reload
- graceful
- help
- configtest
なども定義されています。
これらのコマンドはsytemctl
では対応できないので、service
コマンドで実行してきたこれらのコマンドの実行方法を事前に検証しておく必要があります。
$ sudo apachectl configtest
$ sudo apachectl graceful
systemdでは各ユニットのログ出力を収集して独自のバイナリファイルに保存しています。
収集対象のログは
- プロセスのSTDOUT/STDERR
- syslogへの出力
- journald APIで渡されたデータ
となります。
ログの収集、保管はsystemd-journald.service
が行っています。
$ systemctl status systemd-journald
systemd-journald.service - Journal Service
Loaded: loaded (/usr/lib/systemd/system/systemd-journald.service; static)
Active: active (running) since 水 2015-07-29 01:05:54 UTC; 4h 5min ago
Docs: man:systemd-journald.service(8)
man:journald.conf(5)
Main PID: 468 (systemd-journal)
Status: "Processing requests..."
CGroup: /system.slice/systemd-journald.service
└─468 /usr/lib/systemd/systemd-journald
journaldで収集されたログはjournalctl
で確認します。
$ sudo journalctl
-- Logs begin at 水 2015-07-29 01:05:52 UTC, end at 水 2015-07-29 05:15:00 UTC. --
7月 29 01:05:52 localhost.localdomain systemd-journal[97]: Runtime journal is using 6.2M (max 49.6M, leaving 74.5M of free 490.4M, current limit 49.6M).
7月 29 01:05:52 localhost.localdomain systemd-journal[97]: Runtime journal is using 6.2M (max 49.6M, leaving 74.5M of free 490.4M, current limit 49.6M).
7月 29 01:05:52 localhost.localdomain kernel: Initializing cgroup subsys cpuset
7月 29 01:05:52 localhost.localdomain kernel: Initializing cgroup subsys cpu
7月 29 01:05:52 localhost.localdomain kernel: Initializing cgroup subsys cpuacct
7月 29 01:05:52 localhost.localdomain kernel: Linux version 3.10.0-229.el7.x86_64 ([email protected]) (gcc version 4.8.2 20140120 (Red Hat 4.8.2-16) (GCC) ) #1 SMP
...
-k
オプションを付与するとdmesg
相当の内容を確認できます。
$ sudo journalctl -k
特定のユニットのログを確認するには-u UNIT
を付与します。
$ sudo journalctl -u myapp
また-o OUTPUT
で出力フォーマットを指定したり、-f
でtail -f
と同様に出力をリアルタイムで確認できます。
$ sudo journalctl -u myapp -o json-pretty -f
ログの出力先について、/etc/systemd/journald.confのデフォルト設定(Storage=auto
)では、次のような動作をします。
/var/log/journald
ディレクトリが存在すればそこに書き込む/var/log/journald
ディレクトリが存在しないか書き込み不可な場合は、/run/log/journal
ディレクトリに書き込む
/run/log/journal
ディレクトリはtmpfsで作成された一時領域なので再起動時にログは消えてしまいます。
ログを残す場合は/var/log/journal
ディレクトリを作成してシステムを再起動します。
$ sudo mkdir /var/log/journal
$ sudo chmod 700 /var/log/journal
$ sudo reboot
# -*- mode: ruby -*- | |
# vi: set ft=ruby : | |
Vagrant.configure(2) do |config| | |
config.vm.box = "boxcutter/centos71" | |
config.vm.network "private_network", ip: "172.16.33.10" | |
config.vm.provider "virtualbox" do |vb| | |
vb.cpus = 3 | |
vb.memory = 1024 | |
end | |
config.vm.provision "shell", inline: <<-SHELL | |
sudo yum install -y tcpdump nc iptables-services | |
sudo systemctl enable iptables && sudo systemctl start iptables | |
sudo yum install -y bind-utils lsof strace dstat | |
sudo yum install -y httpd perl perl-core | |
sudo wget -O - https://cpanmin.us | perl - --sudo App::cpanminus | |
sudo /usr/local/bin/cpanm --notest Mojolicious | |
if [ ! -e /home/vagrant/myapp.pl ]; then (cd /home/vagrant && sudo su -l vagrant -c 'mojo generate lite_app'); fi | |
SHELL | |
end |