やつらシンクロしやがった

おまとめ三行

少なくともこれだけやればlsyncdが動くぞ
第三、第四のslaveが現れても対応できる
順調にいけば数分で設定は完了します
AWSで複数台のサーバーを運用している場合、CodeDeployなどを使ってソースを最新の状態にしたりすることがあるかと思うのですが、そんなにたくさんのサーバーを管理しているわけじゃないのなら、例えば二台くらいだったら、lsyncdを使ってサーバー間でファイルを同期させる方法も考えられます。

lsyncd自体はずっと前からある技術なんで、調べれば使い方に関する情報はいくらでも手に入るんですが、逆にありすぎるせいで情報が錯綜し、結果的に設定がめんどい印象を受けなくもない。でもどうせ使うんだったらパパッと簡単に使いたいですよね。めんどいんだったらそれこそおとなしくCodeDeploy使っとけば良いだろって話だし。

ということで、今回はなるべく簡潔に、少なくともこれだけやればlsyncdが動くぞという、アムロが初めてガンダムを動かした時くらいに最短最速の(?)手順でlsyncdの設定を完結させたいと思います。

条件は以下の通り。

・EC2のインスタンス二台でファイルを同期
・片方のサーバー(以下master)にファイルをアップロードしたらもう一方のサーバー(以下slave)に同期させる

EC2のインスタンスの作成方法は今回は省略します。すでに二台のサーバーが用意できているという前提で進めますんで夜露死苦。



同期するフォルダを作成

まずはファイルの同期を行うフォルダをmasterとslaveに先に作っておきます。ここでは「/var/test」というフォルダをそれぞれのサーバーに作ります。

//rootユーザーに切り替え
$ sudo su -

//フォルダを作成
$ mkdir /var/test

//slaveの場合は所有者を変更
$ chown ec2-user:ec2-user /var/test

できたてのサーバーはフォルダの権限が基本的にrootになってると思うんで、ec2-userがフォルダを作成しようとしてもパーミッションがどうとか言われるかもしれない。なのでsudoコマンドを使うかrootユーザーに切り替えてroot権限でフォルダを作成します。

masterはフォルダの所有者がrootのままでも大丈夫ですが、slaveの方はec2-userにしといてください。フォルダのパーミッションを777にするとかでも良いけど、とにかくec2-userユーザーの書き込み権限を有効にしておいてくれいってことです。



(master)公開鍵の作成

次に公開鍵を作成します。SSHでmasterに接続して「ssh-keygen」コマンドで公開鍵を作成し、その内容をメモします。

//rootユーザに切り替え
$ sudo su -

//コマンドを実行
$ ssh-keygen -t rsa

//鍵ファイルを作るパスを設定
Enter file in which to save the key (/root/.ssh/id_rsa):

//鍵ファイルにパスワードを設定
Enter passphrase (empty for no passphrase):
Enter same passphrase again:

//公開鍵ファイルを開いて中身をコピペ
$ cat /root/.ssh/id_rsa.pub

先ほど同様、作業はroot権限で行います。コマンドを実行すると鍵ファイルの置き場所やパスワードの設定を求められると思いますが、別に何も入力しなくて大丈夫です。そのままエンターを押せばオッケー。

鍵の作成が完了すると「/root/.ssh/」というフォルダの中に「id_rsa.pub」という公開鍵ファイルができるので、catコマンドとかでファイルを開いて中身をまるっとメモ帳などにコピペしておきます。



(slave)公開鍵のコピー

今度はSSHでslaveに接続して、先ほどコピペした内容を「authorized_keys」というファイルにつけ足します。これはroot権限で実行しなくても良いです。

//viモードでファイルを開く
$ vi /home/ec2-user/.ssh/authorized_keys

//コピペした内容を追加して保存
:wq

authorized_keysというのも公開鍵ファイルです。ファイル名が違うんでややこしいですが、ようはmasterで作成した公開鍵をslaveに引っ越しさせるってことですね。

authorized_keysを開くと最初から「ssh-rsa うんたらかんたら」っていう内容が書かれていますが、それを消して上書きしちゃうと通常のSSHでの接続ができなくなってしまうんで、それは残したまま、下に追加する感じで。



これでmasterからslaveにSSHで接続できる状態になりましたので、再びmasterに戻って、sshコマンドを実行してみましょう。

//masterからslaveに接続
$ sudo su -
$ ssh ec2-user@slaveのプライベートIP

@の後ろはパブリックIPじゃなくてプライベートIPね。

もしも上手くつながらない場合は公開鍵認証の設定の問題かもしれないので、後述のおまけ1を試してみてください。



(master)lsyncdをインストール

これでmaster ー slave間の開通式が無事に終わりましたので、いよいよlsyncdのインストールに入ります。masterに戻ってlsyncdをやむりましょう。

