0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

test-your-sysadmin-skillsを翻訳してみて答えられなかった質問8選

Posted at

というリポジトリがあります。

システム管理者としてどれくらいの実力があるかの質問と答えを集めたものです。
これで自分の実力を知ることができます。

このリポジトリをほぼChatGPTに投げて日本語にしてみました。

ジュニア

一般

シニア

とレベルが別れているのですが、一般レベルはなんとかなりつつもシニアレベルが大変でした。

ここでは筆者が答えられなかった質問とその答えを載せておきます。
もっと挑戦したい方はぜひ以下へ↓

サーバーをデバッグしようとしている他の管理者が誤って入力してしまった:chmod -x /bin/chmod。パーミッションをデフォルトに戻すには?

答え
# 1:
cp /bin/ls chmod.01
cp /bin/chmod chmod.01
./chmod.01 700 file

# 2:
/bin/busybox chmod 0700 /bin/chmod

# 3:
setfacl --set u::rwx,g::---,o::--- /bin/chmod

# 4:
/usr/lib/ld*.so /bin/chmod 0700 /bin/chmod

useradd または adduser コマンドを使わずに新しいユーザーを追加する方法は?

useraddやadduserコマンドが何をしているかというのを答える質問
手動でやると面倒

答え
  1. vipw コマンドを使って、/etc/passwd にユーザーの詳細を追加します:
# username:password:UID:GID:Comments:Home_Directory:Login Shell
user:x:501:501:test user:/home/user:/bin/bash

構文には注意してください。直接エディタで編集しないでください。vipw はファイルをロックするため、他のコマンドが同時にファイルを更新しようとすることはありません。

  1. 同じ名前のグループを /etc/groupvigr で作成する必要があります(vipw と似たツールです)。
user:x:501:
  1. ユーザーにパスワードを与えます:
passwd user
  1. mkdir コマンドを使ってユーザーのホームディレクトリを作成します:
mkdir -m 0700 /home/user
  1. /etc/skel から新しいホームディレクトリにファイルをコピーします:
rsync -av --delete /etc/skel/ /home/user
  1. chownchmod を使って所有権と権限を修正します:
chown -R user:user /home/user
chmod -R go-rwx /home/user

アプリケーションにパフォーマンスの問題が発生しています。最適化すべきコードを見つける必要があります。Linux環境でアプリをプロファイルする方法は?

あまりシステム管理っぽくない質問
ツールにお任せしているところをコマンドでできるかな?

答え

理想的には、プロセスにアタッチして、メモリ使用量、スレッド数、CPU使用率の定期的なスナップショットを記録するアプリが必要です。

  1. topをバッチモードで使用できます。バッチモードでは、終了するまで、または指定した回数の反復が完了するまで実行されます。
top -b -p `pidof a.out`

または

top -b -p `pidof a.out` -n 100
  1. psも使用できます (例えばシェルスクリプトで):
ps --format pid,pcpu,cputime,etime,size,vsz,cmd -p `pidof a.out`

Linuxマシンでアプリケーションのパフォーマンスを記録する手段が必要です。

  1. パフォーマンスデータを記録する:
perf record -p `pidof a.out`

または10秒間記録するには:

perf record -p `pidof a.out` sleep 10

または、コールグラフを記録するには:

perf record -g -p `pidof a.out`
  1. 記録されたデータを解析する
perf report --stdio
perf report --stdio --sort=dso -g none
perf report --stdio -g none
perf report --stdio -g

これはテストプログラムのプロファイリングの例です

  1. テストプログラム(C++)を実行します:
./my_test 100000000
  1. 実行中のプロセスのパフォーマンスデータを記録します:
perf record -g  -p `pidof my_test` -o ./my_test.perf.data sleep 30
  1. 次に、モジュールごとの負荷を分析します:
perf report --stdio -g none --sort comm,dso -i ./my_test.perf.data

# Overhead  Command                 Shared Object
# ........  .......  ............................
#
    70.06%  my_test  my_test
    28.33%  my_test  libtcmalloc_minimal.so.0.1.0
     1.61%  my_test  [kernel.kallsyms]
  1. 次に、機能ごとの負荷を分析します:
perf report --stdio -g none -i ./my_test.perf.data | c++filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
    29.14%  my_test  my_test                       [.] f1(long)
    15.17%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator new(unsigned long)
    13.16%  my_test  libtcmalloc_minimal.so.0.1.0  [.] operator delete(void*)
     9.44%  my_test  my_test                       [.] process_request(long)
     1.01%  my_test  my_test                       [.] operator delete(void*)@plt
     0.97%  my_test  my_test                       [.] operator new(unsigned long)@plt
     0.20%  my_test  my_test                       [.] main
     0.19%  my_test  [kernel.kallsyms]             [k] apic_timer_interrupt
     0.16%  my_test  [kernel.kallsyms]             [k] _spin_lock
     0.13%  my_test  [kernel.kallsyms]             [k] native_write_msr_safe

  ...
  1. 次に、コールチェインを分析します:
