MySQLからAWS Auroraへの移行でハマったことなど

MySQLからAWS Auroraに移行した際の振り返り。
RDSはもとより、ほぼDBなど触ったことがなかったのでとてもいい経験になりました。辛かったけど。

概要

オンプレで稼働しているDB(MySQL)をAWS Auroraに移行する。
移行するデータは数百GB〜TBぐらい。
本番を切り替える際のDB停止時間は可能な限り短くする。(数時間)
オンプレで稼働しているDBのバックアップを取得して、Auroraにリストア。
停止できる時間が限られているため、オンプレ ==> Aurora間でレプリケーションを貼り、
タイミングを見計らって数時間の間で本番DBを切り替える。
mysqldumpとxtrabackupというMySQLのバックアップツールの2択で検討していて 、
AWSのドキュメントにも方法が記載してあり、(容量にもよると思うが)リストアがmysqldumpよりも高速という理由でxtrabackupを選択。
しかし色々失敗して結局mysqldumpで移行することに。

移行時に気をつけるポイントなど

InnoDBが破損していないかチェック

S3に置いたバックアップファイルからAuroraを起動した際に失敗したので
xtrabackupを使って移行する場合は確認した方が良さげ。 InnoDB破損に気がつかず、結構な時間を無駄にした。 チェックする際はMySQLの停止が必要。

MySQL :: MySQL 5.6 リファレンスマニュアル :: 4.6.1 innochecksum — オフライン InnoDB ファイルチェックサムユーティリティー

Auroraは圧縮テーブルをサポートしない

これにハマった時点で圧縮テーブルのことすら知らなかった。
Auroraはrow_formatが"Compressed"なテーブルはサポートしていない。 事前にrow_formatを確認しておき、"Compressed"テーブルがあった場合は"Compact"などにALTER TABLEしておく。

RDS MySQL スナップショットの Aurora への移行 - Amazon Relational Database Service

ドキュメント見逃してた。

データが大きい時は解凍用にEC2を立てる

移行元データが大きい場合、というかネットワーク越しにデータ転送する場合は
大体gzipとかした状態で転送すると思うが、今回のケースではバックアップファイルを圧縮した状態で
Aurora起動できなかったので、EC2で解凍 => 再度S3に上げなおすという方法をとった。 移行元のサーバのDisk容量が逼迫してるとか、そういう時に。

mysqldumpで巨大なテーブルをリストアする場合

巨大なテーブルをリストアする際、セカンダリインデックスを後から作成する、という手法を使うとリストアが早くなる。
テーブルの定義とデータを分けてdumpを取得したり、dumpしたファイルを書き換えるなど手間はかかる。

www.saintsouth.net 参考にさせていただきました。

Auroraでセカンダリインデックスを作成する場合はインスタンスサイズに注意。
インスタンスサイズごとに内部ストレージの容量が決まっており、
内部ストレージの容量以上の量のインデックスファイルを作ろうとすると、エラーが発生する。
あらかじめインデックスファイルの容量は"show table status"などで把握しておくと良い。

time zone設定でハマる

オンプレ => Auroraのレプリケーションで更新されていくカラムの時刻がオンプレと9時間ズレていることが発覚。
オンプレのシステム時刻がJSTで、Auroraのシステム時刻がUTCということから起きる現象。
オンプレ側のシステム時刻を明示的にJST(Asia/Tokyo)にしておくことで回避できるはず。
念のためbinlogの中身を確認してtimezoneが指定されていることを確認しておく。

qiita.com 参考にさせていただきました。

MySQLからAuroraへのユーザ移行

MySQLとAuroraのユーザテーブル(mysql.user)の構造が違うため、
dumpをそのままインポートとかはできない。
Auroraには独自のカラムが追加されていたり、付与できない権限などあり、ハマった。
Auroraにユーザ移行を行う場合は素直にパスワード情報など確認してからgrantコマンドで作るなどした方がよい。

binlogを有効にしているとゼロダウンタイムパッチが効かない

メンテナンスなどでAuroraに再起動などが走った際、セッションが切れないゼロダウンタイムパッチという機能がある。
binlogを有効をしていると、この機能が使われないので注意が必要。フェイルオーバーした時にうっかり若干停止してしまった。

Amazon Auroraアップデート – 空間インデックス・ゼロダウンタイムパッチ | Amazon Web Services ブログ

