シェルスクリプトでQNAPからサーバーのバックアップをしようTips

こんにちは。
ジャンクPCを探すために、毎日ヤフオクとメルカリを巡回している系エンジニアです。
 
最近、社内システムのバックアップや構成変更等行いました。
AWS上のインスタンスであれば、EBSのスナップショットやS3へのデータ保存が比較的に容易に行うことができます。
他のクラウドサービスやVPS上で動作しているサービスに関しては、NASであるQNAPに保存を行うことにしました。
 
今回は、QNAPへ保存する際にバックアップを行うシェルスクリプトを作成したので、その際のTipsを紹介したいと思います。

QNAPって?

簡単にQNAPの紹介をします。
一言で言うとQNAPは、「GUI見やすいサービスいろいろあるLinuxベースのNAS」です。
 
ユーザー管理やアクセスマネジメント、VPN機能などが最初からついています。
Linuxベースでコンソールに入ることができるので、自分でNAS上で動作するスクリプトを作成することも可能です。

サーバーごとのアクセス設定やconfig

バッチ系の処理を行う際に、アクセス先のホスト名やSSH, SCPのユーザーパスなど定数の処理をどうするかという問題がでてきます。
以下のように書いてもいいのですが、いろいろな問題が出てきます。
 

 

  • ハードコードディングになってしまっている
  • 複数サーバーのバックアップを効率よく行うことができない
  •  
    などなど。

    この問題を解決するために、設定は別ファイルで持つのが良いと思います。
    そして、複数サーバーのバックアップを効率よく行うために、フォーマットを定めるのが良いでしょう。
    以下はJSONを利用した設定ファイルです。
     

     
    JSONオブジェクトをシェルスクリプトには、以下のコードを利用します。
     

     

    jqコマンドでJSONを扱っています。
    11行目ではダブルクオーテーションを値から削除しています。
     
    上記のような形でスクリプトを書けば割とスマートな感じになるんじゃないでしょうか。

    リモートアクセス方式

    リモートアクセス方法について、SSHにてリモートアクセスしコマンドを実行するためには、認証処理が必要になります。
    こちらに関しては公開鍵による認証ほぼ一択だと思います。
     
    パスワード認証をスクリプト上で頑張って実装することはできますが、先程のconfigファイルと合わせて鍵認証を行うほうが効率がいいです。
    ファイル転送をSCPで行うことで複数のアクセス情報を持つ必要がないということも利点です。
     
    バックアップ対象のサーバーたちに共通の秘密鍵を持つユーザーを作成すると、同じ認証情報を利用してアクセスすることができます。
    こちらに関してはセキュリティをどれくらい求めるかを考えて、各自で判断していただきたいと思います。
     

    リモートログインユーザーをどうするか

    バックアップ対象サーバーへのリモートログインユーザーはどうしようという問題です。
    こちらもセキュリティの問題に含まれます。
     
    もちろんrootユーザーを使用してもいいと思います。
    その場合、鍵の管理やIPアドレスでのアクセス制限をつけてセキュリティ強化を行うと安心でしょう。
    私が行ったのは以下の方法です。
     

  • 各バックアップ対象サーバーに同じ名前のユーザーを作成する(backupuserなど)
  • .sshディレクトリを作成し、共通の秘密鍵をauthorized_keyとして配置する
  • sudoが必要なコマンドに関してはsudoersにて権限を付与する
  •  
    tarコマンドやzipコマンドなど、バックアップユーザーが権限を持たないファイルを圧縮する場合にはsudoが必要になります。
    sudoに関しては次のセクションで注意点を説明します。

    リモートコマンドのTips

    以下は私が実際に使用している、バックアップの際にリモートコマンドを実行する際のスクリプトです。
     

     
    ヒアドキュメントを利用して一度に複数のコマンドを実行しています。
    各行の補足を以下で行います。
     

    1行目

    sshコマンドの「t」オプションはssh接続時にローカルの擬似端末を割り当てるオプションです。
    このオプションは複数回使用することで強制的に擬似端末を割り当てることができます。
    リモートでsudoコマンドを使う時、この擬似端末を要求されることがあるのでつけています。
    なくても動作するサーバーもあります。これはOSのバージョンやsudoのバージョンによって変わるようです。
     

    2行目

    一般的なmysqldumpです。
    一点だけ、「A」オプションはすべてのデータベースのダンプを行うオプションです。
    しかしAオプションではデフォルトで入っている「events」というテーブルが含まれません。
    「E」オプションをつけることでeventsテーブルを含めたすべてのデータベースをダンプすることができます。
    参考:https://qiita.com/crimson_21/items/6171a95f8ddb2861e2e6
     
    バックアップするデータベースが決まっているのであれば、データベース名を指定するほうがスマートだと思います。
     

    3, 4行目

    cdコマンドからのsudo tarコマンドです。
    tarコマンドは、圧縮対象ディレクトリを絶対パスで指定するとwarningがでます。
    絶対パスのディレクトリ構成含めてすべて圧縮するか判断できないからです。
    ですので、一度cdコマンドでバックアップ対象のディレクトリがある場所まで移動しています。
    これは以下のtarコマンドで以下のように書くことで代替可能です。
     

     
    「C」オプションでcdした場合と同じ結果となります。
     
    最後の標準出力と標準エラー出力を捨てている部分ですが、こちらがないとsudoコマンドがうまく動作しませんでした。
    詳しくは以下のリンクからどうぞ。
    参考:https://www.greptips.com/posts/1172/
     

    5行目

    sudo chownコマンドです。tarコマンドをsudo実行しているので、ファイルのオーナーがrootになっています。
    このままではscpのファイル転送を行うことができないので、ログインユーザーにパーミッションを変更します。

    その他のTips

    ファイルの整合性確認方法

    バックアップ対象サーバー上で圧縮したファイルと、NASで受け取ったファイルが同一かどうかを確認します。
    「sha1sum」コマンドを利用しました。「md5sum」コマンドもQNAPは利用可能です。
    以下整合性確認のスクリプトです。
     

     

    アラートメール送信

    バックアップ成功時や失敗時にメール送信機能がほしい場合は、「sendmail」コマンドでメール送信を行うと簡単です。
     

     

    QNAPのcronの設定

    わかりにくい部分ですが、
    /etc/config/crontab
    がcron設定ファイルの本体です。
    「crontab -e」で設定を行っても、定期的に本体のファイルで上書きをするので反映されません。
    /etc/config/crontab を編集し、
    # crontab /etc/config/crontab
    上記コマンドで設定を反映してください。
     

    cronの実行時カレントディレクトリ

    自分も1回ハマりましたが、cronで設定したスクリプトの実行時のカレントディレクトリは、
    スクリプト実行ユーザーのホームディレクトリです。
    ですので、スクリプトからの相対パスでコーディングしていたりすると失敗します。

    おわりに

    バックアップスクリプトというのは頻繁に書くものではないですが、ふとした時に似たようなスクリプトが必要になったりします。
    できるだけ再利用できる部品に分けて、ちょちょいと変更するだけでできるといいなーと思います。
     
    紹介した他にTipsや小技があれば教えてください。
    ではでは〜。

    この記事が気に入ったら
    いいね ! しよう

    Twitter で

    【採用情報】一緒に働く仲間を募集しています

    採用情報
    ページトップへ