perf report --stdio -g graph -i ./my_test.perf.data | c++filt

# Overhead  Command                 Shared Object                       Symbol
# ........  .......  ............................  ...........................
#
    29.30%  my_test  my_test                       [.] f2(long)
            |
            --- f2(long)
               |
                --29.01%-- process_request(long)
                          main
                          __libc_start_main

    29.14%  my_test  my_test                       [.] f1(long)
            |
            --- f1(long)
               |
               |--15.05%-- process_request(long)
               |          main
               |          __libc_start_main
               |
                --13.79%-- f2(long)
                          process_request(long)
                          main
                          __libc_start_main

  ...

この時点で、プログラムがどこに時間を費やしているかがわかります。

また、アプリケーションのプロファイルを作成する簡単な方法は、pstackユーティリティまたはlsstackを使用することです。

もう一つのツールはValgrindです。これをお勧めします。まずプログラムを実行します:

valgrind --tool=callgrind --dump-instr=yes -v --instr-atstart=no ./binary > tmp

プログラムが動作しているときに、プロファイリングを開始するには別のウィンドウで以下を実行します:

callgrind_control -i on

これでプロファイリングがオンになります。オフにして全タスクを停止するには次のコマンドを使用します:

callgrind_control -k

これで、現在のディレクトリにcallgrind.out.*という名前のファイルが生成されます。プロファイリングの結果を確認するには次のコマンドを使用します:

kcachegrind callgrind.out.*

次のウィンドウでSelf列のヘッダーをクリックすることをお勧めします。そうしないと、main()が最も時間を消費しているタスクとして表示されてしまいます。

プロダクションサーバーでルートによって実行されたすべてのコマンドをログに記録するには?

auditdを知っているか使えるかの質問
筆者は使ったことないです

答え

auditdがこの作業には適切なツールです:

  1. /etc/audit/audit.rules に以下の2行を追加します:
-a exit,always -F arch=b64 -F euid=0 -S execve
-a exit,always -F arch=b32 -F euid=0 -S execve

これにより、ルート(euid=0)によって実行されたすべてのコマンドが追跡されます。なぜ2つのルールが必要なのか?execve システムコールは、32ビットおよび64ビットの両方のコードで追跡する必要があります。

  1. ログに auid=4294967295 メッセージを表示させないようにするには、カーネルのコマンドラインに audit=1 を追加します(/etc/default/grub を編集)。

  2. 以下の

session  required                pam_loginuid.so

を、ログインに関連するすべてのPAM設定ファイル(/etc/pam.d/{login,kdm,sshd})に追加しますが、su または sudo に関連するファイルには追加しません。これにより、sudo または su を呼び出すときに、auditd が呼び出し元ユーザーのUIDを正しく取得できるようになります。

システムを再起動してください。

ログインしてコマンドを実行してみましょう:

$ id -u
1000
$ sudo ls /
bin  boot  data  dev  etc  home  initrd.img  initrd.img.old  lib  lib32  lib64  lost+found  media  mnt  opt  proc  root  run  sbin  scratch  seLinux  srv  sys  tmp  usr  var  vmlinuz  vmlinuz.old
$ sudo su -
# ls /etc
[...]

/var/log/audit/auditd.log を読み取って、どのコマンドがログに記録されたかを確認してください。

2>&-、2>/dev/null、|&、&>/dev/null、および >/dev/null 2>&1 の違いを説明してください。

エラー出力やファイルディスクリプタについて
とっさに聞かれてもわからないかも