AWS VPCピアリング接続作成メモ

やりたいこと

VPC同士で接続をする

f:id:kawakamasu:20180929205154p:plain

準備

VPCを2つ作り、異なるAZでサブネットを作る
プライベートサブネット同士で接続したいため、プライベートサブネットで作成する
操作する端末からアクセスできるように、publicも1つ作っておく
(接続したいVPC同士でサブネットが被らない様に考慮しておく)

  • vpc-a 10.1.0.0/16
    vpc-a-public-a(1a) 10.1.10.0/24
    vpc-a-private-a(1a) 10.1.1.0/24

  • vpc-b 10.2.0.0/16
    vpc-b-private-c(1c) 10.2.2.0/24

サブネットごとにルートテーブルを作成し、サブネットと関連付ける

  • rt_vpc-a-public-a ==> vpc-a-public-a
  • rt_vpc-a-private-a ==> vpc-a-private-a
  • rt_vpc-b-private-c ==> vpc-b-private-c

各サブネットに対応するセキュリティグループを作る

  • vpc-a-public-a ssh TCP 22 xxx.xxx.xxx.xxx/32
    アクセス元のグローバルIPのみ受け付ける

  • vpc-a-private-a ssh TCP 22 vpc-a-public-a
    vpc-a-public-aからのみ、受け付ける

  • vpc-b-private-c ssh TCP 22 10.1.1.0/24
    vpc-a-private-aからのみ、受け付ける

各サブネット内にインスタンスを作っておく

やってみる

vpcピアリングを設定する
マネコンのVPC画面から「ピアリング接続」- 「ピア接続の作成」
名前の入力と接続するVPCを2つ選ぶ
接続の承認待ち、みたいになるので、「アクション」から「承諾」ボタンを押すと、アクティブになる

ルートテーブルの変更

ピア接続がアクティブになったら、ルートテーブルの設定を変更する

  • rt_vpc-a-private-a
    送信先: 10.2.0.0/16 ターゲット: 作成したVPCピア接続

  • rt_vpc-b-private-c
    送信先: 10.1.0.0/16 ターゲット: 作成したVPCピア接続

接続してみる

PC ==> public(vpc-a) ==> private(vpc-a) ==> private(vpc-b)
テストなのでssh接続に必要な鍵は事前に各インスタンスに置いておく

publicのインスタンスからprivateのインスタンスに接続

[ec2-user@ip-10-1-10-xxx ~]$ ssh 10.1.1.xxx -i xxxxx.pem
Last login: Thu Sep  6 03:14:49 2018 from 10.1.10.211

      __|  __|_  )
      _|  (     /   Amazon Linux AMI
     ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/

vpc-aからvpc-bに接続

[ec2-user@ip-10-1-1-xxx ~]$ ssh -i xxxxx.pem  10.2.2.xxx
Last login: Thu Sep  6 04:01:55 2018 from 10.1.1.xxx

      __|  __|_  )
      _|  (     /   Amazon Linux AMI
     ___|\___|___|

https://aws.amazon.com/amazon-linux-ami/2017.09-release-notes/
[ec2-user@ip-10-2-2-xxx ~]$

できた

(いまさらだけど)teratermマクロで自動ログイン

teratermを使っていて毎回ユーザー名入力や秘密鍵の指定などがめんどくさいのでマクロ使って楽する為のメモ

やりたいこと

teratermで特定のホストに自動ログインする
セキュリティの観点からパスワードは毎回入力するようにする

実装

ググった先のサイトを参考にしてみたけど中々うまくいかなかったので試行錯誤
適当なエディタでxxx.ttlという拡張子のファイルを作ってデスクトップに置いておく

関数などの詳細はリファレンスを参照
https://ttssh2.osdn.jp/manual/ja/macro/

username = 'ユーザ名'
hostname = 'ホスト名'
keyfile = '鍵へのパス'

msg = 'Enter password for user '
strconcat msg username
passwordbox msg 'Get password'
password = inputstr

msg = hostname
strconcat msg ':22 /ssh /auth=publickey /user=' 
 →ポート変えてる場合は「22」を変更
strconcat msg username
strconcat msg ' /keyfile='
strconcat msg keyfile
strconcat msg ' /passwd='
strconcat msg password
connect msg

デスクトップに置かれたマクロを起動して対象ホストにログインできることを確認

CloudFront経由で静的ページをS3ウェブホスティング

やりたいこと

CloudFrontをたててS3にあるhtmlファイルを独自ドメインで見れるようにする
この構成をつくりたい
http://aws.clouddesignpattern.org/index.php/CDP:Cache_Distribution%E3%83%91%E3%82%BF%E3%83%BC%E3%83%B3
 
参考にしたページ
Developers.IO(クラメソさんの技術ブログ、いつもお世話になってます。)
https://dev.classmethod.jp/cloud/aws/cdn-with-cloudfront-and-s3/
AWS公式
https://docs.aws.amazon.com/ja_jp/AmazonS3/latest/dev/website-hosting-cloudfront-walkthrough.html
  

前提

 独自ドメインを持っていること

1. 準備

S3バケットを作成し、htmlファイルを置く
バケットの名前は公開するURLに合わせるのが良い
例) test.zzz.net で公開する場合、バケットの名前もtest.zzz.netにする
置いたファイルを公開する

