hoomin.kani

KANISAN WEB

インフラ・サーバーサイドを頑張るカニが学んだあれこれ。

ECS on EC2からFargateへの移行(Terraform ver.)

f:id:hoominkani:20190824182840p:plain

はじめに

元々WebシステムをECS on EC2で管理していましたが、EC2の管理から解き放たれるべく、そのままFargateへと移行しました。

今回は移行の際にどのような変更が必要であったかを共有します。

なお、インフラリソースの管理はTerraform v0.11.10を使用しました。

変更対象のリソース

  • EC2
    • 管理不要のため削除
    • 踏み台サーバのみ管理
  • ECS
    • 詳細な変更内容に関しては下記参照

ECS 変更箇所

タスク定義

削除したもの

  • mountPoints
    • ホストサーバとマウントをすることはできないので削除
"mountPoints": [
    {
        "sourceVolume": "${PATH}",
        "containerPath": "${CONTAINER_PATH}"
    }
]
  • volume
 volume {
  name = "nginx.conf"
  host_path = "/nginx.conf"
}
  • portMappings
"hostPort": 80
  • link
    • link設定はできないので削除
"links": [
    "app:app"
]

追加したもの

  • requires_compatibilities
  • network_mode
resource "aws_ecs_task_definition" "app" {
  requires_compatibilities = ["FARGATE"]
  network_mode             = "awsvpc"
}

変更したもの

  • cpu
  • memory

ECS on EC2では自由に設定できていたが、Fargateではあらかじめ定められたパラメータの中から選択することになる。

※ 2018/12/06 現在時点でのパラメータ

CPU メモリ ※1GB=1024
256 512 / 1024 / 2048
512 1024 / 2048 / 3072 / 4096
1024 2048 / 3072 / 4096 / 5120 / 6144 / 7168 / 8192
2048 4096 ~ 16384 ※1024ずつの加算
4096 8192 ~ 30720 ※1024ずつの加算

ECS Service変更箇所

追加したもの

  • Fargate
launch_type = "FARGATE"
 network_configuration {
   subnets = [
     "${aws_subnet.fastladder_public_a.id}",
     "${aws_subnet.fastladder_public_c.id}",
    ]
   security_groups = [
     "${aws_security_group.fastladder_alb.id}",
     "${aws_security_group.fastladder_web.id}",
   ]
   assign_public_ip = "ENABLED"
 }
  • iam_role
execution_role_arn       = "arn:aws:iam::${var.aws_id}:role/ecsAdminRole"

ターゲットグループ変更箇所

追加したもの

  • target_type

Fargateの場合、ターゲットグループのtarget_typeにはipを設定する必要がある。

target_type = "ip"

終わりに

今回は必要最低限の変更内容に関してまとめました。

(EC2のuserdataで実行させていたコマンドを別に移動など、プロジェクトによって別の作業が必要になるケースもありますので、以降前にはご確認を!)

awslogs-datetime-formatとawslogs-multiline-patternの使いどころ

f:id:hoominkani:20190824181419p:plain

awslogs-datetime-formatの使いどころ

  • awslogs-datetime-formatを使用すると、同一時間帯のログレコードが細分化されず、まとまって表示されるため、可視性が上がります。
  • awslogs-multiline-patternと同時に設定されている場合、このオプションは常に優先されます。
#GMTからの時間オフセットとしての時間帯でログをまとめる場合
"logConfiguration": {
  "logDriver": "awslogs",
  "options": {
    "awslogs-group": "${LOGS_GROUP_NAME}",
    "awslogs-datetime-format": "\\[%d/%b/%Y:%H:%M:%S %z\\]",
    "awslogs-region": "ap-northeast-1",
    "awslogs-stream-prefix": "${PREFIX}"
  }
}

awslogs-multiline-patternの使いどころ

特定のログだけをCloudWatch Logsに送信する際に使用します。

#INFOで始まるログを送信する場合
"logConfiguration": {
  "logDriver": "awslogs",
  "options": {
    "awslogs-group": "${LOGS_GROUP_NAME}",
    "awslogs-datetime-format": "^INFO",
    "awslogs-region": "ap-northeast-1",
    "awslogs-stream-prefix": "${PREFIX}"
  }
}

注意点

  • すべてのログメッセージに対して正規表現の解析とマッチングを行うため、ログ記録のパフォーマンスが下がる可能性があります。

【簡単】RDSのバイナリログ(binlog)保存期間を設定する

f:id:hoominkani:20190818174645j:plain

昨今のバックアップ事情

今回はRDSのバイナリログ保存期間を変更する方法を紹介します。

前提として、RDS for MySQLではトランザクションログがデフォルトでS3に保存されており(5分間隔)、

エンジニアは管理画面から復元したい時間を指定するだけでデータのリストアを行うことができます。

AWSが提供しているこちらの機能を使う方がオペミスも少なく安心安全なのですが、案件によってはバイナリログからの手動バックアップを求められることもあります。