答え
  • 番号 1 = 標準出力(STDOUT
  • 番号 2 = 標準エラー(STDERR
  • 明示的に番号が指定されていない場合、シェル(bash)はデフォルトで番号 1を使用します。

これらの機能について説明します。

2>&-

一般的な形式は M>&- で、ここで "M" はファイルディスクリプタ番号です。これは、指定されたファイルディスクリプタ "M" の出力を閉じます。

2>/dev/null

一般的な形式は M>/dev/null で、ここで "M" はファイルディスクリプタ番号です。これは、ファイルディスクリプタ "M" の出力を /dev/null にリダイレクトします。

2>&1

一般的な形式は M>&N で、ここで "M""N" はファイルディスクリプタ番号です。これは、ファイルディスクリプタ "M""N" の出力を単一のストリームに結合します。

|&

これは 2>&1 | の省略形です。Bash 4 で追加されました。

&>/dev/null

これは >/dev/null 2>&1 の省略形です。ファイルディスクリプタ 2(STDERR)とファイルディスクリプタ 1(STDOUT)の出力を /dev/null にリダイレクトします。

>/dev/null

これは 1>/dev/null の省略形です。ファイルディスクリプタ 1(STDOUT)の出力を /dev/null にリダイレクトします。

有用なリソース:

nohup、disown、& の違い。すべてを一緒に使用した場合にどうなりますか?

似たようなものの細かい違いについて
nohup &はよく使われますがどのような違いがあるのでしょう

答え
  • & はジョブをバックグラウンドで実行し、入力の読み込みをブロックし、シェルがジョブの完了を待たないようにします
  • disown はプロセスをシェルのジョブ制御から削除しますが、ターミナルへの接続は維持されます。これにより、シェルはプロセスにSIGHUPを送信しなくなります。明らかに、これはバックグラウンドジョブにのみ適用されるため、フォアグラウンドジョブが実行中にこの操作を行うことはできません
  • nohup はプロセスをターミナルから切り離し、その出力を nohup.out にリダイレクトし、SIGHUP から保護します。効果の1つ(名前に関連するもの)は、プロセスが送信されたSIGHUPを受け取らなくなることです。ジョブ制御とは完全に独立しており、原理的にはフォアグラウンドジョブにも使用できます(ただし、あまり便利ではありません)

これらをすべて一緒に使用すると、プロセスはバックグラウンドで実行され、シェルのジョブ制御から削除され、ターミナルから効果的に切り離されます。

inodeに格納されているフィールドはどれですか?

inodeの話
どのような情報が入っているかはよく知らない人も多いハズ

答え

POSIXシステム内では、ファイルには次の属性があり、stat システムコールによって取得できます:

  • デバイスID(これはファイルを含むデバイスを識別します。つまり、シリアル番号の一意性の範囲です。)

  • ファイルモード(ファイルの種類と、ファイルの所有者、そのグループ、および他のユーザーがファイルにどのようにアクセスできるかを決定します)

  • リンクカウント(inodeを指すハードリンクの数を示します)

  • ファイルのユーザーID

  • ファイルのグループID

  • ファイルがデバイスファイルの場合、そのデバイスID

  • ファイルのサイズ(バイト単位)

  • タイムスタンプ(inode自体が最後に変更された時刻(ctime、inode変更時間)、ファイル内容が最後に変更された時刻(mtime、修正時間)、最後にアクセスされた時刻(atime、アクセス時間))

  • 推奨されるI/Oブロックサイズ

  • このファイルに割り当てられたブロックの数

カーネルの種類とその違いを説明してください。

カーネルに種類あったんだ…

答え

モノリシックカーネル

従来のこのタイプのカーネルアーキテクチャでは、プロセス管理やメモリ管理、割り込み処理などの基本的なシステムサービスがカーネル空間内の単一モジュールにまとめられていました。このアーキテクチャには、以下のような深刻な欠点がありました:

  • カーネルのサイズが非常に大きい
  • メンテナンス性が低く、新しい機能を追加したりバグ修正を行うたびに、カーネル全体を再コンパイルする必要があり、数時間かかることもある

現代のモノリシックアーキテクチャでは、カーネルは動的にロードおよびアンロードできる複数のモジュールで構成されています。このモジュラーアプローチにより、OSの機能を簡単に拡張できるようになり、特定のモジュールに変更やバグ修正があった場合、関連するモジュールだけをロードおよびアンロードするだけで済むため、カーネルのメンテナンスが非常に簡単になりました。

Linuxはモノリシックモジュラーアプローチを採用しています。

マイクロカーネル

このアーキテクチャは、モノリシックアプローチで制御できなかったカーネルコードの増大に対応するために開発されました。このアーキテクチャでは、デバイスドライバの管理、プロトコルスタック、ファイルシステムなどの基本的なサービスがユーザー空間で実行されます。

このアーキテクチャでは、OSの基本サービスがユーザー空間の一部となり、システム内の他のプログラムがこれらのサービスを利用する際に、プロセス間通信(IPC)を介してサーバーとして実行されます。

例: デバイスドライバ、ネットワークプロトコルスタック、ファイルシステム、グラフィックスなどにサーバーがあります。マイクロカーネルのサーバーは、他のプログラムと同様にデーモンプログラムですが、一部のサーバーには物理メモリの一部にアクセスできる特権が与えられています。

ハイブリッドカーネル(モジュラーカーネル)

これは上記の2つの組み合わせであり、OSサービスがカーネル空間に存在し、メッセージパッシングやパフォーマンスオーバーヘッドがなく、ユーザー空間でサービスを実行することによる信頼性の向上もありません。

これは、MicrosoftのNTカーネル(最新のWindowsバージョンまで)で使用されています。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?