バケットポリシー
{
  "Version": "2012-10-17" ,
  "Statement": [
    {
      "Sid": "PublicReadForGetBucketObjects",
      "Effect": "Allow",
      "Principal": "*",
      "Action": "s3:GetObject",
      "Resource": "arn:aws:s3:::xxxxx.xxx.xxx/*"
    }
  ]
}
※xxxx.xxx.xxxはバケット名

準備出来たらアクセス出来るか試してみる
   

2. CloudFrontディストリビューション作成

 [CreateDistribution]-[web Distribution]のGet startedを選択
 [Origin Domain Name] をクリックするとS3バケットが選べるので、先程公開したバケットを指定
 [Alternate Domain Names]にアクセスさせる予定のCNAMEを入力(cdn.xxx.xxとか)
 [Default Root Object] にindex.htmlなど、ファイル名を入力
 [Create Distribution]で作成
 15分ぐらいで出来上がり
 出来上がったらCloudFrontのDistribution画面の[DomainName]に表示されているxxx.cloudfront.netをコピーか何かしておく

3. Route53でCNAME設定

 [Create Record set]からCNAMEを作成する
 [Name]にCloudFrontディストリ作成したCNAMEを入力
 [value]にxxx.cloudfront.netを入力
 [Save Reacord Set]で保存
   

4. CNAMEで作ったレコードでアクセスしてみる

 webページが表示されれば成功
   

5. ちょっとだけハマったこと

 最初CloudFrontのディストリ作成のところで[Default Root Object]に何も入れずに進めてアクセスしたらAccess DeniedとかなったのでRootObjectには入れておいたほうが良いのかも

AWSでEBSを動的に拡張する

EBSをオンラインで拡張する