そんなケースにも対応できるよう、事前にバックアップ期間を指定しておくのが今回の目的です。

やることはたった一つ

まずは現在の設定を確認してみましょう。

MySQLでこちらのコマンドを打ち、設定の確認を行います。

call mysql.rds_show_configuration;

するとこんな内容が返ってきます。

name value description
binlog retention hours null binlog retention hours specifies the duration in hours before binary logs are automatically deleted.


バイナリログの保存期間はデフォルトでnull、つまり保存しない設定になっているので、こちらを変更し、ログを24時間保存するようにします。

call mysql.rds_set_configuration('binlog retention hours', 24);

24の部分を72に変更すれば、3日間のバイナリログを変更することもできます。

変更後の注意

当たり前ではありますが、バイナリログを変更するとDBへの負荷も高まります。

設定後はDBのモニタリングを怠らないようにしましょう。

【Elixir】DateTime.compareで時間を比較する

f:id:hoominkani:20190818173951j:plain

Elixirで時間の比較をしたい!と思ったら、真っ先に思い浮かぶのがDateTime.compareですよね。

今回はDateTime.compareの使い方をサクッと紹介します。

DateTime.compareの使い方

  • 使い方

    • Datetime AとDatetime Bを比較する場合
DateTime.compare(A, B)

たったこれだけです。

iex(1)> DateTime.compare(DateTime.utc_now, DateTime.utc_now)
:lt

3種類の返り値

DateTime.compareを実行すると、3種類のatomのうち、いずれかの値が返ってきます。

  • :lt AがBより早い
  • :eq AとBが等しい
  • :gt AがBより遅い

例えばDatetime AがDatetime Bよりも早い場合に特定の処理を行いたい場合、

if DateTime.compare(a, b) == :lt do
 do_something()
end

などと書くことができます。

【2019年版】3行でmacOSにAWS CLIをインストールする方法

f:id:hoominkani:20190731100609p:plain

前提(pythonが入っていることを確認)

$ python --version

AWS CLIのインストール

$ curl "https://s3.amazonaws.com/aws-cli/awscli-bundle.zip" -o "awscli-bundle.zip"
$ unzip awscli-bundle.zip
$ sudo ./awscli-bundle/install -i /usr/local/aws -b /usr/local/bin/aws

これだけでOK。

あとは

$ aws --version

で動くことを確認し、適宜AWSのcredentialsを設定してあげればすぐにCLIを使うことができます。

Macのファイルディスクリプタ上限を変更する方法

f:id:hoominkani:20190801171045p:plain

稀にERROR: ulimit -n is XXX; XXX is the recommended minimum.のようにファイルディスプリタが足りないよーというエラーに出くわすことがあるので、解決法を共有。

まずは現在の状態を確認

MacBook-Pro$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 256
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 2048
virtual memory          (kbytes, -v) unlimited

256しかない……。

上限を上げる

やること

  • 2つのplistファイルを作成
  • ownerをrootに変更
  • 設定の有効化

2つのファイルを作成

  • /Library/LaunchDaemons/limit.maxfiles.plist
<?xml version="1.0" encoding="UTF-8"?>  
  <!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN"  
          "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
  <plist version="1.0">
    <dict>
      <key>Label</key>
      <string>limit.maxfiles</string>
      <key>ProgramArguments</key>
      <array>
        <string>launchctl</string>
        <string>limit</string>
        <string>maxfiles</string>
        <string>524288</string>
        <string>524288</string>
      </array>
      <key>RunAtLoad</key>
      <true/>
      <key>ServiceIPC</key>
      <false/>
    </dict>
  </plist>
  • /Library/LaunchDaemons/limit.maxproc.plist
<?xml version="1.0" encoding="UTF-8"?>  
  <!DOCTYPE plist PUBLIC "-//Apple/DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">  
    <plist version="1.0">
      <dict>
        <key>Label</key>
          <string>limit.maxproc</string>
        <key>ProgramArguments</key>
          <array>
            <string>launchctl</string>
            <string>limit</string>
            <string>maxproc</string>
            <string>2048</string>
            <string>2048</string>
          </array>
        <key>RunAtLoad</key>
          <true />
        <key>ServiceIPC</key>
          <false />
      </dict>
    </plist>

ownerをrootに変更

sudo chown root /Library/LaunchDaemons/limit.max*.plist

設定の有効化

sudo launchctl load -w /Library/LaunchDaemons/limit.maxfiles.plist
sudo launchctl load -w /Library/LaunchDaemons/limit.maxproc.plist

後は再起動したらOK。

設定後

MacBook-Pro$ ulimit -a
core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
file size               (blocks, -f) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 524288
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 2048
virtual memory          (kbytes, -v) unlimited

かなり増えた!

【git stash】間違って退避していた変更を適用してしまったら

f:id:hoominkani:20190801171030p:plain git stash popやgit stash applyをやっちゃったけど、間違ってコンフリクト起きちゃった!退避させていた状態に戻したい!という時の対処法

git reset HEAD .
git stash save

基本的にはこれでok