Kubernetesのシステム要件に「swapがオフであること」というのがあるので、Ansibleつかってノードの準備を行う際に「swapが有効の場合には無効にする」というのを冪等になるようにやってみた。
対象はCentOS 7
taskの例
Ansibleモジュールに「swapのon/off」というのが見つからなかったので、手作業で無効にするときの操作をそのままPlaybookにしてみました。
だいたいこんな感じ
- name: get swap state shell: swapon -v register: swap_state check_mode: false changed_when: false - name: swap off shell: swapoff -a when: swap_state.stdout != '' - name: swap check (/etc/fstab) shell: grep -v "\s*#" /etc/fstab | awk '{print $2}' | grep swap -c register: swap_state_in_fstab check_mode: false changed_when: false ignore_errors: true - name: disable swap (/etc/fstab) replace: path: /etc/fstab regexp: ([^\s]+\s+swap\s+.*) replace: '# \1' when: swap_state_in_fstab.stdout != '0'
やっていることは以下の通り
現在のswap設定
swapが有効化かチェック
shell: swapon -v register: swap_state check_mode: false changed_when: false
swapが現在有効になっているかどうかはswapon -v
の結果で判断できます。
有効になっていればどのデバイスがswapに使用されているかが出力されますが、無効の場合は何も出力されません。
swapが有効な場合
[zaki@manager-dev ~]$ swapon -v NAME TYPE SIZE USED PRIO /dev/dm-1 partition 3.5G 0B -2 [zaki@manager-dev ~]$ echo $? 0
swapが無効な場合
[zaki@manager-dev ~]$ swapon -v [zaki@manager-dev ~]$ echo $? 0 [zaki@manager-dev ~]$
なのでここでは、swapon -v
を実行するだけで、その結果をregister
を使ってswap_state
に保持します。
また、ここは状態をチェックするだけで何も変更を加えないので、changed_when: false
によってchangedとならないようにしています。
加えて、--check
の場合はshell
はデフォルトで動作しないため、check_mode: false
で強制的に実行させます。
swapを無効化
shell: swapoff -a when: swap_state.stdout != ''
swapを無効化するにはswapoff -a
を実行します。
すでに無効化されてる状態で追加で実行してもまぁ問題はないのですが、せっかくAnsibleを使ってるので「有効だったら無効化する(changed)」「既に無効になっていれば何もしない(ok)」と冪等になるように、前段のswapが有効だった場合のみ実行するようにwhen
を使って「swapが有効だった場合(swap_state.stdout != ''
)」とします。
fstabの編集
上記の処理で現在のswap状態は無効となりますが、/etc/fstab
にswapのディスク設定が残っていると、OSリブート後にまた有効になってしまうので、設定を削除します。
ここでもswapoff
同様に、設定があれば無効化(なければ何もしない)という処理にしてみます。
fstabにswap設定があるかチェック
shell: grep -v "\s*#" /etc/fstab | awk '{print $2}' | grep swap -c register: swap_state_in_fstab check_mode: false changed_when: false ignore_errors: true
チェック処理自体はLinuxコマンドのgrep
とawk
で原始的に。
後の処理をやりやすいよう、-c
オプションを付けてカウント数を取得し、結果をregister
でswap_state_in_fstab
にセット。
前述のswapon -v
と同様に--check
でも動作するようにcheck_mode: false
と、結果がchnagedとならないようにchanged_when: false
を付与。
また、Linuxのgrep
コマンドは、ヒットしない場合はリターンコードが1となるため、swap設定が無い場合はAnsibleの処理的にはエラーとなってしまうため、ignore_errors: true
によって強制的にエラーを無視するようにしています。
fstabのswap設定をコメントアウト
replace: path: /etc/fstab regexp: ([^\s]+\s+swap\s+.*) replace: '# \1' when: swap_state_in_fstab.stdout != '0'
ここではAnsibleのreplaceモジュールを使って、/etc/fstab
ファイルのswap設定の行(設定行の2カラム目がswap
の行)の先頭に#
を入れる、というtaskを記述。
これは正規表現を使ってふつうに。
普通と言いつつ、「ヒットしたswap設定行をキャプチャ、置換先の文字列はキャプチャした文字列の先頭に#
を付加する」だと、繰り返し実行するとどんどん#
が付加され続けて冪等にならないので、前段の/etc/fstab
にswap行がある場合、にwhen
を使い条件を絞ってます。
対象行の削除でもいいけどね。
参考
- check_mode
- ignore_errors
- changed_when
たぶんもっといい書き方ありそう…
なんだけど、手作業の手順をAnsible化しつつ冪等性を考慮する、という題材にはちょうどよいかも。