終電23時11分って早くね?

都内のIT企業で働くカラオケ大好きエンジニアの雑記

【Laravel Practice04】AnsibleでNTPサーバーを構築

f:id:blue_goheimochi:20160629162151p:plain

デプロイサーバーにNTPサーバーをAnsibleで構築してみます。
今回、仮想環境にはCentOS7を使っているので、chronyをインストールしてみます。

ntpdとchronyの違い

CentOS6まではデフォルトのNTPサーバーはntpdだったようですが、
CentOS7ではchronyが標準となっているようです。

大きな違いとしては

ntpd と chronyd の大きな違いの 1 つは、コンピューターのクロックを管理するために使われるアルゴリズムにあります。

とのことで、システムクロックをntpdより迅速に調整することが可能らしいです。

[参考]
第15章 chrony スイートを使用した NTP 設定

yumモジュールでchronyをインストール

今回作業したところは、以下のコミットログにまとまっていますのでご参照ください。
github.com
今回は、ansible/roles/chrony/tasks/main.ymlの1ファイルのみ追加しています。

- name: install chrony
  yum: name=chrony state=latest

Ansibleのyumモジュールでchronyをインストールする際の記述です。

$ sudo yum install -y chrony

と同等の処理が行われます。

Ansible yumモジュールのドキュメント
yum - Manages packages with the yum package manager — Ansible Documentation

他のパッケージをインストールしたい場合は、
たとえばhttpdであれば

- name: install httpd
  yum: name=httpd state=latest

と書けばOKです!簡単ですね。

デフォルトで設定されているNTPサーバーを無効にする

デフォルトで設定されているNTPサーバーを無効にします。
pool.ntp.orgのサーバーは世界中すべてのタイムサーバーを指定しているそうで、
時刻を精度よく保つためには近いゾーンのものを設定するのがよいみたい。
(あとで設定します)

[参考]
pool.ntp.org: プールを利用するためにNTPを設定する方法は?

chronyの設定ファイルは/etc/chrony.confに作成されていると思うので、これを今回はAnsibleのreplaceモジュールで操作してみます。

Ansible replaceモジュールのドキュメント
replace - Replace all instances of a particular string in a file using a back-referenced regular expression. — Ansible Documentation

- name: disable servers
  replace: >
    dest=/etc/chrony.conf
    regexp='^(server \d+.centos.pool.ntp.org iburst)'
    replace='# \1'

destで対象のファイルを指定して、
regexpでファイル内の変更したい箇所を正規表現で指定できます。
replaceは変換後の文字列ですね。

今回は、regexpでマッチする行の先頭に#がつくようにタスクを書いてみました。
2回目以降のAnsible実行の際は、正規表現に当てはまらなくなるので、変更はされません。
changedになってしまう場合は正規表現の書き方を変えてみるとよいと思われます。

日本のタイムゾーンのNTPサーバーを追加する

先述した通り、最も近い日本のタイムゾーンのNTPサーバーを設定します。

- name: add servers
  blockinfile:
    dest: /etc/chrony.conf
    state: present
    content: |

      # ntp servers
      server ntp.jst.mfeed.ad.jp iburst
      server ntp.nict.jp iburst

Ansible blockinfileモジュールのドキュメント
blockinfile - Insert/update/remove a text block surrounded by marker lines. — Ansible Documentation

blockinfileはAnsible 2.0から追加されたモジュールです。
複数行を追加したいときなんかに使います。

insertafter: '[対象の文字列(正規表現可)]'を指定すると対象の行の後に追加したりできますが、今回はファイルの一番最後に、NTPサーバーの設定を追記するようにしています。
詳しい書き方はAnsibleのドキュメントをご参照ください。

ntp.jst.mfeed.ad.jpntp.nict.jpの2つのNTPサーバーが日本標準時を提供してくれているのでそちらを指定させていただきました。

時刻同期を内部から許可する設定を追加

ローカルネットワークからのアクセスを許可する設定を追加します。

- name: add allow ntp client
  lineinfile: >
    dest=/etc/chrony.conf
    insertafter="#allow 192.168/16"
    line="allow 192.168.1.0/24"

Ansible lineinfileモジュールのドキュメント
lineinfile - Ensure a particular line is in a file, or replace an existing line using a back-referenced regular expression. — Ansible Documentation

今度はlineinfileモジュールを使ってみました。
1行の行追加の場合、こちらのモジュールを使うとよさそう。
#allow 192.168/16の下の行にallow 192.168.1.0/24を追加するタスクです。

サービスの起動と自動起動の設定

- name: chrony start and enable
  service: name=chronyd state=started enabled=yes

serviceモジュールを使って、chronydのスタートと自動起動の設定ができます。

Ansible serviceモジュールのドキュメント
service - Manage services. — Ansible Documentation

$ systemctl start chronyd
$ systemctl enable chronyd

のコマンドの実行と同様のタスクになります。
nameに対象のサービスを指定することで別のサービスに対しても実行可能です。

手動での時刻あわせ

手動での時刻あわせのコマンドを実行します。

- name: adjust the time
  shell: chronyc -a makestep
  changed_when: false

shellモジュールはその名前の通り、シェルコマンドを実行できるモジュールです。

Ansible shellモジュールのドキュメント
shell - Execute commands in nodes. — Ansible Documentation

shellモジュールを利用する場合、冪統制は自分で担保する必要があります。(と思います。。)
特に先述のファイルに何かを追加するような処理をshellモジュールで書くと、実行するたびに同様の記述がファイルに書き込まれてしまいます。

例)

- name: add hoge
  shell: echo 'hoge' >> /tmp/text.txt

このような場合実行するたびにhoge/tmp/text.txtに追記されてしまい、そのつど、changedのステータスになってしまいます。
Ansibleのモジュールにはそういう冪統制を担保してくれるものが多いと思うので、可能な限りAnsibleのモジュールに頼ったほうがよいでしょう。
様々なモジュールがあるのでぜひドキュメントを眺めてみてください。

今回の場合は、手動の時刻あわせのコマンドを実行することになりますが、これは毎回実行されても影響はないと考えます。(ファイルの書き込みとかは起こらないと思うので)
こういう場合は、changed_when: falseを指定しておくと必ず、okのステータスになりますので指定してみました。
changed_when: [条件]という風な指定で、条件に合致したときだけchangedとできるので、特定の条件がある場合はそのように記述しましょう。

以上、NTPサーバーを構築するときのAnsibleのタスクを説明してみました!
内容はボリューミーですが、Ansibleの基本っぽい部分が分かるのではないかなぁと思います。

Ansibleはドキュメントもしっかりしていて、日本語の情報も結構あるので、
「このコマンドに対応するモジュールはあるかな?」と思ったら検索してみてください!
大体あります。笑

まとめ

  • CentOS7はchronyが標準のNTPサーバー
  • ntpdよりchronydのほうが時間調整が早いらしい
  • Ansible yumモジュールの簡単な使い方
  • Ansible replaceモジュールの簡単な使い方
  • NTPサーバーはタイムゾーンが近いところを設定する
  • Ansible lineinfileモジュールの簡単な使い方
  • Ansible serviceモジュールの簡単な使い方
  • Ansible shellモジュールの簡単な使い方
  • shellモジュールを使うときは冪統制は自分で考えなきゃいけないから可能な限りAnsibleのモジュールを使うと楽
  • Ansibleはドキュメントがしっかりしてるので見るとはかどる

次回もAnsibleを使ってさらにデプロイサーバーの環境を整えます!
ユーザー追加とかを想定中。

ツッコミお待ちしております!!

初めてのAnsible

初めてのAnsible