maintenanceサーバの構築

環境

環境 Ver.
OS 4.9.32-15.41.amzn1.x86_64
Apache 2.4

▼以下は既に適宜設定/構築されているものとする。

  • EC2起動/基本設定
  • 静的メンテナンスファイルとCSS/JSは “/var/www/html” 配下に配置。
  • “_Health_Check.html”を配置。
  • サーバーの基本設定Apacheの基本設定等が設定済み。
  • ELB HealthCheckも適宜設定済み。
$ cd /var/www/html
$ tree
.
├── _Health_Check.html
├── maintenance.html
└── resources

コンテンツの権限/所有者の変更

$ chown -R apache:apache /var/www/html
$ cd /var/www/
$ find html -type f -exec chmod 0644 {} \;
$ find resources -type d -exec chmod 0755 {} \;

503リダイレクト設定

/etc/httpd/conf.d/maintenance.conf

ErrorDocument 503 /maintenance.html
Alias /maintenance.html /var/www/html/maintenance.html
<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{REQUEST_URI} !^/resources/.*$
  RewriteCond %{REQUEST_URI} !^/maintenance.html$
  RewriteCond %{REQUEST_URI} !^/_Health_Check.html$
  RewriteRule ^.*$ /maintenance.html [R=503,L]
</IfModule>

サーバーへ反映する。

$ service httpd graceful

[Shell Script] DBバックアップ、S3へアップロード

S3バックアップ用IAMユーザーの作成

Management Consoleより、IAMのポリシーを作成し、ユーザーをアタッチする。

S3バックアップ用ポリシー例

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "Stmt1506579924000",
            "Effect": "Allow",
            "Action": [
                "s3:GetObject",
                "s3:ListBucket",
                "s3:ListBucketMultipartUploads",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:PutObjectAcl",
                "s3:PutObjectTagging",
                "s3:PutObjectVersionAcl",
                "s3:PutObjectVersionTagging",
                "s3:ReplicateDelete",
                "s3:ReplicateObject",
                "s3:RestoreObject"
            ],
            "Resource": [
                "arn:aws:s3:::{BUCKET_NAME}",
                "arn:aws:s3:::{BUCKET_NAME}/*"
            ]
        }
    ]
}
# AWS CLIからS3 APIへ接続
$ aws configure --profile s3-bk
AWS Access Key ID [None]:
AWS Secret Access Key [None]:
Default region name [None]: ap-northeast-1
Default output format [None]: text

# 確認
$ aws s3 ls s3://{BUCKET_NAME}/ --profile s3-bk

MySQL接続用ファイルの作成

mysql接続用のユーザー名/パスワードはスクリプト外のファイルで管理する。
./.access-db.conf

[client]
user     = "{DB_USER_NAME}"
password = "{DB_USER_PASS}"

権限を変更する。

chmod 0600 ./.access-db.conf

シェルスクリプト

変数は外部参照。
if文やエラー処理等は省略している。

#!/bin/bash
#
# Backup Database.
#
# Ex. sh database_backup.sh
#
###############################################

BK_PATH=/backups/databases
PROFILE=s3-bk
DB_NAME=test
DB_HOST=test.ap-northeast-1.rds.amazonaws.com
BUCKET_NAME_BACKUP="s3://{BUCKET_NAME}/"

if [ ! -e ${BK_PATH} ]; then
    mkdir -p ${BK_PATH}
fi

cd /root/scripts/backup_script

echo '~~~~~~~~~~~~ Start Backup ~~~~~~~~~~~~'

# MySQLdump DB server
mysqldump --defaults-extra-file=./.access-db.conf --databases ${DB_NAME} --default-character-set=utf8 --add-drop-database --host=${DB_HOST} > ${BK_PATH}/${DB_NAME}-dump.sql

# GZIP SQL files
# -C で絶対パスによるエラー出力を抑制
GZIP=-9 tar czf ${BK_PATH}/${DB_NAME}-dump-`date +%Y%m%d%H%M`.tar.gz -C / backups/databases/${DB_NAME}-dump.sql

echo '~~~~~~~~~~~~ Remove backup files more than 7 days ~~~~~~~~~~~~'
find ${BK_PATH}/ -name "*.tar.gz" -type f -mtime +7 | xargs rm -fv
rm -fv ${BK_PATH}/${DB_NAME}-dump.sql

