Ansibleの概要メモ
Ansibleもくもく会に参加したので学んだことを自分の整理のためメモしておきます。
目次
- Ad-hocコマンド
- playbook
- variables
- Facts
- conditionals
- handlers
- simple loops
- loops over hashes
- templates
- roles
Ad-hocコマンド
AnsibleはPlaybookでの実行だけでなく、Ad-hoc的にコマンド実行もできます。
$ ansible [node名 or グループ名] -m ansibleモジュール -a オプション
以下は、commandモジュールを利用する例です。実行したいlinuxコマンドを-aオプションに書きます。この場合、node1で"id"コマンドを実行します。
$ ansible node1 -m command -a "id"
ansible-docコマンド
ansible-docコマンドを実行すると、ansibleで利用できるモジュールを調べることができます。
利用できるモジュールを一覧表示をする
$ ansible-doc -l
あるモジュールの利用方法を調べる
$ ansible-doc モジュール名
playbook
playbookには3つの重要な要素があります。
- hosts: tasksで定義したタスクの実行対象ホストを定義する
- tasks: 実行するタスクを定義する。モジュールと、モジュールに必要なオプションを記述する。
- become: タスクの実行にroot権限が必要な場合にyesを記述する。
apacheをインストールするplaybookの例
--- - name: Apache server installed hosts: node1 become: yes tasks: - name: latest Apache version installed yum: name: httpd state: latest
ansible-playbook --syntax-checkでシンタックスエラーがないかをチェックできる
$ ansible-playbook --syntax-check apache.yml
variables
ansibleでは変数を利用できます。以下のように{{ }} で囲うと変数を展開することができます。
{{ variable }}
変数の定義は、様々な箇所でできます。しかし、host_varsとgroup_varsの2つのディレクトリを作成するのがおすすめらしいです。
- group_vars/配下にはあるグループ共通で利用する変数を定義する
$ cat ~/ansible-files/group_vars/web.yml --- stage: dev
- host_vars/配下にはあるnodeに特有の変数を定義する
$ cat ~/ansible-files/host_vars/node2.yml --- stage: prod
- 以下のようにplaybook内で変数を利用できる
--- - name: Copy web.html hosts: web become: true tasks: - name: copy web.html copy: src: "{{ stage }}_web.html" dest: /var/www/html/index.html
この時、group_vars/web.htmlよりも、host_vars/node1.ymlのほうが優先して利用されます。
Ansible Facts
Ansible Factsは、Ansible実行時に、対象のサーバーからデフォルトで取得する変数のことです。取得された変数はplaybook内で利用することができます。
*デフォルトで取得される Factsの一覧を確認する
$ ansible node1 -m setup
- 特定のFactsの内容だけを確認する
$ ansible node1 -m setup -a 'filter=ansible_eth0'
以下のように、Factsを変数として利用することで、IPアドレスなどの実行対象サーバー 固有の値に設定してTaskを実行できます。
--- - name: Output facts within a playbook hosts: all tasks: - name: Prints Ansible facts debug: msg: The default IPv4 address of {{ ansible_fqdn }} is {{ ansible_default_ipv4.address }}
conditinos
playbookの中で条件式を使うことができます。例えば、webというインベントリーグループにあるホストだけにnginxインストールすることができます。
handlers
handlersでは、playbook実行により、システムに変更が加わった時にだけ、あるタスクを呼び出すことができます。 例えばapacheの設定ファイルを変更した時に、設定を反映するために、apacheを再起動することができます。
--- - name: manage httpd.conf hosts: web become: true tasks: - name: Copy Apache configuration file copy: src: httpd.conf dest: /etc/httpd/conf/ notify: - restart_apache handlers: - name: restart_apache service: name: httpd state: restarted
Locust でhtml reportの出力を試す
Locust でhtml reportの出力を試す
locust v1.4.2からhtmlを出力するオプションが追加されたので試してみました。--headlessオプションをつけてGUIなしで実行したときには結果が見にくいなと思っていたのでとても便利だと思います。
■locustを最新のv1.6.0にバージョンアップ
pi@raspijuichi:~/Locust$ pip3 install -U locust pi@raspijuichi:~/Locust$ locust -V locust 1.6.0
■--htmlオプションを付ける
pi@raspijuichi:~/Locust$ locust -f locustfile.py --headless --html test.html -u 1 -t 60 -r 1 -H http://127.0.0.1 #印加終了後 pi@raspijuichi:~/Locust$ ls locustfile.py __pycache__ test.html
■test.htmlの内容
リクエストにfailがある場合にはFailures Statistics
の欄も出力される。
csvの出力を試す
--csv オプションをつけて実行する
pi@raspijuichi:~/Locust$ locust -f locustfile.py --headless --html test.html --csv test -u 1 -t 60 -r 1 -H http://127.0.0.1
4つのcsvファイルが出力される。
#印加終了後 pi@raspijuichi:~/Locust$ ls locustfile.py __pycache__ test_exceptions.csv test_failures.csv test.html test_stats.csv test_stats_history.csv
感想
locustでGUIを利用しない時には、--html
オプションやcsv
オプションをつけて実行すると結果出力できる。
とりあえず--htmlオプション
を出力しておけばよさそう。
Locustでmaster-worker構成で分散試験を試す
Locustでmaster-worker構成で分散試験を試す
2021/07/04
概要
Locustで分散試験を試してみました。サーバー1台ではリソース不足で大量のリクエストを実行することが難しいので複数台のサーバーで試験を実施する必要があります。マルチコアのマシンで複数プロセスを立てて分散試験をすることもできます。
今回はマルチコアのマシンで分散試験を試してみました。ほとんど--master
オプションと--worker
オプションをつけてlocustを実行起動するだけなので簡単です。
参考
環境
■locustのバージョンは1.3.2
■nginxが80番ポートでリクエストを待ち受けている。ここに対してリクエストを実施する。
pi@raspijuichi:~$ curl http://127.0.0.1:80 <!DOCTYPE html> <html> <head> <title>Welcome to nginx!</title> <style> body { width: 35em; margin: 0 auto; font-family: Tahoma, Verdana, Arial, sans-serif; } </style> </head> <body> <h1>Welcome to nginx!</h1> <p>If you see this page, the nginx web server is successfully installed and working. Further configuration is required.</p> <p>For online documentation and support please refer to <a href="http://nginx.org/">nginx.org</a>.<br/> Commercial support is available at <a href="http://nginx.com/">nginx.com</a>.</p> <p><em>Thank you for using nginx.</em></p> </body> </html> pi@raspijuichi:~$ curl http://127.0.0.1:80
■シナリオ
pi@raspijuichi:~/Locust$ cat locustfile.py from locust import HttpUser, task, constant_pacing class HttpMeasurementUser(HttpUser): wait_time = constant_pacing(1) @task def get_nginx_welcom_page(self): self.client.get("/")
まずは分散試験ではない通常のやり方で印加してみる
■実行コマンド
pi@raspijuichi:~/Locust$ locust -f locustfile.py --headless -u 1 -t 60 -r 1 -H http://127.0.0.1
master-worker構成で分散試験をする
#master pi@raspijuichi:~/Locust$ locust -f locustfile.py --master #slave locust -f locustfile.py --worker --master-host=127.0.0.1 #masterのUIを開いてユーザー数とspawnrateとホストを指定して実行 http://<masterノードのip or ホスト名>:8089
→ユーザーは各ノードで均等に作成される。(例)worker2台で10ユーザーを印加すると、1台5ユーザーできる。
cronとanacronの違い
cronとanacronの違い
- cron
- デーモンプロセスが常駐する(crond)
- 分単位で実行を指定することができる
- 指定した時間通りに実行する
- 実行時にサーバーが停止していたときなど、何らかの原因で実行されなかった場合、次の実行タイミングまで実行されない
- 各ユーザーごとに設定できる
- anacron
- デーモンプロセスは常駐しない
- 一日単位でしか指定できない。最高で一日一回しか実行できない
- 指定した時間に加えて、「ランダム時間」をプラスしてジョブを実行する
- ジョブの実行に失敗した場合は、再度実行する
- rootユーザーのみ設定できる
試して理解 Linuxのしくみを読んだ時のメモ
「試して理解Linuxのしくみ」を読んだ時のメモです。 実際にコードを実行しながら学ぶことで、プロセス、メモリ、ストレージ周りのしくみの理解が深まりました。しくみがわかることでシステムのトラブルシューティングなどに役立つのかなと思います。
2章 ユーザーモードで実現する機能
- CPUにはユーザーモードとカーネルモードがある。
- ユーザーモードで動くプログラムには、プロセスに固有のプログラムやOS外のライブラリやOSのライブラリなどがある。
- カーネルモードで動くプログラムは、「プロセスの生成や削除、メモリの確保開放、プロセス間通信や、ネットワーク、ファイルシステムの操作、ファイル操作(デバイスアクセス)」がある。これらの処理を実現したいときには、ユーザーモードで動くプロセスがシステムコールを介してカーネルに処理を依頼する。この時、CPUの状態がカーネルモードに遷移して処理が実行される。
sarコマンドでプロセスがユーザーモードとカーネルモードどちらで実行しているかの割合を確認できる。sarコマンドは、システムの負荷状況を確認するコマンドで、過去に遡って情報を取得することができる。%systemがカーネルモード。%userと%niceがユーザーモード。%niceはnice値の変更により、優先度を変更されたプロセスが実行された割合。
- システムコールを呼び出す際には、各言語に用意されたシステムコールラッパー関数を利用する。もしもラッパー関数が存在しなかったら、アセンブリ言語でシステムコールを呼び出すプログラムを自分で書かなければいけなくなり、大変。
- lddコマンドで、プログラムがリンクしているライブラリを確認できる。
glibcは標準Cライブラリであり、システムコールラッパー関数も含んでいる。pythonは内部的に、libcをリンクしている。
straceコマンドでプログラムが呼び出すシステムコールを確認できる。
3章 プロセス管理
Linuxにおいて、プロセス生成には2つの目的がある
fork関数とexecve関数が使われる。
fork関数は、親プロセスをもとに子プロセスを生成する。親プロセスのメモリから子プロセスのメモリを複製し、親プロセスと子プロセスが違うコードを実行するように分岐する。
execve関数は、全く別のプログラムを生成するのに使われる。execve関数を発行したプロセスのメモリの内容を、実行ファイルのデータで上書きして新規のプロセスを生成する。このようにexecve関数では、プロセスの数は変わらず、あるプロセスを別のプロセスに置き換える。
_exit関数は、プログラム終了時に利用される。プロセスに割り当てていたメモリをすべて回収する。
4章 プロセススケジューラー
- プロセススケジューラーとは、複数のプロセスを同時に動作させるためのLinuxカーネルの機能(実際には順番に一定時間CPU時間を割り当てられて実行する)
- 一つのCPU上で同時に処理するプロセスは一つだけ
- 複数プロセスが実行可能な場合、個々のプロセスを適当な長さの時間(タイムスライス)ごとにCPU上で順番に処理する
プロセスの状態
- 実行状態(現在論理CPUを使っている)
- 実行待ち状態(CPU時間の割当を待っている)
- スリープ状態(何らかのイベントが発生するのを待っている。イベント発生までCPU時間は使わない。)
- ゾンビ状態
CPUのアイドル状態とは、アイドルプロセスという特殊なプロセスが割り当てられてCPUの動作が休止している状態。実行待ち、実行状態のプロセスが存在しない時にアイドル状態になる。sarコマンドのidleの部分。
- コンテキストスイッチとは、論理CPU上で動作するプロセスが切り替わること。頻繁に発生するとオーバーヘッドにより性能が低下する。
- スループットは、単位時間あたりの総仕事量。高いほどよい
- レイテンシは、それぞれの処理開始から終了までの経過時間。短いほどよい。
- 複数の論理CPUが存在する場合には、ロードバランサー、グローバルスケジューラー機能によって、プロセスを公平に分配する。
- timeコマンドで、プロセスの開始から終了までの経過時間と、プロセスが実際に論理CPUを使用した時間を確認できる。
- nice()システムコールでプロセスの実行優先度を変更できる。0がデフォルト。-19~20で数値が低いほど優先度が高い。rootユーザーだけ優先度を高くできる。システムに存在するプロセスは平等にCPU時間を得るが、nice値を変更することで特定のプロセスのCPU時間を増減させることができる。
わからないこと
- ゾンビ状態
ゾンビプロセスをなかなか見ることができない理由 | NHN Cloud Meetup
5章 メモリ管理
- Linuxカーネルのメモリ管理システムでシステムに搭載されている全メモリを管理している。
- Out Of Memoryとは、開放可能なメモリ領域もない状態でメモリ使用量がいっぱいになること。この時、メモリ管理システムはOOM killerという機能により適当なプロセスを選んで強制終了する。この挙動はOOM発生時にシステムを強制終了に変更することができる。
- Linuxではプロセスにメモリを割り当てる際に、物理メモリのアドレスを直接割り当てるのではなく、仮想メモリアドレスを割り当てる。プロセスは仮想メモリアドレスを介して間接的に物理メモリにアクセスする。
- 仮想メモリアドレスと物理メモリアドレスのマッピングの情報は、カーネルのメモリのページテーブルに保持される。ページテーブルの一つの対のデーターをページテーブルエントリーと呼ぶ。
- 仮想メモリアドレスを利用するメリット
- メモリの断片化を防ぐ
- 別用途のメモリへのアクセスを防ぐ
- マルチプロセスの扱いを簡単に
- ファイルマップは、ファイルの領域を仮想アドレス空間上にメモリマップする機能。ファイルの内容を物理メモリに読み出して仮想メモリアドレスにマッピングする。マップされた領域から読み出しや書き込みができる。その後、所定のタイミングでストレージデバイスのファイルに書き戻される。普通は、ファイルを開いてread()やwrite()のシステムコールでストレージ上のファイルを操作する。
- デマンドページングは、プロセスに仮想アドレスを割り当てるが、物理メモリの割当ては、仮想アドレス空間のページに最初にアクセスした時に実施する機能。これにより、無駄なメモリ消費を避ける。
- コピーオンライトは、プロセス生成のfork()システムコールを高速化する。親プロセスから子プロセスを生成時には、ページテーブルだけをコピーして親プロセスと子プロセスが共有のメモリを利用する。プロセスに書き込みを行う時に、実際にプロセスのメモリのコピーを作成する。
6章 記憶階層
記憶装置 (アクセス速度は上から順に速い) |
---|
レジスタ(CPU内) |
キャッシュメモリ(CPU内or外) |
メモリ |
ストレージデバイス |
キャッシュメモリは、CPUのレジスタ上での計算速度とメモリへのアクセス速度の差による遅延をなくすためのもの。メモリへのアクセス速度は、レジスタ上の計算に比べてとても遅い。そのため、計算が早くてもメモリへの読み書きの速度がボトルネックになり処理全体が遅延してしまう。キャッシュメモリからレジスタへのアクセスは、メモリからレジスタへのアクセスの数十倍高速である。メモリからレジスタへデータを読み出す際に、まずはキャッシュメモリがデータを読み込み、保存する。レジスタはキャッシュメモリからデータを読み込む。再度同じデータをCPUが読み出したい場合、キャッシュメモリから高速に読み出すことができる。
書き込みの場合は、CPUはレジスタで書き換えたデータをキャッシュメモリに書き込む。変更された(ダーディーである)という印をキャッシュライン(キャッシュメモリ上のデータ)につける。ダーティーなキャッシュラインはすぐにメモリに書き込まれず、所定のタイミングで書き込まれる。これをライトバックと呼ぶ。
ページキャッシュは、ストレージ上のファイルデータをメモリにキャッシュすること。プロセスがファイルデータを読み出す時、まずはカーネルのメモリ領域にファイルデータをページキャッシュとしてコピーする。そして、ページキャッシュをプロセスのメモリ領域にコピーする。再度、同じデータを読み出すときには、ページキャッシュからデータを高速に読み出すことができる。 書き込みの場合は、プロセスのメモリ上のデータを書き換えた後、ページキャッシュのデータだけを書き換えて、ダーティーマークをつけておく。ダーディなページは所定のタイミングでストレージに書き込まれる。これをライトバックと呼ぶ。
ページキャッシュはメモリに空き容量がある場合、作成され続ける。メモリの空き容量がいっぱいになってくると、ページキャッシュが解放される。解放の時は、ダーディーではないキャッシュを優先して解放する。足りない場合は、ダーディーなページをストレージに書き込んでから解放する。この時ストレージアクセスが生じるため、システム性能が劣化する。
sar -d -p コマンドで、ストレージデバイスごとにI/Oの統計情報を確認できる。
- sar -B コマンドでページインとページアウトの量の統計情報を確認できる。
- ページアウトは、ストレージからページキャッシュにデータを読み込むこと
- ページインは、ページキャッシュからストレージにデータを書き出すこと
7章 ファイルシステム
ファイルシステムとは、ストレージデバイス上のデータを名前、位置、サイズなどの情報を付加ファイルという単位で管理するもの。ストレージデバイス上のデータを扱いやすくする。
Linuxは、自身が動作しているハードウェア上のデバイスを、ほぼ全てファイルとして表現している。デバイスファイルは/dev以下にある。デバイスファイルも、通常のファイルと同様に、open(),read(),write()などのシステムコールを介してアクセスできる。デバイスファイルにはキャラクタデバイスとブロックデバイスの二種類がある。
fdiskコマンドでパーティションの作成、削除、情報表示ができる。
- tmpfsはメモリ上に作成するファイルシステム。ext4などのように好きなディレクトリにマウントできる。メモリ上にあるので電源を切るとファイルは消える。ストレージへのアクセスがなく高速にアクセス可能。再起動後に残る必要のない/tmpや/var/runにマウントされることが多い。
ネットワークファイルシステムは、リモートホスト上のファイルにアクセスする。windowsホスト上のファイルにはcifs。UNIX系OSホスト上のファイルにはnfsというファイルシステム。
procfs は、通常/proc以下にマウントされているファイルシステム。システムに存在するプロセスの情報やCPU、デバイス、リソース情報が保存されている。
df -a オプション サイズが 0 ブロックのファイルシステムや タイプがignore'または auto'のファイルシステムも リスト表示に含める (デフォルトでは省かれる)。例えば、procファイルシステムを表示できる。