S3 に5分毎に出力される AWS LB ログファイルを時間帯を指定してまとめてダウンロード
概要
AWS で LB のログを S3 に保存設定をしている場合に、 インシデントがあった時間帯のログがまとめて欲しいという時に awscli でまとめてログ取得しています。
その時の手順を備忘録としてまとめました。
AWS で LB のログを S3 に保存設定をしている場合に、 インシデントがあった時間帯のログがまとめて欲しいという時に awscli でまとめてログ取得しています。
その時の手順を備忘録としてまとめました。
完全な備忘録です。
6月に入って数日、
ecs-cli の latest をインストールすると latest が 1.6.0 となりecs-cli compose ...
を実行すると以下のようなエラーが出るようになりました。
1 | level=error msg="Unable to open ECS Compose Project" error="Volume driver is not supported" |
1.4.0 では問題なかったタスク定義でしたが
1.6.0 では Volume driver is not supported
となったそうで処理がこけるようになりました。
その対応として 1.4.0 にバージョン固定した設定です。
AWS Vault は IAM の認証情報 (Access Key Id, Secret Access Key) を安全に OS のキーストアに保存しアクセスできる仕組みを提供するツールです。
Vault = 金庫 というだけあって
PC 落としても秘匿情報が漏れにくい仕組みにしてくれます。
AWS Vault で複数アカウントのコンソールログインを簡単にしたいと思います。
前回 ECR への Docker イメージをプッシュする際の認証コマンドを実行せずにプッシュできる様にしました。
ECR にログイン(aws ecr get-login)無しでプッシュする
ですが、
設定が手間というのがあり、CircleCI, AWS CodeBuild 等でワンライナーでささっと書きたいときには不便です。
awscli profile
で設定した profile を利用し ecs-cli を利用することで認証をよろしくやってくれます。
1 | ecs-cli push <image> --aws-profile <profile> --region <region> |
1 | aws configure set --profile hogehoge aws_access_key_id $ACCESS_KEY_ID |
1 | ecs-cli push 123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/stg-mogemoge-rails:latest \ |
以上で aws ecr get-login
を使用せず、ECR へプッシュができる様になりました♪
Docker version 1.11 で実装された credential-helper を利用し
ECR へのプッシュを安全に簡易的に行う仕組みを実装します。
1 | $ sudo apt-key adv --keyserver hkp://p80.pool.sks-keyservers.net:80 --recv-keys 58118E89F3A912897C070ADBF76221572C52609D |
1 | $ docker pull pottava/amazon-ecr-credential-helper |
以下 3 つの中から 1 つ利用ください。
EC2 であれば、1. インスタンスロールで認証
が一番すっきりしていてコードの見通しが良いです。
1 | docker run --rm \ |
1 | sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login |
1 | docker run --rm \ |
1 | sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login |
1 | export AWS_ACCESS_KEY_ID=AKIAIOSFODNN7EXAMPLE |
1 | docker run --rm \ |
1 | sudo sh -c 'cat << EOF > /usr/bin/docker-credential-ecr-login |
1 | mv $HOME/.docker/config.json $HOME/.docker/config.json.org |
これで aws ecr get-login
から解放されます ♪
ECS を利用していて幾つかはまったポイントがあったのでまとめました。
1 | $ ecs-cli compose service up ... |
ecs-cli compose service up でデプロイ時にタスク起動を実行するものの、起動が正しくできていない状態です。
こちらはコンテナ起動時の処理に問題がある場合があります。
1 | service hogehoge was unable to place a task because no container instance met all of its requirements. |
port mapping を以下の様に設定していた。
1 | "portMappings": [ |
新しいタスクでも 0:80 のポートを利用しようとする為、エラーとなります。
以下の様に設定することで回避できました。
1 | "portMappings": [ |
1 | INFO[0031] (service hogehoge) was unable to place a task because no container instance met all of its requirements. The closest matching (container-instance a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6) has insufficient memory available. For more information, see the Troubleshooting section of the Amazon ECS Developer Guide. timestamp=2018-03-09 15:45:24 +0000 UTC |
タスク更新(ecs-cli compose service up
)実行時、
上記の様なメモリ不足が出る場合はインスタンスタイプを上げる、また、他タスクを削除する等、メモリーリソースを増やす対応が必要です。
no space on device で イメージを pull できない。
df -hT
コマンドで 容量の使用状況確認
未使用のコンテナ・ボリュームを強制削除しお掃除
1 | docker system prune -af --volumes |
1 | msg="Couldn't run containers" reason="RESOURCE:CPU" |
タスクで指定している cpu (vCPU) が不足しています。
インスタンスタイプを上げる、もしくは、他タスクを削除する等、 CPU リソースを増やす対応が必要です。
1 | level=error msg="Create task definition failed" error="ClientException: When networkMode=awsvpc, the host ports and container ports in port mappings must match.\n\tstatus code: 400, request id: a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6" |
起動タイプ Fargate で以下の様な設定だと、NG
1 | ports: |
こちらだと OK。
1 | ports: |
ホストポートとコンテナポートのマッピングが必要です。
volume_from
は Fargate では使用できません。
1 | level=error msg="Create task definition failed" error="ClientException: host.sourcePath should not be set for volumes in Fargate.\n\tstatus code: 400, request id: a1b2c3d4-e5f6-g7h8-j9k0-l1m2n3o4p5q6" |
IAM Role に権限を適宜付与します。
1 | level=info msg="(service hogehoge) failed to launch a task with (error ECS was unable to assume the role 'arn:aws:iam::123456789012:role/ecsTask |
イメージ pull できないというエラーも権限を付与していないことに起因することが主です。
1 | CannotPullContainerError: API error (500): Get https://123456789012.dkr.ecr.ap-northeast-1.amazonaws.com/v2/: net/http: request canceled while waiting for connection" |
現在稼働している ECS の IAM Role の権限を参考してください。変更される可能性があるのであくまで参考にし、適宜最新の情報を以ってご対応ください。
1 | { |
以上です。
また何か発生したら追記していきたいと思います。
AWS WAF (Web Application Firewall) を利用し Cloudfront でのリファラ制御を実装しましたのでそのまとめです。
直リンク禁止対策として導入しました。
以下手順になります。
サービス > WAF & Shield と辿り Go to AWS WAF クリック
ACL (Access Control List) を設定していきます。
特にチェックせず Next ボタンクリック
以下、設定項目を設定し、Next ボタンクリック
Item | Value |
---|---|
Web ACL name | (任意) 例では Cloudfront の CNAME を設定しています。 |
CloudWatch metric name | Web ACL name を入力すると自動で入力される。変更したい場合のみ変更 |
Region | Global(CloudFront) 選択 |
AWS resource to associate | 対象となる Cloudfront を選択する箇所。運用中の Cloudfront を対象とすると場合は後々設定。 |
今回は文字列一致を条件とする為、 String match conditions にて Create condition
ボタンクリック
以下設定し Add filter
ボタンクリック。
複数 filter がある場合、Add filter を繰り返します。
Item | Value |
---|---|
Name | (任意) |
Part of the request to filter on | Header |
Header | Referer |
Match type | Contains |
Transformation | Convert to lowercase |
Value to match | 対象となるドメイン設定 |
Add filter
後、 Create
ボタンクリック。追加したもののすぐに反映されていない。
そのまま Next
ボタンクリック
Create rule
ボタンクリック。
Name, Cloudwatch metric name を設定し
Add conditions で条件を追加します。
その後、Create
ボタンクリック。
やはり Rule は反映されていない。ですが、続けてBlock all requests that don't match any rules
をチェックし Review and create
ボタンクリック。
※対象の Cloudfront に反映させたくない場合は、Cloudfront を選択したリソースを解除する必要があります。
※最後に関連付けができるのでここではするべきではないと思います。
Confirm and create
ボタンクリック。
WEB ACLs より選択し Edit web ACL
ボタンクリック
Add rule to web ACL
ボタンクリックUpdate
ボタンクリック[f:id:kenzo0107:20171005183720p:plain]
Add association
ボタンクリック
Resource で 対象の Cloudfront を選択し Add
ボタンクリック
以上で数分後 WAF+CloudFront によるリファラチェックが確認できる状態になります。
自環境では
ローカルの /etc/hosts 修正し対象ドメインから Cloudfront CNAME へのリンクを貼って確認しました。
Cloudfront CNAME ドメインでのリソースを直接アクセスすると
以下の様な エラーページが表示されることが確認できました。
上記のエラーページは Cloudfront > Error Pages で Create Custom Error Response
で S3 上のパスを指定することでカスタマイズが可能です。
是非サイトコンセプトに合ったエラーページをご用意されるとよりユーザフレンドリーな配信になるかと思います。
以上
ご参考になれば幸いです。
AWS Elasticsearch Service (ES) 2.3 → 5.5 へバージョンアップを実施に際して
以下記事をまとめました。
1 | $ curl https://<Elasticsearch 2.3 Endpoint Domain> |
その他クラスターへ設定している情報をメモ
ロール ARN arn:aws:iam::
Service を es.amazonaws.com に編集
1 | { |
es-index-backup-user
とし プログラムによるアクセスにチェックを入れて 次のステップ
クリック次のステップ
クリックes-index-backup-user
を作成し独自ポリシーで先ほど作成した role へのアクセス許可設定をアタッチします。1 | { |
S3 > バケットを作成する
でバケット作成してください。
スナップショットを管理するリポジトリを Elasticsearch に作成する必要があります。
Elasticsearch へのアクセス可能なサーバにて以下スクリプト実行します。
1 | from boto.connection import AWSAuthConnection |
1 | $ chmod +x register_es_repository.py |
リポジトリ登録完了しました。
snapshot 名を 20170926
とします。
1 | $ curl -XPUT "https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926" |
20170926
という snapshot 名で取得したことが確認できます。
1 | $ curl -s -XGET "https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/_all" | jq . |
スナップショット 20170926
を削除する場合、DELETE メソッドを実行します。
1 | $ curl -XDELETE https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926 |
以下が作成されているのがわかります。
はじめ meta-_ が作成できたら完了なのかなと思いきや
snap-_ も作られるまで待つ必要がありました。
1 | $ curl -s -GET https://<Elasticsearch 2.3 Endpoint Domain>/_snapshot/index-backups/20170926 |
Elasticsearch 2.3 の設定に倣って作成します。
register_es_repository.py の host 部分を新規ドメインに修正します。
1 | from boto.connection import AWSAuthConnection |
1 | $ chmod +x register_es55_repository.py |
20170926
のスナップショットをリストアします。
1 | $ curl -XPOST "https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore" |
1 | $ curl -XGET "https://<Elasticsearch 5.5 Endpoint Domain>/_cat/indices" |
1 | { |
1 | curl -XPOST https://<Elasticsearch 5.5 Endpoint Domain>/_snapshot/index-backups/20170926/_restore -d '{ |
indices
を用い、スナップショット内のインデックスの中からマッチする正規表現のみをリストアできます。
自身ではこの様な解決法を実施し回避できました。
その他良い方法があれば御指南いただけますと幸いです。
Terraform で ES 2.2 → 5.5 バージョンアップを実施した所
1 時間以上経過してようやくアップデートが完了しました。
1 | aws_elasticsearch_domain.elasticsearch: Still destroying... (ID: arn:aws:es:ap-northeast-1:xxxxxxxxxxxx:domain/***, 59m11s elapsed) |
これは辛い (>_<)
Terraform で管理している場合、
スナップショットを取得したら aws console 上でドメイン削除した方が早い。
ブルーグリーン的に ES 5.5 作成して ES 2.2 から乗り換えて
しばらく運用して問題なければ ES 2.2 を削除する方法が一番確実だなと思いました。