name: overview class: title, smokescreen, shelf, no-footer # クラウドコンピューティング演習<br>〜サーバ操作の基礎〜 <div class=footnote> <small> 3年、秋学期後半(4Q)、選択 </small> </div> --- class: compact # はじめに <div class=footnote> <small> (脚注) 簡単な図は<B>手書き</B>でもなんでもよい。 業界人は<B>ポンチ絵</B>という。 業界外では通じないかな?とも思うけれど、 英国の雑誌パンチ (Punch, すでに幕末の日本にPunchもどきの雑誌があった)の一コマ漫画に由来する表現なので、 日本人なら誰にでもつうじるんではなくて? </small> </div> - 作業前に**ドキュメントと構成図**を書いてください。 ドキュメントとは言っても**簡単なメモ**と**簡単な図(ポンチ絵)**くらいでよいので、 作業内容をまとめておいてください - 作業直前にブリーフィング(briefing)はしたほうがいいとおもう <br> (もっとも一人作業だとしませんけども...) - 作業を**やりっぱなしにしない**こと - 作業後、ドキュメントに**変更点を反映**させておくこと <br> (**だいたい次の日には忘れてるもんだし**) --- class: compact # 課題1: システムの基本情報をまとめる <div class=footnote> <small> (脚注) SSH(Secure SHell) = 暗号化された論理回線でログインするプログラムおよびプロトコル名: いまではOpenBSDプロジェクトのOpenSSHが主要OSすべてに搭載されているので、 どのOSでも(Windows10ですらプロンプトで)sshコマンドが使えるはずです </small> </div> - ログイン先サーバ(いわゆる**踏み台**)の情報を入手する - これは顧客なり担当者なりに聞きます(その方法しかありません) - 以下がサーバの情報です。ワークシートの該当する欄を埋めましょう。なお、 ワークシートの図にある検索サイトは [http://os-ex.niij.fml.org/shop.html](http://os-ex.niij.fml.org/shop.html) でアクセス | 項目 | 詳細 | 備考 | |------------ |-------------------- |---------------- | | サーバ名 | os-ex.niij.fml.org | | | ポート番号 | 993/tcp | デフォルトの22/tcpではない | | プロトコル | SSH | | | 認証方法 | パスワード認証 | 今回のみ | | パスワード | | メールで送付済 | --- class: compact # システムにSSHでログインする - sshコマンドを`-l ユーザ名`と`-p ポート番号`オプションつきで実行 ``` $ ssh -l 学籍番号 -p 993 os-ex.niij.fml.org ``` - 注: $はプロンプト、実際に打ち込むコマンドはssh以降(右側) - 学籍番号はb29029290のような文字列、また入力後のENTERは省略してあります (雑誌だとデザイナーさんが書き込んでくれると思いますけどテキストではうまく書けない) ``` $ ssh -l 学籍番号 -p 993 os-ex.niij.fml.org The authenticity of host '[os-ex.niij.fml.org]:993 ([59.106.191.18]:993)' can't be established. ECDSA key fingerprint is SHA256:yQWqxzUbKsNDuA7SFn2j0bTUncDtLkvMJ/+opzmbydU. Are you sure you want to continue connecting (yes/no)? ``` - yesを入力してENTER(注: この情報を記録し、同名の偽サーバは警告してくれます) - このあと、パスワードの入力を求められるので事前情報のとおりに入力 --- class: compact # 課題2: システムを調査し構成図を埋めてください - 課題2: システムを調査し、ワークシートの構成図を埋めてみてください - 次ページ以降、調査に必要なコマンドの使い方の解説が続きます ![height480px](images/os-worksheet_09_figure.png) --- class: compact # 調査: プロセスの一覧を表示 - psコマンド(process statusの略)でプロセス一覧を表示出来ます <br> auxwwオプションが慣例的によく使うオプション(意味は各自しらべてください)なので、 実用上は、ひとつながりの`ps auxww`として覚えてOK ``` $ ps auxww USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 996 4 ? Ss 10:42 0:00 /sbin/docker-init -- /sandbox/entrypoint.sh root 8 0.0 0.0 2388 280 ? S 10:42 0:00 /bin/sh /sandbox/entrypoint.sh root 22 0.0 0.0 65660 1664 ? Ss 10:42 0:00 nginx: master process /usr/sbin/nginx www-data 23 0.0 0.1 66276 3916 ? S 10:42 0:00 nginx: worker process www-data 24 0.0 0.1 66276 3916 ? S 10:42 0:00 nginx: worker process www-data 25 0.0 0.2 66276 4664 ? S 10:42 0:00 nginx: worker process root 26 0.0 1.0 41552 21116 ? S 10:42 0:01 /usr/bin/python3 /var/www/libexec/www.py root 29 0.0 0.2 15852 4300 ? S 10:42 0:00 /usr/sbin/sshd -E /var/log/sshd.log -D root 82 0.1 0.1 5032 3584 pts/0 Ss 12:16 0:00 /bin/bash root 90 0.0 0.1 8804 3068 pts/0 R+ 12:17 0:00 ps auxww ``` --- class: compact # 調査: psコマンドの表示の意味 ``` $ ps auxww (抜粋) USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND root 1 0.0 0.0 996 4 ? Ss 10:42 0:00 /sbin/docker-init -- /sandbox/entrypoint.sh root 22 0.0 0.0 65660 1664 ? Ss 10:42 0:00 nginx: master process /usr/sbin/nginx root 26 0.0 1.0 41552 21116 ? S 10:42 0:01 /usr/bin/python3 /var/www/libexec/www.py ``` - **USER**がコマンドを実行したユーザ、PIDは**プロセスID**(プロセスの識別番号)、 また各行最後(右端)の文字列が実際に実行したコマンドです。 なお、サーバプロセスでは、 psで表示される文字列を変更し、付加情報を付け加えたりなどすることも多いです。 この例ではPID 22のnginxが**マスター**プロセスだ!と表示してくれていて親切 - その他の情報(とりあえず今は無視してよい): %CPUはCPUの利用率、%MEM VSZ RSSはメモリ関係の情報、TTYは利用している端末、STARTは開始時間、TIMEは総実行時間 - 講義では取り上げませんでしたが**Unixプロセス群はPID 1を親とする木構造**です - この例ではPID 1が/sbin/docker-initです。 この名前で推測できるとおり、みなさん、じつはdocker上のコンテナイメージにログインしています - **PID 1はUnixで最初に作成されるプロセス**で、歴史的に**init**という名前のプログラム --- class: compact # 調査: pstreeコマンドでプロセスの木構造を表示 - pstreeという便利なコマンドがあります。 PIDを表示する-gオプションと、 コマンド名を詳しく表示する-aオプションをつけて実行してみましょう。 表示は次のとおり <br> **コマンド名,PIDの数字 (あれば詳細な引数やオプションこみのコマンド名を表示)** - PID 1 (この例ではdocker-init,1)をルートにした木構造なのが分かりますね? <br> 普通のOSではプロセスが数十個くらい表示されますが、 この環境は今回の演習に必須のプロセスのみ存在しているのでコンパクトです ``` $ pstree -g -a docker-init,1 -- /sandbox/entrypoint.sh ├─entrypoint.sh,8 /sandbox/entrypoint.sh │ ├─sshd,8 -E /var/log/sshd.log -D │ └─www.py,8 /var/www/libexec/www.py └─nginx,22 ├─nginx,22 ├─nginx,22 └─nginx,22 ``` --- class: compact # 調査: ssコマンドでサーバプロセスを調べる - 走っているプロセスたちは分かりましたが、どれがどのサーバに相当するものかよくわかりません。 たとえば、このpython3もサーバなの?とかも気になります - まずはssコマンドで、この環境がサーバとしてサービスしているものを調べます。 -l オプション(listenのL)はサーバらしきものを表示、 -4 はIPv4のみを、 -n はポート番号を数字で表示するという意味です。 サービス内容はポート番号で(**おおむね**)分かりますよね? **5列目(Local ...)の下3行(8080,80,22)はサーバらしきポート番号**です。 一方、127.0.0.11は普通使わないIPアドレスで、 インターネット側との通信はできない(ルーティングされてない)ため無視しておきましょう (これは実のところdockerの名前解決) ``` $ ss -l -4 -n etid State Recv-Q Send-Q Local Address:Port Peer Address:Port udp UNCONN 0 0 127.0.0.11:49209 0.0.0.0:* tcp LISTEN 0 128 127.0.0.11:42983 0.0.0.0:* tcp LISTEN 0 5 0.0.0.0:8080 0.0.0.0:* tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* ``` --- class: compact # 調査: lsofコマンドでサーバプロセスを調べる - 怪しげなサーバプロセスが無いか?を調べるにはssコマンドでサクッと調べるのが良いのですが、 プロセスとの対応関係がはっきりしません。 こういうときに便利なコマンドとして**lsof** (LiSt of Open Files)があります。 -n と -P オプションで数字での出力を促し、 -i 4TCP オプションはIPv4でTCPのサーバプロセスに限定するという意味です - 各行左端の「コマンド」と右端の「アドレス:ポート番号」に注目です。 `*:80`の`*`は**サーバの全IPアドレス**で**ポート番号80を待受(listen)している**と読みます - これでプロセスとポート番号の組み合わせ、 nginxが80/tcp、 www.py (pythonアプリ)が8080/tcp、 sshd (opensshサーバ)が22/tcpで待っていることが分かりました ``` $ lsof -n -P -i 4TCP COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME nginx 22 root 6u IPv4 675545 0t0 TCP *:80 (LISTEN) www.py 26 root 3u IPv4 675553 0t0 TCP *:8080 (LISTEN) sshd 29 root 4u IPv4 674529 0t0 TCP *:22 (LISTEN) ``` --- class: compact # 調査: ipコマンドでサーバのIPアドレスを調べる - 前ページで`*:80`の`*`は**サーバにある全IPアドレス**でしたが、 このサーバに付けられているIPアドレスは一体なにとなに?を確認するには**ip**コマンドを使います - **lo**:や**eth0**@if360:の**lo**と**eth0**(@より左側)が**ネットワークインターフェイス**です。 左端の「数字:」(1:や359:)部分に特別な意味はないので気にしなくてOKです - inet の次の部分がインターフェイスに付いているIPアドレスで、 **lo (ループバック)は 127.0.0.1/8**、**eth0 (自分に付けられたIP、インターネットへの出口)は 172.31.0.3/16** ``` $ ip address 1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000 link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00 inet 127.0.0.1/8 scope host lo valid_lft forever preferred_lft forever 359: eth0@if360: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc noqueue state UP group default link/ether 02:42:ac:1f:00:03 brd ff:ff:ff:ff:ff:ff link-netnsid 0 inet 172.31.0.3/16 brd 172.31.255.255 scope global eth0 valid_lft forever preferred_lft forever ``` --- class: compact # 調査: *:80は結局どういう意味だったのか? - 「`*:80`の`*`は**サーバにある全IPアドレス**」は、前頁のとおり次の2つのIPです - **lo (ループバックアドレス) = 127.0.0.1/8** - **eth0 (自分に付けられたIP) = 172.31.0.3/16** - よって`*:80`は次の意味になります - 127.0.0.1 で 80/tcp を listen - 172.31.0.3 でも 80/tcp を listen - ちなみに`*`と`0.0.0.0`は同義語なので、*:80を0.0.0.0:80と表示するコマンドもあります --- class: compact # 調査: ssコマンドで通信をすべて見る <div class=footnote> <small> (脚注) ヒント: では(2)(3)は何にあたるのでしょうか? </small> </div> - -a オプションで全ての通信を表示させることができます。 TCPの状態(State)に関わらず表示するので、 ESTAB(Established)だけでなくTIME-WAIT(終了しかけ)なども表示されます。 ちょうどブラウザが通信している(ESTABの)瞬間を見るのは難しいですが、 TIME-WAITの行で各セッションの名残りが見えています - たとえば(1)は27.133.139.44からnginx(80/tcp)へのセッションです(でした) ``` $ ss -a -4 -n Netid State Recv-Q Send-Q Local Address:Port Peer Address:Port tcp LISTEN 0 5 0.0.0.0:8080 0.0.0.0:* tcp LISTEN 0 128 0.0.0.0:80 0.0.0.0:* tcp LISTEN 0 128 0.0.0.0:22 0.0.0.0:* tcp LISTEN 0 128 127.0.0.11:35677 0.0.0.0:* tcp TIME-WAIT 0 0 172.31.0.3:80 27.133.139.44:48276 (1) tcp TIME-WAIT 0 0 127.0.0.1:8080 127.0.0.1:41046 (2) tcp TIME-WAIT 0 0 172.31.0.3:39482 172.31.0.2:3306 (3) ``` --- class: compact # 調査: ipコマンドでサーバのルーティング情報を調べる - ipコマンドは「ip サブコマンド 引数およびオプション」という形式で多くの操作が可能です。 ルーティングを調べるときはip routeを使います - このサーバではデフォルトルートが設定されているだけなんですね - 各行の左端がdestination(目的地)で、defaultとある行はデフォルトルートになります。 via の次のIPアドレスはルータのIPアドレスです。 dev eth0 は、 そのルータへ向かうパケットを送り出すインターフェイスが eth0 であることを意味しています - 172.31.0.0/16 dev eth0 の行は自分( eth0 )についているIPアドレス情報です ``` $ ip route default via 172.31.0.1 dev eth0 172.31.0.0/16 dev eth0 proto kernel scope link src 172.31.0.3 ``` --- class: title, smokescreen, shelf, no-footer # 調査: [その他] サーバのハードウエア情報(CPU, メモリ) <div class=footnote> <small> (注意) docker内から見えているハードウエアはdockerを走らせているサーバの最大リソース量ですが、 dockerで制限をかけていて、すべてのリソースは使えない可能性があります </small> </div> --- class: compact # 調査: [その他] サーバのハードウエア情報(CPU, メモリ) - 専用のコマンド群もあるのですが、/proc (procファイルシステム)でカーネルの情報が見えるようになっているので、 **cat**コマンドだけで、いろいろ分かります ``` $ cat /proc/cpuinfo processor : 0 vendor_id : GenuineIntel cpu family : 6 model : 61 model name : Intel Core Processor (Broadwell) ... 以下80行くらい続くので省略 ... $ cat /proc/meminfo cat /proc/meminfo |head MemTotal: 2042956 kB MemFree: 205044 kB MemAvailable: 1189376 kB ... 以下40行くらい続くので省略 ... ``` --- class: compact # 調査: [その他] サーバのハードウエア情報(ストレージ) <div class=footnote> <small> (脚注) たいていは / = 巨大なサーバは別としても、 いまどきのユーザ向けPCではファイルシステムを一つしか作成しないので、 ログインした先のファイルシステムは / になります </small> </div> - **df**(display free disk space)コマンドで、ストレージの概要がわかります。 引数でファイルシステムが指定できるので、**.** を指定すると、 いま作業しているディレクトリの情報 (ふつうはログインした先のホームディレクトリなどがある場所で、たいていは/)の容量がわかります - デフォルトはKBですが、-mオプションでMB単位にできます - 2列目がディスクの全容量です。 この例では全部で200MB、 そのうち19MB(全体の11%)が使用中で、 のこりは169MBであることがわかります ``` $ df -m . ファイルシス 1M-ブロック 使用 使用可 使用% マウント位置 overlay 198546 19193 169199 11% / ```