//rootに切り替え
$ sudo su -

//EPELリポジトリをインストール
$ yum install https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm

//lsyncdをインストール
$ yum install --enablerepo=epel lsyncd

lsyncdは通常のyumではインストールできません。なので先にEPELリポジトリをインストールします。「EPELリポジトリってなんぞ?」って方は……すまん、俺も詳しいことは分からん。

ちなみにEC2にEPELをインストールする方法はAWSの公式のサポートにも情報が載ってます。

https://aws.amazon.com/jp/premiumsupport/knowledge-center/ec2-enable-epel/

EPELリポジトリがすでにサーバーに入っていればリポジトリのインストールは必要ないです。「/etc/yum.repos.d」というフォルダの中に「epel.repo」ってファイルがあればすでにインストールされている状態です。



lsyncdのインストールが終わったらetcフォルダの中にlsyncd.confというファイルができているので、viモードで開いて必要な設定を書き込む。

//ファイルを開く
$ vi /etc/lsyncd.conf

//以下の設定を記述
settings {
  logfile = "/var/log/lsyncd/lsyncd.log",
  statusFile = "/var/log/lsyncd/lsyncd.status",
  nodaemon = false,
}

sync {
  default.rsync,
  source="/var/test/",
  target="ec2-user@slaveのプライベートIP:/var/test/",
  rsync={
    archive = true,
  },
}

大事なのは「source」と「target」ですね。sourceには同期させたいフォルダを書きます。targetは同期先のホスト名とフォルダをコロンでつなげて書く。「host」と「targetdir」という項目に分けて書いたりもできるのですが、その辺は今は置いとこう。

これで設定は完了なので、lsyncdを起動させて同期を開始します。

$ service lsyncd start

特にエラーが出なければ同期できる状態になっているので、master側で適当にtestフォルダの中にファイルを作成してみてください。slave側にも同じファイルが作られているはずです。

もしエラーがあったりした場合はログファイルにエラーの内容が書き込まれているので、そこで確認できます。ログファイルは「logfile」で指定した場所にあります。上記の場合だと「/var/log/lsyncd/lsyncd.log」ですね。



lsyncd自体のエラーではないのですが、こんな(↓)メッセージが出て上手く起動ができなかった場合。

Redirecting to /bin/systemctl start lsyncd.service

どうやら新しいOSではserviceコマンドが「systemctl」とかいうやつに変わってるみたいです。

$ systemctl start lsyncd.service

これで起動するはず。



おまけ1

masterからslaveにSSH接続するところがもしも上手くいかなかった場合は、公開鍵での認証が禁止されている状態かもしれません。その場合はsshd_configというファイルで公開鍵認証を許可すればつながるようになると思います。

//sshd_configファイルを開く
$ vi /etc/ssh/sshd_config

//公開鍵認証を許可
PubkeyAuthentication yes

//sshdを再起動
$ service sshd restart

僕の場合は「PubkeyAuthentication」がコメントアウトされたままでも特に問題なくつながったのですが……OSのバージョンとかの関係なのかな?



おまけ2

今回は二台での話でしたが、もしも三台目にも同期させたい場合。masterでファイルを更新したらslave1とslave2に同期させたいって場合は、lsyncd.confに設定を追加すればオッケーです。

settings {
  logfile = "/var/log/lsyncd/lsyncd.log",
  statusFile = "/var/log/lsyncd/lsyncd.status",
  nodaemon = false,
}

//slave1の設定
sync {
  default.rsync,
  source="/var/test/",
  target="ec2-user@slave1のプライベートIP:/var/test/",
  rsync={
    archive = true,
  },
}

//slave2の設定
sync {
  default.rsync,
  source="/var/test/",
  target="ec2-user@slave2のプライベートIP:/var/test/",
  rsync={
    archive = true,
  },
}

もうちょい共通する部分をまとめる書き方もできたと思うが……とにかくこんな感じで追加してけば第三、第四のslaveが現れても対応できるってことです。






最速最短と言いつつもわちゃわちゃと説明が入ってるせいで結果的にはだいぶ長くなっちゃいましたが、作業自体はそこまで多くないので、順調にいけば数分で設定は完了します。

lsyncd.confの詳しい中身についてはあまり触れませんでしたが、書き方次第で特定のフォルダは同期させないとか結構いろいろと設定できます。あと今回のやり方はmasterからslaveへの一方通行な同期ですが、双方向に同期させることもできるようです。ただそこまでは僕も試してないので、双方向にやりたいって場合はすみませんが他の方の情報を参考にしてください。

僕個人としてはソースコードを同期させるだけなら双方向にする必要ってあまりないように思うんだけどな……ファイルをアップするときは常にmasterからってルールを決めとけば。