ことぶきぶろぐ

日々の記録

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の内容

f:id:kotobuki39:20210704204412p:plain
htmlの出力内容

f:id:kotobuki39:20210704204533p:plain
htmlの出力内容2

リクエストにfailがある場合にはFailures Statisticsの欄も出力される。

f:id:kotobuki39:20210704204626p:plain
リクエストにfailがあった場合のhtml

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を実行起動するだけなので簡単です。

 参考

docs.locust.io

progrhy.me

環境

■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章 ユーザーモードで実現する機能

3章 プロセス管理

  • Linuxにおいて、プロセス生成には2つの目的がある

    • 同じプログラムの処理を複数のプロセスに分けて処理する(例 webサーバーによる複数リクエストの受付)。fork関数のみ使われる。
    • 全く別のプログラムを生成する。(bashから新規プログラムの生成)

    ​ 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章 ファイルシステム

SSL証明書の備忘

SSL証明書の備忘

SSL証明書まわりについて何度も忘れてググってを繰り返すので備忘としてメモを残しておきます。

SSL証明書の役割

  • 信頼できるサーバーで有ることを証明する。例えば、ドメイン認証の場合、ドメインの利用権を持っていることを証明する。ユーザーはアクセスしているURLが偽装されたものでないことを確認できる。
  • SSL証明書に含まれる「公開鍵」「共通鍵」、サーバー側の「秘密鍵」を利用して、ブラウザとサーバー間の通信データを暗号化する(HTTPS)

SSL証明書の種類

SSL証明書は3種類ある。種類によって認証項目が違う。EV認証が最も信頼性が高い。

HTTPS通信の流れ

  • ブラウザからサーバーにアクセス
  • サーバーからSSL証明書が送られてくる。SSL証明書にはサーバーの公開鍵が含まれている。中間認証局またはルート認証局秘密鍵で署名がしてある。
  • ブラウザが持っている認証局の公開鍵で署名を検証する。SSL証明書の正当性を確認する。信頼性のあるサーバーかどうかがわかる。
  • ブラウザは、証明書に含まれていたサーバーの公開鍵で共通鍵を暗号化しサーバーに送信する。
  • サーバーは、サーバーの秘密鍵により共通鍵を復号する。これ以降サーバーブラウザ間の通信は共通鍵による暗号化通信が行われる。