- 投稿日:2019-10-24T22:54:48+09:00
ECRでコンテナ脆弱性診断が実装されていたので試してみた
ECRでスキャン?
今日の業務中にふとECR画面見たら、「スキャン」の表示を見つける。
コンテナの脆弱性診断が実装されてる?
ん?こんなのあったっけ。見落としていただけかな。ということで触ってみた。触ってみた
リポジトリ作成
「プッシュ時にスキャン」画面メニューがある。とりあえず、リポジトリ作成してみる。
なるほど、docker push
でコンテナ登録する時にスキャンが走るようだ。有効にしてみる。コンテナをECRに登録
試しにcentosのコンテナをpushして、スキャンをしてみる。
docker pull centos:latest docker tag centos:latest [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.0 $(aws ecr get-login --no-include-email --region ap-northeast-1) docker push [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.0・
centos:latest
のコンテナをローカルに落とす。
・ECR用のタグを設定。
・ECRログイン。
・ECRのcentos
リポジトリにpushする。スキャン完了。そして脆弱性確認へ・・・
スキャンは完了!脆弱性があるようなので、詳細を見てみる。
概要で脆弱性の件数とパッケージ毎の脆弱性説明が表示される。
例では重要度がCritical
はないが、High
とMedium
がそれぞれ指摘された。
名前がリンクになっているのでクリックすると・・・脆弱性の対応をしてみる。
パッケージのバージョンアップをすることで、脆弱性指摘が減るか確認してみる。
FROM centos:latest LABEL maintainer "portfield" RUN yum -y update && yum clean allOSアップデートする
Dockerfile
を書く。シンプル。
centos
ディレクトリにファイルを配置。docker build -t [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.1 centos docker push [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.1・ECR用でバージョン上げてDockerイメージ作成。
・ECRのcentos
リポジトリにpushする。再びスキャン完了。脆弱性確認へ・・・
上がOSアップデート前、下がOSアップデート後のDockerイメージ。
脆弱性件数が減っていることから、OSアップデートにより、脆弱性が減ったことが分かる。
詳細も見てみよう。
OSアップデートだけでは対処出来なかった脆弱性が表示される。
名前のリンクと説明を頼りに対応しよう。今回は対応しない。。スキャンを有効にしていなくてもOK。
まとめ
・以上のように、リポジトリの設定を有効にするだけで、簡単に使用することが出来た。
CI/CDの一環でソース更新時にDockerイメージを自動作成し、ECRにpushしているケースも多いと思うので、便利に使用出来そう。
・というか、元々あったのだろうか???ドキュメント探しても見つからない。。
裏で何をベースにスキャンしているとか、情報があったら欲しいです。。
- 投稿日:2019-10-24T22:54:48+09:00
ECRでコンテナ脆弱性診断が標準実装されていたので試してみた
※2019/10/25(金)追記:
本機能は使用出来なくなっているようです。ECRでスキャン?
今日の業務中にふとECR画面見たら、「スキャン」の表示を見つける。
コンテナの脆弱性診断が実装されてる?
ん?こんなのあったっけ。見落としていただけかな。ということで触ってみた。リポジトリ作成
「プッシュ時にスキャン」画面メニューがある。とりあえず、リポジトリ作成してみる。
なるほど、docker push
でコンテナ登録する時にスキャンが走るようだ。有効にしてみる。コンテナをECRに登録
試しにcentosのコンテナをpushして、スキャンをしてみる。
docker pull centos:latest docker tag centos:latest [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.0 $(aws ecr get-login --no-include-email --region ap-northeast-1) docker push [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.0・
centos:latest
のコンテナをローカルに落とす。
・ECR用のタグを設定。
・ECRログイン。
・ECRのcentos
リポジトリにpushする。スキャン完了。そして脆弱性確認へ・・・
スキャンは完了!脆弱性があるようなので、詳細を見てみる。
概要で脆弱性の件数とパッケージ毎の脆弱性説明が表示される。
例では重要度がCritical
はないが、High
とMedium
がそれぞれ指摘された。
名前がリンクになっているのでクリックすると・・・脆弱性の対応をしてみる。
パッケージのバージョンアップをすることで、脆弱性指摘が減るか確認してみる。
FROM centos:latest LABEL maintainer "portfield" RUN yum -y update && yum clean allOSアップデートする
Dockerfile
を書く。シンプル。
centos
ディレクトリにファイルを配置。docker build -t [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.1 centos docker push [AWSアカウントID].dkr.ecr.ap-northeast-1.amazonaws.com/centos:1.1・ECR用でバージョン上げてDockerイメージ作成。
・ECRのcentos
リポジトリにpushする。再びスキャン完了。脆弱性確認へ・・・
上がOSアップデート前、下がOSアップデート後のDockerイメージ。
脆弱性件数が減っていることから、OSアップデートにより、脆弱性が減ったことが分かる。
詳細も見てみよう。
OSアップデートだけでは対処出来なかった脆弱性が表示される。
名前のリンクと説明を頼りに対応しよう。今回は対応しない。。スキャンを有効にしていなくてもOK。
まとめ
・以上のように、リポジトリの設定を有効にするだけで、簡単に使用することが出来た。
CI/CDの一環でソース更新時にDockerイメージを自動作成し、ECRにpushしているケースも多いと思うので、便利に使用出来そう。
・というか、元々あったのだろうか???ドキュメント探しても見つからない。。
裏で何をベースにスキャンしているとか、情報があったら欲しいです。。
- 投稿日:2019-10-24T22:53:14+09:00
AWS 無料枠使用する際はCloudTrailに要注意
経緯
AWSを仕事で使うようになり、どうせならちゃんと勉強しよう!ということで無料枠の利用を開始した。
そして”AWS 無料枠"などで調べると下記のような文言が沢山出てきて設定しなければ!と取り敢えず設定してしまう。
その中に今回の発端になったものが入ってたらしい。どの記事だったかは忘れたが。"まず初めに設定する事""これだけは設定しよう!"
そして自分と同じようなCloud Trail(S3)の設定を行うと以下のメールがやってくる。
AWS_FreeTier_limit_alertputs 'Dear AWS Customer, Your AWS account XXXXXXXXXX has exceeded 85% of the usage limit for one or more AWS Free Tier-eligible services for the month of DDDDD. AWS Free Tier Usage as of MM/DD/YYYY AWS Free Tier Usage Limit x,xxx Requests 2,000 Put, Copy, Post or List Requests of Amazon S3 'このメールに気が付いた時の私「!!!!!?!sdfjさぢfjsぢうjふぃjふぁp「っだspdかそだkだ」
Qiitaの記事だったりで請求金額が凄い事になったというのを見ていた私はこのままいったら大変なことになると焦りまくる。
結果として、何も調べたりもせずに全部記事通りに設定した自分が悪かった。
設定でCloudTrailのログをS3へ...としていたことより今回のメールがとんできました。対処法
1.CloudTrailの設定で作成した証跡情報を削除
2.S3のパケットを削除
課金額は全然高くないのですが...取り敢えず無料枠内でやっていきたい人は削除しましょう。
- 投稿日:2019-10-24T21:28:17+09:00
AWS ECSにSchemaSpyを乗せてサーバレスでER図を作成する
TL;DR
公式のDockerを参考にしつつ
entrypoint.sh
の末尾にS3に吐き出す処理を書く要件
- 任意の間隔でER図を定期的に生成したい
- ER図ドキュメントは特定のIPからのみアクセス可能にしたい
- EC2などサーバの面倒をみたくない。運用コストは最小限に。
流れ
今回は「ER図 自動生成」とかで検索するとヒットしやすいSchemaSpyを採用。特に深い理由は無いので好きなER図生成ツールを使う。ただしS3にアップロードする関係上静的ファイルを生成するツールを採用したほうが良い。
dockerfile
S3に吐くためにawscliが必要だが公式のimageにはもちろんのこと入っていないので入れてあげる。
entrypoint.sh
も自作のを使うのでCOPYする必要がある。DockerfileFROM schemaspy/schemaspy:snapshot USER root RUN apk --update --no-cache add \ python \ curl RUN curl https://bootstrap.pypa.io/get-pip.py |python RUN pip install awscli COPY ./entrypoint.sh / USER java ENTRYPOINT ["/entrypoint.sh"]entrypoint.sh
ドキュメントを生成するまでは同じだが、生成されたドキュメントをS3にアップロードする処理を入れる必要がある。
entrypoint.sh#!/bin/sh export MAIN_CLASS=$(unzip -p schemaspy*.jar META-INF/MANIFEST.MF | grep Main-Class | awk -F ': ' '{sub(/\r/,"",$2);print $2}') [ "$(ls -A /drivers)" ] && export DRIVER_PATH=/drivers/ || export DRIVER_PATH=/drivers_inc/ echo "Running Main-Class $MAIN_CLASS" echo -n "With drivers:" ls -Ax $DRIVER_PATH | sed -e 's/ */, /g' java -cp *:$DRIVER_PATH* $MAIN_CLASS -o /output -t pgsql -host $DB_HOST -u $DB_USER -db $DB_NAME -p $DB_PASS aws s3 rm $S3PATH --recursive aws s3 cp /output $S3PATH --recursive公式のentrypoint.shは
exec java -jar /usr/local/lib/schemaspy/schemaspy*.jar -dp $DRIVER_PATH -o $OUTPUT "$@"となっており、java実行時に引数をすべて渡すようになっているが、S3にアップロード処理を書く際に汎用性とセキュリティの観点から環境変数で指定してあげるようにする。
java -cp *:$DRIVER_PATH* $MAIN_CLASS -o /output -t pgsql -host $DB_HOST -u $DB_USER -db $DB_NAME -p $DB_PASS aws s3 rm $S3PATH --recursive aws s3 cp /output $S3PATH --recursiveこれで以下の環境変数を設定する必要が発生する。
- DB_HOST
- DB_USER
- DB_NAME
- DB_PASS
- S3PATH
s3を一度削除しているのはテーブル構成の変更で不要なファイルが発生することがあるため。
ECR
何かとECSで動かす場合はECRに乗せたほうが幸せになるので乗せる
FIY
Amazon ECR で AWS CLI を使用する - Amazon ECR
AWS CLI で Amazon ECR に docker イメージを push する - Qiita例) er-documentsというリポジトリで作成していた場合
docker build -t er-documents . aws ecr get-login --no-include-email --region ap-northeast-1 |bash - docker tag er-documents:latest 000000000.dkr.ecr.ap-northeast-1.amazonaws.com/er-documents:latest docker push 000000000.dkr.ecr.ap-northeast-1.amazonaws.com/er-documents:latestECS
今回は常時起動ではなくスケジューリングで動かすので以下の記事を参考にタスクの定義まで行ってください
Amazon ECS入門 〜公式のDockerイメージを使って10分で構築してみる〜 | DevelopersIO
AWS ECSでDockerコンテナ管理入門(基本的な使い方、Blue/Green Deployment、AutoScalingなどいろいろ試してみた) - Qiitaタスクの定義が終わったらスケジューリングを行います
参考例を上げておきますFargateがタスクスケジュールをサポートし定期実行処理の幅が超広がりました! | DevelopersIO
後は実行されるのを待てば完了です
- 投稿日:2019-10-24T20:36:48+09:00
Cognito UserPoolのユーザーIDとメールアドレスの文字数の限界にトライしただけ
TL;DR
ユーザーIDは128文字、メールアドレスは320文字(2019-10-24時点)
検証
ユーザーID
129文字(
test+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
)
128文字(
test+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
)
メールアドレス
321文字(
test+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234@example.com
)320文字(
test+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123@example.com
)
- 投稿日:2019-10-24T20:36:48+09:00
Cognito UserPoolのユーザーネームとメールアドレスの文字数の限界にトライしただけ
TL;DR
ユーザーネームは128文字、メールアドレスは320文字(2019-10-24時点)
検証
ユーザーネーム
129文字(
test+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234
)
128文字(
test+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123
)
メールアドレス
321文字(
test+1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234@example.com
)320文字(
test+123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123@example.com
)
- 投稿日:2019-10-24T19:50:56+09:00
Webアプリを作る【Webサーバー, ユーザー認証, データベース】
WebアプリのWebサーバー, ユーザー認証, データベースってどうすればいいのかな...
はじめに
今回はWebアプリケーションのサーバサイド, Webサーバー, ユーザー認証, データベースが使えるようになるチュートリアルの紹介です.
まだWebアプリのフロントサイドを作ってない人でも大丈夫. テンプレが用意されています.紹介するチュートリアルはこちら. AmazonのAWSというサービスを使っていきます.
準備するものは, AWSのアカウント(無料で作れます)だけ. AWSの無料利用枠でこのチュートリアルができます.ではいきましょっ! 超簡単です.
AWSのサービス
Webアプリなので, ブラウザで表示させるHTMLやCSSなどのファイルがあります. そういったファイルはS3(上の図の①)と呼ばれるWebサーバーに保存します.
ユーザーの管理や認証はCognito(②)で行います. 今回は, メールアドレスとパスワードで認証します.
Webサイトからデータベースにアップロードする仕組みを作るために, API Gateway④, Lambda⑤, DynamoDB⑥を使います(それぞれの説明は後述).
チュートリアルの紹介
AWSのチュートリアルを実行すれば, WebアプリのWebサーバー, ユーザー認証, データベースの仕組みが理解できます.
ただAWSのチュートリアルは少し手順が多いので, 目的や流れを先に理解しておきましょう.チュートリアルの目的
作るWebアプリでは, まずメールアドレスとパスワードでユーザー認証ができます. さらにウェブサイト上の地図をクリックすると, その地点に乗馬のリクエストが送れて, そこに馬のアイコンが走ってくるというWebアプリです.
チュートリアルの目的は, WebサーバーにHTMLなどのファイル(テンプレが用意されている)を置いて, ユーザー認証を作り, データベースへアクセス(乗馬リクエスト)することです.チュートリアルの流れ
1. WebサイトのファイルをWebサーバーにアップロードして公開する
a. Webサイトのファイル(HTML, CSS, JavaScriptなど)をWebサーバー(S3)にアップロードする.
b. 匿名ユーザーがWebサーバーにアクセスできるようにする.
c. URLからWebサーバーにアクセスできるようにする.2. ユーザー管理と認証の仕組みを作る
a. ユーザーを管理するフォルダ(Cognitoのユーザープール)を作る.
b. Websiteからアクセスできるようにする(メアドとパスワードでの認証設定はアップロードしたファイルに記述済み).3. データベースにアクセスする処理を作る
a. 乗馬リクエストをアップするためのデータベース(DynamoDBのバケット)を用意する.
b. 乗馬リクエストをアップして, 馬のアイコンを送る処理(Lambdaの関数)を作る.
c. bの処理をWebsiteから呼び出すための仕組み(API GatewayのAPI)を作る.以上の流れを意識しながら, ぜひチュートリアルをやってみてください!
- 投稿日:2019-10-24T18:26:34+09:00
PHP Slim 環境構築(14) ECS(手動で設定するEC2編)
PHP Slim 環境構築(14) ECS(手動で設定するEC2編)
Introduction
前回は、EC2上にNginxとPHP-FPMの両方を格納したDockerコンテナを構築し、AWSの各種サービス(RDB、DynamoDB、S3)とアクセスさせてみました。
今回は、同じDockerコンテナをECS上に構築します。この一連のシリーズは、自分への備忘録が第一目的のため、だいぶ不親切です。
申し訳ございません。変更点
ソースコードの変更は、Dockerfileのみです。
このシリーズで構築した環境では、Dockerfileのパス(/compose/web_hoge)とソースコード(/src/hogeや/src/vendor)が離れており、docker-composeのvolumesを使ってコンテナにソースを組み込んでいます。ソースツリー$(PROJECTROOT) /compose /web_hoge Dockerfile /src /hoge /vendordocker-compose.ymlweb_hoge: build: context: ./web_hoge volumes: - ../src/hoge:/var/www/hoge - ../src/vendor:/var/www/vendor - ../credentials:/usr/local/etc/myapp/credentialsDockerfileの変更
Dockerfileでは、作業ディレクトリよりも親への参照ができません。(例: COPY ../../src/web_hoge など)
したがって、docker build -f compose/web_hoge/Dockerfile .
のように-fオプションで子ディレクトリ内のDockerfileを指定することになります。これに伴い、Dockerfile内のファイル参照のパスも変更されます。
具体的な変更箇所は、COPYコマンドのコピー元が$(PROJECTROOT)からの相対パスで記述されるようになったことと、docker-composeのvolumesの代わりにソースをコピーするようになったことです。DockerfileFROM alpine:3.10.2 ARG environment ..(略).. # supervisord RUN mkdir -p /etc/supervisor.d COPY compose/web_hoge/supervisord.conf /etc/supervisord.conf # settings COPY compose/web_hoge/settings-${environment}.yml /usr/local/etc/myapp/settings.yml # PHP COPY compose/web_hoge/php.ini /php.ini COPY compose/web_hoge/php-fpm.conf /php-fpm.conf COPY compose/web_hoge/php-fpm-supervisor.conf /php-fpm-supervisor.conf RUN cp /php-fpm.conf /etc/php7/php-fpm.d/z-php.conf \ && cp /php.ini /etc/php7/conf.d/config.ini \ && cp /php-fpm-supervisor.conf /etc/supervisor.d/php-fpm.conf # Nginx COPY compose/web_hoge/nginx.conf /nginx.conf COPY compose/web_hoge/nginx-server.conf /nginx-server.conf COPY compose/web_hoge/nginx-supervisor.conf /nginx-supervisor.conf RUN cp /nginx.conf /etc/nginx/nginx.conf \ && cp /nginx-server.conf /etc/nginx/conf.d/default.conf \ && cp /nginx-supervisor.conf /etc/supervisor.d/nginx.conf ..(略).. # ソース追加(以下三行追加) COPY src/hoge /var/www/hoge COPY src/vendor /var/www/vendor COPY credentials /usr/local/etc/myapp/credentials EXPOSE 3128 ENTRYPOINT ["/usr/bin/supervisord", "-c", "/etc/supervisord.conf"]AWS
ECR
今回はDockerリポジトリとして、Amazon ECRを使用することにします。
ECRサービスメニューから、リポジトリの作成を選びます。
パラメータ 値 リポジトリ名 hoge-repo このリポジトリのURIは、
<<AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo
になります。ビルド
適当なEC2上でビルドすることにします。なお、以下の条件が整っているものとします。
- aws configureで接続設定済み (regionはap-northeast-1)
- dockerコマンドがインストール済み
- gitコマンドやファイルコピーなどで最近のソースが取得可能
- ECRへの操作権限を持っている
# $(aws ecr get-login --no-include-email) # ACCOUNT_ID=$(aws sts get-caller-identity | grep Account | grep -oE '[0-9]+') # cd <<PROJECT_ROOT>> # docker build -t hoge-repo:latest --build-arg environment=devaws -f compose/web_hoge/Dockerfile . # docker tag hoge-repo:latest $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest # docker push $ACCOUNT_ID.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latestIAM(ロールの作成)
Dockerコンテナの持つロールを定義しておきます。
RDS、DynamoDBなどにアクセスすることからそれらを操作する権限が必要です。
(接続確認を優先したため、権限が大きい(FullAccess)です! 本番注意)。
パラメータ 値 ロール名 hoge-ecs-user AWSサービス Elastic Container Service Task ポリシー AmazonRDSFullAccess, AmazonDynamoDBFullAccess, AmazonS3FullAccess EC2(ターゲットグループ)
ロードバランサの設定前に、そのターゲットグループを設定しておきます。
ポートは、nginxへのアクセスポートである3128です。
パラメータ 値 名前 hoge-target ターゲットの種類 インスタンス ポート 3128 ヘルスチェック http /favicon.ico EC2(セキュリティグループ)
以下の二種類のアクセスに対するセキュリティグループを定義します。
- ロードバランサへのアクセス
外部からのhttp(s)のアクセスです。
パラメータ 値 名前 hoge-http-sg インバウンド 80(0.0.0.0/0), 443(0.0.0.0/0)
- Dockerコンテナへのアクセス
ECSのインスタンスへ直接SSHアクセスするための定義(ポート22)と、ALBからのアクセス(動的ポートマッピングを使用するのでその範囲)。
パラメータ 値 名前 hoge-instance-sg インバウンド 22(SSH接続可能なIP), 32768-65535(ロードバランサのVPC)
- AWS Certificate Manager
SSLを使う場合は、こちらで証明書を発行します。発行後、承認されるまでは最大72時間かかるので注意が必要です
(詳細は本筋と外れるので省略)。
- EC2(ロードバランサ)
ALBの設定を行います。
パラメータ 値 名前 hoge-alb スキーム インターネット向け リスナー 80, 443(証明書が必要です) AZ ap-northeast-1a, 1c, 1d全部 セキュリティグループ hoge-http-sg ターゲットグループ hoge-target
- ECS(クラスター)
ECS用のクラスターを作成します。なお、この設定を行った際に、自動的にEC2(Auto Scalingグループ)とEC2(起動設定)が作成されます。
パラメータ 値 クラスターテンプレート EC2 Linux + ネットワーキング クラスター名 hoge-cluster プロビジョニングモデル オンデマンド EC2インスタンス t2.micro インスタンス数 1 キーペア 直接インスタンスにアクセスする場合は設定する。本番環境等ではなし VPC 既存のVPC サブネット ap-northeast-1a, 1c, 1dの全部 セキュリティグループ hoge-instance-sg コンテナインスタンスIAMロール ecsInstanceRole(自動生成される)
- EC2(起動設定)
クラスターを生成したときに自動生成された起動設定をコピーし、修正します。
ユーザーデータでは、サーバに必要な設定の変更なども行います (ここに示しているのはあくまでサンプルです)。
パラメータ 値 名前 hoge-launch-config IAMロール ecsInstanceRole モニタリング 詳細モニタリングを無効に ユーザーデータ (下記参照) IPアドレスタイプ 直接インスタンスにアクセスする場合は割り当てる。本番環境等では割り当てない ユーザーデータ#!/bin/bash cat <<'ECS_EOF' >> /etc/ecs/ecs.config ECS_CLUSTER=hoge-cluster ECS_BACKEND_HOST= #ECS_LOGLEVEL=debug ECS_EOF cat <<'SYS_EOF' >> /etc/sysctl.conf net.core.somaxcon=65535 SYS_EOF sysctl -p /etc/sysctl.conf cat <<'FLIMIT_EOF' > /etc/security/limits.d/filelimits.conf * soft nofile 32768 * hard nofile 32768 FLIMIT_EOF ulimit -n 32768
- EC2(Auto Scalingグループ)
クラスターを生成したときに自動生成されたオートスケールグループ設定をコピーし、修正します。
パラメータ 値 起動設定 hoge-launch-config
- ECS(タスク定義)
ECSで生成されたインスタンスにDockerコンテナを載せるためのタスク定義を行います。
パラメータ 値 起動タイプ EC2 タスク定義名 hoge-task タスクロール hoge-ecs-user ネットワークモード タスク実行ロール ecsTaskExecuteRole(自動生成される) タスクメモリ なし (本当はちゃんと設定する) タスクCPU 1024 (本当はちゃんと設定する) コンテナ名 hoge-container イメージ <<AWS-ACCOUNT-ID>>.dkr.ecr.ap-northeast-1.amazonaws.com/hoge-repo:latest メモリ制限 ハード/300MB (本当はちゃんと設定する) ポートマッピング ホスト(0) : コンテナ(3128) (自動ポートマッピングを使用するのでホストポートは0)
- ECS(サービス追加)
タスクを元にECSにサービスを追加します。
パラメータ 値 起動タイプ EC2 タスク定義 hoge-task クラスタ hoge-cluster サービス名 hoge-service サービスタイプ REPLICA タスクの数 1 デプロイ ローリングアップデート ロードバランサー hoge-alb サービス用IAMロール AWSServiceRoleForECS ロードバランス用コンテナ hoge-container:0:3128 サービスの検出の統合の有効性 無効 ロードバランス用のコンテナターゲット hoge-target AutoScaling 無効 接続確認
ここまで完了すれば、うまく動いている(はず)です。
うまくいっていれば、以下のURLにアクセスすれば"BEFORE:Hello, World!:AFTER"が表示されます。
SSL接続するケースや、独自ドメインを使用するケースはここでは割愛します。
http://hoge-alb-<<ALBに割り当てられたID>>.ap-northeast-1.elb.amazonaws.com/
- 投稿日:2019-10-24T18:07:11+09:00
AWS CLIを使ってAmazon SNSからPushKitのVoIPプッシュ通知を送る
これはなに
AWS CLIを使ってAmazonSNSからiOSのVoIPプッシュ通知(PushKit通知)を送る手順について、主にデバッグ用途です。
当方、AWSに詳しくないので内容に誤りがある場合はご指摘ください。準備
- AWS CLIをインストールする
- AmazonSNS full access権限のあるIAMを払い出す(もしくは最小限のアクセス権限)
- 環境変数にIAMの情報をセットする
# env | grep AWS AWS_SECRET_ACCESS_KEY=XXXXX.... AWS_DEFAULT_REGION=ap-northeast-1 AWS_DEFAULT_OUTPUT=json AWS_ACCESS_KEY_ID=YYYYY...エンドポイントの登録
試験用であればAmazonSNSのGUIから登録すればよい、手順は省略。
注意点とし、手元の環境では東京リージョンに登録したエンドポイントへはcliから送信できなかった。米国東部 (バージニア北部)にアプリケーションを作成して登録したら送信できた(要調査)。
aws cli からVoIPプッシュ通知を送る
開発環境(sandbox)の例
endpointのarnが
arn:aws:sns:us-east-1:xxxxxxxxx:endpoint/APNS_VOIP_SANDBOX/your_app_name/yyyy....
の場合のコマンドaws sns publish \ --target-arn arn:aws:sns:us-east-1:xxxxxxxxx:endpoint/APNS_VOIP_SANDBOX/your_app_name/yyyy.... \ --message-attributes \ '{ "AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"voip"}}' \ --message '{"APNS_VOIP_SANDBOX":"{\"aps\":{\"foo\":\"bar\"}}"}' \ --message-structure jsonポイントは
--message-attributes
で"AWS.SNS.MOBILE.APNS.PUSH_TYPE":{"DataType":"String","StringValue":"voip"}
を指定すること--message
でAPNS_VOIP_SANDBOX
キーにaps
を含むデータを入れること本番環境の例
基本的に開発用の場合と同じ、ただし
APNS_VOIP_SANDBOX
をAPNS_VOIP
に変更すること。要調査
- 東京リージョンに登録した場合にcliで送信できない件、仕様なのか手順ミスなのか
参考情報
- 投稿日:2019-10-24T17:23:39+09:00
Amazon QuickSightの埋め込み手順
はじめに
クラスメソッドさんの記事を見ながらやったら思いの外ハマりにハマった話。
前提条件
- QuickSightのプランがエンタープライズであること
確認は、QuickSightの画面の右上の人のマークをクリック、「QuickSightの管理」をクリックすれば左上の画面に出てくる。
ハマった点
aws cliから挑んだところこんな感じのエラー
記事通りaws cliを使って試してみました。
arata.honda@hoge:$ aws quicksight get-dashboard-embed-url --aws-account-id [AWSプロジェクトアカウント] --dashboard-id [ダッシュボードID] --identity-type IAM --session-lifetime-in-minutes 15 An error occurred (AccessDeniedException) when calling the GetDashboardEmbedUrl operation: User: arn:aws:iam::[AWSプロジェクトアカウント]:user/honda is not authorized to perform: quicksight:GetDashboardEmbedUrl on resource: arn:aws:quicksight:ap-northeast-1:[AWSプロジェクトアカウント]:dashboard/[ダッシュボードID]ちなみにダッシュボードIDは公開したダッシュボードのURLについてます。(下図黒塗り)
ポリシーアタッチで既にハマった
まぁAccessDeniedExeptionだから、ポリシーとかRoleなんだろうなと思い。公式を見ました。
https://aws.amazon.com/jp/blogs/news/embed-interactive-dashboards-in-your-application-with-amazon-quicksight/みたところ上記エラーのポリシーを作ってロールでアタッチしているようでした。
なので、
quicksight-policy.json{ "Version": "2012-10-17", "Statement": [ { "Action": "quicksight:RegisterUser", "Resource": "*", "Effect": "Allow" }, { "Action": "quicksight:GetDashboardEmbedUrl", "Resource": "arn:aws:quicksight:ap-northeast-1:[AWSプロジェクトアカウント]:dashboard/*", "Effect": "Allow" } ] }としてみました。変えたのはResourceのところで、
arn:aws:quicksight:ap-northeast-1:[AWSプロジェクトアカウント]:dashboard/*
ここは、どのダッシュボードでも埋め込みできるようにワイルドカードである"※"をつけております。また公式ドキュメントはus-eastにresionがなっているのでap-northeastにしています。
これを作ってまずcreate-policyしました。
arata.honda@hoge:~$ aws iam create-policy --policy-name quicksight-embed-policy(任意でつけた) --policy-document file://quicksight-policy.json { "Policy": { "PolicyName": "quicksight-embed-policy", "PolicyId": "英数字の羅列", "Arn": "arn:aws:iam::[AWSプロジェクトアカウント]:policy/quicksight-embed-policy", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "CreateDate": "2019-10-24T03:02:50Z", "UpdateDate": "2019-10-24T03:02:50Z" } }この時 "file://quicksight-policy.json"の"file://"がないと
An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: This policy contains invalid Json怒られます。(ここで一回ハマりました。)
次に、公式通り、このポリシーを一時的に信頼するAssumeRolePolicyも作っておきました。
quicksight-role-trust-policy.json{ "Version": "2012-10-17", "Statement": { "Effect": "Allow", "Action": "sts:AssumeRole", "Resource": "arn:aws:iam::[AWSプロジェクトアカウント]:role/quicksight-embed-policy" } }ここのResourceはさっきつくった"quicksight-policy"を書いておきましょう。(公式のコピペは絶対に動きません)
AssumeRolePolicyなので、それ用のコマンドをうつと怒られました。aws iam create-role --role-name quicksight-embed-role --assume-role-policy-document file://quicksight-role-trust-policy.json An error occurred (MalformedPolicyDocument) when calling the CreateRole operation: Has prohibited field ResourceここをみるどうやらResourceは定義できないとのこと。
なので諦めて普通にポリシーとして登録しました。(偉い人がいれば教えて下さい)
ここでもハマりました。上と同様にアタッチすると普通に通りました。aws iam create-policy --policy-name quicksight-embed-trust-policy --policy-document file://quicksight-role-trust-policy.json { "Policy": { "PolicyName": "quicksight-embed-trust-policy", "PolicyId": "英数字の羅列", "Arn": "arn:aws:iam::[AWSプロジェクトアカウント]:policy/quicksight-embed-trust-policy", "Path": "/", "DefaultVersionId": "v1", "AttachmentCount": 0, "PermissionsBoundaryUsageCount": 0, "IsAttachable": true, "CreateDate": "2019-10-24T03:26:19Z", "UpdateDate": "2019-10-24T03:26:19Z" } }ユーザーおるやん編
作ったら次にawsコマンドをうっているユーザに2つのポリシーをアタッチしました。
2つのポリシーをアタッチして再度aws cliでgetEmbdedコマンドをうってみました。
arata.honda@hoge:~$ aws quicksight get-dashboard-embed-url --aws-account-id [AWSプロジェクトアカウト] --dashboard-id [ダッシュボードID] --identity-type IAM --session-lifetime-in-minutes 15 An error occurred (QuickSightUserNotFoundException) when calling the GetDashboardEmbedUrl operation: Could not find user information in QuickSight 訳:ユーザーおらんやでユーザーおるやんってずっとおもってまたハマりました。
実は、QuickSightのユーザーはエンタープライズになるとIAMでつくったユーザも管理できるようで、追加する必要がありました。
追加して、コマンドを打つと、
arata.honda@hoge:~$ aws quicksight get-dashboard-embed-url --aws-account-id [AWSプロジェクトアカウント] --dashboard-id [ダッシュボードID] --identity-type IAM --session-lifetime-in-minutes 15 { "Status": 200, "EmbedUrl": "https://ap-northeast-1.quicksight.aws.amazon.com/embed/cf1d3e05c8da41728eacd08653d58921/dashboards/[ダッシュボードID]?isauthcode=true&identityprovider=quicksight&code=英字の羅列", "RequestId": "26ffa865-bbbc-47a8-8dc3-efedea981d47" }やっときました。
見れへんで編
このEmbedUrlをクリックして早速確認しました。
しらこい画面しやがって!!!!!!!キーーーーーーって癇癪起こしそうになってしばらくハマってました。
実はまだあって、公開したダッシュボードで共有しないとまだ見れないです。
「ダッシュボードの共有」を押し、
追加しましょう。おわりに
公式もみるのは大事だし、基本的なことがあまりわかってないのがわかりました。(小並感
参考
- 投稿日:2019-10-24T16:27:19+09:00
Proxy環境下でWinSCPを使う
- 投稿日:2019-10-24T16:19:53+09:00
【検証】AWS Aurora Ver.1系 ⇄ 2系のクラスタ間レプリケーション
趣旨
MySQL 5.6互換の Aurora 1.14.4 から 5.7互換の 2.0x へ移行しようとしており、
移行にあたり課題が2つあるため検証を行った。前提
- Aurora 1 のインスタンスから、直接 Aurora 2 へアップグレードすることはできない
- Aurora 1 のスナップショットを作成し、別のクラスターとして Aurora 2 にアップグレード(復元)する
- 不要になったタイミングで Aurora 1 クラスターを削除する
- Aurora 2 のスナップショットから Aurora 1 の復元は不可能
- つまり Aurora 1 クラスターを削除すると 5.6互換へは切り戻しができなくなる
検証すること
- 稼働中の現 DB(Aurora 1) 群の中に可能な限り止めたくない DB がある
- 現 DB(Aurora 1) から新 DB(Aurora 2) へのクラスタ間レプリケーションが必要
- 公式ドキュメントでは Aurora 1 と Aurora 2 でできるとか、できないとか言及はないが可能なのか?
- 新 DB(Aurora 2) を作成した後で移行検証を行いたい
- 新 DB(Aurora 2) の検証期間中のデータを現 DB(Auora 1) に反映させたい
- これもクラスタ間レプリケーションが必要だがそれは可能なのか?
公式ドキュメントと、Qiita の先人の知恵を参考に実施する。
https://docs.aws.amazon.com/ja_jp/AmazonRDS/latest/AuroraUserGuide/AuroraMySQL.Replication.MySQL.html
https://qiita.com/kometarou/items/2e79b2ade4d37cbbf9bc
https://qiita.com/kooohei/items/ee3f1463419d0201e00f注記
公式ドキュメントに記載されている通り、クラスターパラメータグループ の binlog_format 設定、
Master 側 DB の Security Group で Slave 側のインバウンド許可をする必要があるが、本記事では省略する。Aurora 1(Master) -> 2(Slave) へのクラスタ間レプリケーション検証
Master 側となる MySQL 5.6互換の Aurora 1 インスタンスを作成しておく。
Master 側 エンドポイント情報
5H0G0-aurora1-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.comMaster 側 でバイナリログの保持期間設定(7日間)
AWS 公式ドキュメントに従い、Aurora MySQL DB クラスターからのレプリケーションを有効にするためにバイナリログの保持期間を設定する。
下記は Aurora に接続するための EC2 インスタンスにログインし、Aurora に接続した際のログ。[ec2-user@verify-01 ~]$ mysql -h 5H0G0-aurora1-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 151 Server version: 5.6.10-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> CALL mysql.rds_set_configuration('binlog retention hours', 168); Query OK, 0 rows affected (0.01 sec) MySQL [(none)]> CALL mysql.rds_show_configuration; +------------------------+-------+------------------------------------------------------------------------------------------------------+ | name | value | description | +------------------------+-------+------------------------------------------------------------------------------------------------------+ | binlog retention hours | 168 | binlog retention hours specifies the duration in hours before binary logs are automatically deleted. | +------------------------+-------+------------------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec) Query OK, 0 rows affected (0.00 sec)Master 側 レプリ用ユーザ作成
クラスタ間レプリケーションを行う際、Master 側 の DB でレプリケーション専用のユーザーを作成する必要がある。
ユーザーを作成した後に、正しく作成できているか確認しておく。MySQL [(none)]> CREATE USER 'repl_user'@'10.1.0.0/255.255.0.0' IDENTIFIED BY '123asd456fgh'; Query OK, 0 rows affected (0.01 sec) MySQL [(none)]> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'10.1.0.0/255.255.0.0' IDENTIFIED BY '123asd456fgh'; Query OK, 0 rows affected, 1 warning (0.01 sec) MySQL [(none)]> SELECT Host, User FROM mysql.user;また、ユーザーには REPLICATION CLIENT および REPLICATION SLAVE 権限が必要なため、権限を付与する。
MySQL [(none)]> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'192.168.32.0/255.255.0.0' IDENTIFIED BY '123asd456fgh'; Query OK, 0 rows affected, 1 warning (0.01 sec) MySQL [(none)]> SHOW GRANTS for 'repl_user'@'192.168.32.0/255.255.0.0'; +----------------------------------------------------------------------------------------------+ | Grants for repl_user@192.168.32.0/255.255.0.0 | +----------------------------------------------------------------------------------------------+ | GRANT REPLICATION SLAVE, REPLICATION CLIENT ON *.* TO 'repl_user'@'192.168.32.0/255.255.0.0' | +----------------------------------------------------------------------------------------------+ 1 row in set (0.00 sec)レプリケーションを開始する際に、バイナリログファイル名、ポジションを指定する必要があるため、事前に確認しておく。
MySQL [(none)]> SHOW MASTER STATUS\G *************************** 1. row *************************** File: mysql-bin-changelog.000006 Position: 793 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)この状態で Aurora 1 のスナップショットを作成して Aurora 2 クラスターを新たに起動(復元)。
Slave 側 エンドポイント情報
mysql -h 5H0G0-aurora2-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.comSlave 側 レプリケーション開始
Aurora 2 のインスタンスが起動したら、EC2 からログインし、早速レプリケーションを開始する。
先ほど確認したバイナリログファイル名、ポジションを指定する。[ec2-user@verify-01 ~]$ mysql -h mysql -h 5H0G0-aurora2-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 25 Server version: 5.7.12-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> CALL mysql.rds_set_external_master ('5H0G0-aurora1-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com', 3306, 'repl_user', '123asd456fgh', 'mysql-bin-changelog.000006', 793, 0); Query OK, 0 rows affected (0.11 sec) MySQL [(none)]> CALL mysql.rds_start_replication; +-------------------------+ | Message | +-------------------------+ | Slave running normally. | +-------------------------+ 1 row in set (1.00 sec) Query OK, 0 rows affected (1.00 sec)Master 側 テーブルを作成する
Master 側で行なった操作が Slave 側にレプリケーションされることを確認する。
試しに sample_tbl というテーブルを作成する。MySQL [sample_db]> create table sample_tbl ( -> id int, -> username varchar(255), -> password char(255) -> ); Query OK, 0 rows affected (0.05 sec) MySQL [sample_db]> show tables; +---------------------+ | Tables_in_sample_db | +---------------------+ | sample_tbl | +---------------------+ 1 row in set (0.00 sec) MySQL [sample_db]> desc sample_tbl; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | username | varchar(255) | YES | | NULL | | | password | char(255) | YES | | NULL | | +----------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec) MySQL [(none)]> SHOW MASTER STATUS\G *************************** 1. row *************************** File: mysql-bin-changelog.000006 Position: 1063 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)Slave 側 で反映確認
Master 側で作ったテーブルが Slave 側にもできていることを確認。
MySQL [(none)]> use sample_db Reading table information for completion of table and column names You can turn off this feature to get a quicker startup with -A Database changed MySQL [sample_db]> show tables; +---------------------+ | Tables_in_sample_db | +---------------------+ | sample_tbl | +---------------------+ 1 row in set (0.00 sec) MySQL [sample_db]> desc sample_tbl; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | username | varchar(255) | YES | | NULL | | | password | char(255) | YES | | NULL | | +----------+--------------+------+-----+---------+-------+ 3 rows in set (0.01 sec)ログのポジション も 1063 に更新されている。
Seconds_Behind_Master が 0 であり、レプリケートが Master に追いついていることを示していることも確認。MySQL [(none)]> show slave status \G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 5H0G0-aurora1-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com Master_User: repl_user Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin-changelog.000006 Read_Master_Log_Pos: 1063 Relay_Log_File: relaylog.000003 Relay_Log_Pos: 500 Relay_Master_Log_File: mysql-bin-changelog.000006 Slave_IO_Running: Yes Slave_SQL_Running: No Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: mysql.rds_replication_status,mysql.rds_monitor,mysql.rds_sysinfo,mysql.rds_configuration,mysql.rds_history Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 1396 Last_Error: Error 'Operation CREATE USER failed for 'repl_user'@'192.168.32.0/255.255.0.0'' on query. Default database: 'sample_db'. Query: 'CREATE USER 'repl_user'@'10.1.0.0/255.255.0.0' IDENTIFIED BY PASSWORD '*38BF48B12A98F78945AA3F98DDA81879D857FAC3'' Skip_Counter: 0 Exec_Master_Log_Pos: 293 Relay_Log_Space: 1165398 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 1396 Last_SQL_Error: Error 'Operation CREATE USER failed for 'repl_user'@'192.168.32.0/255.255.0.0'' on query. Default database: 'sample_db'. Query: 'CREATE USER 'repl_user'@'192.168.32.0/255.255.0.0' IDENTIFIED BY PASSWORD '*38BF48B12A98F78945AA3F98DDA81879D857FAC3'' Replicate_Ignore_Server_Ids: Master_Server_Id: 213430958 Master_UUID: 24497ba1-74bb-3d70-8719-c53fbb93e3e5 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: 190724 04:36:11 Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 Replicate_Rewrite_DB: Channel_Name: Master_TLS_Version: 1 row in set (0.00 sec)Aurora 2(Master) -> 1(Slave) へのクラスタ間レプリケーション検証
Aurora 2 で稼働に問題がないか検証している最中、保険として今まで動いていた Aurora 1 に検証期間中のデータを反映させたい。
その場合、冒頭に書いた通り Aurora 2 のスナップショットから Aurora 1 へは復元ができない。
とすると、Aurora 1 も 2 も稼働した状態で、2 -> 1 へクラスタ間レプリケーションを張る以外に解決策がない。
(mysqldump は大変な手間がかかると訊いているため、お客様の環境では避けたい)実際の移行作業と同じくするため、あらかじめ Aurora 1 の DB を作成し、
table なども作成しておき、スナップショットから Aurora 2 を復元。
Aurora 2 から Aurora 1 へのレプリケーションを張る。(事前作業) Slave 側 エンドポイント情報
すでに稼働中の移行前 Aurora 1 を模した Slave 側の DB を事前に作成しておく。
mysql -h 5H0G0-aurora3-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com(事前作業) Slave 側 テーブルを作成
レプリケーション後に DB の内容に変更を加え、反映確認を行うため事前にテーブルを作成しておく。
(レプリケーションを張った後でも良い。順不同。)[ec2-user@verify-01 ~]$ mysql -h 5H0G0-aurora3-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 151 Server version: 5.6.10-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> show databases; +--------------------+ | Database | +--------------------+ | information_schema | | mysql | | performance_schema | | sample_db2 | +--------------------+ 4 rows in set (0.01 sec) MySQL [(none)]> use sample_db2; Database changed MySQL [sample_db2]> create table sample_tbl ( -> id int, -> username varchar(255), -> password char(255) -> ); Query OK, 0 rows affected (0.03 sec) MySQL [sample_db2]> desc sample_tbl; +----------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | username | varchar(255) | YES | | NULL | | | password | char(255) | YES | | NULL | | +----------+--------------+------+-----+---------+-------+ 3 rows in set (0.00 sec)Master 側 エンドポイント情報
この状態で Aurora 1 のスナップショットを作成して Aurora 2 を復元する。
mysql -h 5H0G0-aurora4-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.comMaster 側 でバイナリログの保持期間設定(7日間)
[ec2-user@verify-01 ~]$ mysql -h mysql -h 5H0G0-aurora4-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com -P 3306 -u root -p Enter password: Welcome to the MariaDB monitor. Commands end with ; or \g. Your MySQL connection id is 25 Server version: 5.7.12-log MySQL Community Server (GPL) Copyright (c) 2000, 2016, Oracle, MariaDB Corporation Ab and others. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. MySQL [(none)]> CALL mysql.rds_set_configuration('binlog retention hours', 168); Query OK, 0 rows affected (0.01 sec)Master 側 レプリ用ユーザ作成
MySQL [(none)]> CREATE USER 'repl_user'@'10.1.0.0/255.255.0.0' IDENTIFIED BY '123asd456fgh'; Query OK, 0 rows affected (0.01 sec) MySQL [(none)]> GRANT REPLICATION CLIENT, REPLICATION SLAVE ON *.* TO 'repl_user'@'10.1.0.0/255.255.0.0' IDENTIFIED BY '123asd456fgh'; Query OK, 0 rows affected, 1 warning (0.03 sec)Master 側 バイナリログファイルの名前確認
MySQL [(none)]> SHOW MASTER STATUS\G *************************** 1. row *************************** File: mysql-bin-changelog.000008 Position: 742 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)Slave 側 レプリケーション開始
MySQL [(none)]> CALL mysql.rds_set_external_master ('5H0G0-aurora4-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com', 3306, 'repl_user', '123asd456fgh', 'mysql-bin-changelog.000008', 742, 0); Query OK, 0 rows affected (0.17 sec) MySQL [(none)]> CALL mysql.rds_start_replication; +-------------------------+ | Message | +-------------------------+ | Slave running normally. | +-------------------------+ 1 row in set (1.01 sec) Query OK, 0 rows affected (1.01 sec)Master 側 テーブルの変更
テーブルに phonenumber という column を追加してみる。
MySQL [sample_db2]> ALTER TABLE sample_tbl ADD phonenumber int; Query OK, 0 rows affected (0.06 sec) Records: 0 Duplicates: 0 Warnings: 0 MySQL [sample_db2]> desc sample_tbl; +-------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | username | varchar(255) | YES | | NULL | | | password | char(255) | YES | | NULL | | | phonenumber | int(11) | YES | | NULL | | +-------------+--------------+------+-----+---------+-------+ 4 rows in set (0.00 sec)バイナリログを確認する。
MySQL [sample_db2]> SHOW MASTER STATUS\G *************************** 1. row *************************** File: mysql-bin-changelog.000008 Position: 935 Binlog_Do_DB: Binlog_Ignore_DB: Executed_Gtid_Set: 1 row in set (0.00 sec)Slave 側 で反映確認
テーブルに phonenumber という column がレプリケートされていることを確認。
MySQL [sample_db2]> desc sample_tbl; +-------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +-------------+--------------+------+-----+---------+-------+ | id | int(11) | YES | | NULL | | | username | varchar(255) | YES | | NULL | | | password | char(255) | YES | | NULL | | | phonenumber | int(11) | YES | | NULL | | +-------------+--------------+------+-----+---------+-------+ 4 rows in set (0.00 sec)ログのPosition も742 から 935 に更新されている。
Seconds_Behind_Master が 0 であり、レプリケートが Master に追いついていることを示していることも確認。MySQL [sample_db2]> MySQL [sample_db2]> show slave status \G *************************** 1. row *************************** Slave_IO_State: Waiting for master to send event Master_Host: 5H0G0-aurora4-cluster.cluster-xxxxxxxxxxxx.ap-northeast-1.rds.amazonaws.com Master_User: repl_user Master_Port: 3306 Connect_Retry: 60 Master_Log_File: mysql-bin-changelog.000008 Read_Master_Log_Pos: 935 Relay_Log_File: relaylog.000002 Relay_Log_Pos: 489 Relay_Master_Log_File: mysql-bin-changelog.000008 Slave_IO_Running: Yes Slave_SQL_Running: Yes Replicate_Do_DB: Replicate_Ignore_DB: Replicate_Do_Table: Replicate_Ignore_Table: mysql.rds_replication_status,mysql.rds_monitor,mysql.rds_sysinfo,mysql.rds_configuration,mysql.rds_history Replicate_Wild_Do_Table: Replicate_Wild_Ignore_Table: Last_Errno: 0 Last_Error: Skip_Counter: 0 Exec_Master_Log_Pos: 935 Relay_Log_Space: 655 Until_Condition: None Until_Log_File: Until_Log_Pos: 0 Master_SSL_Allowed: No Master_SSL_CA_File: Master_SSL_CA_Path: Master_SSL_Cert: Master_SSL_Cipher: Master_SSL_Key: Seconds_Behind_Master: 0 Master_SSL_Verify_Server_Cert: No Last_IO_Errno: 0 Last_IO_Error: Last_SQL_Errno: 0 Last_SQL_Error: Replicate_Ignore_Server_Ids: Master_Server_Id: 1008868745 Master_UUID: 8f48e04b-7279-3784-9b5b-2afce563c3b8 Master_Info_File: mysql.slave_master_info SQL_Delay: 0 SQL_Remaining_Delay: NULL Slave_SQL_Running_State: Slave has read all relay log; waiting for the slave I/O thread to update it Master_Retry_Count: 86400 Master_Bind: Last_IO_Error_Timestamp: Last_SQL_Error_Timestamp: Master_SSL_Crl: Master_SSL_Crlpath: Retrieved_Gtid_Set: Executed_Gtid_Set: Auto_Position: 0 1 row in set (0.00 sec)まとめ
今回は MySQL 5.7で廃止・削除されたレコードや、新規追加されたレコードを使うような検証はしていないが、
普通のクラスタ間レプリケーションと同じく、手順を踏めばレプリケーションを張ることが出来ることがわかった。
- 投稿日:2019-10-24T15:26:47+09:00
RDS Aurora Cluster 自動起動停止簡易版(Lambda不使用)
概要
- AuroraClusterの停止機能がリリースされていた
- 開発環境の費用節約のために夜間休日などAuroraを停止したい
- Lambda+CloudWatchなどの組み合わせでもよい手間がかかる
- シンプルにawscliとcronだけで動かす
- 環境はCentsOS7系(AmazonLinux2)
事前準備
- AWSCLIは最新である必要がある(この時点でaws-cli/1.16.264)
- 少しでも古いとAuroraClusterに関する制御系が存在しない
- Pythonは最新である必要がある(この時点でPython3.6系と3.7系)
- Pyenvなどは最新にしておくこと
詳細
Pythonアップデート
- 新しいPythonを入れてセットしておく
$ python --version $ pyenv install --list $ pyenv install 3.6.4 $ pyenv global 3.6.4 $ python --version Python 3.6.4古いCliがあれば削除
- 古いawscliの削除
- 必ずしも必要ではないかも
- 私の場合複数(1.14と1.16)のawscliが入っている状態だったので(なぜかは不明)一旦全削除
$ sudo yum list installed | grep awscli $ pip3 list Package Version --------------- -------- awscli 1.16.264 boto3 1.10.0 botocore 1.13.0 colorama 0.4.1 docutils 0.15.2 jmespath 0.9.4 pip 9.0.1 pyasn1 0.4.7 python-dateutil 2.8.0 PyYAML 5.1.2 rsa 3.4.2 s3transfer 0.2.1 setuptools 28.8.0 six 1.12.0 urllib3 1.25.6 $ pip uninstall awscli ※必要に応じて $ pip3 uninstall awscli : Successfully uninstalled awscli-1.16.264awscliをインストール
- 新しいawscliを入れる
- awsコマンドのパスが通ってない場合がある。その場合はフルパスで実行
$ sudo pip3 install awscli --upgrade : Successfully installed awscli-1.16.266 botocore-1.13.2 $ aws --version aws-cli/1.16.264 Python/3.7.4 Linux/4.9.85-47.59.amzn2.x86_64 botocore/1.13.0 $ pip3 list Package Version --------------- -------- awscli 1.16.266 boto3 1.10.0 botocore 1.13.2 colorama 0.4.1 docutils 0.15.2 jmespath 0.9.4 pip 9.0.1 pyasn1 0.4.7 python-dateutil 2.8.0 PyYAML 5.1.2 rsa 3.4.2 s3transfer 0.2.1 setuptools 28.8.0 six 1.12.0 urllib3 1.25.6権限設定
ポリシー設定
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "logs:CreateLogGroup", "logs:CreateLogStream", "logs:PutLogEvents", "logs:GetLogEvents" ], "Resource": [ "*" ] }, { "Effect": "Allow", "Action": [ "rds:DescribeDBClusters", "rds:ListTagsForResource", "rds:StartDBCluster", "rds:StopDBCluster" ], "Resource": [ "*" ] } ] }グループ
- EC2の起動停止ポリシーはここでは関係ないので無視してください
ユーザ
アクセスキー
動作確認
- まずhelpが動くか確認
- DB停止を周知して停止コマンドを実行してみる
$ aws rds stop-db-cluster help $ aws rds stop-db-cluster --db-cluster-identifier <cluster_name> $ aws rds start-db-cluster --db-cluster-identifier <cluster_name>cron設定
$ sudo vi /etc/cron.d/startRdsAuroraCluster 30 9 * * 1-5 appuser /usr/local/bin/aws rds start-db-cluster --db-cluster-identifier <cluster_name> $ sudo vi /etc/cron.d/stopRdsAuroraCluster 0 23 * * 1-5 appuser /usr/local/bin/aws rds stop-db-cluster --db-cluster-identifier <cluster_name>遭遇したエラー1
- 適切なポリシーが設定できていない場合以下のエラーとなる
- RDSのインスタンスではなくクラスターに対する権限が必要
$ aws rds start-db-cluster --db-cluster-identifier <cluster_name> An error occurred (AccessDenied) when calling the StartDBCluster operation: User: arn:aws:iam::**********:user/stopstart_user is not authorized to perform: rds:StartDBCluster on resource: arn:aws:rds:ap-northeast-1:**********:cluster:<cluster_name>遭遇したエラー2
$ aws rds start-db-cluster --db-cluster-identifier <cluster_name> You must specify a region. You can also configure your region by running "aws configure".$ aws configure AWS Access Key ID [None]: ******************* AWS Secret Access Key [None]:******************* Default region name [None]: ap-northeast-1 Default output format [None]: json $ aws configure list Name Value Type Location ---- ----- ---- -------- profile <not set> None None access_key ****************YUOM shared-credentials-file secret_key ****************zrkd shared-credentials-file region ap-northeast-1 config-file ~/.aws/config
- 必要であればaws configureをしておく
- 私の場合デフォルトリージョンを設定してなかったのでawsコマンド実行時エラーで警告された
- この際のユーザもRDSの起動停止のポリシーだけ作成し、それをセットしたユーザのアクセスキーを使用する事が望ましい
- 面倒であればRDSFullAccessでも
- 投稿日:2019-10-24T14:46:14+09:00
AWSのssmってコスパがいいと思う
はじめに
AWSって簡単にサーバ建てたり、いろいろなことをポチッとするとすぐ動かせていいですよね。
ただ、簡単に建てられるので、管理するのが大変だったりしません?
ssm入れるといろいろさくっと行けそうな感じなので、そこらへんを書こうと思います。EC2にssm入れようと思った経緯
たくさんのEC2の管理がめんどくさいなと思ったので、
Run_commandとか使ってまとめて管理をしたいと思ったため。ssmって何ができるんすか?
ssmの正式名称は、AWS system managerです。
機能としては、awsリソースのマネージメントをするってこと、つまり管理ができるんです。
リソース管理って全部?一部どこまでなんでしょうか、あと他にはどんな機能があるんでしょうか。SSMの項目一覧
何ができるか、運用管理で使われやすそうなところをざっくりと調べてみました。
細かい部分は今回は割愛してます。ここは、OpsCenterです。
ここの項目って、OpsItemという単位で、運用上の問題を管理するってことなんです。たとえば、CloudWatchが検知した、あるイベントが起こったら、EC2を停止してしまうとか
、cloudwatchで設定できるものとは違ったすこしカスタマイズしたトリガーを作れたりします。ここは、オートメーションですね。
管理の自動化の部分なんですが、たとえば、Linuxのパッチ適用をされた状態の
最新AMIを取っておけるので、オートスケーリンググループを更新できたりします。ここは、セッションマネージャーとコマンド実行です。
セッションマネージャーは、AWSコンソールからsshをできる機能なんすが、
料金無料で、sshキーの管理不要になります。まあ、クラウドなんで、本来はこういう使い方をするのが
良いはずです。サーバに直接ログインも基本的には不要になるんで、運用も手間が減りますね。コマンド実行です。
これは、Run_commandという機能を使って、ssmのエージェントを入れて、管理しているインスタンスに
対して、コマンド実行できるものです。
例えば、全インスタンスのカーネル情報が見たいとか。
一回叩けば、情報をまとめて取得可能です。これも無料です。パラメータストアは、
秘密データと設定データをまとめて管理することができます。
たとえば、DBの平文データとか、パスワードとか、設定データとか
外にバレて、悪用されると、とてもまずいものをまとめて管理OKですってかんじですね。
しかも、管理すると、コードから上記の大事なデータは分離できるというメリットつきです。料金は、スタンダードタイプなら基本無料ですが、APIの叩く回数が上限を超えると
追加課金をされるというイメージですね。さいごに
ざっと書いてみましたが、ssmの印象はコスパ良しってところです。
基本的な使い方なら、それほど追加料金が発生せずに、やりたいことができるっていう
印象でした。目標は、サーバに入る必要ありませんってところをやりたいなと思います。
参考記事:https://qiita.com/numasawa/items/ed1f1ef6c7c3c6b4c56b#%E8%BF%BD%E8%A8%98-2018%E5%B9%B410%E6%9C%88
ありがとうございます。
- 投稿日:2019-10-24T12:46:24+09:00
MediaLive で 4K/UHD ライブストリーミング
ようやっと新しいホイールが届いたので早く付けたくてウズウズしている streampack 木村です。
4Kライブをお手軽にやろうとすると、今まで実質 Wowza くらいしか選択肢がなかったのですが、MediaLive も 4K/UHD 配信に対応したので、以前試した下記の記事の Wowza を MediaLive + MediaPackage に変えて実験してみます。
【前回記事】ffmpeg でファイルから4K HEVC疑似ライブストリーミング
構成
Encoder (ffmpeg on EC2) -> RTP -> MediaLive -> MediaPackage -> Player
なんで MediaPackage を使うかというと、以前の案件で Wowza から 4K DASH を出していたから、今回も DASH ろうという魂胆です。
設定
MediaLive
Input
前回は ffmpeg から UDP MPEG-TS で投げてましたが、MediaLive では受けれないので、
RTP_PUSH
で取ることにします。Channel
Output groups
をMediaPackage
に。
DASH 要らんわって方は S3 でも MediaStore でも良いでしょう。3840x2180 UHD H.265 30fps で出力します。
ビットレートは10MbpsMediaPackage
Endpoints
DASH とついでに CMAF も両方作ってみる
Encoder
Encoder は前回と同じく ffmpeg
今回は RTP で投げるので下記コマンドで。
ぐるぐる回すファイルの作成方法は前回記事で。$ ffmpeg -re -stream_loop -1 -i hevcuhd.mp4 -c copy -map 0 -f rtp_mpegts -fec prompeg=l=5:d=20 rtp://xxx.xxx.xxx.xxx:5000視聴
Mac で確認してみます。
左が Safari (CMAF)、右が VLC (MPEG-DASH) です。
4K ディスプレイでフルスクリーンにしてもキレイですよ!
- 投稿日:2019-10-24T07:10:50+09:00
Web開発環境についてのまとめ(随時更新)
Web開発環境について調べたこと、試したことをまとめています。WebデザイナーのWeb制作レガシー環境からWebエンジニアのWeb開発モダン環境への脱皮の過程になるはず…(随時更新中)
Chromeのデベロッパーツール
いつもお世話になっているデベロッパーツール。デベロッパーツール上で直接HTML、CSS、JSを打ち直して修正を検証する方法。
※参考:Chromeデベロッパーツール事始め!HTML、CSS、JSを直感的に修正しよう
Googleアナリティクス
GAの基本、ユーザー、セッション、PVの理解。
※参考:【Googleアナリティクス】ユーザー分析の基本(ユーザー、セッション、PV)
GAからイメージできるユーザー層
※参考:【Googleアナリティクス】主なメニューからユーザー層をイメージする
スマホ、タブレットでのプログラミング
プログラミング=PCというイメージだがタブレットのソフトウェアキーボードでどこまでできるのか検証
※参考:【iPad】ソフトウェアキーボード(QWERTY、フリック、グライド)と物理キーボード比較
次に、スマホだけでプログラミングができるか検証
※参考:【Textastic】もしかしてだけどスマホで技術ブログかけちゃうんじゃないの?
フロントエンド開発環境
WebPackについて調べたら心トキメいた(後に銀の弾丸ではないことを知る…)
※参考:webpackを理解するために調べたこと(Webデザイナー→フロントエンドエンジニアへの脱皮)
フロントエンドの開発環境について調べるとわからない単語の数珠つなぎw 一つずつ調べる。
※参考:フロントエンドのモダンな開発環境を作るために調べていること
ターミナル(黒い画面)
ターミナル(黒い画面)に苦手意識があるWebデザイナーは多い。はじめての黒い画面体験。
※参考:初めてのPython(インストール〜Hello world)と初めての黒い画面
ターミナルになれるために、ターミナルだけでWebページを作ってみる。
※参考:黒い画面だけでWebページを作成する - 前編:ファイル、フォルダの作成
※参考:黒い画面だけでWebページを作成-後編:viエディタでコーディング!
GitHub
バージョン管理がどんな物かを体験したく、GitHubのアカウントを始めようとしたら、もう初めていた、という話w
ターミナル(黒い画面)を使わずに、ブラウザだけでどこまでのことがやれるか検証。
※参考:ブラウザ上だけでお手軽GitHub体験(リポジトリの作成と変更)
ターミナル(黒い画面)を使わずにGUIツールSourceTreeを使ってGitHub Pagesに同期させる。
※参考:GitHubとSourcetreeでGitHub Pagesとローカルファイルを同期させる
今度はSourceTreeを使ってHerokuに同期させる。
※参考:ローカル→Sourcetree→GitHub→Herokuに同期する方法(黒い画面不要!)
サーバ、クラウド、AWS
VPSサーバとクラウドサービスの違いを理解する。
※参考:Webサービスを公開するためのサーバ仕様比較(VPSとクラウドサービス)
AWSホスティングの大枠の理解
※参考:AWSを理解するために調べたこと(Webサイトホスティング編)
AWSの基本的なキーワードもわからない単語多すぎるので、理解
※参考:AWSを理解するために調べたこと(EC2 、Lightsail、EBS、RDS、ELB、S3)
PWA
Glideというサービスを使ったらほんとに5分でPWAを作れた!
- 投稿日:2019-10-24T00:47:47+09:00
コンテナとKubernetesとEKSの概要を理解する
はじめに
最近コンテナ技術に興味があっていろいろ調べてみたので、
自分なりに理解したコンテナ、Kubernetes、EKSの概要を紹介してみます。自分の理解が違うようであればご指摘いただけると嬉しいです。
コンテナ技術とは
- OS上に他のプロセスからは隔離されたアプリケーション実行環境を構築する技術のこと
- 仮想的な動作環境をより少ないコンピュータリソースで実現する
コンテナのデファクトスタンダードはDocker
コンテナ技術のメリット
- コンテナイメージを作成することで環境のパッケージ化ができる
- どんな場所でも同じように動かせる
- 起動が高速である
- ゲストOSの起動が必要ないため
- アプリケーションのデリバリ方法が簡単かつ統一されている
- docker push/pull/run等のコマンド
- メモリ消費が抑えられる
⇨ 同一の環境を高速にたくさん起動できるので、スケールがしやすい
Kubernetesとは
- コンテナはスケールがしやすい≒コンテナの管理が難しい…
⇨コンテナの管理を便利にしてくれるのがKubernetes- コンテナを動かすマシンにあるエージェント(kubelet)とAPIサーバ(マスターコンポーネント)が通信をすることで、コンテナに対して様々な操作をすることができる
- いろんなことができるよ
- ホストの管理
- コンテナの起動/停止のスケジューリング
- コンテナの死活監視
- 自動修復
- 負荷分散
- アプリケーション設定の管理
などなどEKSとは
- Kubernetes環境で実行されているアプリケーションをAWS上で動かすためのマネージドサービス
- KubernetesをAWSで使いたいときのためのサービス
- コンテナが稼働するためのマシン(データプレーン)はEC2を使用する
EKSとEC2の関係性
ECR
参考資料
より詳しく知るには
AWSオンラインカンファレンスの「はじめてのコンテナワークロード」というセッションがおすすめです!
コンテナオーケストレーションの仕組みについてわかりやすく解説されています。
- 投稿日:2019-10-24T00:25:54+09:00
AWSで、パブリックサブネットに作成したインスタンスのIPを取得する
作業用に使えそうだったのでメモ
AWSで、パブリックサブネットに作成したインスタンスに、ElasticIPアドレスを割り当てていないと、
再起動の際に毎回違うパブリックIPが割り当てられるので、取得が面倒ですよね。。
ElasticIPアドレスを割り当てていない作業用のssh踏み台サーバーへ楽にssh出来る方法を考えてみましたインスタンスを起動したタイミングで以下のシェルを実行すると、
楽にsshできるようになります実行方法./getPublicIpAddress.sh ssh test_server1getPublicIpAddress.sh#!/bin/bash ip=$(aws ec2 describe-instances --filter "Name=tag:Name,Values=test_server1" | jq '.Reservations[].Instances[].PublicIpAddress' ) echo $ip sed -i -e "/test_server1$/s/\([0-9]\{1,3\}\.\)\{3\}[0-9]\{1,3\}/${ip//\"/}/" /etc/hosts([0-9]{1,3}.){3}[0-9]{1,3}:IPアドレス変換用の正規表現
${ip//\"/}:変数をパラメータ展開して、変数ipについている”を除外/etc/hosts127.0.0.1 localhost localhost.localdomain localhost4 localhost4.localdomain4 ::1 localhost localhost.localdomain localhost6 localhost6.localdomain6 0.0.0.0 test_server1シェル実行によって「0.0.0.0 (ネームタグの名前)」の部分が置き換わります
停止時に実行するとnullが入ってしまうので、起動時に実行します/etc/ssh/ssh_configHost test_server1 User ec2-user IdentityFile /(鍵の場所)/my-keypair.pemローカル環境:CentOS7
- 投稿日:2019-10-24T00:21:08+09:00
ECS(Fargate)+APIGateway(Cognito認証)でAPIサーバーを構築する
前提条件/構成条件
- APIサーバーはNginx + Golang
- ユーザー情報はCognitoに格納されている
- ユーザー認証をAPIGatewayのAuthorizerで行なう
- CloudFront → API Gateway → Fargate
※AWSの設定作業はコンソールより手作業で行ないます
infra as codeはありません構成図
コンテナの準備
以下のDockerfileを準備します。
配置場所は当記事では{ルートdir}/release/app/
および{ルートdir}/release/nginx/
配下としています。まずはGoで作成するアプリケーションです。
FROM golang:1.13.0-alpine as builder ENV ROOT_PATH /go/src/github.com/xxx/yyy WORKDIR $ROOT_PATH RUN apk add --no-cache alpine-sdk git RUN addgroup -g 10001 -S admin \ && adduser -u 10001 -G admin -S admin # modules COPY go.mod go.sum ./ RUN go mod download # application COPY . . # build RUN CGO_ENABLED=0 GOOS=linux GOARCH=amd64 go build -ldflags="-w -s" -o /go/bin/app && \ chmod 755 /go/bin/app && \ chown admin:admin /go/bin/app FROM scratch COPY --from=builder /etc/group /etc/group COPY --from=builder /etc/passwd /etc/passwd COPY --from=builder /go/bin/app /go/bin/app USER admin EXPOSE 9000 CMD ["/go/bin/app"]アプリケーションはとりあえず以下な感じでよいでしょう。
go.modとgo.sumも配置しておいてください。main.gopackage main import ( "github.com/labstack/echo" "net/http" ) func main() { e := echo.New() e.GET("/", func(c echo.Context) error { return c.String(http.StatusOK, "Hello World!") }) e.Logger.Fatal(e.Start(":9000")) }続いてNginxです。
FROM nginx:1.17.4-alpine ADD ./release/nginx/nginx.conf /etc/nginx/conf.d/default.confFargateは
127.0.0.1
で待ち受けます。
PortはGo側で設定したもの(9000
)を設定します。nginx.confserver { listen 80 default_server; listen [::]:80 default_server; include /etc/nginx/default.d/*.conf; location / { proxy_pass http://127.0.0.1:9000; } }AWS構築手順
VPC
VPCの作成
特に言及することはありません。
既に利用されているものがあればそのまま使いましょうサブネットの作成
プライベートサブネットで作成します。
Fargateの場合はサーバーに固定IPを割り振りませんので、NATゲートウェイを設定しておきます。当記事では以下の2つのCIDRブロックとしています。
- 10.1.12.0/24(ap-northeast-1a)
- 10.1.52.0/24(ap-northeast-1c)
後述するNATゲートウェイも作成する場合は、パブリックサブネットも一緒に作成しておきます。
NATゲートウェイ
NATゲートウェイを作成します。ElasticIPが必要になりますので新しく作成しましょう。
※既に利用されているものがあればそのまま使いましょう作成後は、先ほど作成したサブネットのルートテーブルに紐付けるのを忘れないようにしましょう。
※NATゲートウェイ自体が配置されているパブリックサブネットはインターネットゲートウェイが必要になります。
忘れないように設定しておきましょう。セキュリティグループ作成
続いてセキュリティグループを作成します。
このセキュリティグループはNLBからコンテナ(Nginx)へのアクセスで用いられます。
NLBについては後述します。以下のように先ほど作成したサブネットのCIDRブロックを記述して反映します。ロードバランサー
NLBの作成
APIGatewayからロードバランサーへルーティングする場合、VPCリンクで繋ぐ必要があります。
当記事ではAPIをVPCのプライベート空間(インターネットに公開しない)に配置するためNLBによる構築となります。スキームは
内部
、リスナーはTLS(セキュアTCP)
を選択します。
VPCは先ほど作成したVPCとサブネットを指定します。証明書
ACMに既に証明書が存在する場合はそのまま使いましょう。
当記事ではセキュリティポリシーをELBSecurityPolicy-TLS-1-2-2017-01
を選択しています。ターゲットグループの作成
新しくターゲットグループを作成します。
ターゲットの種類はIP
を選択します
次画面のターゲットの登録は、一旦スキップでOKです。ドメインの確保
NLBの作成が完了したらDNSを自身のドメインに設定します。
Route53を利用していればAliasレコードで登録できるかと思います。
当記事ではホスティングゾーンが別のためCNAMEで設定します。
※このドメインはサービスのエンドポイントではありません。
CloudFront→①→APIGateway→②→NLB の②にあたる部分です。
①については後ほど設定します。例: elb-origin.domain.com など
ECR
リポジトリの作成
ECRにリポジトリを作成しておきます。
当記事ではリポジトリは以下の名称にしています。
- {サービス名}/app
- {サービス名}/nginx
これでコンテナのURIが以下のようになると思います。
- {AWSのアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/{サービス名}/app
- {AWSのアカウントID}.dkr.ecr.ap-northeast-1.amazonaws.com/{サービス名}/nginx
コンテナのプッシュ
当記事の初めに準備したコンテナをプッシュします。
※CI環境では自動プッシュ/デプロイを設定することになります。今回は最初だけ手動プッシュとします。まずはビルド
$ docker build --no-cache -t {appコンテナ名}:latest -f release/app/Dockerfile . $ docker build --no-cache -t {nginxコンテナ名}:latest -f release/nginx/Dockerfile .タグ付け
$ docker tag {appコンテナ名}:latest {ECRのコンテナURI}:latest $ docker tag {nginxコンテナ名}:latest {ECRのコンテナURI}:latestECRにログインします
※awscliが使えない場合はインストールしてください$ $(aws ecr get-login --no-include-email)プッシュします
$ docker push {ECRのコンテナURI(app)}:latest $ docker push {ECRのコンテナURI(nginx)}:latestECS
クラスターの作成
まずはクラスターを作成します。クラスターは単なる名前空間になります。
コンテナの設定、配置する数やスペックについては後述するサービス
、タスク
による定義で設定します。クラスターテンプレートは
ネットワーキングのみ
を指定して作成します。IAMロールの作成
次にIAMロールを作成します。2つ作成します
タスクロール
このロールはコンテナ内部でAWSへのAPIリクエストを行なうためにタスクで使用するものです。
例えばS3にアクセスが必要なアプリケーションの場合、S3へのアクセスが可能なロールを定義します。コンソールから作成する場合は、以下の項目を信頼されたエンティティとして作成します。
Elastic Container Service Task
タスク実行ロール
このロールはタスクのプルやログの発行などを管理するロールです。
AmazonECSTaskExecutionRolePolicy
というポリシーを付与して作成します。タスク定義の作成
コンソールから設定する場合、まず
タスクロール
とタスク実行ロール
を指定します。
先ほど作成したIAMロールを指定します。
タスク実行ロールにはAmazonECSTaskExecutionRolePolicy
がアタッチされているロールを指定します。タスクサイズはとりあえず最低スペック(メモリ0.5GB、CPUが0.25vCPU)にしておきます。
続いてコンテナの追加ですが、ECRにプッシュしてあるappコンテナとnginxコンテナを指定します。
ヘルスチェックやログ出力などの細かい設定はとりあえずデフォルトのまま進めます。nginxコンテナは、ポートマッピングを設定します。
80
を設定してください。appコンテナとnginxコンテナを設定できればタスク定義の作成を完了します。
サービスの作成
サービスはクラスターの中から作成することができます。
ステップ1 サービスの設定
ステップ1の
サービスの設定
については特に難しくはありません。
起動タイプをFARGATE
とし、タスク定義やクラスターは先ほど作成したものを選択します。
タスクの数は最低料金に抑えるため1
にしておきます。(商用では適切なタスク数を検討してください)
デプロイメントについては、当記事ではローリングアップデート
で進めます。ステップ2 ネットワーク構成
ステップ2のネットワーク構成です。
VPCとセキュリティグループは、先ほど作成したVPCとサブネット、セキュリティグループを選択します。
当記事では以下のサブネットを作成していました。
- 10.1.12.0/24
- 10.1.52.0/24
パブリックIPの自動割り当てについては
DISABLED
にしておきます。続いて、ロードバランサーの設定です。先ほど作成したNLBを指定します。
ターゲットグループ名も、先ほど作成しているので選択します。
サービスの検出(オプション)
という項目については当記事ではOFFで設定します。ステップ3 Auto Scaling(オプション)
ステップ3はAutoScaleingの設定です。
商用で利用する場合は必ず設定しましょう。当記事では設定せずに先に進みます。
API Gateway
VPCリンクの作成
APIGatewayよりVPCリンクを作成します。
ターゲットNLBを先ほど作成したNLBとします。APIGatewayの作成
APIGatewayを作成します。
メソッドの作成
一旦、
/
パスにGETメソッドを定義します。
統合タイプはVPCリンク
を選択し、先ほど作成したVPCリンクを設定します。
エンドポイントURLは、先ほど作成したNLBのAliasレコード(もしくはCNAME)を設定します。
ここはNLBでインポートしたACMに対応するドメインである必要があります。APIのデプロイ
メソッドが作成したらデプロイを行ないます。(コンソールから作業するとよく忘れます。。)
ステージ名は適当にdev
とでもしておきます。CloudFront
Create Distribution
CloudFrontを設定していきます。
各項目については以下の通りです。これ以外の項目については要件により適宜設定してください。
項目 内容 Origin Domain Name 先ほど作成したAPIGatewayのドメイン
例:xxxxx.execute-api.ap-northeast-1.amazonaws.com
(ステージ名は除く)Origin Path APIGatewayのステージ名
例:/dev
Origin Protocol Policy HTTPS Only Viewer Protocol Policy Redirect HTTP to HTTPS Allowed HTTP Methods GET, HEAD, OPTIONS, PUT, POST, PATCH, DELETE Alternate Domain Names(CNAMEs) 自身のサービス用ドメイン(APIのエンドポイント) SSL Certificate Custom SSL Certificate (example.com): (自身のACM証明書を選択) ここまで出来れば、自身のドメインでアクセスすることで
Hello World!
が表示されるはずです。Authorizerの設定
Cognito
前提条件として、Cognitoにエンドユーザー(当APIにアクセスするユーザー)の情報が格納されていることとします。
Cognitoの扱い方については当記事では対象外となります。APIGateway
新しいオーソライザーの作成
自身のAPIGatewayのメニューより、
オーソライザー
>新しいオーソライザーの作成
を選択します。
タイプをCognito
とし、ユーザープール名を指定します。
トークンのソースはAuthorization
とします。オーソライザーを作成したら、新しく
POST
のAPIおよびメソッドを作成します。
このAPIではCognitoより、認証されたユーザーの情報を受け取る検証をするためPOST
としています。オーソライザーは以下の
メソッドリクエスト
の認可
より設定します。次に
統合リクエスト
のマッピングテンプレート
を選択します。
以下の形式でCognitoからのパラメータ群を取得することができます。{ "sub": "$context.authorizer.claims.sub", "username": "$context.authorizer.claims['cognito:username']", "birthdate": "$context.authorizer.claims.birthdate", "gender": "$context.authorizer.claims.gender", ...(省略) }アプリケーション側(Go)では以下のように取得できるかと思います。
main.gopackage main import ( "github.com/labstack/echo" "net/http" ) type User struct { Sub string `json:"sub"` Username string `json:"username"` BirthDate string `json:"birthdate"` Gender string `json:"gender"` Name string `json:"name"` Locale string `json:"locale"` Email string `json:"email"` Picture string `json:"picture"` } func main() { e := echo.New() // ユーザーの取得 e.POST("/test", func(c echo.Context) error { user := new(User) if err := c.Bind(user); err != nil { return err } return c.JSON(http.StatusOK, user) }) e.Logger.Fatal(e.Start(":9000")) }CI構築
当記事ではCI環境をCodePipelineで行ないます。
CodeBuild
ビルドプロジェクトの作成
まずはCodeBuildを設定します。
送信元については、当記事ではGithubを設定しています。
ビルド環境についてはAmazon Linux 2
を選択します。(好きなものでいいです)Buildspacについては
buildspec.yaml
を配置する予定のパスを指定します。buildspec.yamlの配置
内容は以下の通りです。
buildspec.yamlversion: 0.2 phases: install: runtime-versions: docker: 18 commands: pre_build: commands: - $(aws ecr get-login --no-include-email) build: commands: - docker build --no-cache -t {appコンテナ名}:latest -f release/app/Dockerfile . - docker build --no-cache -t {nginxコンテナ名}:latest -f release/nginx/Dockerfile . - docker tag {appコンテナ名}:latest {appのコンテナURI}:latest - docker tag {nginxコンテナ名}:latest {nginxのコンテナURI}:latest post_build: commands: - docker push {appのコンテナURI}:latest - docker push {nginxのコンテナURI}:latest - | printf '[{"name":"app","imageUri":"%s"},{"name":"nginx","imageUri":"%s"}]' \ {appのコンテナURI}:latest {nginxのコンテナURI}:latest > imagedefinitions.jsonCodeDeploy
※CodeDeployについてはBlue/Greenデプロイを利用する場合のみ設定します。
当記事ではローリングアップデートで進めるためこちらの作成は不要です。CodePipeline
新規のパイプラインを作成する
続いてCodePipelineを作成します。
ソースステージについては、当記事ではGithubを選択しています。ビルドステージについては先ほど作成したプロジェクトを指定します。
デプロイステージについては
Amazon ECS
を指定します。
Blue/Greenデプロイの場合は別途Amazon ECS(ブルー/グリーン)
を指定します。
イメージ定義ファイルはimagedefinitions.json
です。CodeBuildのbuildspec.yaml
で出力するJSONです。APIGatewayのデプロイ
APIGatewayについても、今後手動で設定していくのが辛いのでCI環境内でデプロイしたいものです。
今回は、CodeBuild上でデプロイします。
buildspec.yaml
のpost_build
(ビルド完了後)に以下のコマンドを追記します
CodeBuiildの実行ロールにAPIGatewayの実行権限を付与するのを忘れないでください。buildspec.yaml# API Gateway Deploy - aws apigateway put-rest-api --rest-api-id {APIGatewayのID} --mode overwrite --body file://openapi.yaml - aws apigateway create-deployment --rest-api-id {APIGatewayのID} --stage-name {APIGatewayのステージ名}ここで
openapi.yaml
というファイルが登場しています。
こちらは、APIGatewayの構成を記述したOpenAPI(もしくはSwagger)形式のyamlとなります。
APIGatewayのステージ
>エクスポート
よりエクスポートができ、追記したものをインポートしデプロイすることができます。アプリケーション側でAPI、メソッド等を追記したらこのファイルも更新しましょう。
openapi.yamlopenapi: "3.0.1" info: title: "{Your API Title}" version: "xxx" servers: - url: "https://example.execute-api.ap-northeast-1.amazonaws.com/{basePath}" variables: basePath: default: "/dev" paths: /: get: responses: 200: description: "200 response" content: application/json: schema: $ref: "#/components/schemas/Empty" x-amazon-apigateway-integration: uri: "https://elb-origin.domain.com/" responses: default: statusCode: "200" passthroughBehavior: "when_no_match" connectionType: "VPC_LINK" connectionId: "xxx" httpMethod: "GET" type: "http" components: schemas: Empty: title: "Empty Schema" type: "object"以上で全行程が完了です。
- 投稿日:2019-10-24T00:17:51+09:00
firelensを使用した、ログ分割と監視処理
ここ最近、FireLensの機能選定を行っており
fluentbitのカスタムイメージを作成し、FireLensに接続するまでの機能調査を行いました。FireLens実装サンプル
https://github.com/antennix/firelens
概要
VPC内で稼働しているwebアプリケーションのEC2インスタンスを、fargate化したいという話がありました。
改修に伴い、fargateコンテナをステートレスにする為、ログの管理方法が話題に上がりました。また、監視業務を内製化したいという要望もあった為、ログの検知システムも検討しました。
構成図
- A:アクセスログ、B:エラーログ、C:アプリケーションログの三種類をS3に保存します。
- B,Cのみログ監視を行い、特定の要件を満たした場合、slackにアラートを発報します。
- 突然のコンテナの破棄に対して、ログが失われないように設計します(ステートレス)
検討した内容
Firelens,FluentBit,datadogを組み合わせて検討する事になりました。
FireLens
FireLensは、ECSのコンテナの標準出力を、fluentd/fluentbitにお手軽に転送できる機能です。
- 簡単な転送なら、JSONの設定だけで、自動でfluentdのコンテナを起動し、転送してくれます。
- 複雑な設定も、専用の設定ファイルを作成すれば可能です。
- 標準の追加プラグインを使いたい場合は、カスタムしたfluentd/fluentbitのコンテナを作成すると、可能です。
Fluent Bit
Firelensの記事は、Amazon Kinesis Data Firehoseや、Amazon CloudWatch Logsとの
連携記事が多く見られますが、
bigqueryやazure等、組み込みoutput pluginへの出力も可能です。Amazon / aws-for-fluent-bit (fluentbit v1.3.2)
https://hub.docker.com/r/amazon/aws-for-fluent-bit/tags
fluentbit output plugin
https://docs.fluentbit.io/manual/output
v1.2.0からサポートされている、datadogを使用する事にしました。なお、fluentdでも同様の機能は実装可能ですが
コンテナ費用の事を考え、軽量なfluentbitを選択しました。datadog
https://app.datadoghq.com
クラウド監視ツールですが、機能の一つとしてログ監視機能(datadog logs)があります。
元々使用経験もあり、ログの整形機能(pipeline)や、リアルタイムアラート機能
S3へのアップロード機能もあり、要件を満たせそうでした。S3へのアップロード
datadogにはS3へのアップロード機能があり、ログを全種まとめてdatadogで管理する案もありましたが
アクセスログのレコード数が非常に多く、datadogを経由すると膨大なコストが掛かる可能性があり
アクセスログだけはdatadogの監視を通さず、fluentbitからs3に直接アップロードすることにしました。実現可能なプラグインは存在しましたが、標準のfluentbitコンテナには搭載されていないので
カスタムのfluentbitのコンテナを作成する必要が出てきました。
https://github.com/cosmo0920/fluent-bit-go-s3実装手順
- ローカルで、datadog/s3へデータを転送できるdockerイメージを作成する
- 作成したdockerイメージを元に、firelensで動作するように調整する
あと2回ほど記事を書いてまとめようと思うので、時間が出来次第更新致します。