【連載01】206.SELinux設定Diabledを適用する為サーバを再起動する【Ansible 非同期処理】


当記事はケーススタディの連載となっています。目次は【こちら】です。
最新のソースコードは【GitHub】で公開中です。
サーバの責務はこちらで確認ください。

1.サーバ再起動概要

SELinuxのDiable設定を有効にする為、サーバを一度だけ再起動する。

2.playbookファイルの相関

3.playbook(site.yml)

${ANSIBLE_HOME}/site.yml
メインとなるplaybook(site.yml)参照

4.SELinux無効化適用のplaybook(/operations/0031_reboot.yml)

\${ANSIBLE_HOME}/operations/0031_reboot.yml

# ===================
# SELinuxのDisable設定を有効にするため再起動する(reboot.yml)
# ===================
# ===================
# 全てのサーバのSELinuxを無効設定を有効にするため再起動
# ===================
- hosts: adminserv01
  sudo: no
  remote_user: root
  tasks:
# ===================
# getenforeにてdisableが帰ってきた場合は再起動しないため確認
# regiter: selinux_resultはshellで表すと
# selinux_result = `getenforece`
# と同様
# registerが変数名でshellが実行したコマンド
# ===================
    - name: SELinuxのDisable状態の確認
      shell: "getenforce"
      register: selinux_result

  # ===================
  # (shellモジュール:)2秒スリープしたのち再起動する
  #
  # (async/pollモジュール:)「async=終了まで待つ時間」、「poll=終了までチェックする間隔」
  # asyncで指定しpollでのチェック間隔で終了チェックをし続け、終わらなければエラーとなる
  # 以下の場合、poll=0を設定しており、ポーリングは行われず且つasyncの時間を待たずに完全に非同期処理となり
  # 次のタスクを実行する
  #
  # (whenモジュール:)で上記で変数指定したselinux_resultのstdout(標準出力結果)
  # がdisable以外の場合のみ再起動する(whenはif文と同様)
  #
  # ignore_errorsは全てのサーバで【 shell: sleep 2 && shutdown -r now "サーバ再起動"】が失敗しても処理を終了せず
  # 次のタスクを実行するが、今回のようなshutdownは特別でSSH接続自体が出来なくなる為、ignore_errorsは効果が出ない
  #
  # 待たずに次のタスクを行う
  # ===================
     - name: SELinuxのDisableでない場合サーバ再起動
      shell: sleep 2 && shutdown -r now "サーバ再起動"
      async: 1
      poll: 0
#      ignore_errors: true
      when: selinux_result.stdout != "Disabled"

# ===================
# 上記のタスクはasyncモジュールを使用しているので完了前に当該タスクが呼ばれる事になる
# wait_for
# delayの値の間待機したのち
# hostの
# portに接続できるまで1秒(デフォルト)間隔で接続しに行く
# 以下の設定では
# inventory_hostname(Ansibleが設定しているサーバ)に対して20秒待ってから
# 22ポートに対して接続を300秒間(デフォルト)待ち続ける設定になる
# ただし、当該タスクも条件(whenモジュール)に指定の
# selinux_resultのstdout(標準出力結果)
# がdisable以外の場合のみ再起動する(whenはif文と同様)
# ===================
    - name: SELinuxのDisableでない場合サーバ再起動待ち
      local_action: wait_for host={{ inventory_hostname }} port=22 delay=10
      when: selinux_result.stdout != "Disabled"
shellモジュール

shellを実行する。commandモジュールより直感的に扱えたりパイプが使えたりするshellの方が高機能。

書式:

shell : \${実行するシェルコマンド} chdir=${シェルを実行する際に事前にcdするパス

例:

shell: "getenforce" 
registerモジュール

変数設定する。shell等のコマンドの実行結果を変数として保存。
保存した変数を使用して後続タスクを実行する/しないを判断するためのキーとして使用する。

shellのリターンコードを取得したい場合、
\${変数名}.rc
→実行したshellのリターンコードが返る
※bashでの\$?を取得した場合と同様になる。

${変数名}.stdout
→実行したshellの標準出力が返る
※bashでのaaaa = `ls(等のコマンド)`と同様になる。

書式:

register: \${変数名}

例:

register: selinux_lisult 
async/pollモジュール

該当タスクを指定間隔で指定時間終了を待って次のタスクを実行する
通常Ansibleはタスク内のモジュールは同期処理(そのタスクを行うすべてのサーバが完了するまで待つ)だが、asyncで秒数を指定するとその秒数まで終了を待つ。
終了したかのポーリングチェックはpollに秒数を指定する。

async=10でpoll=1の場合、10秒間の間中1秒毎に終了をチェックし、終了したら後続のタスクを実行する。終了しなかった場合はエラーとなる。
(ignore_errors=trueの場合はエラーでも後続処理に移動する。但しshutdown(再起動)のようなSSH接続自体が行えない場合はエラーとなる)

async=10でpoll=0の場合は10という数字は無視され poll=0(処理を待たない設定) のみ効き、完全なバックグラウンドでの非同期処理となる。 shutdown(再起動)を実行する場合などは何を待つ必要はない為、async=1 poll=0が良い。

書式:

async: \${当該タスクの終了まで待つ時間}

例:10秒間当該タスクの終了を待つ

async 10 

書式:

poll: \${asyncの諸元となるshellが終了しているかpolling(ポーリングチェックを行う)間隔秒数}

例:3秒毎に終了したかチェック

poll 3
ignore_errorsモジュール

エラー発生時に後続タスクを続けるかを指定する。
Ansibleデフォルトでは全てのサーバでエラーが発生した場合に処理が中断する為、通常はエラーがあっても無視をする場合に使う。

書式:

ignore_errors: \${true エラーが発生しても後続タスクを続行する}

例:

ignore_errors: true

以下のようなタスクを指定した場合、後続タスクは実行される。
「igonore_errors:false」又は「ignore_errors」を指定をしていない場合はエラーで終了する。

  • name: 存在しないファイルのmove
shell: mv /afdsdfdf/fdfsd /rwrwew/fdsfsd
ignore_errors:true
  • name: 処理続行確認
debug:msg="処理続行確認"
whenモジュール

別のタスクで定義した(regsiter)変数の状態を評価し、当該タスクを実行するか判断する。
whenモジュールはshellスクリプトや多数のプログラム言語で言うところのIF文。

書式:

when: \${regsiterで登録した変数 (== または =!) 状態}

例:

# register_varが0の場合実行
when: register_var == 0
#register_varが標準出力を伴うコマンドの時に標準出力された文字がOKの場合実行
when: register_var.stdout == "OK"
#register_varのコマンドリターンコードが0の場合実行
when: register_var.rc = 0
local_action wait_forモジュール

Ansibleを起動する端末(今回で言えばmanageterm)の操作を行う。
「local_action」の「wait_for」は対象のサーバを待つ処理となる。

例:

local_action: wait_for host={{ inventory_hostname }} port=22 delay=10
local_action
ローカルの端末での操作を行うモジュール
wait_for
接続を行うサーバ名を指定
{{ inventory_hostname }}
Ansibleがもつマジック変数で実行しているサーバ名が入る
port
接続するサーバのポート
delay
指定秒間待機した後1秒間隔でwait_forのサーバのportにSSH接続を試みる

次回は「Firewalldを一時的にストップする」について。

連載の目次は【こちら】です。