[ec2-user@ip-172-31-6-252 ~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        488M   56K  488M   1% /dev
tmpfs           497M     0  497M   0% /dev/shm
/dev/xvda1      7.8G  1.1G  6.7G  14% /

EBSのメニューから
ボリュームの変更でサイズ変更
今回は8GB → 20GBに変更
5分しないぐらいで完了
※増やすことはできても減らすことは出来ないようだ

[ec2-user@ip-172-31-6-252 ~]$ sudo fdisk -l /dev/xvda
Disk /dev/xvda: 21.5 GB, 21474836480 bytes, 41943040 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disk label type: dos
Disk identifier: 0x00000000

    Device Boot      Start         End      Blocks   Id  System
/dev/xvda1               1    16777215     8388607+  ee  GPT

リサイズ

[ec2-user@ip-172-31-6-252 ~]$ sudo resize2fs /dev/xvda
resize2fs 1.42.12 (29-Aug-2014)
resize2fs: Device or resource busy while trying to open /dev/xvda
Couldn't find valid filesystem superblock.

起動ディスクなど、パーティション切られてるとちょっとめんどくさいみたい。
めんどくさいのでEBS作り直してもう一度

[root@ip-172-31-6-252 ~]# mount /dev/xvdf /tmp
[root@ip-172-31-6-252 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        488M   60K  488M   1% /dev
tmpfs           497M     0  497M   0% /dev/shm
/dev/xvda1      7.8G  1.1G  6.7G  14% /
/dev/xvdf       4.8G   10M  4.6G   1% /tmp

[root@ip-172-31-6-252 ~]# fdisk -l /dev/xvdf

Disk /dev/xvdf: 5368 MB, 5368709120 bytes, 10485760 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

5GBのディスクを10GBに拡張する

[root@ip-172-31-6-252 ~]# fdisk -l /dev/xvdf

Disk /dev/xvdf: 10.7 GB, 10737418240 bytes, 20971520 sectors
Units = sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes

[root@ip-172-31-6-252 ~]# resize2fs /dev/xvdf
resize2fs 1.42.12 (29-Aug-2014)
Filesystem at /dev/xvdf is mounted on /tmp; on-line resizing required
old_desc_blocks = 1, new_desc_blocks = 1
The filesystem on /dev/xvdf is now 2621440 (4k) blocks long.

[root@ip-172-31-6-252 ~]# df -h
Filesystem      Size  Used Avail Use% Mounted on
devtmpfs        488M   60K  488M   1% /dev
tmpfs           497M     0  497M   0% /dev/shm
/dev/xvda1      7.8G  1.1G  6.7G  14% /
/dev/xvdf       9.8G   12M  9.3G   1% /tmp

増えとる!!


OS起動するディスクとか、パーティションが切ってあるEBSは安易に変更しないほうがいい
(当然かもしれないが)後々に拡張する可能性があるデータは別でディスクを用意するのが良い、パーティションは切らない
EBSは細かい容量でアタッチできるのでパーティション切るような運用はやめたほうがいいのかもしれない

AWS Beanstalk でdockerを使う

beanstalk触り始めの時に理解に苦しんだので備忘録。

やりたいこと
aws beanstalk dockerを使ってデプロイする

マルチコンテナを使ったwebアプリのデプロイ

まずはシンプルな構成で、
1インスタンス1コンテナを起動するところから

使った環境
操作端末:EC2 (Amazon Linux)
aws eb cliを使用


beanstalkでdockerを使うにあたって、Dockerrun.aws.jsonというファイルを作る

[ec2-user@ip-10-0-2-9 bs-docker-1]$ cat Dockerrun.aws.json 
{
  "AWSEBDockerrunVersion": "1",
  "Image": { "Name" : "nginx:latest" },
  "Ports" : [{ "ContainerPort": "80"}],
  "Volumes": [{"HostDirectory": "/var/app/current/html","ContainerDirectory": "/usr/share/nginx/html"}]}

jsonに馴染みがないので苦戦。。

今回はEC2で作ったファイルをbeanstalkのインスタンスにデプロイするという形。

Linux上でmkdirでディレクトリを作って、それを丸ごとアップデートしてデプロイする感じ。
Linuxからだとzipする必要がないらしい。
"eb create"コマンドで対話的に環境を作ることができる
アップロードされたディレクトリは、beanstalk上のインスタンスの"/var/app/current"にアップされる。

Windows環境からファイルを作成した場合はフォルダにいれないでファイルを直接zipすればOK(多分)

AWS上でのWordPress落とし穴

前回WordPressのインストールをした後の気づきです。

WordPressの表示がおかしい

AWS上のEC2インスタンスにテスト環境を作ったのですが、しばらく使わないだろうという理由で一旦シャットダウンしていました。
その後、ちょっと確認したい事があったのでEC2を起動してWordPressにアクセスしたのですが、表示が壊れている状態となっていました。

  • IP直打ちでインストールした際の注意点

調べてみるとよくある現象のようですが、インストール時にパブリックIP直打ちでインストールした場合、WordPressのサイトアドレスに「http:(IPアドレス)」と設定されてしまい、EC2のシャットダウン、起動によりサーバのIPアドレスが変わってしまうため、諸々設定が読み込めず、サイトの表示が壊れてしまうようです。

ぱっと思い浮かんだ対処としては、以下2点。
1. インストール後、EC2を落とさずにWordPressの設定からサイトアドレスを変更
 [設定]-[一般]-[サイトアドレス(URL)]を変更
2.ドメイン設定してからインストール(今回はRoute53を使用)

WordPressの管理画面から「更新」などができない

AWS上だけに限った話ではないですが、インストールディレクトリの所有者をroot等にしている場合、更新する際にFTPの情報を求められると思います。今回の環境ではwebサーバはapacheを使っているので、インストールディレクトリ(/var/www/wordpress)の所有者をapacheにしてあげることで回避可能。

chown -R apache:apache /var/www/wordpress