# Sync S3
aws s3 sync ${BK_PATH}/ ${BUCKET_NAME_BACKUP} --acl private --profile=${PROFILE}

echo '~~~~~~~~~~~~ Finished Backup ~~~~~~~~~~~~'

exit 0
  • 外部ファイルから、DB(MySQL)接続ユーザーとパスワードは指定する。
  • 最高品質を保つ圧縮の”GZIP=-9″で”tar.gz”を作成。
  • 本日より7日前以上のファイルは削除。

Cronへ仕込み

$ crontab > /root/crontab
$ vim /root/crontab
$ crontab < /root/crontab
$ crontab -l
05 2 * * * /bin/sh /root/scripts/backup_script/contents_backup.sh 1> /dev/null 2> /dev/null
10 2 * * * /bin/sh /root/scripts/backup_script/database_backup.sh 1> /dev/null 2> /dev/null

参考サイト

関連記事

[Linux] “-f”オプションを付与してコマンドを実行しても、対話形式となってしまう場合がある

$ cp -f foo.conf bar.conf

サーバーによっては、例えばコマンド”cp”にエイリアス “alias cp=’cp -i'” (確認オプション)がデフォルト指定されている場合がある。
“-f”を利用する場合、コマンドの先頭に “\” もしくは “¥” を付けて実行させる。そうすることにより、エイリアスが無効になる。

$ ¥cp -f foo.conf bar.conf

AWS Elastic Beanstalkの拡張機能 “ebextensions” で “commands” (若しくはcontainer_commands)を利用する場合は、”¥” もしくは “\” を付与してはならない。Deploy自体が失敗してしまう為である。Amazon Linuxの場合は、エイリアスを無効にせずとも、”-f” オプションは有効となる。

[Elastic Beanstalk] commandsとcontainer_commandsの違い

commands

  • シェルコマンドを実行可能。
  • アルファベット順に処理される。
  • アプリケーションとWebサーバーがセットアップされ、アプリケーションのバージョンファイルが抽出される前に実行される。

container_commands

  • シェルコマンドを実行可能。
  • アプリケーションとWebサーバーがセットアップされ、アプリケーションバージョンのアーカイブが抽出された後、アプリケーションのバージョンが展開される前に実行される。
  • アルファベット順に処理される。
  • container_commands以外は、アプリケーションソースコードを抽出する前に実行される。
  • 1つのインスタンスが”AutoScaling Group”のleaderとなり、”leader_only: true”の場合、コマンドはleaderのインスタンスでしか実行されない。
packages:
  yum:
    tree: []
    dstat: []
    sysstat: []
    htop: []
    iotop: []

commands:
  install-mod_extract_forwarded:
    command: "sudo yum -y install mod_extract_forwarded --enablerepo=epel"
    ignoreErrors: true

container_commands:
  remove-webxml:
    command: "rm -f /etc/tomcat7/web.xml"
    ignoreErrors: true
  replace-webxml:
    command: "cp -f /tmp/deployment/application/ROOT/.ebextensions/web.xml /etc/tomcat7/"
    ignoreErrors: true
  overwrite-mod_extract_forwarded:
    command: "cp -f /tmp/deployment/application/ROOT/.ebextensions/mod_extract_forwarded.conf /etc/httpd/conf.d/mod_extract_forwarded.conf"
    ignoreErrors: true
    leader_only: true

files:
  "/opt/elasticbeanstalk/hooks/appdeploy/pre/server-setup.sh":
    mode: "000755"
    owner: root
    group: root
    content: |
      #!/bin/bash
      ## change hostname
      HOSTNAME="test.com"

      ## file parameter check
      if test "$HOSTNAME" = "" ;then
        echo "HOSTNAME Parameter error"
        exit 1
      fi
      echo "127.0.0.1   localhost localhost.localdomain localhost4 localhost4.localdomain4 $HOSTNAME" > /etc/hosts
      echo "::1         localhost6 localhost6.localdomain6" >> /etc/hosts
      sed -i s/localhost.localdomain/$HOSTNAME/ /etc/sysconfig/network
      hostname $HOSTNAME

      ## change timezone
      cp -fp /usr/share/zoneinfo/Asia/Tokyo /etc/localtime
      sed -i s@\"UTC\"@\"Asia/Tokyo\"@ /etc/sysconfig/clock

      ## stop iptables
      chkconfig iptables off
      chkconfig ip6tables off
      chkconfig --list | grep ip

      exit 0