20220110のAWSに関する記事は25件です。

aws ds パイプライン構築時考慮事項のメモ

粒度をそろえるのが難しいので表形式でメモ。変に切り口をこねるよりも表形式だと粒度やフローに沿ってまとめやすい。 粒度 手段 特徴 or ユースケース サービス athena 非構造化データ、半構造化データ、構造化データすべてが対象データレイクから直でアドホックなSQLを実行したい場合BIチームなどにも情報へ素早くアクセスしてほしい場合例:アドホックな分析 redshift 構造化データに対するアナリティクスが対象 スケールとパフォーマンスを追求する場合、より本格的なワークロードを実行したい場合。 テーブル作成 parquetによるパフォーマンス最適化 パーティション モダンなクエリエンジンのストレージに対するプッシュダウンを活用してディスクの異なる領域にランダムにスキップすることなくデータをシークできるようにする 辞書エンコーディング 小数のカテゴライズされた列に対して各カテゴリを表す小数のビットでカテゴリを識別したいケース 型圧縮 (String,String)(Integer,Integer)のように効率的に保存 ベクトル化集計 列指向フォーマットなのででぅすくコントローラがデータを1回だけ集計する。 ENCODE属性の付与による列の圧縮を通じたパフォーマンス最適化 zstd 汎用圧縮アルゴhttps://docs.aws.amazon.com/ja_jp/redshift/latest/dg/zstd-encoding.html az64 Oct 8, 2019リリース。Amazon Redshift に保存されている数値および日付/時刻データの最適な解凍パフォーマンスが得られます。 bytedict 有限カテゴリに有効。https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_Byte_dictionary_encoding.html SORTKEYによるパフォーマンス最適化 よく参照するデータに応じてSORTKEYを設定 DISTを使用したテーブル分散スタイル データの移動を最小限に抑える目的https://docs.aws.amazon.com/ja_jp/redshift/latest/dg/c_choosing_dist_sort.html参照 ALL 分散 EVEN 分散 KEY 分散 レコード挿入時 ETLタスクのテクニック selectの結果をテーブルに取り込む 例えばcast(year(date(hoge_date)) as INTEGER) as yearとして念を抽出した列を作成するなどすると手間は減る コマンド COPY まだテーブルが存在しない時点で新たにS3等のデータソースからテーブルを作成する場合 INSERT INTO データがすでにテーブルとして存在し、データのサブセットをロードする場合 所感 - 46993975×16列の行挿入(not parquet)で5分くらいかかった気がするので1億レコードを超えるようなら良いパフォーマンスを発揮する構文を調べる。 - UNLOAD(export)も43929550×16列のデータをparquetで保存するのにElapsed time: 8m 37.9sもかかるので最適化させる必要あり。 - ノード1だがなんとなーくbigqueryの方が速いような気がするのでちゃんと使いこなしたうえでそのうち実行速度や使い勝手などについて調べる。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

受験談 AWS Certified Developer - Associate 認定

AWS Certified Developer - Associateを受験しました。 受験される方の参考になりましたら。 前提 2021年 8月:SAA (受験談) 9月:SAP 11月:SOA (受験談) 12月:SCS (受験談) 2022年 1月:DVA(今回ココ) SAA受験談に私のAWSの事前知識・経験が書いてありますが、業務等での経験はほぼゼロです。 これまでUdemyの講座をかなり使用してましたが、今回は以下の3つの問題をひたすら繰り返してました。 書籍 ポケットスタディ AWS認定 デベロッパーアソシエイト (アソシエイト試験ポケットスタディ) ただ、分厚いのと小さいのが個人的には難点なのと、どの順番で受験するか?にもよると思いますが、とても細かく書かれている印象で全てを読む気にはなれなかった。各章ごとと巻末に問題がついているので、問題だけを解く形で活用しました。 公式サンプル問題 次はこれですね。 10問ではありますが、雰囲気や難易度をつかむには十分かなと思います。 AWS BenchPrep認定試験練習 いつからか、「AWS Skill BuilderからAWS認定無料版模擬試験」が登場してました。前回のSCS受験の時から活用してます。20問の模擬問題を受けられますし、一問一答で解説も全ての選択肢についているのでおすすめです。 koiwaclub こちらもSCSから使っているサイトです。 46x7で、全322問あります。とにかく問題数をこなしたいという感じで活用しました。 Googleスプレッドシート ここからは毎度自分の定番なのですが、とにかく間違えた問題などを後でチェックできるようにその都度まとめてます。 実際の試験 これもどの認定試験から受験するかにもよると思いますが、SAAやSCSなどの蓄積があったのもあり、手応えとしては今までで一番あった気がします。それでもあいまいな記憶のまま回答したのも7、8問はありましたので、出題される問題にもよるかとは思いますが・・。 まとめ いつも合格したらそこで一度区切りと思うのですが、記憶があるうちに・・・となり、次の試験を目指す形になってます。ただ、このあととなるとプロフェッショナルかスペシャリティになるので、きっと今回こそ一区切りにしよっと
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Lightsailに独自ドメインを紐づけした

概要 なにかしらのサーバーが必要になったのだが、月額固定料金にしたかったので AWS Lightsailでサーバーをたてた。せっかくなので、サーバーに固定IPと独自ドメインを設定まで行った。 前提 独自ドメインの取得 数日前に国内サービスを使用して取得した。業務で取得や管理をしたことはあったが、個人用としては初めて取得。個人情報だだもれ防止用に「Whois情報公開代行」に気を付けるくらいで、あとは期間とお金の問題でたいしたことない。 なぜAWS Route 53? AWSのサーバーのDNSのことなので、Route 53を使うことにした。他のサービスでもできると思われるが、あえてAWSを避ける意味もないので、Route 53とした。 Lightsailの固定IP Networking > PUBLIC IPから設定した。サーバーが起動している限り無料とのことなので設定しておく。サーバーが不要になって停止するときに解放忘れすると知らぬ間に費用がかかってしまうらしいので気にしておく。困ることなく設定できた。 本題 取得したドメインとIPアドレスが紐づくように設定していく。 ホストゾーン作成 AWSにログインして、Route 53のダッシュボードからホストゾーンの作成を選択 取得したドメイン名を入力して、「ホストゾーン」の作成をクリック ホストゾーン詳細 4つのネームサーバーをメモする。ドメイン登録サービスの管理画面で入力するのに使う。 ドメイン登録サービスへの設定 AWS Route 53 > ホストゾーン > 「独自ドメイン」で得た4つのネームサーバーを入力した 反映まで時間がかかることもあるらしい。 ネームサーバーが反映されているか確認。入力した4つのネームサーバーが出てきたらOK。 nslookup -type=NS [独自ドメイン] IPアドレスが返ってくるか確認。が、返ってこない。 nslookup - [独自ドメイン] どうやらAレコードの設定が抜けていた。 その他 Lightsailのサーバーからpingが返ってこない。デフォルト設定では返ってこないのかも
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Elastic Beanstalkの環境変数を一覧で表示する

経緯 クラスメソッドさんの記事のコマンドがうまく通らなくて、jqが良く分からんから作った。 コード import boto3 from pprint import pprint import sys args = sys.args session = boto3.Session(profile_name=args[1]) eb = session.client('elasticbeanstalk') hoge = eb.describe_environments()["Environments"] ebname = [i['EnvironmentName'] for i in hoge] apname = [i['ApplicationName'] for i in hoge] for i, j in zip(ebname, apname): ebconf = eb.describe_configuration_settings( ApplicationName=j, EnvironmentName=i ) for i in ebconf['ConfigurationSettings']: print("---EnvironmentName " + i['EnvironmentName']) for f in i["OptionSettings"]: if f["Namespace"] == "aws:elasticbeanstalk:application:environment": print(f["OptionName"] + "," + f["Value"]) 実行 Python ebenvname.py $ProfileName jqの記法嫌い jsonも嫌い
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ソリューションアーキテクト対策

はじめに 今回AWS Solutions Architect - Associateを受けたので自分の備忘録としてまとめました。 (ただメモとして書き殴っただけですので参考になるかわかりませんが、、、) 年末にノリで申し込んで約10日後に受験しました。(無事取得できました) 特にAWSをガッツリ触っているわけでなく、Azureを業務で軽く触っているぐらいです。 主にUdemyで勉強しました。Udemyオススメです。 IAM IAMとは、安全にAWS操作をするための認証・認可の仕組みと思えば良い ルートアカウント AWSアカウントを作成した時に用意したEメールアドレスとパスワードを使用してサインインできるアカウント 権限が最強すぎるのでこのアカウントは基本的に使用しないようにする ルートアカウントしかできないこと AWSアカウントの停止 IAMユーザーの課金情報へのアクセス S3バケットへのMFAによる削除の有効化 CloudFrontのキーペア作成 etc IAMポリシー どのリソースに対してどの操作をするかJSON形式で定義するもの ユーザー、グループ、ロールにアタッチできる (1)Effect (2)Action (3)Resource [ARNで記述](4)Condition ポリシーのタイプ (1)ユーザーベースのポリシー IAMユーザーに対してアタッチする (2)リソースベースのポリシー AWSリソースに対してアタッチ 信頼ポリシー (3)アクセス許可の境界 管理ポリシーを使用してユーザーベースのポリシーがIAMエンティティに付与できるアクセス許可の上限を設定できるが、アクセス許可は付与しない機能 IAMロール AWSリソースに対してアクセス権限をロールとして付与できる NAT インターネットGW NAT GW 機能 NAT (VPC⇆インターネット) NAT(インターネットとの接続にはインターネットGW必要) NATの種類 static NAT Dynamic NAPT 場所 VPC (Public)Subnet 速度 なし 5-45Gbps 【Static NAT】 NATテーブルには通信前から「プライベートIPとパブリックIPの変換ルール」がt定義されているので、EC2から始まる通信であってもインターネットのクライアントから始まる通信であってもIPは変換され通信が可能 1対1変換でありインターネットからの通信も変換 【NAT Gateway】 プライベートIP(多)⇆パブリックIP(1) 複数EC2インスタンスから発する通信が各々のプライベートIPでNAT-GWを通過する際、NAT-GWで1つのパブリックIPに変換 複数のプライベートIPを1つのパブリックIPに変換してしまうと、戻りの通信においてどの通信がどのプライベートIPに変換すれば良いか一意に定まらない → TCP/UDPのポート番号も変換する →この方式を「動的NAPTT = Dynamic NAPT」 EC2 【ストレージ選択】 (1)インスタンスストア 物理的に接続、内臓ハードディスク的な 一時的なストレージで、無料で使用可能 (2)EBS ネットワーク接続 EC2と独立に管理 別途コストかかる 【AMIの利用】 Amazon Machine Image, OSの設定をしたやつ EC2のBUとしてEBSを含んだ形でAMI作成できる ゴールデンイメージ : 最適なEC2インスタンスを作成してそれをAMIにしたもの AMI共有 : AWSアカウントIDを指定して権限を委譲するだけでAMIを特定のAWSアカウントを共有 リージョンの移動 : 別リージョンにコピー可能 【キャパシティ予約】 : リザーブドインスタンスとセットで利用 キャパシティ予約 : インスタンスタイプが起動可能であることの確保権。あらかじめキャパシティを確保しておくことで実行時のキャパシティ不足エラーを抑制 【スポットフリート】 スポットインスタンスの買い方の一種で条件を指定しておくとAWSがEC2のスポットインスタンスの価格を監視、条件があったEC2を見つけ出して起動、逆に使いたい価格より高くなったEC2は自動的に廃棄 【スポットブロック】 スポットインスタンスを1h-6hの間中断することなく継続利用可能 スポットフリートのオプション 安定化できる 【EC2フリート】 オンデマンドとスポットで構成されるインスタンスグループとして設定を定義する仕組み 利用上限も決められる 【Elastic Fabric Adapter】 HPCとMLを高速化するためのEC2用ネットワークデバイス 【Run Command】 マネージドコンソール上からPowerScript, windows updateの設定などのコマンド各種コマンドを実行できる機能 【ハイバーネーション】 シャットダウンする前にメインメモリの内容をハードディスク等に退避し、次回起動時にまたメインメモリに読み込んで、シャットダウンする前と同じ状態で起動する機能 【プレイスメントグループ】 インスタンス間における⭐️低レイテンシ⭐️な通信を実現するための機能 複数のインスタンスを論理的にグループ化して、パフォーマンスの向上・耐障害性を高める機能 (1)クラスタプレイスメントグループ パフォーマンスを高めるもの 一般的に使用される、単一AZ内のインスタンスを論理的にグループ化 EC2間で高ネットワークスループットが発生する場合に適している ⭐️ 低レイテンシ、高スループット、の時採用 ⭐️ ネットワークトラフィックの大部分がグループ内のインスタンス間で発生してる場合 (2)パーティションプレイスメントグループ 耐久性を高めるもの➡︎ ⭐️ アプリケーションに関連するハードウェア障害の頻度を軽減する 複数のAZに分散させることができる HDFSなど大規模なワークロードに適している ⭐️ Hadoop, cassandra, kafkaなどの大規模な分散及び複製ワークロードで一般的に利用 (3)スプレッドプレイスメントグループ 耐久性を高めるもの 異なるハードウェアに配置されるグループで複数のAZにまたがることが可能 ⭐️ インスタンスが同じラックを共有するときに発生する可能性のある同時障害のリスクを減らせる ⭐️ 少数の重要なインスタンスが互いに分離して保持される必要があるアプリケーションに推奨 【起動テンプレート】 インスタンスの作成ウィザードから設定していたパラメータをテンプレートにすることができる 一度テンプレートにしてインスタンスの情報を決めてしまえばそれ以降はテンプレートから作成することで手間を減らせる 起動設定の代わりに起動テンプレートを定義すると、複数のバージョンのテンプレートを使用できる 【起動設定】 ASGがEC2インスタンスを起動するために使用するインスタンス設定テンプレート 予約 (コスト削減) 名前 説明 オンデマンドインスタンス ・起動するインスタンスに対して秒単位で課金される Savings Plans ・1-3年間、EC2の利用時間に関係なく、1時間につき一定の料金を支払うことを決めてEC2を利用するプラン ・RIと同等の割引が適用されることに加え、スケールアップ等、構成の変更を行った場合でも割引が適用される Reserved Instance ・1年、3年単位で購入できる格安インスタンス Spot Instance ・AWS上サーバー上に存在し使われていないEC2インスタンスに値段をつけ、その入札価格が現在のスポット価格を上回っている限りそのインスタンスを利用→インスタンスが中断することがある。・継続的な処理が必要なく重要なタスクでない・バッチ処理ジョブなどの一時的な処理に利用される Dedicated Hosts ・専有ホスト。ホストサーバーを保有したい場合利用。セキュリティー的にとか Bare Metal ・仮想サーバのような仮想化ハイパーバイザを使わず、物理サーバをそのままユーザが利用できるサービス ・AWSの各種サービスとの連携が可能でOSが直接下層のハードウェアにアクセス可能 ハードウェア占有インスタンス(Dedicated インスタンス)  ハードウェア占有インスタンスは、他のアカウントのEC2インスタンスと共有されることはない。言い換えると、同じアカウントのインスタンスとは共有されることになる SP(Savings Plans) 説明 Compute EC2, EMR, ECS, EKSクラスターの一部、Fargate, Lambda 最大、66%の割引が可能 EC2 Instance EC2のみ 最大,72%の割引が可能 RI(Reserved Instance) 説明 Standard 割引率が最も高く、設定変更などがあまり発生しない定常状態の使用に良い Convertible ・割引きが適用、スタンダードと違ってリザーブドインスタンスの属性を変更できる ・コンバーティブル(Convertible)のみ変更可能→ インスタンスファミリー, OS, テナンシー, 支払いオプション キャパシティ予約 インスタンスタイプが起動可能であるという確保権。リザーブドインスタンスとはセットで使う 予めキャパシティを確保しておくことで実行時のキャパシティ不足エラーを抑制する 確実なEC2 Instanceの起動を確保する 主なリザーブド EC2リザーブドインスタンス RDSリザーブドインスタンス ElastiCacheリザーブドノード DynamoDBリザーブドキャパシティ Redshiftリザーブドノード ⭐️ 基本にSaving Planを優先して考える→柔軟性が高いため ⭐️ スタンダードRIとEC2 Instance SP, コンバーティブルRIとCompute SPの割引率は同一 ⭐️ RIを選択するケースとしては、SP非対応のAWSを使用するとき 【インスタンスタイプ】 用途 インスタンスファミリー 説明 汎用 a, t, m ウェブサーバーやコードリポジトリなど、インスタンスのリソースを同じ割合で使用するアプリケーションに最適 コンピューティング最適化 c バッチ処理、機械学習推論、科学モデリング メモリ最適化 r, x, z メモリ内の大きいデータセットを処理するワークロードに対して高速なパフォーマンスに最適なインスタンス 高速コンピューティング p, g, f 浮動小数点計算、グラフィックス処理、データパターン照合など ストレージ最適化 i, d, h ローカルストレージの大規模データセットに対する高いシーケンシャル読み取りおよび書き込みアクセスを必要とするワークロード用 AutoScaling 3要素 : (1) Auto Scalingグループ - Auto Scalingを実行するサーバーグループを指定 (2) Launch Config - AMIインスタンスタイプ、IAMなどを設定知って起動する (3) スケーリングプラン - どのようにインスタンスを起動するか Auto Scaling設定プロセス (1) ELB作成 (2) ターゲットグループの作成 (3) 起動するインスタンスの設定 (4) Auto Scalingグループ作成 (5) AutoScalingポリシー or スケジュール設定 AutoScalingが閾値を超えたにも関わらずスケーリングがうまく実行されず24時間立ったとき自動的にAutoScalingは停止 【Auto Scaling Groups】 EC2インスタンスの開始から削除まで全ての動作に対する規則とポリシーを含んでいる ex) 最小サイズ、最大サイズ、お望みの容量、拡大できる容量 【Auto Scaling Plan】 どのようにスケールするか (1)手動スケーリング : バッチ処理など高負荷な処理への対応 (2)スケジュールドスケーリング : アクセス予測が可能なとき、日時指定などして指定 (3)動的スケーリング : ⭐️スケーリングポリシー⭐️に従い、自動的にスケーリング 【Auto Scaling Plan】 4.1 : シンプルスケーリングポリシー 4.2 : ステップスケーリングポリシー 4.3 : ターゲット追跡ポリシー : スケーリングメトリクスを選択してターゲット値を設定 ex) AutoScalingグループの平均集計CPU使用率を40パーセントに維持 【Auto Scalingの挙動】 インスタンスが最も少ないAZでインスタンスを起動 再分散の実施 : AZ間でインスタンス数を不均衡あると調整 【ターミネーションポリシー(終了ポリシー)】 Auto Scalingでスケールインが発生した時に、どのインスタンスを終了させるかを決めるルール ⭐️ 終了ポリシー (デフォルト) 最もインスタンスが多いAz選択 → OldestLaunchConfiguration(最も古い起動構成) → ClosestToNextInstanceHour (課金が近い) → ランダム 種類 説明 OldestInstance 最も古いインスタンスを終了する NewestInstance 最も新しいインスタンスを終了 OldestLaunchConfiguration 最も古いLaunch Configuration ClosestToNextInstanceHour 課金のタイミングが近い クールダウンタイム : AutoScalingグループが追加のインスタンスを起動または削除することができない時間 【ヘルスチェック】 Auto-Scaling配下のEC2のヘルスチェックにはEC2のステータス情報またはELBのヘルスチェックのどちらかを利用 (1) EC2ステータス : インスタンスのステータスがrunning以外の状態を異常と判断 (2) ELB : ELBのヘルスチェック機能を活用する(正常なインスタンスのみをELBに追加) 【ライフサイクルフック】 インスタンス起動時 or 削除時にインスタンスを一時停止してカスタムアクションを実行 用語 説明 Desired Capacity Auto Scalingが実行されない状態でのインスタンス数を設定この数値を変更することで、手動でスケーリングさせることも可能 Minimum capacity スケールイン時にインスタンスを削除する際の下限のインスタンス数を設定 Maximum capacity 最大キャパシティはスケールアウト時に起動するインスタンスの最大数を設定する Redshift フルマネージド型のDWH DBに対するアクセス競合が発生せず、ノードを増やせば増やすほどリニアに性能が向上 Redshiftクラスターは1つのリーダーノードと複数のコンピューティングノードから構成 リーダーノードは課金の対象外となり、コンピューティングノード数とノードタイプが課金対象 【Leader Node】 SQL処理コードの生成と展開 クライアントアプリケーションからクエリを受け取ってクエリを解析しクエリ実行プランを作成 コンピューティングノードに対するこれらのプランの並列実行を調整しコンピューティングノードから得た中間結果を集計してから、最終的にクライアントアプリケーションに結果を返す クラスタの全てを管理 【Compute Node】 実際の処理 ローカル列志向ストレージ、クエリの並列実行 クエリ実行プランを実行し、これらのクエリを処理するためにデータをコンピューティングノード間で伝送する 集計の中間結果は、クライアントアプリケーションに送り返される前にリーダーノードに送り返される コンピューティングノードタイプ 種類 説明 DS(高密度ストレージノードタイプ) ストレージに最適化されたHDDDS1とDS2の2種類ある DC(高密度コンピューティングノードタイプ) コンピューティングに最適化されたSSDDC1の1種類しかない 【ノードスライス】 コンピューティングノードはスライスという処理の実行単位に分けたもの 各スライスは、ノードのメモリとディスク容量の一部を割り当てられて、ノードに割り当てられたワークロードを一部分を処理 リーダーノードは、スライスへのデータの分散を管理し、クエリまたは他のDB操作のワークロードをスライスに分配 【MPP(Massive Parallel Processing)】 リーダーノードが1タスクを複数のコンピューティングノードで分散割り当てして実行 コンピューティングノードを追加することで容易にスケールアウト可能 【シェアードナッシング】 複数のサーバやコンピュータを利用した分散処理のシステムにおいて、それぞれに占有のストレージ領域を与えることで、自律的な並列処理を可能とすること 同一データなどに対する競合を防ぐことができる雨、処理速度を向上させられる。DWHなどに利用される 各のノードスライスは、専用のCPUコア、メモリ、ディスクを持っており、各ノードスライス間で基本的にデータを共有するようなことはしない 【パラメータグループ】 パラメータグループ : DBのコンフィグ 静的なパラメータの変更は、DBインスタンスを再起動する必要あり パラメータグループを変更することも可能 ex) - auto_analyze - enable_user_activity_logging - require_ssl - search_path - statement_timeout ⭐️ 【拡張 VPCルーティング】 Redshiftはクラスターとデータリポジトリ間の全てのCOPYとUNLOADトラフィックがVPCを通るように強制 Route53 ①シンプルルーティング 静的マッピングによるルーティング方式 複数の値を1つのレコードに設定すると、ランダムに応答する(DNSラウンドロビン) ②加重ルーティング 指定した比率で複数リソースにトラフィックをルーティングする 比率の合計100 ex)A/Bテスト, Blue/Greenデプロイ, サーバー性能に応じた負荷平準化 ③フェイルオーバールーティング ヘルスチェックの結果に応じて利用可能なリソースのみを応答する方式 プライマリやセカンダリを登録 事前にヘルスチェックを作成し、設定時にヘルスチェックとの関連づけが必要 ④複数値回答ルーティング IPアドレス単位での正常・非正常を判断してルーティングできる 複数レコードのうち、正常なレコードのみランダムで応答させる方式 MAX IP8つ登録 ⑤レイテンシールーティング ネットワークレイテンシーが最も低いリージョンのリソースを応答する方式 設定時に指定したIPアドレスのリージョンが選択されるので、セットIDを入力して登録 ⑥位置情報ルーティング⭐️ クライアントの位置情報に基づいて応答する方式 ex)適切な言語でローカライズされたコンテンツの提供 ⑦地理的近接性ルーティング⭐️ ユーザーとリソースの地理的場所に基づいて応答 【IPフローティング】➡︎ ENIの付け替え 障害発生時にダウンタイムをなくすため、Elastic IPを自動で付け替える機能 CloudFront 世界中にあるエッジロケーションを利用してCDNとして利用できるグローバルなコンテンツ配信サービス GZIP圧縮によってコンテンツを軽くすることで高速な処理可能 : リクエストヘッダー Accept-Encoding:gzip → 圧縮ファイルを供給すると非圧縮ファイルを供給するよりもコスト安い リージョナルエッジキャッシュというロケーションが追加されたが、ユーザー側で選択可能ではない 無料で新規ユーザーは50GBのデータ通信と2,000,000件のHTTPorHTTPSリクエストを毎月1年間利用できる CloudFrontへのHTTP GET/POST/PUTリクエストの最大ファイルは20GB ⭐️ プロキシされるHTTPメソッド PUT/POST/PATCH/OPTIONS/DELETEは直接オリジンに送信される (エッジキャッシュがスキップ) ⭐️ リクエスト時に決定される動的コンテンツもエッジキャッシュをスキップしてオリジンサーバーへアクセス webサイトのパフォーマンスを改善できる CloudFront → S3 OAI 署名付きURL 署名付きcookie 【コスト】 ざっくり : 転送量 x 単価 + リクエスト数 x 単価  = 料金 インターネットへのリージョンデータ転送アウト(GB単位) HTTPメソッドのリクエスト料金(1万件あたり) オリジンへのリージョン内データ転送アウト 【CDN(Content Delivery Network)】 webサーバーがコンテンツを配信する際にその前段としてCDNを配置 コンテンツをキャッシュすることでwebサーバーの負荷を軽減 キャッシュがないときはサーバーに取りに行く キャッシュがあるときはCDNがコンテンツを返す 【CloudFrontディストリビューション (CloudFrontの設定のこと)】 オリジンサーバーでオブジェクトを保存した後、オブジェクトがどこにあるかをCloudFrontに伝える役割を持つ ディストリビューションを作成すると、CloudFrontはあなたがオブジェクトを管理するために使用する一意のドメイン名を提供 作成可能なディストリビューションは2つ (1)ダウンロードディストリビューション : HTTP or HTTPSを使用してコンテンツを配信 (2)ストリーミングディストリビューション コンテンツオリジン : どのサービスのコンテンツ配信を高速化するか 地域制限 : 特定の国のユーザーがコンテンツにアクセスできないようにする セキュリティ : HTTPSを必須にするかどうか アクセスログ : cloudFrontでviewerのアクティビティを示すアクセスログを作成するかどうか 【オリジンアクセスアイデンティティ(OAI)】 S3にあるwebコンテンツを配信する時に、CloudFrontからのみアクセスさせる仕組み 閲覧者のS3への直接アクセスはブロック 【署名付きURL】 URLを知っている人だけが、CloudFrontからコンテンツを取得することができる 個々のファイルへのアクセスを制御する場合に使用 署名付きCookieはRTMPディストリビューションではサポートされていないため署名付きURLを利用する ユーザーがCookeiをサポートしてない場合は使う 【署名付きcookie】 特定のcookieをセットされている人だけが、cloudfrontからコンテンツを取得することができる 複数の制限されたファイルへのアクセスを提供する場合など URLを変更したくないときに利用 ⭐️ 【コスト】 トラフィックの分散 リクエスト数 データ転送アウト 用語 説明 OAI ・OAIはS3バケットへのアクセスをCLoudFrontからのリクエストを絞るための仕組み・OAIと呼ばれる特別なユーザーを作成し、そのユーザーに限定してアクセスを許可 カスタムヘッダー カスタムヘッダーをオプションで設定して、カスタムオリジンへのアクセスを制限する仕組み Viewer Protocol Policy ・HTTPとHTTPS両方nにアクセスできる・HTTPをHTTPSにリダイレクトにする・HTTPSのみアクセスさせる Origin Protocol Policy CloudFrontからオリジンへのアクセスプロトコルをここで指定できる 【キャッシュ有効期限】 用語 説明 TTL CloudFront配信時に設定されるキャッシュ保持時間 Expires キャッシュの期限切れを設定 Cache-Control max-age CloudFrontがオリジンサーバーからオブジェクトを再度取得するまでオブジェクトをキャッシュに保持する期間を指定 【フィールドレベル暗号化】 個人を特定できる情報などの機密データのセキュリティをより強化 ユーザーが決めたフィールド固有の暗号化キーを使用して、リクエストがオリジンに転送される前にhttps内で機密データをさらに暗号化 Global Accelerator TCP or UDPを介して様々なアプリケーションのパフォーマンス向上 1つ以上のAWSリージョンで実行されているアプリケーションにエッジでパケットをプロキシすることにより、TCPまたはUDPを介した幅広いアプリケーションのパフォーマンスを向上 CloudFrontに似ている HTTPだけでなく、TCP/UDPのトラフィック・ルーティングに対応 クライアント証明書は利用する、クライアントIPは保存する アプリケーションをエッジロケーションで実行、CDNのアプリケーション版 キャッシュを使わず幅広く柔軟に対応できるので Global Accelerator、キャッシュを使ってお手軽にCDNを構築するのでCloudFront HTTPの特に静的IPアドレスを必要とするユースケースや、高速なリージョン間フェイルオーバーに適しているだけでなく、HTTP以外のユースケース、例えばゲーム(UDP), IoT(MQTT), VoIPにも適している S3 (Simple Storage Service) オブジェクトストレージ デフォルトで複数AZに冗長化 ⭐️ アプリケーションでバケット内のprefixごとに1sあたり3,500回以上のPUT/COPY/POST/DELETEリクエスト or 5,500回以上のGET/HEADリクエスト達成できる prefixを増やせば並列化できる 名称 取り出し時間 説明 S3 standard(標準) 即時 ・複数箇所にデータ複製、最もコストが高い・頻繁にアクセスされるデータに高い耐久性、可用性、パフォーマンスオブジェクトストレージ S3 Standard-IA (標準-低頻度アクセス) 即時 ・標準に比べて安価・データの読み出しに対してコスト発生・低頻度アクセス用だが読み込みはすぐできる S3 Intelligent-Tiering 即時 ・アクセスパターンに基づいてコスト効率の高いストレージ階層に自動で移動、または不明な存続期間が長いデータ向け S3 One Zone IA (1ゾーン低頻度アクセス) 即時 ・標準-IAより安価。・1つのAZのみにデータを保存。・ログファイルとかがベスト・データへのアクセス頻度が低く、高い耐久性を必要とせずかつ必要に応じてすぐに取り出したい場合に適している。・AZで障害時にデータが消滅する場合がある Glacier 数分-数時間 ・アーカイブ目的。標準と比べても格納コスト1/5・データの読み出しに料金がかかる・最低保持期間が90日 S3 Glacier Deep Archive 数時間 ・長期アーカイブデータ向け・Glacierより安価。 - S3 Glacier S3 Glacier Deep Archive 迅速 1-5分 利用なし 標準 3-5h 12時間以内 大容量 5-12h 48時間以内 【コスト】 ストレージ容量 データ転送 : 課金されるのはS3からの送信だけ、受信(upload)は無料 *インターネットへの送信、別のAWSリージョン、CloudFrontへの送信は別料金 *同一リージョン内のAWSサービスとの通信は無料 リクエスト数 *S3では、GET/PUT/POST/LIST/COPYなどのリクエストに対しても課金ある *GETは安い、PUT/POST/LIST/COPYは高め *DELETEは無料 【署名付きURL(Presigned-URL)】 特定のURLからのみS3にアクセスできるようにする機能 【ライフサイクル機能】 S3上で一定期間経過したオブジェクトを自動的に削除したり標準IAやGlacierに移行する機能 【バージョニング】 有効にすると、S3内のオブジェクトのあらゆるバージョンを取得できる 意図しないオブジェクトの削除を行ったときも復元できる ⭐️ 一度バケットのバージョニングを有効にすると、バージョニング無効の状態に戻すことはできない (停止は可能) 【静的webサイトホスティング】 htmlファイルや画像ファイルなどをS3において、クライアントからのリクエストに応じてそのまま表示 サーバーなしにwebサイトをホスティング可能 サーバーが必要ないために値段が安い 動的サイトは不可、SSL設定はCloudFront必須 【S3の暗号化】 名前 説明 鍵の管理場所 手間 料金 SSE-S3 ・AES-256 暗号化タイプ ・"x-amz-server-side-encryption":"AES256" ・利用状況の監査証拠がとれない S3 少 無料 SSE-KMS ・"x-amz-server-side-encryption":"aws:kms"ヘッダーを設定して利用する・cloudtrailにより証跡ログが取得可能 KMS 中 KMSの料金が適用 SSE-C ・AES-256 暗号化タイプ ユーザー 多 ? CSE(Client Side Encryption) クライアント側 ユーザー 多 ? KMSでカスタマーマスターキー(CMK)を削除することは破壊的行為であ利、危険性を伴う だから、KMSには削除待機期間が設定されている KMSでCMKを削除するには、キーの削除スケジュールを設定しておく必要がある 待機期間は、最短7日から最長30日(デフォルトでは30日) 【アクセス制御】 種類 対象 説明 ACL バケット・オブジェクト 簡単に設定できるがその分柔軟なアクセス制御はできない バケットポリシー バケット 設定は複雑、柔軟なアクセス可能 IAMポリシー IAMユーザー/グループ S3への操作権限をIAMユーザー・グループに対して付与 Public Access バケットポリシーが不正に書き換えられ、バケット内のオブジェクトが公開されることを防ぐ機能 外部に公開しないバケットは有効化 【CORS (Cross-Origin Resource Sharing)】 すでにドメインが設定されているS3バケットを他のドメインに共有することができる 【S3 クロスリージョンレプリケーション(CRR)】 S3オブジェクトを別リージョンのバケットに自動で複数することが可能 オブジェクトの登録と同時に実行 バケットにおけるオブジェクトの作成・更新・削除をトリガーにレプリケーションを実行 【S3 select vs Athena vs Redshift Spectrum】 用語 説明 s3 select ・単一ファイルが対象・GZIP圧縮データやCSV・jsonに対して実行可能・クエリの機能が少ない Athena ・複数のファイルを対象にできる・クラスタ(サーバ)を必要とせず、S3にデータがあればすぐに利用可能リトライ機能がなく、データを絞って高速にスキャンするS3上のログ等にデータを保管しておりそれを分析用途に簡単に利用したい場合S3をデータレイクとして位置付け、S3上のデータに直接アクセスできるインターフェースを用意Athena SQLクエリでSageMaker機械学習モデルを呼び出し、機械学習による推論も実行可能 Redshift Spectrum Redshiftクラスタが起動されている前提であるため、RedShiftを利用している場合におすすめ大規模データに対して、複数クラスタで動作するため高速なレスポンスが期待できる ・S3にデータをおいたままそのデータにアクセスできる方法 Macie 機械学習によりS3の機密データを検出、分類、保護する、フルマネージド型のサービス S3をデータレイクとして位置付け、S3上のデータに直接アクセスできるインターフェースを用意 S3に格納された複数のファイルに対してクエリを行う→Athena, Redshift Spectrum 【S3 Transfer Acceleration】 地理的に一番近いエッジロケーションを利用して高速にデータアップロードを実施 送信元から遠く離れたs3へのデータ転送をAWSのエッジロケーションとしてネットワークプロトコルの最適で高速化するサービス ユースケース : 世界中からアップロード, 大陸間で定期的にGBからTBのデータを転送するケース 費用 : 1GB uploadあたり、$0.04が上乗せ 【S3 マルチパートアップロード】 大容量のファイルを分割して転送する機能→S3へのアップロード時間の短縮 オブジェクトサイズが100MB以上の場合は、単一のオペレーションでオブジェクトをアップロードする代わりにマルチアップロードを使用する必要がある S3 Transfer Accelerationと併用すると転送速度が一段と向上 S3バケットに保存できるオブジェクトの最大ファイルサイズ→5TB prefixを利用して日付ベースでuploadを分散することで少なくとも3,500 request/s, データ取得で5,500/sサポート S3のPath : s3://<bucket>/<prefix>/<object> (prefix : ディレクトリみたいなもの) 【S3イベント】 S3オブジェクト操作と連動したシステム連動処理 SNS / SQS / Lambdaに通知設定 RDS (Relational Database Service) RDBSサービス データ操作にSQL使用 障害時や誤作動が起きた際に5分前の状態に戻せる RDSインスタンスにSSHはできない DBインスタンスはMAX7日間停止できる 最大で5個のリードレプリカを作成して、読取処理の負荷分散可能 ファイルシステムとの連携はサポートされていないため、連携を実現するためにはEC2インスタンスにデータベースをインストールしてサーバを構築する必要がある ライフサイクルポリシーによるBUはできない EC2インスタンス+EBSの構成が例えばMYSQLをインストールして動かしている マルチAZ構成のRDSでは、プライマリデータベースのインスタンスがダウンした場合に管理者の介入なしにDB操作できるようにフェールオーバーが自動的に処理される。フェイルオーバーするとRDSはDBインスタンスのCNAMEレコードをスタンバイから切り替えて、新しいプライマリに昇格 【RDS暗号化】 RDSの暗号化されたDBインスタンスDBでは、基盤となるストレージに保存されているデータが暗号化され、自動化されたバックアップ、リードレプリカ、スナップショットも同様に暗号化される 【RDSのスケールアップ】 インスタンスサイズの変更 インスタンスタイプの変更 ストレージタイプの変更 【リードレプリカ】 RDSにおいてDB読み取り処理をオフロードすることできる機能 読み込み専用 マスターの複製DB マスターの読み取りにかかる負荷を軽減でき、これによりマスターのパフォーマンスが向上 【レプリケーションラグ】 リードレプリカは非同期にレプリケート レプリケーションデータが遅れることが多く、最新のトランザクションのいくつかを表示できないことあり 【IAMデータベース認証】 通常のパスワードを使ったデータベースの認証の代わりが権限を付与したIAMロールを用いることで認証を行う 【RDSプロキシ】 アプリケーションとRDSの間に配置され、ProxyとしてDBへの接続を効率的に管理 高速フェイルオーバーによる可用性の向上 Lambdaを利用してRDSのデータベースnに接続する際は、RDSプロキシをエンドポイントの代わりに利用して、接続することでコネクションを効率的に実行することができる 「接続が多すぎる」エラーが頻繁に発生するDBインスタンスやクラスターは、プロキシ経由が良い Lambda -> RDS Proxy -> RDS Good! 【ストレージオートスケーリング】 実際にストレージが少なくなって来ると自動でストレージがサイズアップしてくれるようになり、実際に使う分+αだけ支払えば良い ⭐️【読み取りリクエストが急増した時の対応】 リードレプリカ増設(コスト低い) インスタンスタイプの性能変更 キャッシュレイヤーでElastiCache(コスト高) Aurora 大規模なクエリ処理が発生するRDB クラウド専用の分散型のRDS MySQLと比べて最大5倍、標準的なPostgreSQLと比べて最大で3倍高速 商用DBと同等のセキュリティ、可用性とかを1/10で実現 最大15のリードレプリカを利用した高速読み込みが可能 Auroraはクラスターが3つのAZに分散されて構成され、さらにRDSと同様にマルチAZのフェールオーバー構成を有効化することが可能 フェールオーバーの実行時間はAuroraレプリカを作成している場合は30s以内に完了 【Aurora Multi-Master】 全てのDBインスタンスで書き込みオペレーションを実行 ⭐️ DBの書き込み操作のためダウンタイムを許容できない時使用 【Aurora Serverless】 自動でスケールして、アクセスがなければ勝手に停止するAWSのMySQL/PostgreSQLインフラ 【Aurora Global Database】 Auroraクラスターを複数のリージョンにまたがって構築 AWSリージョン障害時の災害復旧実現 世界中からデータベースを高速に読み書き実現 プライマリ・リージョンから別リージョンへ低レイテンシーにデータがレプリケート 書き込み転送機能 : 有効にするとセカンダリリージョンでは読み込みだけでなく書き込みも可能 DynamoDB マネージドのNoSQLデータベースサービス データが3つのAZに分散して格納されるため耐久性が高く、格納容量に上限がない また、key-value形式で簡易に操作できるかつレイテンシーが低いため、キャッシュやwebセッションの格納先としても利用 小規模データを保存、処理するためにはNoSQLDBを利用することが最適 API経由操作キーに対するvalueのCRUD操作は可能、ただしJOIN/Transaction/Commit/rollbackは不可 Read/Writeが多いシステムにgood WEBセッション管理, S3オブジェクトのメタデータの保存に使用 データサイズは無制限、1つのデータは400KBに制限 【DAX (DynamoDB Accelerator)】 DynanoDBに特化したインメモリキャッシュ→DynamoDBテーブルへの数ミリ秒のレイテンシーを数マイクロ秒に短縮 DAXは、開発者がキャッシュの無効化、データ入力、クラスターの管理を実施する必要なし 【DynamoDBストリーム】 テーブル上の作成、更新、削除の時に別のAWSサービス(ほぼlambda)をトリガーとする機能 トリガーを利用してLambdaを実行するなど DynamoDBテーブルに保存された項目の追加・変更・削除の発生時の履歴をキャプチャできる機能 データの保存 過去24時間以内のデータ変更の履歴を保存し、24時間を経過すると削除される データ容量はマネージド型で自動的に管理 データ保存の順番 : 操作が実施された順番に応じてデータはシリアライズされる 【DynamoDBグローバルテーブル】 ほかのリージョンにテーブルのレプリカ作成 グローバルテーブルを作成するためにはまず1つのDynamoDBテーブルを作成してストリームを有効にする 【DynamoDB AutoScaling】 テーブルとインデックスを監視してアプリケーショントラフィックの変化に応じて、自動的にスループットを調整 DynamoDBテーブルを作成するとAutoScalingがデフォルトで有効 CloudWatchのモニタリングに基づいてトラフィックパターンに応じてプロビジョンスループット性能をユーザーにかわって動的に調整 【整合性モデル】 結果整合性 強い整合性 【料金】 (1) キャパシティユニット(read/write) (2) ストレージ容量 (3) データ転送量 ElastiCache 大量かつミリ秒未満の応答時間のデータを扱うアプリケーションのインメモリデータストアとして活用 キャッシュエンジンは、RedisとMemcached が選択可能 ユーザー行動データの高速な処理には最適なDB ノード、シャード、クラスタの単位が存在する ユースケース : セッション管理, メタデータの蓄積、ソーシャルメディアのデータ分析、DBキャッシュ処理、Pub/Sub処理、ランキング、レコメンデーション ノード(Node) キャッシュサーバで、ElastiCacheの最小単位 選択したノードタイプによって性能(メモリやCPUなど)が異なる シャード(Shard) ノードをまとめるグループ 1つのシャードにプライマリノード1個と、リードレプリカ(読み込み専用)0-5個持つ クラスタ シャードをまとめるグループ クラスタ毎にキャッシュエンジンを選択可能 クラスタモードは有効と無効を選択可能 インメモリキャッシュパターン CDNのデータベース版 頻繁にアクセスするデータをDBではなくインメモリキャッシュに格納することで、DBの負荷を軽減する設計パターン Redis Memcached ・高速に値をRead/Writeできるインメモリキャッシュ型DB・シングルスレッド・スナップショット機能がある・データを永続化できる ・ 高速に値をRead/Writeできるインメモリキャッシュ型DB・マルチスレッド ・スナップショット機能がない・データを永続化できない・フェイルオーバーや復元できない ・複雑なデータ型が必要な時・永続化が必要な時・ フェールオーバーが必要な時・pub/subが必要な時 ・シンプルなデータ型だけで充分な時・マルチスレッドが必要な時・バックアップと復元の機能がない・ キーストアに永続性がない Redis : インターネットスケールのリアルタイムアプリケーションにミリ秒未満のレイテンシーで動作する超高速インメモリデータストア Redis : ゲームリーダボード、機械学習、メディアストリーミング、リアルタイム分析、セッションストア *RedisをDynamoDBと統合することもできるが、DynamoDBにフィットしているDAXを使うことに比べるとはるかに複雑 ElastiCache for Memcached はS3の静的コンテンツを配信するためのキャッシュとしては使用できない 移行関連 ①AWS Application Discovery Service(ADS) 移行計画を支援するサービス ②AWS Database Migration Service(DMS) データベースを短期間で安全にAWSに移行することが可能 DB移行ツール ③AWS Server Migration Service(SMS) 仮想マシンの移行サービス VMware, Hyper-V, Azure上の仮想サーバーをAMIとしてAWSに移行 手間がかからない 無料 ④AWS Schema Conversion Tool あるDBエンジンにおける既存のDBスキーマを、別のDBエンジンのスキーマに変換するツール LB (1) 【Connection Draining】 バックエンドのサーバーがELBから切り離されてもセッションを持ち続ける機能 バックエンドのEC2を登録解除しても処理中のリクエストが終わるまで一定期間待つ ソフトウェアのメンテナンスなどで使える機能 既存の接続を開いたまま、登録解除または異常なインスタンスへのELBのリクエスト送信を停止することができる これにより、LBは登録解除または異常なインスタンスに対して行われた実行中のリクエストを完了するトラフィック処理を実施 LBが接続を維持する最大時間を指定 : 1~3,600s (デフォルトは300s) (2) 【スティッキーセッション】 セッションの維持を行う機能→クライアントからのリクエストを毎回同じインスタンスに転送する機能のこと HTTPレスポンスにELBでCookieを埋め込んでそのCookieを基にバインド先のインスタンスを固定する 送信先のEC2が障害によってダウンした場合は、セッションが途切れる問題が発生するのでELBによるスティッキーセッションは一時的に利用が良い (3) 【Cross-Zone Load Balancing】 配下のEC2の負荷分散に応じて、複数のAzにまたがるEC2インスタンスに均等に負荷分散を行う 各LBはすべてのAZの有効なインスタンスにリクエストを分散する これによりクライアントのDNSキャッシュが効いていてもバックエンドのインスタンスには適切に負荷分散がかけられる ALBでは常にクロスゾーンバランシングが有効になっている 【Proxy Protocol (プロキシプロトコル)】 HTTPでいうところのX-Forwaded-forをHTTP以外で使いたい時のプロトコル EBS (Elastic Block Store) EC2インスタンスに接続して利用できるブロックレベルのストレージ OSから見えるストレージボリュームで、アプリケーションやユーザーデータなどを格納 スナップショットでバックアップされS3に保存、増分バックアップ スナップショットはEBSの利用状況に関係なく、非同期に作成 EC2とは独立 SGによる通信制御対象外であり、全ポートを閉じてもEBSは利用可能 他のAZのインスタンスにはアタッチできない プロビジョンドIOPSのみ複数インスタンスで共有できる スナップショットの管理→DLMによる管理 ストレージタイプ 名称 説明 ①汎用SSD(GP2,GP3) ・デフォルトのボリュームタイプ・安定したI/O性能が利用できる ・ストレージの読み書きに関しては課金されない ②プロビジョンドIOPS SSD (io1, io2, io2 block express) ・汎用SSDよりも高いI/O性能が求められるケース・複数のEC2への接続が可能・ストレージ容量だけでなく指定したIOPS数に対しても課金されるため注意。 ③スループット最適化HDD(st1) ・主にファイルのシーケンシャルアクセスが多い場合に高いスループットを提供するタイプ。・大規模なデータを扱う時good ・用途としてはMapReduce,ETL処理、ログ処理、DWH、ビックデータ分析など ・小さなファイルサイズを大量に読み書きするには向いていない ④コールドHDD ・高いスループトが不要な場合には、より低価格なコールドHDDのタイプ。・ログファイルの保管など高いスループットを求められないバックアップ領域などが主な用途 ⑤マグネティック 旧世代のボリュームタイプ IOPS : ストレージが1sあたりに処理できる(I/O)アクセスの数(ストレージに書き込むのが早いかどうか) スループット : 単位時間あたりでどれくらいデータを転送できたか(処理能力が高いかどうか) ⭐️ ブートボリュームとしてスループット最適化HDD, Cold HDDは使用できない 【DeleteOnTermination】 インスタンスが終了すると、EC2は接続されていた各EBSボリュームのDeleteOnTermination属性を使用して、ボリュームを存続させるかどうか判断 「非有効化」にすることでEBSボリュームのみ保持可能 【DLM(Data Lifecycle Management)】 EBSのスナップショット作成や削除をスケジューリングできる EBSの定期的なバックアップスケジュールを実施して貴重なデータを保護 古いBUを削除してストレージコストを削減する 【EBSボリュームの削除】 インスタンスを終了すると、EC2は接続されていた各EBSボリュームのDeleteOnTermination属性を使用してボリュームを存続させるか削除すべきか判断する 1 2 ルートボリュームのEBS デフォルト設定ではEC2インスタンスの削除と共にEBSボリュームも削除される DeleteOnTermination属性 ・有効にしているとEC2インスタンスの削除に応じてEBSも削除される・非有効化することでEBSボリュームのみ保持可能 1 2 EBS ネットワークで接続されたブロックレベルのストレージでEC2とは独立管理 EC2を終了してもEBSデータは保持可能SnapshotはS3で保存 インスタンスストア EC2の一時的なデータが保持され、EC2の停止・終了と共にデータがクリアされる EBSミラーリング : 同じデータを複数のディスクに書き込むこと可能 【Multi-Attach機能】 1つのプロビジョンドIOPS SSD(io1, io2)ボリュームを同じAZにある複数のインスタンスにアタッチ可能 【RAID】 RAID0 : 複数のディスクを1台のディスクのように扱う、ストライピング RAID1 : 2つのボリュームを同時に、ミラーリング 【インスタンスストア】 EBSよりもパフォーマンスが優れる データは揮発性 インスタンスが停止・終了だとデータは失われる スナップショットを取得することもできない ただし、再起動ではデータは維持される EBSは「ボリューム、IOPS、スナップショット」で費用が発生するのに対し、インスタンスストアの費用はEC2に含まれる EFS (Elastic File System) 複数のEC2インスタンスからアクセス可能な共有ストレージ(インターネットからは直接アクセスできない) 複数AZに分散して保存 NFSv4プロトコル (Amazon FSx ときたら SMB Protocol) 【マウントターゲット】 EC2インスタンスから接続先のマウントターゲットを設定 EC2→マウントターゲット→EFSの流れ 【EFS Standard】 最高レベルの耐久性と可用性を必要とするワークロードに最適 【EFS Standard-IA】 EFSの低頻度アクセス用のストレージ 低頻度アクセスと判断されたものが自動的に安価なEFS IAストレージに移行してくれる ライフサイクル管理を有効に パフォーマンスモード 使用例 汎用 ・ウェブ配信環境・コンテンツ管理システム・一般的なファイルサービス 最大I/O ・ビッグデータ解析・メディア処理 AWS DataSync オンプレミスストレージとEFSの間でデータを迅速かつ簡単に移動することができるマネージド型のデータ転送サービス 【Amazon FSx for Lustre】 多くのスーパーコンピュータで利用される高性能な分散ファイルシステム データリポジトリとのシームレスな統合 S3のデータセットとAmazon FSx for Lustreファイルシステムを関連づけ実際に処理を行う時にのみLustreを使用する 処理が終了したら、ファイルシステムを削除したらFXs for Lustreについては課金されない Kinesis 【Kinesis Data Stream】 バッチ間隔を60sに設定など、バッチサイズまたはバッチ間隔を指定可能 kinesis data streamのデータ保持期間はデフォルトで24時間で、最大値は168時間 配信ストリームは自動的にスケーリングされ1つのシャードは1sあたり1MBのデータを取り込むことができ、書き込みは1sあたり1,000レコードを取り込み可能 送信先にアップロードされたデータをKMS暗号化キーを指定して、自動的に暗号化を実施 コンソールやCloud Watchからメトリクスを参照可能 送信データ量とデータ形式の変換に対してのみ料金が発生 ビッグデータのストリーミングをリアルタイムで処理 CloudWatch 【VPCフローログ】 VPCフローログはネットワークトラフィックを取得しCloudWatchでモニタリングできるようにする機能 NICを送信先/送信元とするトラフィックが対象 キャプチャウィンドウと言われる時間枠10minで収集・プロセッシング・保存する SQS フルマネージド型のメッセージキューサービス SQSを利用したポーリング処理 : イベントのトリガーをタイミングに依存しない連携が可能- 水平スケーリング : webシステムおアプリケーションの間にSQSキューを追加することによりスケーリングを実現 SQSのキューによってEC2インスタンス側のワーカー処理を複数で並行処理をすることが可能 メッセージ数は無制限 (ただし、拡張クライアントライブラリーを利用すると2GBまでのメッセージのやりとりが可能) SQSに送信できる最大サイズは256KB デフォルト4日間 (SQS側での最長保持期間は14日間) オンプレ上でメッセージングサービスを利用しているシステムをそのまま移行する場合MQで、クラウドネイティブなサービスを構成する場合はSQSを利用する SQSは、リクエスト毎に課金が発生。MQは、利用した時間およびMQを通過したデータ量に応じて課金が行われる キューの種類 種類 説明 スタンダード ・一回以上の配信 : 1回は確実に送信されるが、複数回送信されることもある・⭐️ベストエフォート型 : メッセージが送信された時と異なる順序で配信されることがある ・メリットはほぼ無制限のスループット・基本的に、順序性に依存せず、処理の重複を許容できるのであればスタンダードキュー FIFO ・ ⭐️ 一回だけの送信 : メッセージの重複は発生しない・ 順序保証 : 先入れ先出しのため・ バッチ処理を使用する時は、FIFOキューはAPIメソッド(SendMessageBatch, ReceiveMessage, DelettetMessageBatch)ごとに1sあたり最大3,000のトランザクションをサポート 3000のトランザクションは300のAPIコールを表し、それぞれに10このメッセージのバッチがある デフォルトではFIFOキューは1sあたり300メッセージしか処理できない 【ライフサイクル】 Producerがメッセージ送信 Consumerがメッセージを取得 Consumerが処理を終了し、メッセージを削除 *最長メッセージ保持期間を超えてキューに残っているメッセージは自動的に削除される *デフォルトのメッセージ保持期間は4日間 【可用性タイムアウト】 この時間内は他のコンシューマによる同じメッセージの受信と処理が防止される メッセージのデフォルトの可視化タイムアウトは30s (min0s, max 12h) 【遅延キュー】 キューへの新しいメッセージの配信を数秒延期させることができる 遅延期間の間コンシューマーに表示されなくなる 【SQSパラメータ】 パラメータ - receiveMessageWaitTimeSeconds ・Lambdaがメッセージをポーリングして応答を返す前に待機する時間(1-20s) ・ 0を指定すればショートポーリング0を指定すればショートポーリング visibilityTimeout メッセージがキューから読み取られた後、メッセージがconsumerに表示されない時間の長さ maxReceiveCount メッセージをDLQに移動する前に、送信元キューに表示されるように配信できる回数 maximumBatchingWindow Lambda関数を起動する前に。SQSのレコードを集めるための最大時間。最大300sまで設定可能 1 2 Step Function ・細分化した機能を連結させて、視覚的に設計ができるサービス・ユースケース : 注文処理、在庫追跡、複雑なユーザー登録プロセス、管理者が承認した場合に限り処理を行う Simple WorkFlow ・ワークフローを構築・実行するためのサービス・EC2インスタンスを利用したサーバーベースのワークフロー機能であるためサーバーレスオーケストレーションは提供していない SNS フルマネージド型のPub/Subメッセージングサービス Push機能 更新を定期的に確認したり、「ポーリング」したりする必要性がない 送信側がトピックを作成して受信側をポリシー指定することで制御された非同期通信を実現 Amazon MQ メッセージブローカー 業界標準のAPIおよびプロトコルをサポート (従来のメッセージコードを書き換える必要なく現状維持できる) VPN VPN設定に必要 : 仮想プライベートゲートウェイ, カスタマーゲートウェイ CloudFormation 用語 説明 変更セット ・スタックの更新前にリソースの更新や削除を把握することができる ドリフト ・CFテンプレートの内容と、実際のリソースの異なる点を発見してくれる便利な機能 StackSets ・複数のアカウントおよびリージョンのスタックを一度のオペレーションで、作成、更新、削除できる機能 AWS Secrets Manager DBの認証情報やパスワードなどの任意のシークレット情報をAPIコールで取得できるもの アプリケーションにシークレット情報を保存する必要がなくなる DB認証情報を格納して自動ローテートするたのセキュアな方法 AWS KMS(Key Management Service) データを暗号化するための鍵の管理を行ってくれるサービス 暗号鍵をAWSの責任範囲において保管したり、更新したりしてくれる データの暗号化の鍵(データキー)と暗号化のための鍵(マスターキー)を管理 CloudHMSより安価 サポートされる暗号鍵は、KMS:共通鍵, CloudHMS : 共通鍵と公開鍵 AWS CloudHSM 専用のハードウェアで暗号化キーを保管 CloudHSMの方がより安心してキーを管理することができる KMSに比べると高価 AWS Directory Service セキュリティ保護サービス (1) AWS WAF (2) AWS Shield : DDoS攻撃からリソースを守るサービス (3) GuardDuty : 脅威を検出するサービス CloudTrailイベントログ、VPC フローログ、DNSログなどの複数のAWSデータソース全体で何百億件ものイベントを分析 AWSのアカウント、ワークロード、S3に保存されたデータを保護するために、悪意あるアクティビティや不正な動作を継続的にモニタリングする脅威検出サービス 設定画面でGuardDutyを無効にする : GuardDutyがAWS環境を監視して新しい結果を生成するのを停止するだけでなく、既存の結果とGuardDutyの設定も失う (4) Inspector : セキュリティの脆弱性評価 自動化されたセキュリティ評価サービスで、EC2インスタンスへの意図されていないネットワーク経路や、脆弱性をチェックできる AWS Storage Gateway オンプレミス環境にあるデータをクラウド上のストレージにおく。そのためのゲートウェイ EC2インスタンスだけでなくオンプレミスサーバーにs3をマウントして利用も可能 データを暗号化できる データの格納先 : S3, EBS, Glacier(ストレージゲートウェイの種類によって格納先が異なる) 1 2 3 (1)ファイルゲートウェイ ・オンプレミスに保存しているファイルをS3のオブジェクトとして保存・S3の1オブジェクト = オンプレミスの1ファイル・NFS / SMBプロトコルで接続NFS / SMBプロトコルで接続 (2)ボリュームゲートウェイ キャッシュ型 ・プライマリはS3ストレージ・プライマリーデータをS3に保存して、頻繁にアクセスされるデータはキャッシュしてローカルに保存 保管型 ・プライマリーオンプレミスストレージ ・メインデータはローカルに保存する一方で、そのデータを`非同期にS3にバックアップする (3)テープゲートウェイ ・物理テープライブラリへの代替として、ストレージゲートウェイを仮想テープライブラリとして使用 API Gateway APIの作成・管理を行う REST(ステートレス)とWebSocket(ステートフル)のAPI対応 【設定項目】 用語 説明 メソッドリクエスト リクエストに認証が必要か、どのようなクエリパラメータを受け付けるかといったAPI Gatewayの受付設定を行う 統合リクエスト アップストリームの指定、リクエストボディの変換といったAPI Gatewayとアップストリーム間の統合を行う 統合レスポンス ステータスレコードのマッピング、レスポンス内容の変換といったアップストリームとAPI Gateway間の統合を行う メソッドレスポンス ステータスレコードごとのレスポンスヘッダーやレスポンスボディの設定といったAPI Gatewayからクライアントへのレスポンス設定を行う 【APIの公開】 作成したAPIを外部に公開するためにはデプロイを行う 各APIはデプロイ先としていくつかのステージを持ち、それぞれ異なるバージョンのAPIを公開することができる 【スロットリングの利用】 リクエスト数が多すぎる場合、制限をかけることで、トラフィックの急増に対してバックエンドサービスを守る 1 2 サーバ側 全てのクライアントに対するリクエストを制御する。全体のリクエストが多すぎるためにバックエンドサービスが処理できなく事を防ぐ クライアントあたり クライアントごとに「使用プラン」に応じて制限を行う。特定のユーザーからのリクエストが多い場合に有効 【アクセス制御】 ◇ リソースポリシー(RESTのみ) JSON形式のリソースポリシーを定義することで、API Gatewayのどのリソースに、どのアクセスからの、どのようなアクションを許可/拒否するかを指定できる API Gatewayのリソースポリシー作成・更新のために必要な権限 : apigateway:UpdateRestApiPolicyとapigateway:PATCH権限必要 リソースポリシーを設定・変更したら、APIのデプロイを実行 ◇ IAM認証 APIの各要素へのアクセス権限を設定したIAMポリシーを作成し、アタッチすることによりAPIへのアクセスの制御が可能になる これには、対象の各APIメソッドでIAM認証を有効化する必要がある ⭐️ ◇ Lambdaオーソライザー Lambda関数を作成することで、認証プロバイダーでの認証結果を元にAPIへのアクセス制御をメソッド単位で行えるようにする ◇ Cognitoオーソライザー 認証プロバイダーとしてCognitoユーザープールを用いて、APIへのアクセス制御をメソッド単位で行うことも可能 Lambda関数を作成する必要がない ◇ APIキー API Gatewayの使用量を制限するために発行するアクセスキー APIキーの使用量制限はそれぞれのAPIキーに対して設定するのではなく、使用量プランという設定項目でスロットリング設定を行い、APIキーで使用量プランに紐付けることで設定 Lambda DynamoDBから取得したデータに任意の集計をかける関数 Lambda関数は実行数に応じて支払いが発生するため、Lambda関数が無期限に実行されないようにタイムアウト設定がされている 同一アカウントの同一リージョン内で1,000までの同時実行をサポート Lambdaの言語サポート : C#/.NET, Go, Java, Node.js, Python, Ruby 【Lambdaの制限】 タイムアウト(デフォ3s, max15分) ⭐️ 実行数はデフォルト100, max1000 /tmp ディレクトリのストレージの保存可能容量512MB Lambdaレイヤー MAX5つまで Lambda関数は最大512MBまでのデータ容量 【Lambdaレイヤー】 Lambdaファンクション間で共通するコンポーネントをLambda Layerとして定義し参照できる(5つまで) Fargate コンテナを実行する時にホストマシンとなるEC2のスペックを意識することなく設計できる ⭐️ コンテナ化されたアプリケーションが使用するvCPUとメモリリソースの量に応じて課金される vCPUとメモリリソースは、コンテナイメージがPullされてからECSタスクが終了するまでの時間が計算され、最も近い秒数に切り上げれる ⭐️ EC2起動タイプのECSは、使用されたEC2インスタンスとEBSボリュームに基づいて課金 AWS Systems Manager AWSで利用のインフラストラクチャーを可視化し制御するためのサービス RGごとに運用データを確認できる EC2のパッチ、更新、設定変更、削除、停止、およびデプロイなどを自動化 AWS Step Functions JSON形式でステートマシンを定義して、ワーカーフローやワーク処理系のアプリケーションを構築することが可能 Lambda関数およびAWSの複数のサービスをビジネスプロセスとして配列することができるサーバーレスのワークフロー作成・管理サービス ワークフローに手動アクションを必要とするいくつかのタスクが存在する可能性があると、その手動アクションが処理されなければワークフローがアクション待ちの状態となるため、タスクが停滞 AWS Organizations 複数のAWSアカウントに対してポリシーを設定してアクセス権限を管理 AWSアカウントの作成と管理の自動化 複数アカウントをまとめたグループを作成し、アカウントを自動化し、それらのグループにサービスコントロールポリシーを適用することが可能 単一の組織内の複数AWSアカウントの支払いを統合できる →ストレージの利用量を統合して請求することによって、コストを削減できる可能性 AWS X-Ray ユーザーがAmazon APIからのAPIリクエストを通じてサービスを呼び出した場合に、ユーザーリクエストを追跡および分析できる アプリケーションが処理するリクエストに関するデータを収集するサービスで、レスポンスタイムやレスポンスステータス、アプリケーションに対するリクエストに関するデータを収集し、コンソール上で表示したり分析することで問題を特定 サービスマップと呼ばれるグラフから全体のパフォーマンスを確認することができ、リソースのレイテンシーや障害の発生率の特定などを確認できる サービスマップ アプリケーションから生成されたトレースしたデータを可視化したもの クライアントが始点で、各サービスのノードが終点になる コストまわり AWS Billing and Cost Management AWS Budgets コストまたは使用量が予算額を超えた時にアラートを出すカスタム予算を設定可能 予約アラートできる Cost Explorer これまでに発生したコストをグラフィカルに視覚化(過去のコスト確認) 課金状況を確認 RIの使用率レポート / カバレッジレポート 課金状況を確認 RIの使用状況までわからない コストと使用状況レポート (Cost & Usage Reports) 利用可能な最も包括的なコストと使用状況のデータが含まれている RIの使用状況わかる AWSのコストと使用状況に関する最も包括的なデータを提供でき、またAthenaのデータ統合機能を使うことで、自分のコストと使用状況に関する情報に対してSQLできる Redshift or QuickSightにデータをupload可能 コストを時間または日、製品または製品リソース、または自分で定義したタグごとに分類したレポートを受け取ることができる AWS 料金計算ツール 費用見積もりツール 1ヶ月は730時間を前提 AWS Snowball 物理ストレージデバイスを使用してS3に大量のデータを送るデバイス (1)Snowball (古い) 50TB, 80TB (2)Snowball Edge (推奨) 100TB転送 (利用可能は80TB) 複数ディスクでクラスタリングを組むことできる snowballよりエンドポイントの選択肢が多い 1 2 Snowball Edge Compute Optimized 機械学習とか Snowball Edge Storage Optimized 大規模なデータ移行と定期的な転送ワークフロー、およびさらに高容量を必要とするローカルコンピューティングに適している *Snowball Edge Storage Optimized : 数十テラバイトからペタバイトのデータをAWSに安全かつ迅速に転送する必要がある時に採用 IAMロール アプリケーションやAWSサービスに権限を与える仕組み。以下の2つの機能 ①Switchロール IAMユーザーが異なるAWSアカウントを管理するために使用できる機能 ②IDフェデレーション AWSのIDとは異なるIDを連携させる (IAMユーザーを作成しなくても、FacebookのアカウントにAssumeRoleで権限を引き渡す) (1) Open ID Connector (2) AD Connector (3) SAML2.0 : オンプレでID管理サーバがSAML2.0に対応している場合 【IAMの記録管理】 用語 説明 IAM アクセスアナライザー 外部エンティティと共有されているS3バケットやIAMロールなど分析してt、セキュリティ上のリスクであるリソースとデータへの意図しないアクセスをt特定 Access AdvisorのService Last Accessed Data IAMエンティティが、最後にAWSサービスにアクセスした日付と時刻を表示する Credential Report 利用日時などが記憶されたIAM認証情報のレポートファイル AWS Config AWS ConfigはIAMユーザー、グループ、ロール、ポリシーの変更履歴、構成変更を管理するサービス AWS CloudTrail 各種アカウントアクティビティやAPIコールをログに記録し、モニタリングするサービス 用語 AWS Lake Formation : S3を利用したデータレイク構成を容易に実施 cloud9 : クラウドベースのIDE,エディタのインターフェースと実行環境を一緒にしたIDE AWS Service Health Dashboard : すべてのAWSリージョンで全てのAWSサービスの現在のステータスを確認できる AWS Artifact : 重要なコンプライアンス関連情報の頼りになる一元管理のリソース Amazon Lightsail : コンピューティング、ストレージ、データ転送などwebサイトやwebサービスなどに使うサーバーとして必要な機能を組み合わせてパッケージしたもの Amazon Elastic Transcoder : クラウドメディア変換サービス Amazon Polly : 文章をリアルな音声に変換するサービス Amazon Rekognition : 画像分析と動画分析をアプリケーションに簡単に追加 Amazon Lex : 音声やテキストを使用して任意のアプリケーションに対話型インターフェースを構築するサービス AWS IoT Core : 外部のデバイスとクラウド側を安全に接続するためのサービス。IoTに特化したサービスなので、IoTを扱う場合はAPI Gatewayなどではなくこちらのサービスを使用することでデバイスからAWSにアクセスする際のエンドポイントや認証処理、イベント実行などを統合的に管理することができる QuickShight : RedShift, S3, Athena, Aurora, RDS, IAM, CloudTrainl, CloudDirectoryなどのAWSサービスと連携してBIツールとして EMR : オープンソースとしてのフレームワークであるsparkとHadoopを使用して、膨大な量のデータを迅速かつコスト効率よく処理。高速データ処理 AppSync : GraphQLというwebAPIを用いてデータにアクセスでき、処理を行うことができるもの。APIで自動でデータを取りにいってくれる Neptune : グラフDB 試験Tips エッジロケーションで提供しているサービス : CloudFront, Route53, WAF VPC Peering : 中国リージョンでは利用できない 顧客からの読み取りリクエスト増加対応 (1)リードレプリカの増設 (2)インスタンスタイプの変更 (3)キャッシュレイヤーでのElastiCacheの利用 (これは高価) 特定の国からアクセスを拒否 Route53の位置情報ルーティングする CloudFrontの地域制限を利用する CPU70%でアプリが応答しない RDS DBインスタンスにリードレプリカを追加して、アプリケーションの読み込み負荷を分散する 複数のRDS DBインスタンスを構築し、データをシェーディングする webページの平均読み込み時間を短縮 セッションとSQLクエリを保存するためにElastiCacheを使用し、DBの負荷を軽減する RDSのリードレプリカを使用する 特定のユーザーに配信可能な方式 cloudFrontへのアクセスをOAIに限定 cloudFrontの署名付きURLを利用 VPC間の管理を効率化 = AWS Transit Gateway S3へのファイルをアップロード速度を向上させるための最も費用効果の高い方法 マルチパートアップロード S3 Transfer Acceleration 用語 説明 simple AD AWS側にフルマネージド型のディレクトリを新規作成 AD Connector オンプレミス環境のActive DirectoryとIAM管理を統合SSOと連携したtシングルサインオンが可能 AWS Managed Microsoft AD AWS側にMicrosoft Active Directoryとの互換性があるフルマネージド型のADを作成 参考文献 【合格したので】AWS SAA 対策まとめ Amazon Redshift まとめ Amazon SQSの学習(AWS認定Developer associate対策) Amazon API Gateway Redshift Spectrumと Athenaの違いを探ってみた AWSソリューションアーキテクト取得に向けて~Auto Scaling~ Udemy : 【世界で3万人が受講】演習テスト: AWS 認定 ソリューションアーキテクトアソシエイト Udemy : AWS認定ソリューションアーキテクト アソシエイト試験:短期突破講座(300問の演習問題)
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS ALB パスベースルーティングを実装してみました。(EC2 + ALB + Apache)

はじめに こんんちは、山田です。 今回は、Appliation Load Balancerを用いて、URLのパスごとに接続先のポート番号を変更する方法について記載していきます。 全体構成図 今回使用するAWSリソースは以下の通りです。 AWSリソース名 個数 備考 VPC 1 - Subnet 4 PublicSubnet 2つPrivateSubnet 2つ EC2 3 EC2-①(Windows)EC2-②(RHEL)EC2-③(RHRL) InternetGateWay 1 - ALB 1 - Route53 1 PrivateHostZone 1つ 以下に全体構成図を記載します。 ALBに関しては、接続元URLごとに、接続先のポート番号が変わるように設定します。今回はホスト名は「yamada.test.local」で同一とし、パスごとにルーティングをするように設定します。また、Webサーバソフトウェアとして、「Apache」を使用します。 URL ポート番号 http://yamada.test.local/hoge1 80 http://yamada.test.local/hoge2 81 ① UserはInternetGateWayを介して、EC2にSSH接続する。 ② EC2ログイン後、ALBに接続する。その際、Route53のプライベートホストゾーンを用いて、名前解決をする。 ③ ALBはトラフィックを、EC2-②、EC2-③に振り分ける。 構築手順 以下より実際の構築手順に関して、記載していきます。 前提条件 VPC、Subnet、EC2、InternetGateWay(IGW)は構築済みとします。 Apacheの設定 ① EC2-①に、リモートデスクトップ接続します。 ② 「TeraTerm」を用いて、EC2-②にSSH接続します。 ③ Apacheをインストールします yum -y install httpd ④ Listenするポート番号を追加します。 cd /etc/httpd/conf vi httpd.conf --------------------------- Listen 80 Listen 81 #81を追加 --------------------------- ⑤ バーチャルホストの設定をします。 cd /etc/httpd/conf.d vi vhost.conf #バーチャルホスト設定ファイル作成 ---------------------------------------------------------------------- <VirtualHost *:80> DocumentRoot /test #今回はドキュメントルートとして「/test」を設定 ServerName localhost </VirtualHost> <VirtualHost *:81> DocumentRoot /test ServerName localhost </VirtualHost> ---------------------------------------------------------------------- ⑥ ディレクトリ,ファイルを作成します。 cd / mkdir test cd /test mkdir hoge1 cd hoge1 vi index.html ---------------------------------------- <html> <head> <title>EC2-2</title> </head> <body> hoge1 </body> </html> ------------------------------------------ mkdir hoge2 cd hoge2 vi index.html ---------------------------------------- <html> <head> <title>EC2-2</title> </head> <body> hoge2 </body> </html> ------------------------------------------ ⑦ Apache起動,自動起動の設定をします。 systemctl start httpd #Apache起動 systemctl enable httpd #Apache自動起動設定 systemctl status httpd #runningになっていることを確認 ⑧ EC2-③にログインし、③~⑦の設定を同様に行います。 ApplicationLoadBalancer(ALB)作成 ① AWS管理コンソール画面->EC2->ロードバランサー->ロードバランサーの作成をクリックします。 ② 以下のような画面が表示されるので、ALBを選択します。 ③ 以下に設定項目を記載します。 設定項目 設定値 備考 name test-alb - Scheme Internal 今回は内部向けなのでInternalを選択 IP address type IPv4 - VPC 検証用VPC(作成したVPC選択) - Mapping PrivateSubnet-1a、PrivateSubnet-1c(作成したPrivateSubnetを選択) 今回は内部向けなのでPrivateSubnetを指定 SecurityGroup SecurityGroup(作成したSecurityGroupを選択) - Listener 後ほど変更 - ④ ターゲットグループを作成します。 設定項目 設定値 備考 target type Instances - target group name targetgroup-01targetgroup-02 ポート番号80,81番用に2つ作成 Protocol Port HTTP 80 (targetgroup-01)HTTP 81 (targetgroup-02) - Protocol version HTTP1 - Health check protocol HTTP - Health check path /hoge1/index.html (targetgroup-01)/hoge2/index.html (targetgroup-02) - Target Instance EC2-②EC2-③ - ④ リスナー設定変更 リスナー->リスナー追加をクリックします。  以下に設定項目を記載します。 ホスト パス 転送先 yamada.test.local /hoge1 または /hoge1/* targetgroup-1 yamada.test.local /hoge2 または /hoge2/* targetgroup-2 Route53、プライベートホストゾーン設定 ① AWS管理コンソール->Route53->ホストゾーン->ホストゾーンの作成をクリックします。 ドメイン名「test.local」、ホストゾーンタイプは「プライベートホストゾーン」で作成します。 ホストゾーン種類 ドメイン名 プライベートホストゾーン test.local ② レコードを作成します。 設定項目 設定値 レコード名 yamada.test.local レコードタイプ A トラフィックルーティング先 internal-test-alb-1273242164.ap-northeast-1.elb.amazonaws.com(ALBのDNS名) ルーティングポリシー シンプルルーティング 動作確認 ① 「http://yamada.test.local/hoge1/」、「http://yamada.test.local/hoge2」にそれぞれアクセスし、「hoge1」「hoge2」の文字列がそれぞれ表示されることを確認できれば、完了です!
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

あるユーザに、ある情報だけを共有

自分の組織で、あるユーザに、ある情報だけを共有したいとなった場合の方法です。 具体的には、s3 バケットを作成して、その中に情報を入れます。そのバケットを、IAM および s3 のポリシーにより制御します。 新しいユーザーを新しいグループに所属させ、その部ループに、新しいロールをアタッチします。 管理者権限ユーザで IAM を開きます。 IAM グループを作成します。 (一例) custom-group 管理者権限ユーザで IAM を開きます。 以下の内容でポリシーを作成します。 ポリシー名(一例) My-read-s3-custom-bucket { "Version": "2012-10-17", "Statement": [ { "Sid": "AllowBucketList1", "Effect": "Allow", "Action": "s3:ListBucket", "Resource": "arn:aws:s3:::<BucketName>" }, { "Sid": "AllowBugetGet1", "Effect": "Allow", "Action": [ "s3:GetBucketVersioning", "s3:GetObject*" ], "Resource": [ "arn:aws:s3:::<BucketName>", "arn:aws:s3:::<BucketName>/*" ] } ] } 上記ポリシーを、グループに紐付けます。 管理者権限ユーザで s3 を開きます。 の「アクセス許可」を開きます。 以下のバケットポリシーを作成します。 なお、複数のユーザーを追加する場合は、配列にします。 ユーザーグループは有効な Principal ではないため。 { "Version": "2012-10-17", "Statement": [ { "Sid": "CustomBucketPolicy1", "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::<ACCOUNT_ID>:user/user1" }, "Action": "s3:GetObject", "Resource": "arn:aws:s3:::<BucketName>/*" } ] } ユーザーを作成します。 ユーザを追加します。 (一例) user1, user2(user2 を追加するために、上記バケットポリシーを修正してみてください)。 ユーザーに、以下のリンクを教えます。 なお、ユーザーは s3 全体をリストできないので、リンクを教えておく必要があるためです。 https://s3.console.aws.amazon.com/s3/buckets/<BucketName> 端的に言えば、上記リンクを LMS ログイン後のページに書いてリンクさせます。 (参考) https://docs.aws.amazon.com/AmazonS3/latest/userguide/example-bucket-policies.html
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Certified SysOps Administrator - Associate(SOA-C02)を受けてきました

はじめに 2022-01にAWS Certified SysOps Administrator - Associate(SOA-C02)を受けてきました。 試験勉強や試験の流れを紹介しますので、これから受験を考えている方の参考になれば幸いです。 この記事は2022/1/10時点の情報です。 試験の概要 AWS Certified SysOps Administrator - Associateから紹介します 試験の概要 レベル: アソシエイト 時間: 試験完了までに 180 分 コスト: 150 USD  フォーマット: 65 問 (単一選択/複数選択/試験ラボ) 配信方法: ピアソン VUE テストセンターまたはオンラインでの監督付き試験 SOA-C01→SOA-C02で、以下の変更があったようです。 試験時間:130分→180分 フォーマット:単一選択/複数選択→単一選択/複数選択/試験ラボ 試験勉強 次の3つを使って勉強しました。 1. AWS公式の試験の準備の資料  色々あります。「試験ガイド」を見るのはもちろんですが、特に「サンプル問題(11問)」と「公式練習問題(25問)」は、試験のイメージを掴むためにやっておいた方がよいと思います。 2. AWS試験予約後に届いた、試験ラボのサンプル問題  2022-01-01に申込みしたところ、申込日当日に「ピアソン VUE 試験予約のご案内」という件名で、試験ラボのサンプル問題(1問)がメールで届いたため使いました。   3. aws koiwa club  2022/1現在、SOAの試験ラボの練習問題はないですが、選択式問題の勉強のため、利用しました。  (利用するには会員登録が必要です。) 試験申込 AWS Training and Certificationから、試験の登録に進んで、「ピアソン VUE によるスケジュール」から試験を申込 試験 AWS Certified SysOps Administrator - Associate (SOA-C02) 試験ガイドから紹介します 回答形式 回答形式 試験には次の 3 種類の設問があります。 • 多肢選択式: 正しい選択肢が 1 つ、誤った選択肢 (不正解) が 3 つ提示される • 複数回答式: 5 つ以上の選択肢のうち、正解が 2 つ以上ある • 試験ラボ: AWS マネジメントコンソールまたは AWS CLI で実行する一連のタスクで構成されるシナリオが表示される 回答形式は「多肢選択式」「複数回答式」「試験ラボ」の3つ 多肢選択式と複数回答式: 多肢選択式と複数回答式:設問の記述に最もよく当てはまるもの、または正解となるものを 1 つ以上選択します。不正解の選択肢は、知識や技術が不完全な受験者の誤答を誘うため、通常、設問内容の分野と一致するもっともらしい回答になっています。 多肢選択問題と複数回答問題は、試験開始時に 1 つのセクションに表示されます。このセクションの最後には、多肢選択問題および複数回答問題に戻って確認できるレビュー画面が表示されます。この画面以降は、質問への回答や選択した回答の変更はできません。受験する試験に試験ラボが含まれている場合、試験ラボに関するセクションは、多肢選択問題と複数回答問題の後に表示されます。2 番目のセクションを開始すると、最初のセクションに戻ることはできません。 試験は「多岐選択式と複数回答式の問題」→「試験ラボ」の順に進めます。 一度試験ラボを開始すると、多岐選択式と複数回答式の問題に戻ることはできません。 なので、多岐選択式と複数回答式の問題を回答後は十分に見直してから、試験ラボに進みます。 試験ラボ: 試験ラボ: 提供された AWS アカウントの AWS マネジメントコンソールまたは AWS CLI で、特定のシナリオに必要なタスクを完了します。 試験が開始すると、多肢選択問題および複数回答問題の設問数と試験ラボセクションの試験ラボ数に関する通知が届きます。また、試験ラボの作業内容により採点されるスコアのパーセンテージも確認できます。各試験ラボの完了に与えられる時間は 20 分と想定してください。 次の試験ラボに移動する前に、試験ラボのすべての作業を完了する必要があります。前の試験ラボに戻ることはできません。試験ラボでの作業中は、仮想マシンのメモ帳または AWS CLI を使用できます。 試験開始時に、「多肢選択と複数回答の問題数」と「試験ラボの問題数」が表示されます。 試験ラボ1問につき20分は使えるよう、試験開始時に、「多肢選択と複数回答の問題数」と「試験ラボの問題数」の時間配分を決めると良いと思います。 また、試験ラボは複数ありましたが、次の試験ラボに移動すると、前の試験ラボに移動できないため、1問ずつ見直ししてから進めた方が良いです。 試験結果の確認 AWS Certified SysOps Administrator - Associate (SOA-C02) 試験ガイドから紹介します 最終結果は、試験終了後 5 営業日以内にお知らせします。 試験結果は5営業日以内にお知らせ、と書いてありましたが、試験終了後3時間ほどでAWS Training and Certificationに結果がでてきました。 また、同じくらいのタイミングで新しいバッジ発行のお知らせメールが届きました。 終わりに SOA-C02になって実技(試験ラボ)が入ったことで難しくなったようです。 しかも、2022/1/10時点では試験ラボの練習問題が少ない(実質2問)ので、AWS公式のサンプル問題の試験ラボと、試験申込時に送られてくる試験ラボを試して、感覚を掴んでおくとよいと思います。 今後は試験ラボのサンプルも増えるのかもしれませんが。。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編

はじめに 「ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編」の続きになります。前回の記事をご覧になっていない方はぜひそちらもご覧ください! 以下に分けて記事を作成しているので、上から順にご覧ください。 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編 前提 ・コンソールの最低限の操作ができること ・各サービスについての最低限の知識があること ・VPCが作られていること(前回作成したVPCで構築することを前提に記載しています。) ・EC2インスタンスが作成されていること ・RDS(MySQL)が作成されていること Multi-AZ配置 RDSをマルチAZ配置にすることにより、複数のAZにデータベースを配置することが可能です。そのような冗長構成を取ることにより、可用性を高めることができます。 前の作業で作成したRDSをマルチAZ配置にしていきます。 RDS → データベース → test-database-1 → 変更の順でクリックします。 可用性と耐久性で、「スタンバイインスタンスを作成する」を選択し続行をクリックします。 変更のスケジューリングを「すぐに適用」に変更してください。(反映されるまでに10分程度かかりました。) ステータスが利用可能になればOKです。 動作確認 現在はAZ-aで起動しているデータベースを再起動することにより、スタンバイのデータベースがプライマリに昇格することを確認します。 想定される結果としては、リージョンが「ap-northeast-1a」から「ap-northeast-1c」に変わる結果になるはずです。 対象のデータベースを選択後、アクションから再起動を実行します。 フェイルオーバーで再起動しますか?にチェックをつけて確認をクリックします。 再起動後にフェイルオーバーがされているので、AZがap-northeast-1cに変わっています。 これで動作確認はOKです。 さいごに 以上でシステムの構築が完了になります! 記事数が5つになる程長引いてしまい申し訳ございません。 必要のない方はEC2インスタンスやRDSなどのリソースの削除を忘れずに! 最後までご覧いただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編

はじめに 「ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編」の続きになります。前回の記事をご覧になっていない方はぜひそちらもご覧ください! 以下に分けて記事を作成しているので、上から順にご覧ください。 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編 前提 ・コンソールの最低限の操作ができること ・各サービスについての最低限の知識があること ・VPCが作られていること(前回作成したVPCで構築することを前提に記載しています。) ・EC2インスタンスが作成されていること。 セキュリティグループの作成 ELBを用いて負荷分散を行うわけですが、現在のEC2インスタンスのセキュリティグループは、SSHのみ許可している状態なので、ELBからのアクセスは通さない設定になっています。 なので、前回作成したec2-sgを少し修正します。 今回はELBからHTTPの80番ポートで通信を行います。 EC2 → セキュリティグループ → ec2-sg → インバウンドのルールを編集の順でクリックします。 ルールの追加をクリックし、タイプ「HTTP」の、ソースを0.0.0.0/0にします。 (後ほど修正しますが、一旦仮で値を設定しています。) LAMP環境構築 LAMP環境とは、OSをLinux、ウェブサーバをApache HTTP Server、データベースをMySQL、プログラミング言語をPHPとしたサーバ環境のことをいいます。これらの頭文字を取ってLAMPと呼ばれます。 PHPの記述方法が分からない方も多いと思いますので、私の記載内容をコピペすればできるようになっています!ちなみに、私もPHP触ったことないのでコピペしまくりました!(笑) パッケージインストール まずはEC2に接続して必要なパッケージをインストールします。 EC2の接続については以前の記事で記載しているので割愛します。 MySQLインストール まず始めに、EC2インスタンスにはデフォルトでMariaDBがインストールされているためそれを削除します。 $ sudo yum remove mariadb-libs MySQL公式のyumリポジトリを追加します。 $ sudo yum install https://dev.mysql.com/get/mysql80-community-release-el7-1.noarch.rpm -y MySQLのインストールを行います。 $ sudo yum install mysql-community-server バージョンを確認します。 8.0以降になってればOKです。 $ mysql --version mysql Ver 8.0.27 for Linux on x86_64 (MySQL Community Server - GPL) PHPインストール PHPのバージョン7.4をインストールします。yum install phpでphpのインストールを行うと、バージョンが古いためデータベースに書き込みができなくなりますので注意。 $ sudo amazon-linux-extras install php7.4 バージョン確認を行います。7.4になっていればOKです。 $ php -v PHP 7.4.21 (cli) (built: Jul 7 2021 17:35:08) ( NTS ) Copyright (c) The PHP Group Zend Engine v3.4.0, Copyright (c) Zend Technologies Apache HTTP Server、MySQL Native Driverをインストールするために、以下のコマンドを実行します。 $ sudo yum install -y httpd php-mysqlnd サーバ側の準備 一つ目は初期表示画面を定義したファイルで、二つ目は初期表示画面で入力された内容をMySQLに書き込むファイルです。 ファイルを作成する場所は/var/www/html/配下になります。なのでディレクトリを移動します。 $ cd /var/www/html/ 一つ目のファイルを作成します。viエディタを開きます。 $ sudo vi hello_word.php aを押すと左下に-- INSERT --と表示されると思います。 表示されている状態でないと書き込みができないので注意してください。 INSERTが表示されたら以下のコードをコピペします。 <!DOCTYPE html> <html> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <head> <meta charset="utf-8"> <title>Top Page</title> <style type="text/css"> .jumbotron-extend { position: relative; height: 225px; } </style> </head> <body> <header> <nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark"> <a class="navbar-brand" href="hello_word.php">Hello Word</a> </nav> </header> <div class="jumbotron text-center jumbotron-extend"> <div class="container-fluid"> <div> <h1 class="display-4">Hello, word!</h1> <h4> <?php $ch = curl_init("http://169.254.169.254/latest/meta-data/placement/availability-zone"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, True); $resp = curl_exec($ch); echo "アベイラビリティーゾーン:" . $resp; curl_close($ch); ?> </h4> <p class="lead">以下の項目を入力して送信ボタンをクリックすれば、入力したひと言がデータベースに登録されます。</p> </div> </div> </div> <form action="test.php" method="POST"> <div class="form-row justify-content-center"> <div class="form-group col-md-6"> <label>ホスト名</label> <input type="text" class="form-control" name="host" required> <label>ユーザ名</label> <input type="text" class="form-control" name="username" required> <label>パスワード</label> <input type="password" class="form-control" name="passwd" required> <label>データベース名</label> <input type="text" class="form-control" name="dbname" > <label>ひと言</label> <input type="text" class="form-control" name="word"> </div> </div> <div class="row justify-content-center"> <input class="btn btn-primary" type="submit" value="送信"> </div> </form> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> </body> </html> コピペが完了したら、escを押します。 すると-- INSERT --が消えるので、:wqの順に押しEnterを押します。 詳しくは「vi コマンド」などで検索すると出てきます。 同じ容量で二つ目のファイルを作成します。 $ sudo vi test.php コードは以下の通りです。 <!DOCTYPE html> <html> <link href="https://stackpath.bootstrapcdn.com/bootstrap/4.4.1/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-Vkoo8x4CGsO3+Hhxv8T/Q5PaXtkKtu6ug5TOeNV6gBiFeWPGFN9MuhOf23Q9Ifjh" crossorigin="anonymous"> <head> <meta charset="utf-8"> <title>Access Page</title> </head> <body class="text-center"> <header> <nav class="navbar navbar-expand-md navbar-dark bg-dark"> <a class="navbar-brand" href="hello_word.php">Hello Word</a> </nav> </header> <?php $host = $_POST["host"]; $username = $_POST["username"]; $passwd = $_POST["passwd"]; $dbname = $_POST["dbname"]; $word = $_POST["word"]; ?> <main role="main"> <div class="jumbotron text-center"> <h1 class="jumbotron-heading"> <?php $link = mysqli_connect($host, $username, $passwd, $dbname); if(!$link) { die("接続失敗 php" . mysqli_connect_error() ); } echo "接続成功"; ?> </h1> <p> <?php $word = mysqli_real_escape_string($link, $word); $result = mysqli_query($link, "INSERT INTO words VALUES (\"$word\")"); if(!$result){ die("クエリ失敗"); } echo $word . "がデータベースに保存されました"; mysqli_close($link); ?> </p> <a href="hello_word.php" class="btn btn-primary my-2">戻る</a> </div> </main> <script src="https://code.jquery.com/jquery-3.3.1.slim.min.js" integrity="sha384-q8i/X+965DzO0rT7abK41JStQIAqVgRVzpbzo5smXKp4YfRvH+8abtTE1Pi6jizo" crossorigin="anonymous"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.6/umd/popper.min.js" integrity="sha384-wHAiFfRlMFy6i5SRaxvfOCifBUQy1xHdJ/yoi7FRNXMRBu5WHdZYu1hA6ZOblgut" crossorigin="anonymous"></script> <script src="https://stackpath.bootstrapcdn.com/bootstrap/4.2.1/js/bootstrap.min.js" integrity="sha384-B0UglyR+jN6CkvvICOB2joaf5I4l3gm9GU6Hc1og6Ls7i6U/mkkaduKaBhlAXv9k" crossorigin="anonymous"></script> </body> </html> 定義ファイルの作成が完了したのでApachを起動し、起動後に状態確認を行います。 active (running)と表示されていれば無事起動したことになります。 $ sudo systemctl start httpd $ sudo systemctl status httpd ● httpd.service - The Apache HTTP Server Loaded: loaded (/usr/lib/systemd/system/httpd.service; disabled; vendor preset: disabled) Active: active (running) since 日 2022-01-09 04:27:08 UTC; 3min 7s ago Docs: man:httpd.service(8) Main PID: 3423 (httpd) Status: "Total requests: 0; Idle/Busy workers 100/0;Requests/sec: 0; Bytes served/sec: 0 B/sec" CGroup: /system.slice/httpd.service ├─3423 /usr/sbin/httpd -DFOREGROUND ├─3424 /usr/sbin/httpd -DFOREGROUND ├─3425 /usr/sbin/httpd -DFOREGROUND ├─3426 /usr/sbin/httpd -DFOREGROUND ├─3427 /usr/sbin/httpd -DFOREGROUND └─3428 /usr/sbin/httpd -DFOREGROUND 1月 09 04:27:08 ip-10-0-1-236.ap-northeast-1.compute.internal systemd[1]: Starting The Apache HTTP Server... 1月 09 04:27:08 ip-10-0-1-236.ap-northeast-1.compute.internal systemd[1]: Started The Apache HTTP Server. 次に、インスタンス起動時に自動的にApacheも起動するように設定します。 sudo systemctl enable httpdで自動起動を有効にしています。 sudo systemctl is-enabled httpdで状態を確認しenabledと表示されればOKです。 $ sudo systemctl enable httpd Created symlink from /etc/systemd/system/multi-user.target.wants/httpd.service to /usr/lib/systemd/system/httpd.service. $ $ sudo systemctl is-enabled httpd enabled 同じ容量でmysqlも自動起動にしておこうと思います。 $ sudo systemctl enable mysqld ブラウザのURLにEC2インスタンスのパブリックIPアドレスを入力し、以下のような画面が表示されればOKです。以下はApacheが起動していることを確認するテストページになります。 先ほどのURLの後ろに/hello_word.phpとつけてみると以下の画面が表示されるはずです。 ここまで確認できればサーバ側の準備が完了です!次にデータベース側の準備を行います。 データベース側の準備 MySQLへ接続します。分からない方は以前の記事を参考にしてください。 $ mysql -u admin -p -h <エンドポイント> Enter password: ###### パスワードを聞かれる Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 1680 Server version: 8.0.23 Source distribution Copyright (c) 2000, 2021, Oracle and/or its affiliates. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql> ###### これが表示されればOK 以下の4つのコマンドを順に実行していきます。 ・create database sample; sampleという名前のデータベースを作成 ・use sample; 使用するデータベース(sample)を選択 ・create table words (word varchar(50)); sampleデータベース内にカラムwordをもつwordsテーブルを作成する ・select * from words; wordsテーブルの中身を確認(この時点では空) 実行結果は以下の通りです。 mysql> create database sample; Query OK, 1 row affected (0.03 sec) mysql> use sample; Database changed mysql> create table words (word varchar(50)); Query OK, 0 rows affected (0.06 sec) mysql> select * from words; Empty set (0.00 sec) mysql> 次に文字コードの設定変更を行います。 デフォルトでは文字コードは以下のように設定されています。 mysql> SHOW VARIABLES like "char%"; +--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | binary | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-8.0.23.R3/share/charsets/ | +--------------------------+-------------------------------------------+ この中で、utf8mb4という文字コードがありますが、PHPからMySQLに送信する文字コードがutf8mb4には対応していない?らしくデータ送信時にエラーが発生してしまいます。(かなりハマりました・・・) exitでmysqlを抜けます。 viコマンドでファイルの編集を行います。 $ sudo vi /etc/my.cnf 以下のように修正します。aを押せば編集モードになります。 保存する場合は、esc→:wp→Enter # For advice on how to change settings please see # http://dev.mysql.com/doc/refman/8.0/en/server-configuration-defaults.html [client] #### 追加 default-character-set=utf8 #### 追加 [mysql] #### 追加 default-character-set=utf8 #### 追加 [mysqld] # # Remove leading # and set to the amount of RAM for the most important data # cache in MySQL. Start at 70% of total RAM for dedicated server, else 10%. # innodb_buffer_pool_size = 128M # # Remove the leading "# " to disable binary logging # Binary logging captures changes between backups and is enabled by # default. It's default setting is log_bin=binlog # disable_log_bin # # Remove leading # to set options mainly useful for reporting servers. # The server defaults are faster for transactions and fast SELECTs. # Adjust sizes as needed, experiment to find the optimal values. # join_buffer_size = 128M # sort_buffer_size = 2M # read_rnd_buffer_size = 2M # # Remove leading # to revert to previous value for default_authentication_plugin, # this will increase compatibility with older clients. For background, see: # https://dev.mysql.com/doc/refman/8.0/en/server-system-variables.html#sysvar_default_authentication_plugin # default-authentication-plugin=mysql_native_password datadir=/var/lib/mysql socket=/var/lib/mysql/mysql.sock log-error=/var/log/mysqld.log pid-file=/var/run/mysqld/mysqld.pid collation-server = utf8_unicode_ci #### 追加 character-set-server = utf8 #### 追加 サービスの再起動を行います。 $ sudo systemctl restart mysqld $ sudo systemctl restart httpd 動作確認 先ほどのWebページに戻り、以下のように入力します。 ホスト名はエンドポイント、データベース名は先ほど作成したデータベース、ひと言はデータベースに格納するデータになります。 送信をクリック後次の画面に遷移すれば成功です! DBに接続してデータが格納されているか確認します。データベース接続後に以下のコマンドを実行します。 以下のように表が表示されたらOKです。 mysql> use sample; ### 実行 mysql> select * from words; ### 実行 +------+ | word | +------+ | test | +------+ 1 row in set (0.00 sec) mysql> EC2インスタンス作成(二つ目) DBへの接続も確認できたので2つ目のインスタンスを作成します。 もう一つ同じように作成しても良いですが、かなり面倒なのでAMIを取得してインスタンスを作成します。 インスタンスにチェックをつけ、アクション→イメージとテンプレート→イメージを作成の順にクリックします。 イメージ名をsimple web serverなどにして作成しておきます。(AMIが利用可能になるまで数分かかります。) インスタンスの起動をクリックし、インスタンスを作成するわけですが、今回は左タブのマイAMIを選択し、先ほど作成したAMIを利用します。 インスタンスタイプは1つ目と同じくt2.microを選択し、インスタンスの詳細設定では、test-vpcの中のpubsub-cを選択します。 ストレージとタグの設定は特に弄らずそのままにします。セキュリティグループは1つ目と同じセキュリティグループを選択します。 先ほど作成したEC2インスタンスのパブリックIPアドレスを利用して、先ほどのWebページを開けたらOKです。(http://54.199.219.3/hello_word.phpみたいな感じです。) ターゲットグループの作成 ターゲットグループでは、負荷分散を行うターゲットのグループを作成します。 EC2 → ターゲットグループ → ターゲットグループの作成の順にクリックします。 ・ターゲットタイプ 今回はEC2インスタンスに対しての負荷分散なのでインスタンスを指定します。 ・ターゲットグループ名 ターゲットグループの名前を定義します。今回は「web-server-tg」です。 ・プロトコル:ポート デフォルトでOKです。 ・VPC test-vpcを選択します。 ・ヘルスチェックプロトコル ヘルスチェックを行う際のプロトコルを指定します。今回は「HTTP」 ・ヘルスチェックパス どのパスに対してヘルスチェックを行うかを指定します。 指定されたパスに対してリクエストを飛ばし、ステータスコード200が返って来れば正常と判断されます。今回は「hello_word.php」を指定します。 次にどのインスタンスでグループを作成するか聞かれますので、対象のサーバ2つを選択し「保留中として以下を含める」をクリックします。 ELBの作成 次はELBを作成します。ELBを用いれば、EC2に対してのリクエストを付加分散することができます。 EC2 → ロードバランサー → ロードバランサータイプの選択の順でクリックします。 ロードバランサタイプはALB(Application Load Balancer)を選択します。 ・ロードバランサー名 ロードバランサの名前を設定します。今回は「web-server-alb」にします。 ・スキーム インターネット向けに公開するALBなのでインターネット向けを選択します。 ・VPC ALBを配置するVPCを選択します。test-vpcを選択します。 ・マッピング ALBを配置するサブネットを選択します。pubsub-aとpubsub-cを選択します。 ・セキュリティグループ ALBに割り当てるセキュリティグループを指定します。今回は作成していなかったので、「新しいセキュリティグループの作成」をクリックして新規作成します。 ・インバウンドルール 全てのIPアドレスからのHTTPを許可します。 ・セキュリティグループ 先ほどのセキュリティグループを割り当てます。(選択欄に出てこない場合は更新ボタンをクリックしてください。) ・リスナーとルーティング ALBの特定のポートにリクエストが来た際にどのターゲットグループに飛ばすかを指定します。 今回は先ほど作成した「web-server-tg」を選択します。 残りは全てデフォルトの値で作成します。 動作確認 作成後にALBのDNS名をコピーしてください。 先ほどのDNS名+hello_word.phpでブラウザで検索します。URLは以下のような感じです。 すると、EC2のIPアドレスを入力しなくても画面が表示されます。何回かページをリロードするとアベイラビリティーゾーンのところが、ap-norteast-a(もしくはc)に変わります。 それが確認できれば正常に負荷分散ができているということになります。 セキュリティグループの修正 最初の段階では仮で設定した、EC2のセキュリティグループの修正を行います。 C2 → セキュリティグループ → ec2-sg → インバウンドのルールを編集の順にクリック HTTP:0.0.0.0/0のところを修正します。 0.0.0.0/0 → ALBのセキュリティグループに変更(web-server-alb-sg) さいごに 以上でELB関連の設定は終了になります。 次にマルチAZ構成の設定を行いますが、RDSが作成されている前提で記載していますので、まだの方はぜひ過去の記事もご覧ください。 最後までご覧いただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編

はじめに 「ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編」の続きになります。前回の記事をご覧になっていない方はぜひそちらもご覧ください! 以下に分けて記事を作成しているので、上から順にご覧ください。 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編 前提 ・コンソールの最低限の操作ができること ・各サービスについての最低限の知識があること ・VPCが作られていること(前回作成したVPCで構築することを前提に記載しています。) ・EC2インスタンスが作成されていること。 セキュリティグループの作成 まずはじめに、DB用のセキュリティグループを作成します。 EC2 → セキュリティグループ → セキュリティグループを作成の順にクリックします。 セキュリティグループの設定内容は以下の画像のように設定します。 ここで重要なのが、インバウンドルールです。 タイプを「MYSQL/Aurora」にし、ソースを前回作成したec2-sgにします。 ec2-sgと入力すると候補が表示されるのでそれを選択してください。 それを選択することにより、ec2-sgが割り当てられているEC2インスタンスからのリクエストしか受け付けなくなります。 サブネットグループの作成 サブネットグループは、RDSインスタンスが配置されうるVPCサブネット群をグループ化したものです。RDS → サブネットグループ → DB サブネットグループを作成の順でクリックします。 ・名前 サブネットグループの名前を設定します。今回は「rds-test-subnet」にします。 ・説明 そのままですが、サブネットグループの説明を記載します。 ・VPC サブネットグループに使用するサブネットが属しているVPCを選択する必要があるので、前回作成したtest-vpcを選択します。 ・アベイラビリティゾーン サブネットを含むアベイラビリティゾーン(AZ)を選択します。 今回はAZ-aとAZ-cなので、画像の通りに選択します。 ・サブネット サブネットは、プライベートサブネットを2つ選択します。私と同じ通りにサブネット作成していれば10.0.3.0/24と10.0.4.0/24のサブネットを選択すればOKです。 分からない場合は、VPCの設定画面を開いて確認しましょう! データベース作成 RDS → データベース → データベースの作成の順にクリックします。 ・データベースの作成方法を選択 標準作成でOKです。 ・エンジンのオプション 今回はMySQLを利用します。 ・バージョン バージョンはデフォルトのものを利用します。要件がある方は変更してください。 ・テンプレート 今回は、個人的にテストを行うだけなので「無料利用枠」を選択します。 ・VPC 前回作成した「test-vpc」を選択します。 ・サブネットグループ 自動で先ほど作成したサブネットグループになると思いますが、変更されなかった場合は変更してください。 ・パブリックアクセス 外部からRDSに接続する場合はありにする必要がありますが、今回はEC2インスタンスから接続するだけなので、「なし」を選択します。 ・VPCセキュリティグループ 先ほど作成したセキュリティグループを選ぶ必要があるので、「既存の選択」を選びます。 ・既存のVPCセキュリティグループ 先ほど作成した「db-sg」を選択します。 ・アベイラビリティゾーン 今回はAZ-aにプライマリを立てて、AZ-cにスタンバイを立てたいので、「ap-northeast-1a」を選択します。 上記の内容以外は全てデフォルトの設定のままで構いません。作成には結構時間が掛かります。 さいごに 以上でRDS関連の作業は一旦終了になります。 次にELBの作成を行いますが、ELBも前回作成したVPCの上に構築していきます。 最後までご覧いただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編

はじめに 「ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編」の続きになります。前回の記事をご覧になっていない方はぜひそちらもご覧ください! 以下に分けて記事を作成しているので、上から順にご覧ください。 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編 前提 ・コンソールの最低限の操作ができること ・各サービスについての最低限の知識があること ・VPCが作られていること(前回作成したVPCで構築することを前提に記載しています。) セキュリティグループ作成 EC2 → セキュリティグループ → セキュリティグループを作成の順でクリックします。 ・名前 セキュリティグループ名を設定します。今回は「ec2-sg」にします。 ・説明 セキュリティグループの説明を設定します。任意なので入力しなくても大丈夫です。 ・VPC 前回作成したVPCを選択します。 ・インバウンドルール ELBからの通信も許可する必要がありますが、今はとりあえずSSHのみ許可します。ソースはマイIPにすれば自分のPCからのみアクセスが可能になります。IPアドレスの部分は自動で入力されるので分からなくても大丈夫です。 ELBからの通信も許可する必要がありますが、今はとりあえずSSHのみ許可します。 他はデフォルトの値で作成します。 EC2作成(Amazon Linux) EC2 → インスタンス → インスタンスの起動の順でクリックします。 ・マシンイメージ EC2インスタンスのOSをどれにするか選択します。今回はLinuxでやっていきたいので、 「Amazon Linux 2 AMI (HVM) - Kernel 5.10, SSD Volume Type」を選択しました。 ・インスタンスタイプ インスタンスのタイプを選択します。今回は無料使用枠の「t2.micro」を選択します。 ・インスタンスの詳細の設定 EC2インスタンスをどのVPCでいくつ作成するかを決めます。 ネットワークは前回作成した、「test-vpc」を選択し、サブネットは「pubsub-a」を選択します。これで、AZ-aのパブリックサブネットにEC2が構築されます。 また、パブリックIPを有効にしないと、外部公開用のIPアドレスが付与されないため、自動割り当てパブリックIPを「有効」を選択します。 ・ストレージの追加 今回はデフォルトでOKです。 ・タグの追加 特にタグは設定しません。追加したい方は追加してください。 ・セキュリティグループの設定 「既存のセキュリティグループを選択する」をクリックし、先ほど作成した「ec2-sg」を選択します。 ・キーペア EC2インスタンスを作成し接続するために、キーペアというものが必要になります。既にキーペアをお持ちの方はそれをお使いいただいても大丈夫です。 新しいキーペアを作成される方はキーペア名を「test-keypair」とし、「キーペアのダウンロード」をクリックします。すると右下の「インスタンスの作成」ボタンが押せるようになるので、クリックします。 EC2インスタンスは今回2つ作成するので、同じ手順をもう一度行います。と言ってしまいそうですが、それは少し面倒ですよね・・・。 そんな時に便利なのがAMIです。AMIについては後ほど作業を進めていく中で出てくるので少々お待ちください。 ※注意ポイント EC2インスタンスは再起動するとIPアドレスが変更します。つまり、色々な設定を今のIPアドレスで行った後にEC2を再起動すると、再起動後は接続できないといった状態になることがあります。 IPアドレスが変更しないように、ElasticIPという固定IPアドレスをEC2に紐づけることで解決できます。しかし、EC2が起動していない場合はElasticIPの料金が掛かるようになります。停止しているから料金がかからないと油断していると大量の請求が来るので注意・・・。 EC2インスタンス接続 ここまでの手順を行ったら以下のようにEC2インスタンスが作成されています。 次にEC2インスタンスに接続してみます。 Windowsの場合はteratarmで接続し、Macの場合はターミナルから接続します。 私はMacなのでターミナルから接続します。 まず、インスタンスIDをクリックしてパブリックIPアドレスをコピーします。 ターミナルを開き以下のコマンドを実行します。-i オプションでキーペアのパスを指定します。 コマンドを実行すると、yes/no?と聞かれるのでyesと入力します。 $ ssh -i <キーペアのパス> ec2-user@<パブリックIPアドレス> The authenticity of host '13.231.160.61 (13.231.160.61)' can't be established. ECDSA key fingerprint is SHA256:NaOkgbZe5yfKh3Obb4FZgiy10y2V3iQzRkeHmKPBGtE. Are you sure you want to continue connecting (yes/no/[fingerprint])? yes ← yesを入力 Warning: Permanently added '13.231.160.61' (ECDSA) to the list of known hosts. __| __|_ ) _| ( / Amazon Linux 2 AMI ___|\___|___| https://aws.amazon.com/amazon-linux-2/ 6 package(s) needed for security, out of 16 available Run "sudo yum update" to apply all updates. [ec2-user@ip-10-0-2-42 ~]$ ← これが表示されればOKです。 さいごに 以上でEC2関連の設定は一旦終了になります。 次にRDSの作成を行いますが、RDSも前回作成したVPCの上に構築していきます。 最後までご覧いただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編

はじめに よくある構成の中で以下のような構成があります。今回はVPCから一から構築していこうと思います。 以下に分けて記事を作成しているので、上から順にご覧ください。 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!VPC編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!EC2編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!RDS編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!ELB編 ・ ELB+EC2(2台)+RDS(マルチAZ)で耐障害性に優れたシステムを構築してみた!マルチAZ編 前提 ・AWSのアカウントが存在すること ・コンソールの最低限の操作ができること ・各サービスについての最低限の知識があること VPC作成 まず初めに、VPCを作成していきます。 初期で作られているVPCでもいいですが、どうせならここから新しく作っていきます。 VPC → VPCを作成の順でクリックします。 ・名前 VPCの名前を設定します。今回は「test-vpc」 ・IPv4 CIDR IPアドレスの範囲を指定します。今回は「10.0.0.0/16」 その他の設定は全てデフォルトにします。 サブネットの作成 今回は、AZ-aとAZ-cにパブリックサブネットとプライベートサブネットを作成します。 マルチAZ構成にする必要があるためAZを二つ利用する必要があるからです。 パブリックサブネットはEC2を配置し、プライベートサブネットにはインターネットから接続する必要がないRDSを配置します。 VPC → サブネット → サブネットを作成の順でクリックします。 ・VPC 先ほど作成した「test-vpc」を選択します。 ・サブネット名 サブネットの名前を設定します。今回は以下の4つを作成します。 「pubsub-a、pubsub-c、prisub-a、prisub-c」です。 ・アベイラビリティゾーン(AZ) AZはサブネット名の末尾と合わせます。 ・CIDRブロック 各サブネットのCIDRブロックは、「10.0.1.0/24〜10.0.4.0/24」にします。 作成後は以下のようになります。 インターネットゲートウェイの作成 VPC → インターネットゲートウェイ → インターネットゲートウェイの作成の順にクリックします。 ・名前タグ インターネットゲートウェイの名前を定義します。今回は「test-igw」にします。 インターネットゲートウェイ作成後に、作成したものをVPCにアタッチします。 VPC → インターネットゲートウェイ → 先ほど作成したIGWにチェックを付ける → アクション → VPC にアタッチの順でクリックします。 ・使用可能なVPC 先ほど作成したVPCを選択します。 ルートテーブルの作成と紐付け VPC → ルートテーブル → ルートテーブルを作成の順でクリックします。 VPC → ルートテーブル → 先ほど作成したルートテーブルを選択 → ルートを編集の順でクリックします。 送信先を「0.0.0.0/0」、ターゲットを先ほど作成したIGWにします。 これでインターネット向けの通信はIGWを通り通信を行うことが可能になります。 VPC → ルートテーブル → 先ほど作成したルートテーブルを選択 → サブネットの関連付けを編集の順でクリックします。 先ほど作成したパブリックサブネットにのみルートテーブルを紐づけます。 これを行うことにより、パブリックサブネットのみインターネット向けの通信が可能になります。 さいごに 以上でVPC関連の設定は終了になります。 次にEC2の作成を行いますが、EC2は今回作成したVPCの上に構築していきます。 最後までご覧いただきありがとうございました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】Lambda with EFSの構築

きっかけ Lambdaで/tmp上限の500MBを超えるファイルを扱う必要があり、その動作確認のため。 構築Step VPCの構築、SG等の設定 EFS構築、アクセスポイントの設定 Lambda構築、設定、動作確認 1. VPCの構築 適当なVPCを作成 DNSホスト名を有効化 適当なサブネットを作成 Lambda用SGを作成 EFS用SGを作成 インバウンドルールに上記で作成したSGを設定 Lambda用IAMロールを作成 AWSLambdaVPCAccessExecutionRole, AmazonElasticFileSystemClientReadWriteAccessは必要 2. EFSの構築、アクセスポイントの設定 EFSで上記で作成したVPCを選択、カスタマイズを押下 NW設定でSGを上記で作成したEFS用SGを設定 アクセスポイントを作成 3. Lambda構築、設定、動作確認 Lambdaを構築  -  ロール設定を上記で作成したIAMロールに設定 LambdaのVPC設定で上記で作成したVPC,サブネットに設定 Lambdaのファイルシステム設定で作成したEFSアクセスポイントに設定 LambdaにEFSのマウントパス先にファイル作成するコードを記載、デプロイ lambda_function.py file_path = '/mnt/efs/' def lambda_handler(event, context): file_name = 'test-efs.txt' write_string = 'test-efs' with open(file_path + file_name, mode='w') as f: f.write(write_string) with open(file_path + file_name) as f: print(f.read()) テストを押下し、正常終了することを確認 EC2からEFSにアクセスし、想定通りにファイル、コンテンツが作成されていることを確認 EC2にEFSをマウントする方法については過去記事参照 参考URL
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Aurora (Amazon RDS for PostgreSQL) でスロークエリを出力する方法

はじめに 担当しているWebサービスがなぜ遅いのか特定するために、時間のかかるクエリを確認する必要がありました。 今日は、その時に知ったAurora (Amazon RDS for PostgreSQL)で、スロークエリを発行する方法について書きます。 PostgreSQLはMySQLと違って、設定が少しだけ面倒なんです... 最初に結論 パラメータグループに以下を設定します。 1000ms以上かかったクエリが出力される log_statement mod log_min_duration_statement 1000 前提 RDSへの接続がされていることを前提としています。 パラメータグループの作成 1.新規パラメータグループを作成 2.タイプ「DB Cluster Parameter Group」を選択 DB Parameter Group ・・・ 特定のインスタンスにのみ適用できる DB Cluster Parameter Group ・・・ クラスター全体に適用できる 3.作成したパラメータグループを編集 以下の設定で、実行に1000ms以上かかったクエリがログに出力されます。 log_statement mod log_min_duration_statement 1000 適応タイプdynamicは、パラメータの変更をデータベースの再起動なしに変更することができます。 log_statement・・・ ddlは、CREATE、ALTER、およびDROP文といった、データ定義文を全てログに記録します。 modは、全てのddl文に加え、INSERT、UPDATE、DELETE、TRUNCATE、およびCOPY FROMといった、データ変更文をログに記録します。 https://www.postgresql.jp/document/12/html/runtime-config-logging.html log_min_duration_statement・・・ 文の実行に少なくとも指定した時間かかった場合、それぞれの文の実行に要した時間をログに記録します。 この値が単位なしで指定された場合は、ミリ秒単位であるとみなします。 https://www.postgresql.jp/document/12/html/runtime-config-logging.html 4.DBクラスターのパラメータグループに作成したパラメータグループを設定 5.PostgreSQL ログにチェック CloudWatchにスロークエリが出力されるようになります。 実行してみる 2分待つクエリを発行する ログを確認する 以下のログが出力されるようになりました? あとはログはフィルターして、slackに通知したりアレンジしてみてください。 2022-01-10 04:31:25 UTC:10.0.0.96(50174):postgres@postgres:[21202]:LOG: duration: 2004.674 ms statement: select pg_sleep(2); 注意 デフォルトのパラメータグループを使ってデータベースを起動していた場合、変更できないパラメータが存在します。その場合、カスタムパラメータへの変更が発生するため、データベースの再起動が必要です。なので、RDS起動時にカスタムパラメータを使用することをおすすめします。 参考
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

IT業界に転職した私のマインド、学習結果、勉強方法【AWSエンジニア未経験~1年目】

はじめに 初投稿。 何を書くか迷いましたが、youtube、twitterでは自分のスキル、勉強方法やマインド(モチベーション)についてあまり語った事が無かったので初学者向けに語ってみたいと思います。 目次 マインド 勉強した結果 勉強方法 まとめ マインド 高校生へ向けた孫正義氏の言葉 「登りたい山を決める」「志高く、人生一度しかない」 これを聞いたときに目が覚めました。 誰の役に立つのか分からない、お金をもらうに値しない仕事を続けることは辞めようと思ったんですよね。 当時の私は転職したら全く使えない属人的なスキルばかり身についてましたので… AWSをはじめとするITスキルに目を付けた理由以下です。 クラウドの将来性 興味がある分野 習得するまでの期間が短い 習得までに時間が掛かる分野(医者、税理士など)に比べると、ITは比較的楽だと感じました。 ※比較的に楽なだけであって、簡単に身につくわけではないです 勉強した結果 小規模なWeb開発において、フロント~ネットワークの全体像を俯瞰することはできる。 AWSでのコンテナ開発環境の構築や、CI/CDなどの基本的な設定はできる。 例えば、WEBサーバーにNginx、バックエンドにPython(FastAPI)などを用いるコンテナ開発において、基礎インフラ(VPC、セキュリティグループなど)を用意し、AWS側でECS(Fargate、EC2)を用いてデプロイできるようにはなりました。 LinuxはLPIC、Dockerやバックエンド、Gitの操作は参考書や、Udemy等を用いて何度か学習していたため、開発側の知識もある程度身についているのが大きいです。 資格 AWS認定クラウドプラクティショナー AWS認定ソリューションアーキテクト・アソシエイト AWS認定デベロッパー・アソシエイト AWS認定SysOpsアドミニストレーター・アソシエイト ITパスポート CCNA GCP アソシエイトクラウドエンジニア LPIC 101 102 LPIC 201 202 今後の課題 DBに関する知識が乏しい サーバーサイド言語理解の深度化 実務経験が乏しい 作業に時間が掛かる 個人的なアプリ開発の過程で適当にテーブルやユーザーを作ったことしかないので。資格で言うところのアソシエイトレベルの知識は習得しておこうと思います。 サーバーサイド言語はPythonを今後使って行く予定です。他の言語でも良いですが、Django、Flask、FastAPIと、一通り自己学習で触ったフレームワークもあり、世間の注目度も高いので。 実務経験不足のため、ログ設定など本来考慮すべき知識にかなり抜けがある気がします…ここら辺は時間で解決するしかないですかね… 調べれば大体のことを解決できる自信はありますが、知らないことを調べている時間が長いので、後1年くらいは必至に勉強した方が良いなと感じました。 勉強方法 まず勉強する範囲を決めます。これは目標によって異なりますが、AWSエンジニア(開発構築、運用)として勉強べき分野は個人的に大きく分けて以下の5つだと思います。 ネットワーク OS(Linux)+Docker DB(MySQL、PostgreSQL、Oracle など) サーバーサイド言語(Ruby、Python、PHP、Node.js など) AWS ()内は選択で、どれか一つに絞って勉強すれば良いと思います。 AWSは他の4つをある程度知っている前提で使うSaaSなので、AWSだけ勉強するのは個人的におススメしません!※AWS認定だけを盲目的にやり続けてしまうとか… 具体的な勉強方法 簡単そうな事、知らない事、覚えきれてない事 上記に当てはまる事を勉強する。 難しい事、知っている事、覚えている事 は勉強しない。 例えば、プログラミングで関数やクラスが分かるのに、実際に開発しようとしない事は新しい知識が入ってこないですし、いきなりMWの設定ファイルの中身を勉強しようとし、意味が分からないまま時間が経過してしまうのは基本的なIT用語や知識が不足しているので、勉強内容のハードルを下げた方が良いと思います。 ハードルを下げ切った状態で、分からない事を勉強します。 後は資格の受験日や、参考書、Udemyをやりきる日を決め、勉強するだけです。 おおよそ100時間で取得できる資格を1か月で取得するならば、1日平均3時間以上の学習時間を設ける。時間的に難しいなら2か月で1日平均1時間30分にすれば良いと思います。 勉強をサボる=人生詰み 今後も一般的な日本の社会人の平均年収は減り続け、物価は上昇し続けます。 サボったら軽く人生詰みますね☆ 「周りも下がるから別にいいや、何とかなるやろ!」って感じなら気にしないでください。 無理なペースで勉強しなくとも、周りの社会人は5分も勉強していないので、1日1、2時間勉強できたら自分を褒めてください。 私は2021年の1年間、暗いトンネルの中で先が見えず不安だらけでしたが、ようやく出口の光が見えてきたような気がします。 「小さなことを積み重ねることが、とんでもないところへ行くただ一つの道」byイチロー まとめ 偉そうに色々語りましたが、私は実力的に大したことありません。個人的に満足もしていません。 2020年の自分のようにこれから勉強し始める人、勉強し始めたけど先が見えなくて不安な人の参考になれば幸いです。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS上にマイニングリグの監視/自動復旧システム作ってみた(①監視/自動復旧編)

目次 1.背景 2.構成 2-1.監視ロジック 2-2.Lambda 2-2-1.Lambda関数の作成 2-2-2.プログラムソース 2-2-3.コンフィグ 2-2-4.モジュールの導入 2-2-5.外部APIキーの取得 2-2-5-1.NiceHash 2-2-5-2.LINE 2-2-5-3.SwitchBot 2-2-6.EventBridgeによるトリガー定義 2-3.RDB 2-3-1.DB作成 2-3-2.テーブル作成 2-4.電源スイッチとBOTの設置 3.実行結果 4.終わりに 5.更新履歴 1.背景  Windows10にNiceHash入れて稼働させているリグがBSODで死ぬことがあり自動復旧できるようにしたいと思った。OS側が死ぬとquickminer側に実装されているErrorHanding(プロセス再起動)でもどうしようもできないから対策したかった。 2.構成  NiceHash APIで定期的にリグステータスを取得して、ステータスに応じてOSハング有無を判断、ハングしていた場合には、swichbotで物理的にリグをリブートする構成 ※ Win10をホストOSとしてHyper-V上でNiceHashを動かすことも考えたが、仮想化するとGPU性能をフルに活用できなそうだったので、泣く泣く物理的に落としにいく構成とした... 処理の流れ  ①10分に1度、リグ監視用のLambdaがキックされる  ②LambdaからDBサーバへアクセスして監視フラグが有効な場合には、   NiceHash APIによりリグのマイニングステータスを取得する  ③マイニングステータスに変化があった場合には、DBを更新してLINE通知する  ④マイニングステータスが異常の場合には、switchbot APIで対象リグを強制リブートする 2-1.監視ロジック フローチャート 監視状態(監視フラグ/障害フラグ/異常カウンタ)をDBサーバ上で管理して フラグと取得マイニングステータスの状態に応じて実行する処理を制御する 2-2.Lambda 2-2-1.Lambda関数の作成 呼び出されるLambda関数本体を作成する 【Lambda】  関数名:「nicehash-surveillance」  ランタイム:「Python 3.6」  ※DBサーバへアクセスできるようにVPC設定も必要 2-2-2.プログラムソース Lambdaにデプロイするプログラム nicehash-surveillance nicehash-surveillance/ ├ lambda_function.py ├ db_data_deal.py ├ nicehash.py ├ rig_healthcheck.py ├ line_notify.py ├ switchbot.py ├ line_config.py ├ mysql_config.py ├ nicehash_config.py └ switchbot_config.py Lambdaメインプログラム lambda_function.py import json import requests import os import datetime import boto3 import db_data_deal import nicehash import rig_healthcheck import line_notify import switchbot #Function kicked by AWS Lambda def lambda_handler(event, context): Sqldealer = db_data_deal.sqldealer() Sqldealer.get_rig_db_info() # 監視対象Rigが少なくとも一つある場合 if 1 in Sqldealer.db_data_dict['surveillance_FLG']: # NiceHach API 情報取得 Nicehash = nicehash.private_api() rig_miner_status_dict = Nicehash.get_miner_status(Sqldealer.db_data_dict) # Rigの正常性確認 hang_up_rig_name_list = rig_healthcheck.get_hang_up_rig_name_list(rig_miner_status_dict) # Rigで既に障害が発生していた場合 if 1 in Sqldealer.db_data_dict['incident_FLG']: # Rigが正常の場合 if len(hang_up_rig_name_list) == 0: line_notify.send_restore_msg() {Sqldealer.update_incident_flg_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} {Sqldealer.update_error_cnt_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} print("return3 監視対象Rigの復旧を確認しました...") return 3 # Rigが復旧できなかった場合 else: # 復旧試行回数が5回以上の場合 if 5 in Sqldealer.db_data_dict['error_CNT']: line_notify.send_surveillance_stop_msg(hang_up_rig_name_list) {Sqldealer.update_surveillance_flg_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} print("return4 監視対象Rigを復旧できませんでした、監視を停止します...") return 4 # 復旧試行回数が5回未満の場合 else: line_notify.send_reboot_retly_msg(hang_up_rig_name_list) Sqldealer.db_data_dict = rig_healthcheck.add_reboot_req_flg(Sqldealer.db_data_dict, hang_up_rig_name_list) # Rigの再起動 switchbot.hang_up_rig_reboot(Sqldealer.db_data_dict) {Sqldealer.update_error_cnt_increment(rig_name) for rig_name in hang_up_rig_name_list} print("return5 監視対象Rigの復旧を確認できませんでした、再度再起動します...") return 5 else: # Rigが正常の場合 if len(hang_up_rig_name_list) == 0: print("return1 監視対象Rigは正常です...") return 1 # Rigで新たに障害を検知した場合 else: line_notify.send_incident_msg(hang_up_rig_name_list) Sqldealer.db_data_dict = rig_healthcheck.add_reboot_req_flg(Sqldealer.db_data_dict, hang_up_rig_name_list) # Rigの再起動 switchbot.hang_up_rig_reboot(Sqldealer.db_data_dict) {Sqldealer.update_incident_flg_to_1(rig_name) for rig_name in hang_up_rig_name_list} print("return2 監視対象Rigで障害を検知、復旧を試みました...") return 2 else: print("return0 監視対象Rigがないため処理を終了します...") return 0 DBからの情報取得/DB更新処理を行うクラス db_data_deal.py ### Module ### pip install -t ./ mysql-connector-python import os import json from json import JSONEncoder import mysql.connector import boto3 import datetime import mysql_config as SQLconfig class sqldealer: def __init__(self): self.connection = mysql.connector.connect(user=SQLconfig.user, password=SQLconfig.password, host=SQLconfig.host, database=SQLconfig.database) self.db_data_dict = dict() def road_data(self,sql): with self.connection.cursor() as cur: select_sql = sql cur.execute(select_sql) row_db_data = cur.fetchall() return row_db_data def commit_data(self,sql): with self.connection.cursor() as cur: cur.execute(sql) cur.execute('commit;') def get_rig_db_info(self): sql = 'SELECT * FROM nicehash_surveillance_info;' columns = ["rig_no","rig_id","rig_name","surveillance_FLG","incident_FLG","error_CNT","switchbot_dev_id"] self.db_data_dict = {key:[] for key in columns} row_db_data = self.road_data(sql) print("DB-info01:success road_data") for j, col in enumerate(columns): for i in range(len(row_db_data)): self.db_data_dict[col].append(row_db_data[i][j]) print("DB-info02:success get_rig_db_info") def update_incident_flg_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET incident_FLG=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info03:success update_incident_flg_to_0") def update_incident_flg_to_1(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET incident_FLG=1 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info04:success update_incident_flg_to_1") def update_surveillance_flg_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET surveillance_FLG=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info05:success update_surveillance_flg_to_0") def update_surveillance_flg_to_1(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET surveillance_FLG=1 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info06:success update_surveillance_flg_to_1") def update_error_cnt_increment(self,rig_name): idx = self.db_data_dict['rig_name'].index(rig_name) error_CNT = self.db_data_dict['error_CNT'][idx] + 1 sql = 'UPDATE nicehash_surveillance_info SET error_CNT='+str(error_CNT)+' WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info07:success update_error_cnt_increment") def update_error_cnt_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET error_CNT=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info08:success update_error_cnt_to_0") class DateTimeEncoder(JSONEncoder): #Override the default method def default(self, obj): if isinstance(obj, (datetime.date, datetime.datetime)): return obj.isoformat() NiceHashからリグステータスを取得するためのクラス NiceHash APIのリクエスト/引数については、公式のdocsを参照。 nicehash.py from datetime import datetime from time import mktime import uuid import hmac import requests import json from hashlib import sha256 import optparse import sys import nicehash_config as NICEHASHconfig class private_api: def __init__(self, verbose=False): self.key = NICEHASHconfig.key self.secret = NICEHASHconfig.secret self.organisation_id = NICEHASHconfig.organisation_id self.host = NICEHASHconfig.host self.verbose = verbose def request(self, method, path, query, body): xtime = self.get_epoch_ms_from_now() xnonce = str(uuid.uuid4()) message = bytearray(self.key, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(str(xtime), 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(xnonce, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(self.organisation_id, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(method, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(path, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(query, 'utf-8') if body: body_json = json.dumps(body) message += bytearray('\x00', 'utf-8') message += bytearray(body_json, 'utf-8') digest = hmac.new(bytearray(self.secret, 'utf-8'), message, sha256).hexdigest() xauth = self.key + ":" + digest headers = { 'X-Time': str(xtime), 'X-Nonce': xnonce, 'X-Auth': xauth, 'Content-Type': 'application/json', 'X-Organization-Id': self.organisation_id, 'X-Request-Id': str(uuid.uuid4()) } s = requests.Session() s.headers = headers url = self.host + path if query: url += '?' + query if self.verbose: print(method, url) if body: response = s.request(method, url, data=body_json) else: response = s.request(method, url) if response.status_code == 200: print("NiceHash-info01:success request") return response.json() elif response.content: raise Exception(str(response.status_code) + ": " + response.reason + ": " + str(response.content)) else: raise Exception(str(response.status_code) + ": " + response.reason) def get_epoch_ms_from_now(self): now = datetime.now() now_ec_since_epoch = mktime(now.timetuple()) + now.microsecond / 1000000.0 return int(now_ec_since_epoch * 1000) def get_miner_status(self, rig_db_info): rig_miner_status_dict = dict() for rig_id,rig_name in zip(rig_db_info['rig_id'],rig_db_info['rig_name']): rig_info = self.request("GET", "/main/api/v2/mining/rig2/" + rig_id, "", None) rig_miner_status_dict[rig_name] = rig_info['minerStatus'] print("NiceHash-info02:success get_miner_status") return rig_miner_status_dict リグステータスからヘルスチェックする関数リスト rig_healthcheck.py def get_hang_up_rig_name_list(rig_miner_status_dict): # BENCHMARKING/MINING/STOPPEDであれば正常と判定 ACTIVE_STATUS_LIST = ["BENCHMARKING","MINING","STOPPED"] hang_up_rig_name_list = list() for rig_name in rig_miner_status_dict.keys(): if rig_miner_status_dict[rig_name] not in ACTIVE_STATUS_LIST: hang_up_rig_name_list.append(rig_name) print("HC-info01:success get_hang_up_rig_name_list") return hang_up_rig_name_list def add_reboot_req_flg(db_data_dict, hang_up_rig_name_list): db_data_dict['reboot_req_flg'] = [0]*len(db_data_dict['rig_name']) for err_rig_name in hang_up_rig_name_list: idx = db_data_dict['rig_name'].index(err_rig_name) db_data_dict['reboot_req_flg'][idx] = 1 return db_data_dict switchbot経由でリグを再起動する関数 SwitchBot APIのリクエストや引数については、公式Githubを参照。 switchbot.py import json import requests import os import datetime import boto3 import switchbot_config as sb_cnf def hang_up_rig_reboot(db_data_dict): headers = { 'Content-Type': 'application/json; charset: utf8', 'Authorization': sb_cnf.access_token } body = { "command":"turnOn", "parameter":"default", "commandType":"command" } input_action = json.dumps(body) print(input_action) for i,dev_id in enumerate(db_data_dict['switchbot_dev_id']): if db_data_dict['reboot_req_flg'][i] == 1: url = sb_cnf.api_url + "/v1.0/devices/" + dev_id + "/commands" result = requests.post(url, data=input_action, headers=headers) print(result) リグ監視状況をLINE通知する関数 line_notify.py import json import requests import line_config as LINEconfig def send_msg(msg): headers = {"Authorization": "Bearer %s" % LINEconfig.LINE_NOTIFY_ACCESS_TOKEN} url = LINEconfig.NOTIFICATION_URL payload = {'message': msg} requests.post(url, data=payload, headers=headers) def send_incident_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' で障害発生。'+'\n'+'対象リグを再起動します。' send_msg(msg) def send_restore_msg(): msg = '監視対象リグの復旧を確認。'+'\n'+'監視を継続します。' send_msg(msg) def send_reboot_retly_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' の復旧を確認できません。'+'\n'+'再度リブートします。' send_msg(msg) def send_surveillance_stop_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' を復旧できませんでした。'+'\n'+'リグの監視を中止します。' send_msg(msg) 2-2-3.コンフィグ 各サービス/外部APIと連携するためにコンフィグに必要な設定値を指定する 下記コンフィグの設定値詳細については、2-2-5項を参照。 line_config.py NOTIFICATION_URL = "https://notify-api.line.me/api/notify" LINE_NOTIFY_ACCESS_TOKEN = "[LINEアクセストークン]" mysql_config.py user = "[MySQLアクセスユーザ]" password = "[MySQLアクセスユーザpw]" host = "[DBサーバの静的IP]" database = "[MySQLで構築したDatabase名]" nicehash_config.py host = "https://api2.nicehash.com" organisation_id = "[NiceHash組織ID]" key = "[NiceHash APIアクセスキー]" secret = "[NiceHash APIシークレットアクセスキー]" switchbot_config.py api_url = "https://api.switch-bot.com" access_token = "[switchbotアクセストークン]" 2-2-4.モジュールの導入 Lambdaの実行に必要なパッケージを取り込む ・Lambda:nicehash-surveillanceには「mysql-connector-python」が必要なので、AWS Cloud9上でディレクトリを切って、下記コマンドを実行して環境を整備する。LambdaへのデプロイもCloud9上で行うと楽なのでおすすめ。 nicehash-surveillance ec2-user:~/environment (master) $ mkdir nicehash-surveillance ec2-user:~/environment (master) $ cd nicehash-surveillance ec2-user:~/environment/nicehash-surveillance (master) $ pip install -t ./ mysql-connector-python 2-2-5.外部APIキーの取得 外部APIの認証に必要な鍵情報/トークンを取得する 2-2-5-1.NiceHash APIキー(コンフィグに記載) ・こちら記載の手順を元にAPIキーを取得する。 リグID(DBに登録) ・NiceHashのダッシュボード or アプリから確認する。  ※ダッシュボードの場合、以下の黄色部分に記載されている。 2-2-5-2.LINE アクセストークン(コンフィグに記載) ・こちら記載の手順を元に取得する。 2-2-5-3.SwitchBot アクセストークン(コンフィグに記載) ・アクセストークンの取得方法はこちらの記事を参照。 ・外部サービスと連携するために、SwitchBotアプリ側でも「クラウドサービス」をONにしておく。 deviceId(DBに登録) ・下記curlコマンドで各botのdeviceIdを取得する。 /usr/bin/curl -X GET "https://api.switch-bot.com/v1.0/devices" -H "Authorization:[Access_token]" 2-2-6.EventBridgeによるトリガー定義 定期ジョブとしてLambdaをキックするためのトリガーを定義する ・下記トリガーを作成して、Lambda:nicehash-surveillanceにアタッチする ルール:「新規ルールの作成」 ルール名:DailyTrigger ルールタイプ:スケジュール式 固定速度ごと:10分 2-3.RDB リグ情報、監視ステータスを管理するDBを用意する 2-3-1.DB作成 節約のためRDSは使用せずに、UNIX OSのEC2インスタンスにMySQLを直接インストールしてDBを構築する ※MySQLのインストールはこの辺を参照 2-3-2.テーブル作成 nicehash_surveillance_infoテーブルをDB上に定義する、最低限以下定義があればOK。 ※以下はリグ3個で運用している場合の例 mysql> SHOW COLUMNS FROM nicehash_surveillance_info; +------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+--------------+------+-----+---------+-------+ | rig_no | int(11) | YES | | NULL | | | rig_id | varchar(100) | YES | | NULL | | | rig_name | varchar(100) | YES | | NULL | | | surveillance_FLG | int(11) | YES | | NULL | | | incident_FLG | int(11) | YES | | NULL | | | error_CNT | int(11) | YES | | NULL | | | switchbot_dev_id | varchar(100) | YES | | NULL | | +------------------+--------------+------+-----+---------+-------+ 7 rows in set (0.00 sec) mysql> select * from nicehash_surveillance_info; +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ | rig_no | rig_id | rig_name | surveillance_FLG | incident_FLG | error_CNT | switchbot_dev_id | +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ | 1 | [myExcavator1のリグID] | myExcavator1 | 1 | 0 | 0 | [myExcavator1用BOTのdeviceId] | | 2 | [myExcavator2のリグID] | myExcavator2 | 1 | 0 | 0 | [myExcavator2用BOTのdeviceId] | | 3 | [MainPCのリグID] | MainPC | 1 | 0 | 0 | [MainPC用BOTのdeviceId] | +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ 3 rows in set (0.00 sec) rig_no:リグ番号 rig_id:NiceHash上のリグID rig_name:NiceHash上のリグ名称 surveillance_FLG:監視状態を制御するフラグ(1:監視有効/0:監視無効) incident_FLG:障害発生状態管理するフラグ(1:障害発生中/0:正常稼働中) error_CNT:再起動処理のエラーカウンタ switchbot_dev_id:SwitchBot上のdeviceId 2-4.電源スイッチとBOTの設置 SwitchBotでリグを再起動できるように電源スイッチにBOTを設置する でかでか電源ボタンをリグにつないで、BOTがResetボタンを押せるよう固定する。 リグが複数ある場合には、それぞれでかでか電源ボタンとBOTのセットを設置する 3. 実行結果 リグがBSODで死にっぱなしになることがなくなった...! LINEで通知されるメッセージは以下の通り。 4. 終わりに HiveOSなら問題にならないかもですが、NiceHashではBSODで悩まされされることがあるので、物理的に無理やりOS立ち上げるゴリ押し運用でどうにかできるようにしました...(笑) (それにしても、BSODの原因は何なのだろうか。) (マザボ/ライザー/電源/複数GPU間のコンパチが良くないのだろうか...) (そもそも、1万程度のマザボに品質を求めるのはおかしいのか...) 5. 更新履歴 ver. 1.0 初版投稿 2022/01/10
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS上にリグの監視/自動復旧システムを作ってみた(①監視/自動復旧編)

目次 1.背景 2.構成 2-1.監視ロジック 2-2.Lambda 2-2-1.Lambda関数の作成 2-2-2.プログラムソース 2-2-3.コンフィグ 2-2-4.モジュールの導入 2-2-5.外部APIキーの取得 2-2-5-1.NiceHash 2-2-5-2.LINE 2-2-5-3.SwitchBot 2-2-6.EventBridgeによるトリガー定義 2-3.RDB 2-3-1.DB作成 2-3-2.テーブル作成 2-4.電源スイッチとBOTの設置 3.実行結果 4.終わりに 5.更新履歴 1.背景  Windows10×NiceHashのリグが謎のBSODで死ぬことが何度かあり収益が落ち込むことがあったのでどうにかしたかった。OS側が死ぬとquickminer側のErrorHanding(プロセス再起動)ではどうしようもできないので対策が必要だった。 2.構成  NiceHash APIで定期的にリグステータスを取得、ステータスに応じてOSハングを検知する。ハングしていた場合には、swichbot経由で物理的にリグをリブートとするというゴリ押し構成。 ※ Win10をホストOSとしてHyper-V上でNiceHashを動かすことも考えたが、仮想化するとGPU性能をフルに活用できなそうだったので、泣く泣く物理的に落としにいく構成に... 処理の流れ  ①10分に1度、リグ監視用のLambdaがキックされる  ②LambdaからDBサーバへアクセスして監視フラグが有効な場合には、   NiceHash APIによりリグのマイニングステータスを取得する  ③マイニングステータスに変化があった場合には、DBを更新してLINE通知する  ④マイニングステータスが異常の場合には、switchbot APIで対象リグを強制リブートする 2-1.監視ロジック 監視状態(監視フラグ/障害フラグ/異常カウンタ)をDBサーバ上で管理して フラグと取得マイニングステータスの状態に応じて実行する処理を制御する 2-2.Lambda 2-2-1.Lambda関数の作成 呼び出されるLambda関数本体を作成する 【Lambda】  関数名:「nicehash-surveillance」  ランタイム:「Python 3.6」  ※DBサーバへアクセスできるようにVPC設定も必要 2-2-2.プログラムソース Lambdaにデプロイするプログラム nicehash-surveillance nicehash-surveillance/ ├ lambda_function.py ├ db_data_deal.py ├ nicehash.py ├ rig_healthcheck.py ├ line_notify.py ├ switchbot.py ├ line_config.py ├ mysql_config.py ├ nicehash_config.py └ switchbot_config.py Lambdaメインプログラム lambda_function.py import json import requests import os import datetime import boto3 import db_data_deal import nicehash import rig_healthcheck import line_notify import switchbot #Function kicked by AWS Lambda def lambda_handler(event, context): Sqldealer = db_data_deal.sqldealer() Sqldealer.get_rig_db_info() # 監視対象Rigが少なくとも一つある場合 if 1 in Sqldealer.db_data_dict['surveillance_FLG']: # NiceHach API 情報取得 Nicehash = nicehash.private_api() rig_miner_status_dict = Nicehash.get_miner_status(Sqldealer.db_data_dict) # Rigの正常性確認 hang_up_rig_name_list = rig_healthcheck.get_hang_up_rig_name_list(rig_miner_status_dict) # Rigで既に障害が発生していた場合 if 1 in Sqldealer.db_data_dict['incident_FLG']: # Rigが正常の場合 if len(hang_up_rig_name_list) == 0: line_notify.send_restore_msg() {Sqldealer.update_incident_flg_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} {Sqldealer.update_error_cnt_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} print("return3 監視対象Rigの復旧を確認しました...") return 3 # Rigが復旧できなかった場合 else: # 復旧試行回数が5回以上の場合 if 5 in Sqldealer.db_data_dict['error_CNT']: line_notify.send_surveillance_stop_msg(hang_up_rig_name_list) {Sqldealer.update_surveillance_flg_to_0(rig_name) for rig_name in Sqldealer.db_data_dict['rig_name']} print("return4 監視対象Rigを復旧できませんでした、監視を停止します...") return 4 # 復旧試行回数が5回未満の場合 else: line_notify.send_reboot_retly_msg(hang_up_rig_name_list) Sqldealer.db_data_dict = rig_healthcheck.add_reboot_req_flg(Sqldealer.db_data_dict, hang_up_rig_name_list) # Rigの再起動 switchbot.hang_up_rig_reboot(Sqldealer.db_data_dict) {Sqldealer.update_error_cnt_increment(rig_name) for rig_name in hang_up_rig_name_list} print("return5 監視対象Rigの復旧を確認できませんでした、再度再起動します...") return 5 else: # Rigが正常の場合 if len(hang_up_rig_name_list) == 0: print("return1 監視対象Rigは正常です...") return 1 # Rigで新たに障害を検知した場合 else: line_notify.send_incident_msg(hang_up_rig_name_list) Sqldealer.db_data_dict = rig_healthcheck.add_reboot_req_flg(Sqldealer.db_data_dict, hang_up_rig_name_list) # Rigの再起動 switchbot.hang_up_rig_reboot(Sqldealer.db_data_dict) {Sqldealer.update_incident_flg_to_1(rig_name) for rig_name in hang_up_rig_name_list} print("return2 監視対象Rigで障害を検知、復旧を試みました...") return 2 else: print("return0 監視対象Rigがないため処理を終了します...") return 0 DBからの情報取得/DB更新処理を行うクラス db_data_deal.py ### Module ### pip install -t ./ mysql-connector-python import os import json from json import JSONEncoder import mysql.connector import boto3 import datetime import mysql_config as SQLconfig class sqldealer: def __init__(self): self.connection = mysql.connector.connect(user=SQLconfig.user, password=SQLconfig.password, host=SQLconfig.host, database=SQLconfig.database) self.db_data_dict = dict() def road_data(self,sql): with self.connection.cursor() as cur: select_sql = sql cur.execute(select_sql) row_db_data = cur.fetchall() return row_db_data def commit_data(self,sql): with self.connection.cursor() as cur: cur.execute(sql) cur.execute('commit;') def get_rig_db_info(self): sql = 'SELECT * FROM nicehash_surveillance_info;' columns = ["rig_no","rig_id","rig_name","surveillance_FLG","incident_FLG","error_CNT","switchbot_dev_id"] self.db_data_dict = {key:[] for key in columns} row_db_data = self.road_data(sql) print("DB-info01:success road_data") for j, col in enumerate(columns): for i in range(len(row_db_data)): self.db_data_dict[col].append(row_db_data[i][j]) print("DB-info02:success get_rig_db_info") def update_incident_flg_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET incident_FLG=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info03:success update_incident_flg_to_0") def update_incident_flg_to_1(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET incident_FLG=1 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info04:success update_incident_flg_to_1") def update_surveillance_flg_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET surveillance_FLG=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info05:success update_surveillance_flg_to_0") def update_surveillance_flg_to_1(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET surveillance_FLG=1 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info06:success update_surveillance_flg_to_1") def update_error_cnt_increment(self,rig_name): idx = self.db_data_dict['rig_name'].index(rig_name) error_CNT = self.db_data_dict['error_CNT'][idx] + 1 sql = 'UPDATE nicehash_surveillance_info SET error_CNT='+str(error_CNT)+' WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info07:success update_error_cnt_increment") def update_error_cnt_to_0(self,rig_name): sql = 'UPDATE nicehash_surveillance_info SET error_CNT=0 WHERE rig_name="'+rig_name+'";' self.commit_data(sql) print("DB-info08:success update_error_cnt_to_0") class DateTimeEncoder(JSONEncoder): #Override the default method def default(self, obj): if isinstance(obj, (datetime.date, datetime.datetime)): return obj.isoformat() NiceHashからリグステータスを取得するためのクラス NiceHash APIのリクエスト/引数については、公式のdocsを参照。 nicehash.py from datetime import datetime from time import mktime import uuid import hmac import requests import json from hashlib import sha256 import optparse import sys import nicehash_config as NICEHASHconfig class private_api: def __init__(self, verbose=False): self.key = NICEHASHconfig.key self.secret = NICEHASHconfig.secret self.organisation_id = NICEHASHconfig.organisation_id self.host = NICEHASHconfig.host self.verbose = verbose def request(self, method, path, query, body): xtime = self.get_epoch_ms_from_now() xnonce = str(uuid.uuid4()) message = bytearray(self.key, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(str(xtime), 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(xnonce, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(self.organisation_id, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(method, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(path, 'utf-8') message += bytearray('\x00', 'utf-8') message += bytearray(query, 'utf-8') if body: body_json = json.dumps(body) message += bytearray('\x00', 'utf-8') message += bytearray(body_json, 'utf-8') digest = hmac.new(bytearray(self.secret, 'utf-8'), message, sha256).hexdigest() xauth = self.key + ":" + digest headers = { 'X-Time': str(xtime), 'X-Nonce': xnonce, 'X-Auth': xauth, 'Content-Type': 'application/json', 'X-Organization-Id': self.organisation_id, 'X-Request-Id': str(uuid.uuid4()) } s = requests.Session() s.headers = headers url = self.host + path if query: url += '?' + query if self.verbose: print(method, url) if body: response = s.request(method, url, data=body_json) else: response = s.request(method, url) if response.status_code == 200: print("NiceHash-info01:success request") return response.json() elif response.content: raise Exception(str(response.status_code) + ": " + response.reason + ": " + str(response.content)) else: raise Exception(str(response.status_code) + ": " + response.reason) def get_epoch_ms_from_now(self): now = datetime.now() now_ec_since_epoch = mktime(now.timetuple()) + now.microsecond / 1000000.0 return int(now_ec_since_epoch * 1000) def get_miner_status(self, rig_db_info): rig_miner_status_dict = dict() for rig_id,rig_name in zip(rig_db_info['rig_id'],rig_db_info['rig_name']): rig_info = self.request("GET", "/main/api/v2/mining/rig2/" + rig_id, "", None) rig_miner_status_dict[rig_name] = rig_info['minerStatus'] print("NiceHash-info02:success get_miner_status") return rig_miner_status_dict リグステータスからヘルスチェックする関数リスト rig_healthcheck.py def get_hang_up_rig_name_list(rig_miner_status_dict): # BENCHMARKING/MINING/STOPPEDであれば正常と判定 ACTIVE_STATUS_LIST = ["BENCHMARKING","MINING","STOPPED"] hang_up_rig_name_list = list() for rig_name in rig_miner_status_dict.keys(): if rig_miner_status_dict[rig_name] not in ACTIVE_STATUS_LIST: hang_up_rig_name_list.append(rig_name) print("HC-info01:success get_hang_up_rig_name_list") return hang_up_rig_name_list def add_reboot_req_flg(db_data_dict, hang_up_rig_name_list): db_data_dict['reboot_req_flg'] = [0]*len(db_data_dict['rig_name']) for err_rig_name in hang_up_rig_name_list: idx = db_data_dict['rig_name'].index(err_rig_name) db_data_dict['reboot_req_flg'][idx] = 1 return db_data_dict switchbot経由でリグを再起動する関数 SwitchBot APIのリクエストや引数については、公式Githubを参照。 switchbot.py import json import requests import os import datetime import boto3 import switchbot_config as sb_cnf def hang_up_rig_reboot(db_data_dict): headers = { 'Content-Type': 'application/json; charset: utf8', 'Authorization': sb_cnf.access_token } body = { "command":"turnOn", "parameter":"default", "commandType":"command" } input_action = json.dumps(body) print(input_action) for i,dev_id in enumerate(db_data_dict['switchbot_dev_id']): if db_data_dict['reboot_req_flg'][i] == 1: url = sb_cnf.api_url + "/v1.0/devices/" + dev_id + "/commands" result = requests.post(url, data=input_action, headers=headers) print(result) リグ監視状況をLINE通知する関数 line_notify.py import json import requests import line_config as LINEconfig def send_msg(msg): headers = {"Authorization": "Bearer %s" % LINEconfig.LINE_NOTIFY_ACCESS_TOKEN} url = LINEconfig.NOTIFICATION_URL payload = {'message': msg} requests.post(url, data=payload, headers=headers) def send_incident_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' で障害発生。'+'\n'+'対象リグを再起動します。' send_msg(msg) def send_restore_msg(): msg = '監視対象リグの復旧を確認。'+'\n'+'監視を継続します。' send_msg(msg) def send_reboot_retly_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' の復旧を確認できません。'+'\n'+'再度リブートします。' send_msg(msg) def send_surveillance_stop_msg(hang_up_rig_name_list): err_rigs = ','.join(hang_up_rig_name_list) msg = err_rigs+' を復旧できませんでした。'+'\n'+'リグの監視を中止します。' send_msg(msg) 2-2-3.コンフィグ 各サービス/外部APIと連携するためにコンフィグに必要な設定値を指定する 下記コンフィグの設定値詳細については、2-2-5項を参照。 line_config.py NOTIFICATION_URL = "https://notify-api.line.me/api/notify" LINE_NOTIFY_ACCESS_TOKEN = "[LINEアクセストークン]" mysql_config.py user = "[MySQLアクセスユーザ]" password = "[MySQLアクセスユーザpw]" host = "[DBサーバの静的IP]" database = "[MySQLで構築したDatabase名]" nicehash_config.py host = "https://api2.nicehash.com" organisation_id = "[NiceHash組織ID]" key = "[NiceHash APIアクセスキー]" secret = "[NiceHash APIシークレットアクセスキー]" switchbot_config.py api_url = "https://api.switch-bot.com" access_token = "[switchbotアクセストークン]" 2-2-4.モジュールの導入 Lambdaの実行に必要なパッケージを取り込む ・Lambda:nicehash-surveillanceには「mysql-connector-python」が必要なので、AWS Cloud9上でディレクトリを切って、下記コマンドを実行して環境を整備する。LambdaへのデプロイもCloud9上で行うと楽なのでおすすめ。 nicehash-surveillance ec2-user:~/environment (master) $ mkdir nicehash-surveillance ec2-user:~/environment (master) $ cd nicehash-surveillance ec2-user:~/environment/nicehash-surveillance (master) $ pip install -t ./ mysql-connector-python 2-2-5.外部APIキーの取得 外部APIの認証に必要な鍵情報/トークンを取得する 2-2-5-1.NiceHash APIキー(コンフィグに記載) ・こちら記載の手順を元にAPIキーを取得する。 リグID(DBに登録) ・NiceHashのダッシュボード or アプリから確認する。  ※ダッシュボードの場合、以下の黄色部分に記載されている。 2-2-5-2.LINE アクセストークン(コンフィグに記載) ・こちら記載の手順を元に取得する。 2-2-5-3.SwitchBot アクセストークン(コンフィグに記載) ・アクセストークンの取得方法はこちらの記事を参照。 ・外部サービスと連携するために、SwitchBotアプリ側でも「クラウドサービス」をONにしておく。 deviceId(DBに登録) ・下記curlコマンドで各botのdeviceIdを取得する。 /usr/bin/curl -X GET "https://api.switch-bot.com/v1.0/devices" -H "Authorization:[Access_token]" 2-2-6.EventBridgeによるトリガー定義 定期ジョブとしてLambdaをキックするためのトリガーを定義する ・下記トリガーを作成して、Lambda:nicehash-surveillanceにアタッチする ルール:「新規ルールの作成」 ルール名:DailyTrigger ルールタイプ:スケジュール式 固定速度ごと:10分 2-3.RDB リグ情報、監視ステータスを管理するDBを用意する 2-3-1.DB作成 節約のためRDSは使用せずに、UNIX OSのEC2インスタンスにMySQLを直接インストールしてDBを構築する ※MySQLのインストールはこの辺を参照 2-3-2.テーブル作成 nicehash_surveillance_infoテーブルをDB上に定義する、最低限以下定義があればOK。 ※以下はリグ3個で運用している場合の例 mysql> SHOW COLUMNS FROM nicehash_surveillance_info; +------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+--------------+------+-----+---------+-------+ | rig_no | int(11) | YES | | NULL | | | rig_id | varchar(100) | YES | | NULL | | | rig_name | varchar(100) | YES | | NULL | | | surveillance_FLG | int(11) | YES | | NULL | | | incident_FLG | int(11) | YES | | NULL | | | error_CNT | int(11) | YES | | NULL | | | switchbot_dev_id | varchar(100) | YES | | NULL | | +------------------+--------------+------+-----+---------+-------+ 7 rows in set (0.00 sec) mysql> select * from nicehash_surveillance_info; +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ | rig_no | rig_id | rig_name | surveillance_FLG | incident_FLG | error_CNT | switchbot_dev_id | +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ | 1 | [myExcavator1のリグID] | myExcavator1 | 1 | 0 | 0 | [myExcavator1用BOTのdeviceId] | | 2 | [myExcavator2のリグID] | myExcavator2 | 1 | 0 | 0 | [myExcavator2用BOTのdeviceId] | | 3 | [MainPCのリグID] | MainPC | 1 | 0 | 0 | [MainPC用BOTのdeviceId] | +--------+--------------------------+--------------+------------------+--------------+-----------+-------------------------------+ 3 rows in set (0.00 sec) rig_no:リグ番号 rig_id:NiceHash上のリグID rig_name:NiceHash上のリグ名称 surveillance_FLG:監視状態を制御するフラグ(1:監視有効/0:監視無効) incident_FLG:障害発生状態管理するフラグ(1:障害発生中/0:正常稼働中) error_CNT:再起動処理のエラーカウンタ switchbot_dev_id:SwitchBot上のdeviceId 2-4.電源スイッチとBOTの設置 SwitchBotでリグを再起動できるように電源スイッチにBOTを設置する でかでか電源ボタンをリグにつないで、BOTがResetボタンを押せるよう固定する。 リグが複数ある場合には、それぞれでかでか電源ボタンとBOTのセットを設置する 3. 実行結果 リグがBSODで死にっぱなしになることがなくなった...! LINEで通知されるメッセージは以下の通り。 4. 終わりに HiveOSなら問題にならないかもですが、NiceHashではBSODで悩まされされることがあるので、物理的に無理やりOS立ち上げるゴリ押し運用でどうにかできるようにしました...(笑) (それにしても、BSODの原因は何なのだろうか。) (マザボ/ライザー/電源/複数GPU間のコンパチが良くないのだろうか...) (そもそも、1万程度のマザボに品質を求めるのはおかしいのか...) また、常時リグが監視がされている状態だとメンテなどで止める際も、障害と誤検知されてしまい不便なので、LINEから監視を制御できるようにもしてます。詳細は次回の「AWS上にリグの監視/自動復旧システムを作ってみた(②監視抑止操作編)」にまとめます。 5. 更新履歴 ver. 1.0 初版投稿 2022/01/10
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インフラ素人が3週間で、Webサービスのインフラを0から構築して起きた変化

目次 1. インフラ設計 2. ネットワーク構築 3. サーバ・DB構築 4. Lambdaによる自動化 5. Amazon SES・SNS 6. 開発環境構築(docker) 7. jenkins・phpmyadminなど開発ツール設定 8. VPN接続 9. 起きた変化 10. おまけ はじめに インフラ素人同然レベルだった私が実務において、Webアプリケーションのインフラを0から構築することになりました。 期間は約3週間、インフラ設計から行い、構築したインフラ上でWebサービスが稼働できる状態まで持っていくことがゴールになります。  約3週間の間、AWSやミドルウェア周りの技術に触れ、今まで考えてもみなかった知識の習得や、多くのつまづきを通して貴重な経験をすることができました。 チームメンバーと分担しながら進めたので、あくまで自分のやったことベースにはなりますが、3週間どんなことをやったのか、特につまづいたことを中心に書いていきたいと思います。 ※基本的なインフラ構成はほぼ全てAWSのリソースを使用しました。 【使用技術】 ・ AWS(EC2, RDS, VPC, Route53, Lambda, IAM, SES, SNS, ACM, CloudWatch, etc.) ・ docker ・ Nginx(Webサーバ) ・ Puma(アプリケーションサーバ) ・ Ruby on Rails 開始前の筆者のレベルを3行で! ・自社開発エンジニア歴5ヶ月の駆け出しエンジニア ・AWS Cloud Practitionerの資格は持っているが実務でのインフラ(AWS)経験は無し ・ミドルウェア周りの知識はほぼゼロ(Webサーバとアプリケーションサーバってどう違うの?レベル) 1. インフラ設計 まずやったこととして、Webサービスを稼働させる上でどのようなインフラ環境が必要か理解し、可視化することです。 今回、実装するのは、Web開発では基本となる開発環境(development)、ステージング環境(staging)、本番環境(production)からなる構成です。 なんとなくの理解だったので、各環境の役割について、改めて理解するのに良い記事があったので共有します。 事前学習 とはいっても、 VPCってなんぞや? サブネットの切り方ってどうするの? NATゲートウェイとは? ALBとロードバランサーなにが違うの? など、私にとってネットワーク設計やサーバ構築が初めての経験だったので、知識の習得のため最初の数日はとにかくインプット量を意識して手を動かしながら学習しました。 VPC構築、サブネットの設定、EC2構築など実際にAWSマネジメントコンソール上でポチポチやりながら、「こことここが繋がるのか〜」「こうすれば良いのね」といった感じで、体系的にAWSのリソースを理解しながら、知識を蓄えていったところが大きいです。 一部、以下AWSCloudTechのサービスを使ったりなんかもしました。 実装するインフラ構成を図に落とし込む 理解が少し曖昧なところがありながらもなんとか、今回実装するインフラ構成を図に落とし込みました。 ここまででおおよそ3日です。 Webサーバはアクセスを考慮して、現時点では冗長構成にせず単一のインスタンスのみで運用を行い、batchサーバの役割も持たせます。 本番環境では、バウンスメール等はSES,SNSを使用し、通知を行いレートの管理をします。 他ネットワークからのアクセスも可能にするため、AWSClientVPNを使用したVPN接続も実装する予定です。 Excelにインフラ設計情報の詳細をドキュメント化 インフラ設計情報として、開発する上で必要になってくる細かな設定に関しては、都度Excelに記載し、後ほど忘れないためにドキュメント化し管理しました。 ・RDSの詳細設定 ・各インスタンスの詳細設定 ・pemキー情報、IAM情報、各種ログイン情報  ・ssh接続コマンドチートシート などなど 2. ネットワーク構築  ここから実際に手を動かしていきます。上記インフラ構成を実現するためにまずは、サーバを設置する箱となるネットワークの構築(VPC)から始めました。 ざっくり手順は以下のとおり実現しました。 1.VPC設定 2.VPC内にサブネット構築 3.インターネットゲートウェイの設置 4.NATゲートウェイの設置 5.VPC間のピアリング接続の設定 6.サブネットのルートテーブルの設定 具体的な設定についてここでは詳細省きますが、これでおおよそ必要なるネットワーク構成は出来あがります。 1つ注意点として、 VPCやサブネットを作成する際のIPv4CIDRブロックは、以下のプライベートIPアドレスの範囲内で作成する必要があります。 プライベートアドレスは以下のように範囲が定められており、この範囲外のIPアドレスはグローバルアドレスとなってしまうからです。 クラス 範囲 ネットワーク数 クラスA 10.0.0.0 ~ 10.255.255.255 (10.0.0.0/8) 1 クラスB 172.16.0.0 ~ 172.31.255.255 (172.16.0.0/12) 16 クラスC 192.168.0.0 ~ 192.168.255.255 (192.168.0.0/16) 256 パブリックサブネットとプラベートサブネット 自分も勉強していく中で、パブリックサブネットとプライベートサブネットってどう違うのと疑問に思っていました。 サブネット作成のコンソール画面でもパブリック/プライベートの選択などなかったはずです。 【結論】 サブネットのルートテーブルの記述内容で変わる パブリックサブネット すべてのIPアドレス宛のターゲットがインターネットゲートウェイに向いているもの。 送信先 ターゲット 0.0.0.0/0 インターネットゲートウェイ  プライベートサブネット すべてのIPアドレス宛のターゲットがNATゲートウェイに向いているもの。 プライベートサブネットがインターネットと通信するためには、NATゲートウェイのルートテーブルに0.0.0.0/0がインターネットゲートウェイに向かうように設定する必要があります。 送信先 ターゲット 0.0.0.0/0 NATゲートウェイ  3. サーバ・DB構築  サブネット内に必要となるEC2インスタンス、またはRDSを作成していきます。 (EC2,RDSの詳細な作成設定については記述を省略します) パブリックサブネットに配置するインスタンスには、インターネットに接続するため、ElasticIPを関連づける必要があります。 パブリックサブネットに配置したインスタンスは通常、パブリックIPv4アドレスが割り当てられます。 しかし、これだとインスタンスの起動停止のたびに毎回IPアドレスが変わってしまいます。 それでは大変なので、EIPを取得し、インスタンスと関連づけることでEIPを固定のパブリックIPアドレスとして使用することができます。 EC2インスタンス作成とNginxインストール 必要となるEC2インスタンスを作成します。 アプリケーションを動かすインスタンスには、RailsアプリケーションサーバであるPumaと通信するためのWebサーバ(Nginx)を事前にインストールします。 アプリケーションデプロイ後には、NginxとPumaを通信させる必要があります。 EIPの上限はデフォルトだと5個な話 インスタンスにEIPを割り当てるときに、画像のようなエラーがでてきました。 これはEIPの数が制限に達したという警告です。 EIPは、サポートプランにも寄りますが、Developerプランではデフォルトでは5個までしか使用できません。(デフォルトVPC内に2つ使用されているので、実質3個) 5個以上使用する場合には、Service Quatasのダッシュボードから申請を行う必要があります。 https://ap-northeast-1.console.aws.amazon.com/servicequotas なお、一気に20個とか申請すると、「申請する理由を詳しく教えてください」などとAWS側から怒られてしまうので、まずは5個ぐらいから始めると良いと思います。(※申請は全て英語です) 私は、デフォルトVPCに関連づいているEIP2個を外したのと、追加申請5個で足りました。 RDSのフェイルオーバー設定 RDSを作成していきます。 RDSの詳細設定に関しては、各自RDS使用用途によって異なるかと思うので、詳細は省きます。 障害時にはRDSを他AZで起動させるフェイルオーバーをさせる必要があります。 RDSのダッシュボードからサブネットグループの作成を行い、フェイルオーバーす先となるAZをグルーピングします。 フェイルオーバーの確認については、以下記事を参考にテストしてみました。 EC2-RDS間の疎通確認 アプリケーションが動く、EC2インスタンスからRDSへ接続ができることを確認します。 RDSのエンジンとしてMySQLを選択していた場合、EC2インスタンス上で以下コマンドでRDS内のMySQLと接続ができます。 RDSに設定しているセキュリグループのインバウンドルールに接続元EC2からのMySQL通信(3306番ポート)の許可を忘れずに! 接続元ec2 $ mysql -u マスターユーザー名 -pパスワード -h エンドポイント マスターユーザー名,パスワードは、それぞれRDS作成時に決定したものです。エンドポイントはRDS作成後に確認できます。 ALBの使用 一台のEC2ならロードバランサーは使用しなくても良いのでは思ったのですが、単なる負荷分散以外の機能もAWSのロードバランサーは提供してくれるので、そちらのメリットを加味してALBを使用します。 またALBには、Amazon Certificate Manager(ACM)からSSL証明書を取得し、HTTPSでの通信を設定します 4. Lambdaによる自動化 Lambda,EventBridge, CloudWatch, AWSChatBot, SNS このあたりのサービスを使用して開発する上で管理しやすくなる自動化を行いました。 Lambda✖︎EventBridgeによるEC2インスタンス起動・停止の自動化 開発ツール系のインスタンスや使用頻度の高いインスタンスについは起動・停止を自動化すると便利です。 ↓記事を参考に、実装しました。 環境ごとのEC2・RDSの停止忘れ防止 staging環境、production環境(運用開始まで)に属するインスタンス、RDSについては毎日↑のLambdaの停止スクリプトのみを実行し、停止忘れ防止策をこうじました。 AWS ChatbotによるSlack通知 Lambdaの実行結果は、CloudWatchLogsに蓄積されます。 インスタンスの停止スクリプトなどはエラー通知を即座に把握したいため、実務のコミュニケーションツールとして使用しているSlackに通知するように設定しました。 すごく便利!! 5. Amazon SES,SNS  本番環境や開発環境において、AWSからメールを送信するにはAmazon SimpleEmailService(SES)を使用します。 ここでもざっくりと手順を説明すると以下になります。 1.メール送信権限付きIAMユーザー作成後、アクセスキーを取得 2.Railsアプリコード内の ~アプリ名/config/environments/development.rb, staging.rb, production.rb配下にアクセスキーを記載 3.SESでドメイン、メールアドレスの認証 4.認証したドメイン・アドレスからのメール送信の確認 5.SNSでメール通知設定 メール送信権限付きユーザーのアクセスキーを取得 メール送信権限を持つIAMユーザーを作成します。(既存のユーザーでも大丈夫です) アタッチするポリシーは、AmazonSesSendingAccessというデフォルトポリシーがあるのでそれをユーザーにアタッチすれば大丈夫です。 AmazonSesSendingAccess { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ses:SendRawEmail", "Resource": "*" } ] } テストメール送信 ドメイン・メールアドレスの認証を行います。 認証からテストメールの送信の仕方までは↓記事が参考になります。 ※ドメインに関しては、Route53のほうで事前に認証済みのドメインでないとSES上で認証されないので注意が必要です。(経験あり?) バウンスメールのテストについては、上記テストメールの送信先をbounce@simulator.amazonses.comに設定してあげると、バウンスレートを上げることなくバウンスメールのテストを行なってくれます。 その他、通常の成功メールや苦情メールも同様で↓に記載のテスト用アドレスを使用するとレートとは無関係にテストができます。 バウンスメール・苦情メール等については、SNSとSESを連携させて通知設定を行います。 これも↓記事が参考になるので、簡単に設定できます。 ここまでだいたい2週間ぐらいでした。 6. 開発環境構築(docker)  ローカルの開発環境と検証用のdevelopment環境はdockerで構築を行いました。 Dockerfile, docker-compose.ymlを作成し、シェルスクリプトとして開発環境構築用のスクリプトを用意しました。 このスクリプトを叩くだけで、dockerでの開発環境ができあがります。 合わせて、初期データとして必要なrakeタスクも実装しました。 ざっと内容を紹介 setup.sh #!/bin/bash # 作業用ディレクトリ作成 if [ ! -d ./workspace ]; then mkdir workspace fi # 作業用dir配下にプロジェクトをclone git clone git@~~ # キャッシュを使用せず、imageをbuild docker-compose build --no-cache # 必要な初期rakeタスクを流す docker-compose run web bundle exec rake rakeタスク # 停止済みのコンテナを削除 docker container prune -f ridgepole導入時にハマったこと 今回、アプリケーションはmigrationファイルでの管理ではなくridgepoleを使用します。 私自身初めてのridgepole導入だったので少し苦戦しました。 後ほどridgepole導入時にハマったことは詳細をQiitaに投稿しようと思っています。 ridgepoleとは↓・・・ 7. jenkins・phpmyadminなど開発ツール設定  開発ツール用のインスタンスにjenkins, phpmyadminをそれぞれインストールします。 それぞれのインスタンスには、EC2FullAccessなどのポリシーを持ったアクセスキーを配置する必要があります。 jenkinsインスタンス # 認証情報を設定 $ aws configure # 4つ聞かれるのでそれぞれ入力 1. アクセスキー 2. パスワード 3. region 4. output形式 # この配下に認証情報(アクセスキー等がある) $ cd ~/.aws $ ls -la => config, credentials jenkinsのジョブが失敗する アクセスキーの設置が終わり、jenkinsのジョブを作成し実行たところ、エラーになりました。。。 jenkisnのコンソール出力を見ると以下のようなエラーメッセージが unable to locate credentials. you can configure credentials by running "aws configure". おいおい、アクセスキーはちゃんと配置したはずだぞ? 設定を確認してもきちんと登録されているはず・・・ # アクセスキー設定情報を確認 aws configure list => aws_access_key_id = ***************** => aws_secret_access_key = ***************** 【結論】 jenkinsのジョブを実行しているのは、ec2の中のjenkinsユーザー だからjenkinsユーザーに認証情報を設定してあげる必要がある(これまでは、ec2ユーザーとrootユーザーに設定していた) # rootユーザーになる $ sudo su # jenkinsユーザーになる $ su - jenkins # 認証情報が確認すると・・・なにも設定されていなかった $ aws configure list => aws_access_key_id => aws_secret_access_key # 再度認証情報を設定 $ aws configure 無事、ジョブが成功した! 余談ですが、画面上で作成したjenkinsのジョブはサーバ内jenkinsユーザーの以下に格納されているので、確認できます。 jenkinsインスタンス # rootユーザーになる sudo su # jenkinstユーザーになる su - jenkins cd workspace ls -la => 作成したjenkinsジョブ一覧が表示 8. VPN接続  別のネットワークから、この環境へのアクセスを可能にするためAWSClientVPNを使用し、VPN接続を試みます。 パブリックサブネット内のNATゲートウェイにアタッチしたEIPを固定IPアドレスとして、インターネットに接続できることをゴールとします。 ↓記事を参考にするとできるかと思います。 が、私がハマったことで一つ注意点! ClientVPVEndpointと関連づけるサブネットはプライベートサブネットでないといけない これに気づかず、数時間ハマりました。。。 また、VPN接続するときに作成されるENIは、接続のたびに新しいものが作成されます。 ENIに割り当てられるパブリックIPアドレスは接続のたびに毎回変わりますが、それをNATゲートウェイのEIPで固定化するというイメージです。 9. 起きた変化 以上作業を約3週間で行いました。 インフラにほとんど触ったことの無かった素人が3週間のインフラ構築を通して、どのような変化があったのか、技術的な側面と価値観・考え方の側面から感じたことを書いていきたいと思います。 技術面 【AWS】 ・AWSを使用して、迷わず基本的なアーキテクチャの設計ができるようになった ・AWS上のサービスをドキュメントを読むだけで使いこなせるようになった ・AWSリソースの管理能力が向上した 【docker】 ・dockerを使用して、開発環境の構築ができるようになった ・Dockerfile, docker-compose.ymlなど記述内容を理解し、自分の実装したいように改修できるようになった 【その他】 ・Webサーバやアプリケーションサーバのどのレイヤーに対してエラーが発生しているのか感覚的にわかるようになった ・ログを見る習慣/ログからエラーの原因を特定する力がついた ・Linuxサーバ内のディレクトリ構造や必要ファイルなどが把握し、行いたい修正を加えられるようになった ・Webの3層構造を体系的に理解することができた ざっとこんな感じになります。 特に自分として変化を感じたことは、基本的なアーキテクチャ設計をする際のAWSリソースに対して「わからない・これどうやるんだ」という感情がなくなったことです。 今までは、事前知識としてなかったのはもちろんですがどこかAWSを気軽に触れないものだと思っていました。 ですが、毎日AWSを触りながら理解していくことで、AWSに対するハードルが低くなっていくのを強く感じました。 今では、初めて使用するAWS上のサービスでも「まずは触ってみる」ということを大切にし、ドキュメントや参考記事を読めばだいたいのことはなんとかなるようになったと思います。 わずか3週間ですが、自分のエンジニアとしての知識・技術が3週間前と比較し格段に上がったのを感じました! 価値観・考え方 インフラ構築を経験してみることで、インフラの楽しさを感じたのと同時に、改めて、AWSの素晴らしさに感動しました。 マネジメントコンソールをいじるだけでサーバ・ネットワークを作れたり、あらゆるサービスを連携することでできることの無限さを感じました。 インフラというのはどこか、モヤに隠れた分かりづらいものという意識があった中、自分で0から設計し図を書き、それを実際に構築するという経験のおかげで構造的にインフラを捉えられるようになりました。 AWSを理解するにはまず図を書いてみる とよく聞きますが、これは本当にそうだと思います。 図を書きながら、「これってどうやって通信する」「この部分にはどういう制御が必要なんじゃないか」と頭の中で考え、それを実際に手を動かしてみることで必要な処理や構成が感覚的に理解できるようになってきます。 この経験をきっかけとして、これからもインフラに関する知識・技術を勉強し、今後はSAA,さらにはその上のSAPの取得を目指していきたいと思います。 そして、実務としてこのような素晴らしい挑戦の機会をいただけたことに感謝し、これからも成長できるように頑張っていきたいと思います。 10. おまけ 約3週間インフラ構築をする上で、ミドルウェアの操作についてはコマンドラインが主となるので、自然とコマンドを使う機会が多くなりました。 そこで備忘録がてら、よく使用したコマンドを残していきたいと思います。 よく使ったコマンドたち ■ コマンド # ファイル削除 rm -rf ディレクトリ # 検索 grep -r 正規表現 # プロセス確認 ps aux | grep XXX # 環境変数確認 env ■ systemctl # start, stop, restart, statusなど # Nginxの起動状態確認 systemctl nginx status # MySQLの起動状態確認 systemctl mysql status ■ crontab # サーバの初期設定をするcrontabの内容確認 crontab -l ■ Git # 接続先のremoteリポジトリを確認 git remote -v # remoteリポジトリを設定 git remote set-url origin git@~~~ ■ ssh ssh -i ~/.ssh/キー.pem ec2-user@IPアドレス
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

インフラ素人が3週間でWebサービスのインフラを0から構築するためにやったこと

目次 1. インフラ設計 2. ネットワーク構築 3. サーバ・DB構築 4. Lambdaによる自動化 5. Amazon SES・SNS 6. 開発環境構築(docker) 7. jenkins・phpmyadminなど開発ツール設定 8. VPN接続 9. 起きた変化 10. おまけ はじめに インフラ素人同然レベルだった私が実務において、Webアプリケーションのインフラを0から構築することになりました。 期間は約3週間、インフラ設計から行い、構築したインフラ上でWebサービスが稼働できる状態まで持っていくことがゴールになります。  約3週間の間、AWSやミドルウェア周りの技術に触れ、今まで考えてもみなかった知識の習得や、多くのつまづきを通して貴重な経験をすることができました。 チームメンバーと分担しながら進めたので、あくまで自分のやったことベースにはなりますが、3週間どんなことをやったのか、特につまづいたことを中心に書いていきたいと思います。 ※基本的なインフラ構成はほぼ全てAWSのリソースを使用しました。 【使用技術】 ・ AWS(EC2, RDS, VPC, Route53, Lambda, IAM, SES, SNS, ACM, CloudWatch, etc.) ・ docker ・ Nginx(Webサーバ) ・ Puma(アプリケーションサーバ) ・ Ruby on Rails 開始前の筆者のレベルを3行で! ・自社開発エンジニア歴5ヶ月の駆け出しエンジニア ・AWS Cloud Practitionerの資格は持っているが実務でのインフラ(AWS)経験は無し ・ミドルウェア周りの知識はほぼゼロ(Webサーバとアプリケーションサーバってどう違うの?レベル) 1. インフラ設計 まずやったこととして、Webサービスを稼働させる上でどのようなインフラ環境が必要か理解し、可視化することです。 今回、実装するのは、Web開発では基本となる開発環境(development)、ステージング環境(staging)、本番環境(production)からなる構成です。 なんとなくの理解だったので、各環境の役割について、改めて理解するのに良い記事があったので共有します。 事前学習 とはいっても、 VPCってなんぞや? サブネットの切り方ってどうするの? NATゲートウェイとは? ALBとロードバランサーなにが違うの? など、私にとってネットワーク設計やサーバ構築が初めての経験だったので、知識の習得のため最初の数日はとにかくインプット量を意識して手を動かしながら学習しました。 VPC構築、サブネットの設定、EC2構築など実際にAWSマネジメントコンソール上でポチポチやりながら、「こことここが繋がるのか〜」「こうすれば良いのね」といった感じで、体系的にAWSのリソースを理解しながら、知識を蓄えていったところが大きいです。 一部、以下AWSCloudTechのサービスを使ったりなんかもしました。 実装するインフラ構成を図に落とし込む 理解が少し曖昧なところがありながらもなんとか、今回実装するインフラ構成を図に落とし込みました。 ここまででおおよそ3日です。 Webサーバはアクセスを考慮して、現時点では冗長構成にせず単一のインスタンスのみで運用を行い、batchサーバの役割も持たせます。 本番環境では、バウンスメール等はSES,SNSを使用し、通知を行いレートの管理をします。 他ネットワークからのアクセスも可能にするため、AWSClientVPNを使用したVPN接続も実装する予定です。 Excelにインフラ設計情報の詳細をドキュメント化 インフラ設計情報として、開発する上で必要になってくる細かな設定に関しては、都度Excelに記載し、後ほど忘れないためにドキュメント化し管理しました。 ・RDSの詳細設定 ・各インスタンスの詳細設定 ・pemキー情報、IAM情報、各種ログイン情報  ・ssh接続コマンドチートシート などなど 2. ネットワーク構築  ここから実際に手を動かしていきます。上記インフラ構成を実現するためにまずは、サーバを設置する箱となるネットワークの構築(VPC)から始めました。 ざっくり手順は以下のとおり実現しました。 1.VPC設定 2.VPC内にサブネット構築 3.インターネットゲートウェイの設置 4.NATゲートウェイの設置 5.VPC間のピアリング接続の設定 6.サブネットのルートテーブルの設定 具体的な設定についてここでは詳細省きますが、これでおおよそ必要なるネットワーク構成は出来あがります。 1つ注意点として、 VPCやサブネットを作成する際のIPv4CIDRブロックは、以下のプライベートIPアドレスの範囲内で作成する必要があります。 プライベートアドレスは以下のように範囲が定められており、この範囲外のIPアドレスはグローバルアドレスとなってしまうからです。 クラス 範囲 ネットワーク数 クラスA 10.0.0.0 ~ 10.255.255.255 (10.0.0.0/8) 1 クラスB 172.16.0.0 ~ 172.31.255.255 (172.16.0.0/12) 16 クラスC 192.168.0.0 ~ 192.168.255.255 (192.168.0.0/16) 256 パブリックサブネットとプラベートサブネット 自分も勉強していく中で、パブリックサブネットとプライベートサブネットってどう違うのと疑問に思っていました。 サブネット作成のコンソール画面でもパブリック/プライベートの選択などなかったはずです。 【結論】 サブネットのルートテーブルの記述内容で変わる パブリックサブネット すべてのIPアドレス宛のターゲットがインターネットゲートウェイに向いているもの。 送信先 ターゲット 0.0.0.0/0 インターネットゲートウェイ  プライベートサブネット すべてのIPアドレス宛のターゲットがNATゲートウェイに向いているもの。 プライベートサブネットがインターネットと通信するためには、NATゲートウェイのルートテーブルに0.0.0.0/0がインターネットゲートウェイに向かうように設定する必要があります。 送信先 ターゲット 0.0.0.0/0 NATゲートウェイ  3. サーバ・DB構築  サブネット内に必要となるEC2インスタンス、またはRDSを作成していきます。 (EC2,RDSの詳細な作成設定については記述を省略します) パブリックサブネットに配置するインスタンスには、インターネットに接続するため、ElasticIPを関連づける必要があります。 パブリックサブネットに配置したインスタンスは通常、パブリックIPv4アドレスが割り当てられます。 しかし、これだとインスタンスの起動停止のたびに毎回IPアドレスが変わってしまいます。 それでは大変なので、EIPを取得し、インスタンスと関連づけることでEIPを固定のパブリックIPアドレスとして使用することができます。 EC2インスタンス作成とNginxインストール 必要となるEC2インスタンスを作成します。 アプリケーションを動かすインスタンスには、RailsアプリケーションサーバであるPumaと通信するためのWebサーバ(Nginx)を事前にインストールします。 アプリケーションデプロイ後には、NginxとPumaを通信させる必要があります。 EIPの上限はデフォルトだと5個な話 インスタンスにEIPを割り当てるときに、画像のようなエラーがでてきました。 これはEIPの数が制限に達したという警告です。 EIPは、サポートプランにも寄りますが、Developerプランではデフォルトでは5個までしか使用できません。(デフォルトVPC内に2つ使用されているので、実質3個) 5個以上使用する場合には、Service Quatasのダッシュボードから申請を行う必要があります。 https://ap-northeast-1.console.aws.amazon.com/servicequotas なお、一気に20個とか申請すると、「申請する理由を詳しく教えてください」などとAWS側から怒られてしまうので、まずは5個ぐらいから始めると良いと思います。(※申請は全て英語です) 私は、デフォルトVPCに関連づいているEIP2個を外したのと、追加申請5個で足りました。 RDSのフェイルオーバー設定 RDSを作成していきます。 RDSの詳細設定に関しては、各自RDS使用用途によって異なるかと思うので、詳細は省きます。 障害時にはRDSを他AZで起動させるフェイルオーバーをさせる必要があります。 RDSのダッシュボードからサブネットグループの作成を行い、フェイルオーバーす先となるAZをグルーピングします。 フェイルオーバーの確認については、以下記事を参考にテストしてみました。 EC2-RDS間の疎通確認 アプリケーションが動く、EC2インスタンスからRDSへ接続ができることを確認します。 RDSのエンジンとしてMySQLを選択していた場合、EC2インスタンス上で以下コマンドでRDS内のMySQLと接続ができます。 RDSに設定しているセキュリグループのインバウンドルールに接続元EC2からのMySQL通信(3306番ポート)の許可を忘れずに! 接続元ec2 $ mysql -u マスターユーザー名 -pパスワード -h エンドポイント マスターユーザー名,パスワードは、それぞれRDS作成時に決定したものです。エンドポイントはRDS作成後に確認できます。 ALBの使用 一台のEC2ならロードバランサーは使用しなくても良いのでは思ったのですが、単なる負荷分散以外の機能もAWSのロードバランサーは提供してくれるので、そちらのメリットを加味してALBを使用します。 またALBには、Amazon Certificate Manager(ACM)からSSL証明書を取得し、HTTPSでの通信を設定します 4. Lambdaによる自動化 Lambda,EventBridge, CloudWatch, AWSChatBot, SNS このあたりのサービスを使用して開発する上で管理しやすくなる自動化を行いました。 Lambda✖︎EventBridgeによるEC2インスタンス起動・停止の自動化 開発ツール系のインスタンスや使用頻度の高いインスタンスについは起動・停止を自動化すると便利です。 ↓記事を参考に、実装しました。 環境ごとのEC2・RDSの停止忘れ防止 staging環境、production環境(運用開始まで)に属するインスタンス、RDSについては毎日↑のLambdaの停止スクリプトのみを実行し、停止忘れ防止策をこうじました。 AWS ChatbotによるSlack通知 Lambdaの実行結果は、CloudWatchLogsに蓄積されます。 インスタンスの停止スクリプトなどはエラー通知を即座に把握したいため、実務のコミュニケーションツールとして使用しているSlackに通知するように設定しました。 すごく便利!! 5. Amazon SES,SNS  本番環境や開発環境において、AWSからメールを送信するにはAmazon SimpleEmailService(SES)を使用します。 ここでもざっくりと手順を説明すると以下になります。 1.メール送信権限付きIAMユーザー作成後、アクセスキーを取得 2.Railsアプリコード内の ~アプリ名/config/environments/development.rb, staging.rb, production.rb配下にアクセスキーを記載 3.SESでドメイン、メールアドレスの認証 4.認証したドメイン・アドレスからのメール送信の確認 5.SNSでメール通知設定 メール送信権限付きユーザーのアクセスキーを取得 メール送信権限を持つIAMユーザーを作成します。(既存のユーザーでも大丈夫です) アタッチするポリシーは、AmazonSesSendingAccessというデフォルトポリシーがあるのでそれをユーザーにアタッチすれば大丈夫です。 AmazonSesSendingAccess { "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": "ses:SendRawEmail", "Resource": "*" } ] } テストメール送信 ドメイン・メールアドレスの認証を行います。 認証からテストメールの送信の仕方までは↓記事が参考になります。 ※ドメインに関しては、Route53のほうで事前に認証済みのドメインでないとSES上で認証されないので注意が必要です。(経験あり?) バウンスメールのテストについては、上記テストメールの送信先をbounce@simulator.amazonses.comに設定してあげると、バウンスレートを上げることなくバウンスメールのテストを行なってくれます。 その他、通常の成功メールや苦情メールも同様で↓に記載のテスト用アドレスを使用するとレートとは無関係にテストができます。 バウンスメール・苦情メール等については、SNSとSESを連携させて通知設定を行います。 これも↓記事が参考になるので、簡単に設定できます。 ここまでだいたい2週間ぐらいでした。 6. 開発環境構築(docker)  ローカルの開発環境と検証用のdevelopment環境はdockerで構築を行いました。 Dockerfile, docker-compose.ymlを作成し、シェルスクリプトとして開発環境構築用のスクリプトを用意しました。 このスクリプトを叩くだけで、dockerでの開発環境ができあがります。 合わせて、初期データとして必要なrakeタスクも実装しました。 ざっと内容を紹介 setup.sh #!/bin/bash # 作業用ディレクトリ作成 if [ ! -d ./workspace ]; then mkdir workspace fi # 作業用dir配下にプロジェクトをclone git clone git@~~ # キャッシュを使用せず、imageをbuild docker-compose build --no-cache # 必要な初期rakeタスクを流す docker-compose run web bundle exec rake rakeタスク # 停止済みのコンテナを削除 docker container prune -f ridgepole導入時にハマったこと 今回、アプリケーションはmigrationファイルでの管理ではなくridgepoleを使用します。 私自身初めてのridgepole導入だったので少し苦戦しました。 後ほどridgepole導入時にハマったことは詳細をQiitaに投稿しようと思っています。 ridgepoleとは↓・・・ 7. jenkins・phpmyadminなど開発ツール設定  開発ツール用のインスタンスにjenkins, phpmyadminをそれぞれインストールします。 それぞれのインスタンスには、EC2FullAccessなどのポリシーを持ったアクセスキーを配置する必要があります。 jenkinsインスタンス # 認証情報を設定 $ aws configure # 4つ聞かれるのでそれぞれ入力 1. アクセスキー 2. パスワード 3. region 4. output形式 # この配下に認証情報(アクセスキー等がある) $ cd ~/.aws $ ls -la => config, credentials jenkinsのジョブが失敗する アクセスキーの設置が終わり、jenkinsのジョブを作成し実行たところ、エラーになりました。。。 jenkisnのコンソール出力を見ると以下のようなエラーメッセージが unable to locate credentials. you can configure credentials by running "aws configure". おいおい、アクセスキーはちゃんと配置したはずだぞ? 設定を確認してもきちんと登録されているはず・・・ # アクセスキー設定情報を確認 aws configure list => aws_access_key_id = ***************** => aws_secret_access_key = ***************** 【結論】 jenkinsのジョブを実行しているのは、ec2の中のjenkinsユーザー だからjenkinsユーザーに認証情報を設定してあげる必要がある(これまでは、ec2ユーザーとrootユーザーに設定していた) # rootユーザーになる $ sudo su # jenkinsユーザーになる $ su - jenkins # 認証情報が確認すると・・・なにも設定されていなかった $ aws configure list => aws_access_key_id => aws_secret_access_key # 再度認証情報を設定 $ aws configure 無事、ジョブが成功した! 余談ですが、画面上で作成したjenkinsのジョブはサーバ内jenkinsユーザーの以下に格納されているので、確認できます。 jenkinsインスタンス # rootユーザーになる sudo su # jenkinstユーザーになる su - jenkins cd workspace ls -la => 作成したjenkinsジョブ一覧が表示 8. VPN接続  別のネットワークから、この環境へのアクセスを可能にするためAWSClientVPNを使用し、VPN接続を試みます。 パブリックサブネット内のNATゲートウェイにアタッチしたEIPを固定IPアドレスとして、インターネットに接続できることをゴールとします。 ↓記事を参考にするとできるかと思います。 が、私がハマったことで一つ注意点! ClientVPVEndpointと関連づけるサブネットはプライベートサブネットでないといけない これに気づかず、数時間ハマりました。。。 また、VPN接続するときに作成されるENIは、接続のたびに新しいものが作成されます。 ENIに割り当てられるパブリックIPアドレスは接続のたびに毎回変わりますが、それをNATゲートウェイのEIPで固定化するというイメージです。 9. 起きた変化 以上作業を約3週間で行いました。 インフラにほとんど触ったことの無かった素人が3週間のインフラ構築を通して、どのような変化があったのか、技術的な側面と価値観・考え方の側面から感じたことを書いていきたいと思います。 技術面 【AWS】 ・AWSを使用して、迷わず基本的なアーキテクチャの設計ができるようになった ・AWS上のサービスをドキュメントを読むだけで使いこなせるようになった ・AWSリソースの管理能力が向上した 【docker】 ・dockerを使用して、開発環境の構築ができるようになった ・Dockerfile, docker-compose.ymlなど記述内容を理解し、自分の実装したいように改修できるようになった 【その他】 ・Webサーバやアプリケーションサーバのどのレイヤーに対してエラーが発生しているのか感覚的にわかるようになった ・ログを見る習慣/ログからエラーの原因を特定する力がついた ・Linuxサーバ内のディレクトリ構造や必要ファイルなどが把握し、行いたい修正を加えられるようになった ・Webの3層構造を体系的に理解することができた ざっとこんな感じになります。 特に自分として変化を感じたことは、基本的なアーキテクチャ設計をする際のAWSリソースに対して「わからない・これどうやるんだ」という感情がなくなったことです。 今までは、事前知識としてなかったのはもちろんですがどこかAWSを気軽に触れないものだと思っていました。 ですが、毎日AWSを触りながら理解していくことで、AWSに対するハードルが低くなっていくのを強く感じました。 今では、初めて使用するAWS上のサービスでも「まずは触ってみる」ということを大切にし、ドキュメントや参考記事を読めばだいたいのことはなんとかなるようになったと思います。 わずか3週間ですが、自分のエンジニアとしての知識・技術が3週間前と比較し格段に上がったのを感じました! 価値観・考え方 インフラ構築を経験してみることで、インフラの楽しさを感じたのと同時に、改めて、AWSの素晴らしさに感動しました。 マネジメントコンソールをいじるだけでサーバ・ネットワークを作れたり、あらゆるサービスを連携することでできることの無限さを感じました。 インフラというのはどこか、モヤに隠れた分かりづらいものという意識があった中、自分で0から設計し図を書き、それを実際に構築するという経験のおかげで構造的にインフラを捉えられるようになりました。 AWSを理解するにはまず図を書いてみる とよく聞きますが、これは本当にそうだと思います。 図を書きながら、「これってどうやって通信する」「この部分にはどういう制御が必要なんじゃないか」と頭の中で考え、それを実際に手を動かしてみることで必要な処理や構成が感覚的に理解できるようになってきます。 この経験をきっかけとして、これからもインフラに関する知識・技術を勉強し、今後はSAA,さらにはその上のSAPの取得を目指していきたいと思います。 そして、実務としてこのような素晴らしい挑戦の機会をいただけたことに感謝し、これからも成長できるように頑張っていきたいと思います。 10. おまけ 約3週間インフラ構築をする上で、ミドルウェアの操作についてはコマンドラインが主となるので、自然とコマンドを使う機会が多くなりました。 そこで備忘録がてら、よく使用したコマンドを残していきたいと思います。 よく使ったコマンドたち ■ コマンド # ファイル削除 rm -rf ディレクトリ # 検索 grep -r 正規表現 # プロセス確認 ps aux | grep XXX # 環境変数確認 env ■ systemctl # start, stop, restart, statusなど # Nginxの起動状態確認 systemctl nginx status # MySQLの起動状態確認 systemctl mysql status ■ crontab # サーバの初期設定をするcrontabの内容確認 crontab -l ■ Git # 接続先のremoteリポジトリを確認 git remote -v # remoteリポジトリを設定 git remote set-url origin git@~~~ ■ ssh ssh -i ~/.ssh/キー.pem ec2-user@IPアドレス
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【AWS】コンソール上で「amazon-linux-extras list」が動かないとき

AWSの扱い方を学習したくて、Udemyの「AmazonWebServiceマスターコースVPC編」を受講してました。 セクション4の動画15にて WindowsPowerShellから、AWSのEC2サーバーにSSH接続をした後、nginxをamazon-linux-extrasコマンドでインストールしようとしたところ、画面が固まってしまいました。 sudo amazon-linux-extras list (固まってしまう、、、) which amazon-linux-extrasで確認しても、ソフトウェアはインストールされているし、helpコマンドとinfoコマンドは問題なく動きます。 しかし、installコマンドとlistコマンドはなぜか固まってしまいます。 EC2インスタンスやVPCを作り直してもダメだったので、3~4時間くらい格闘したのですが、、、 なんと解決方法は待つことでした、笑 4分くらい待ったら、正しい結果が出力されました。。。 これまでの苦労は何だったんだ???笑 備忘録として残しておきます。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS Cloud Practitioner について勉強してわからないことをまとめた ~モジュール2~

はじめに 「AWS Cloud Practitioner について勉強してわからないことをまとめた ~モジュール1~」の続きです。 僕自身が学んでいて不明だった箇所を纏めておきました。 ぜひともこれから学ぶ方への参考になればとおもいます。 参考:AWS Cloud Practitioner Essentials(Japanese) Amazon Elastic Compute Cloud (Amazon EC2) サイズ変更可能で安全なコンピュティングキャパシティーを Amazon EC2 インスタンスとしてクラウド内で提供する。 従来のオンプレミスのリソース ハードウェアを購入するために先行投資する。 サーバーが届くのを待つ。 サーバーを物理データセンターに設置する。 ウェブサイトの公開に必要な設定を行う。 Amazon EC2 インスタンスを利用した場合 Amazon EC2 インスタンスは数分以内にプロビジョニング、作成できる。 プロビジョニング 必要に応じてネットワークやコンピュータの設備などのリソースを提供できるよう予測し、準備しておくこと。供給や設備などの意味を表すプロビジョン(provison)という単語がもととなって派生した言葉。 ワークロードの実行が終了したら、使用を停止できる。 料金は、インスタンスの実行時に使用したコンピューティング時間に対してのみ支払い。停止時や終了時に料金は発生しない。 必要なサーバー容量に対してのみ支払うことでコストを節約できる。 Amazon EC2 インスタンスタイプ ワークロードやアプリケーション固有のニーズを考慮。 コンピューティング、メモリ、ストレージの機能要件も含まれる。 汎用インスタンス コンピューティング、メモリ、ネットワークのリソースをバランスよく提供する。 以下のようなさまざまなワークロードに使用できる。 - アプリケーションサーバー - ゲームサーバー - エンタープライズアプリケーションのバックエンドサーバー - 小規模および中規模のデータベース コンピューティング最適化インスタンス 高パフォーマンスプロセッサの恩恵を受けることができるアプリケーションに最適。 高性能のウェブサーバー、計算負荷の高いアプリケーションサーバー、専用のゲームサーバーに最適。 1つのグループで多くのトランザクションを処理する必要があるバッチ処理ワークロードに使用することもできる。 メモリ最適化インスタンス メモリ内にロードした大規模なデータセットを処理するワークロードに対して、高速なパフォーマンスを実現するように設計されている。 メモリは一時的なストレージ領域です。中央演算装置 (CPU) がアクションを完了するために必要なすべてのデータと命令を保持します。コンピュータプログラムやアプリケーションは、ストレージからメモリにロードされた後に実行可能となります。このプリロードプロセスによって、CPU からコンピュータプログラムへの直接アクセスが可能になります。 プリロード 先取り、先読み、などの意味をもつ。 この先必要になるデータなどを予め読み込んでおき、読み込みにかかる時間を短縮する仕組みのこと 高速コンピューティングインスタンス ハードウェアアクセラレーターやコプロセッサーを使用して、一部の機能を CPU で実行中のソフトウェアよりも効率的に実行します。こうした機能には、浮動小数点数計算、グラフィックス処理、データパターン照合などがあります。 コンピューティングにおいて、ハードウェアアクセラレーターは、データ処理を高速化できるコンポーネントです。高速コンピューティングインスタンスは、グラフィックアプリケーション、ゲームストリーミング、アプリケーションストリーミングなどのワークロードに最適です。 ハードウェアアクセラレーター なんらかの機能を通常の汎用プロセッサ (CPU) 上で動作するソフトウェア(コンピュータ・プログラム)による実装で処理したのではレイテンシやスループットが遅い、消費電力が大きい、などといった問題があるような場合に、ハードウェア実装による支援で実行速度などを加速(アクセラレーション)し、システム全体の性能や効率を向上させる技術である。 引用: wikipedia ストレージ最適化インスタンス ローカルストレージの大規模なデータセットに対する高速シーケンシャル読み取りおよび、書き込みのアクセスを必要とするワークロード用に設計されている。 Amazon EC2 の料金 Amazon EC2では使用したコンピューティング時間に対してのみ料金が発生する。 オンデマンド 中断できない不規則で短期的なワークロードに最適。 初期費用や最低料金は発生しない。 ユーザーがインスタンスを停止するまで、インスタンスは継続的に実行される。 ユースケースの例には、 アプリケーションの開発とテスト、使用パターンが予測不可能なアプリケーションの実行などがあります。ワークロードを1年以上実行し続ける場合、オンデマンドインスタンスは推奨されません。そのようなワークロードにはリザーブドインスタンスを使用することで大幅にコストを削減できるため。 Amazon EC2 Savings Plans 一定のコンピューティング使用量を1年または3年の期間で契約することにより、コンピューティング料金を削減できる。期間をコミットすることにより、オンデマンドの料金に比べて料金を72%節約できる。 リザーブドインスタンス オンデマンドインスタンスの利用に適用される割引。 スタンダードリザーブドインスタントとコンバーティブルリザーブドインスタンスは1年または3年の契約で購入でき、スケジュールされたリザーブドインスタンスは1年契約で購入できる、3年のオプションの場合、コストを大幅に削減できる。 スポットインスタンス 開始時刻と終了時刻が定まっていないワークロードや、中断可能なワークロードに最適。 スポットインスタンスでは、未使用のAmazon EC2コンピューティングキャパシティーを使用することにより、オンデマンドの料金と比較してコストを最大90%削減できます。 Dedicated Hosts お客様専用の、Amazon EC2インスタンスキャパシティーを備えた物理サーバーです。 ソケット単位、コア単位、またはVM単位の既存のソフトウェア・ライセンスを使用して、ライセンス要件を満たすことができる。 もっとも高価なオプション。 Amazon EC2 のスケーリング スケーラビリティ 変化する需要に応じて自動的にスケールアウトまたはスケールインするアーキテクチャを設計できる。そのため、実際に使用したリソースに対してのみ料金が発生する。お客様のニーズを満たすためのコンピューティングキャパシティーの不足そ心配する必要はない。 Amazon EC2 Auto Scaling Amazon EC2 Auto Scaling を使用すると、アプリケーションの需要の変化に応じて EC2インスタンスを自動的に作成または削除することができる。 必要に応じてEC2インスタンスを自動的にスケールインおよびスケールアウトすることにより、アプリケーションの可用性を更に高めることができる。 Amazon EC2 Auto Scalingには、動的スケーリングと予測スケーリングの2つのスケーリング方法が用意されている。 - 動的スケーリングは変化する需要に対応する - 予測スケーリングは予測された需要に基づいて、適切な数のEC2インスタンスを自動的に用意する。 Elastic Load Balancing を使用してトラフィックを転送する アプリケーションへのトラフィックを、EC2インスタンスなどのリソースへ自動的に分散するAWSのサービス。 ::: note トラフィック 通信の分野におけるトラフィックとは、インターネットやLANなどのコンピュータなどの通信回線において、一定時間内にネットワーク上で転送されるデータ量のことを意味する ::: メッセージングとキューイング モノリシックアプリケーションとマイクロサービス アプリケーションは複数のコンポーネントで構成されている。 コンポーネントはアプリケーションが継続的に実行するために、相互に通信してデータを送信し、リクエストを処理する。 コンポーネント同士が密結合になったアプリケーションがあるとします。 これらのコンポーネントには、データベース、サーバー、ユーザーインターフェイス、ビジネスロジックなどがある。このようなアーキテクチャはモノリシックアプリケーションと呼ばれる。 モノリシックアプリケーションは1つのコンポーネントで障害が発生すると、ほかのコンポーネントでも障害が発生し、場合によってはアプリケーション全体で障害が発生する。 マイクロサービスのアプローチを利用することで1つのコンポーネントで障害が発生してもアプリケーションの可用性を維持することができる。 マイクロサービスのアプローチでは、アプリケーションのコンポーネントが疎結合される。 1つのコンポーネントで障害が発生しても、コンポーネントは相互に通信する関係のため、他のコンポーネントは引き続き機能する。 AWS でアプリケーションを設計する場合、さまざまな機能を実行するサービスやコンポーネントを使用して、マイクロサービスのアプローチを取ることができます。Amazon Simple Notification Service (Amazon SNS) と Amazon Simple Queue Service (Amazon SQS) の 2 つのサービスによって、アプリケーションの疎結合化が容易に実現できる。 Amazon Simple Notification Service(Amazon SNS) Pub/Subサービス。パブリッシャーはAmazon SNS トピックを使用して、サブスクライバーにメッセージを発行できる。 Amazon SNSの場合、サブスクライバーとなるのはウェブサーバー、Eメールアドレス、AWS Lambda関数など。 Amazon Simple Queue Service(Amazon SQS) メッセージキューイングサービス ソフトウェアコンポーネント間でメッセージを送信、保存、受信できる。メッセージが失われることはない。Amazon SQS ではアプリケーションからキューにメッセージを送信する。ユーザーはまたはサービスは、キューからメッセージを受信して処理した後、キューからメッセージを削除する。 キュー(queue) データ構造の一つ(データを格納する入れ物)で、入ってきたデータを順番に格納して、先に格納したデータから順に取り出す。 先入れ先出しのデータ構造。 その他のコンピューティングサービス サーバーレスコンピューティング 「サーバーレス」とは、コードはサーバー上で実行されますが、サーバーのプロビジョニングや管理を行う必要なありません。 サーバーレスコンピューティングのもう1つの利点がサーバーレスアプリケーションが自動的にスケールされるという柔軟性。 サーバーレスコンピューティング向けのAWSサービスは AWS Lambda。 AWS Lambda サーバーのプロビジョニングや管理を行うことなく、コードを実行できるサービス。 AWS Lambdaは使用したコンピューティング時間に対してのみ料金が発生する。 課金されるのはコードが実行されているときのみ。ほぼすべての種類のアプリケーションやバックエンドサービスのコードをを管理作業を行うことなく実行できる。 AWSでは、コンテナ化されたアプリケーションを構築して実行することもできる。 コンテナ アプリケーションのコードや依存関係を1つのオブジェクトにパッケージ化する技術。 セキュリティ、信頼性、スケーラビリティに関する必須要件があるプロセスやワークフローに使用することができる。 Amazon Elastic Container Service(Amazon ECS) スケーラビリティとパフォーマンスに優れたコンテナ管理システム。 このシステムを使用することでコンテナ化されたアプリケーションをAWSで実行及びスケールできる。 Amazon ECSではDockerコンテナをサポートしている。 Amazon Elastic Kubernetes Service(Amazon EKS) AWSでKubernetesを実行できるフルマネージドサービス。 フルマネージドサービス マネージドサービスで提供している内容に加えて、より細やかな監視、障害対応または運用代行サービスを提供しているサービスのこと。 本来であればオプションとして別に請求されるようなセキュリティ監視や24時間365日の障害対応もサービスに含まれている。 Kubernetes コンテナ化されたアプリケーションを大規模にデプロイして管理できるオープンソースソフトウェア。 ボランティアによる大規模なコミュニティによって管理されており、AWSはKubernetesコミュニティと積極的に連携している。 AWS Fargate コンテナ向けのサーバーレスコンピューティングエンジン。 Amazon ECSとAmazon EKSの両方を利用できる。 サーバーのプロビジョニングや管理を行う必要はありません。 サーバーインフラストラクチャはAWS Fargateによって管理される。 料金は、コンテナの実行に必要なリソースに対してのみ発生する。 注意 自己学習のために割愛している部分があるので 公式も合わせてご確認ください。 AWS Cloud Practitioner Essentials(Japanese) 参考書籍: 図解即戦力 Amazon Web Servicesのしくみと技術がこれ1冊でしっかりわかる教科書
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

AWS App Runner と ECS それぞれで同じアプリをデプロイして比較してみる

こんにちは、Masuyama です。 別な記事では、AWS App Runner を使って手軽にコンテナ式アプリをデプロイできることを学びました。 その時は確かに少ないステップでデプロイできることは分かっていただけたと思うのですが、別なサービス (ECSとか) でデプロイする時との違いが分かりにくかったかもしれません。 そこで、App Runner と ECS のそれぞれで同じコンテナアプリをデプロイし、App Runner がどれだけ簡単かを分かっていただこうかと思います。 前回は Workshop に従いましたが、今回はPython の軽量 Web フレームワークの一つである Flask を App Runner でデプロイしてみましょう。 0. 前準備 (共通手順) App Runner 版、ECS 版のどちらでも共通となる コンテナイメージの準備 だけは共通手順として実施します。 0-1. ECR 作成 コンテナイメージをプッシュするためのリポジトリを先に用意しておきます。 [リポジトリを作成] を選択します。 リポジトリ名は今回は app-runner-flask-ecr と設定します。 リポジトリを作成できたら [プッシュコマンドを表示] を選択し、画面に表示される指示に従いローカル端末からイメージのビルド、プッシュコマンドを確認しておきます。 次の手順でサクッと Flask アプリコードを準備し、コンテナイメージを作成したらプッシュコマンドでイメージをリポジトリに上げていきます。 0-2. コンテナイメージ作成 続いて ECR にプッシュするためのコンテナイメージを作成しましょう。 apprunner-flask という名前のディレクトリを用意し、その中に以下の 2 つのファイルを用意します。 app.py requirements.txt それぞれのコードの中身はこのように記述します。 app.py FROM python:3.8 # 以降の RUN, CMD で使われる作業ディレクトリ WORKDIR /app # カレントディレクトリにある情報をコンテナ内の 「/app」 にコピー ADD . /app # requirements.txt に従いパッケージをインストール RUN pip install --trusted-host pypi.python.org -r requirements.txt # 待受ポート指定 EXPOSE 5000 # コンテナが起動時に実行するコマンド CMD ["python", "app.py"] requirements.txt Flask ここまで準備できたら、ECR にリポジトリを作成した時に確認したプッシュコマンドを apprunner-flask ディレクトリ内で実行していきます。 プッシュまで終わったら、リポジトリにイメージが上がっていることを確認しておきましょう。 なお、プッシュする前にローカルでコンテナを起動させて動作確認をする場合は以下のコマンドを実行します。 $ docker run -d -p 5000:5000 app-runner-flask-ecr その後、ブラウザで localhost:5000 にアクセスすると app.py 内で指定した文字が表示されているはずです。 1. App Runner 版 ではイメージを用意できたので、まずは App Runner でイメージから Flask アプリをデプロイしてみます。 1-1. サービス作成 細かい手順は 別な記事で紹介もしているので一部割愛しますが、App Runner ではサービスを作成するという手順だけで済んでしまいます。 なお、サービス作成時に指定する待ち受けポートは Dockerfile 内で指定した通り 5000 と設定しましょう。 ※Dockerfile より抜粋 ... EXPOSE 5000 ... 設定するところといったらこれぐらいです。早い。 さて、少し待ってデプロイが完了したら表示されるデフォルトドメインにアクセスしてみましょう。 Hello ~ が表示されていれば成功です。 2. ECS (Fargate) 版 次に、これまでコンテナアプリのデプロイに多く使われてきた ECS (Fargate) で Flask アプリをデプロイする手順を試してみましょう。 基本的にはできるだけデフォルト設定で簡単に済ませる方針です。 2-1. クラスター作成 ECS のコンソールから [クラスター]->[クラスターの作成] を選択します。 次にクラスターテンプレートを選択していきます。 今回はサクッと Fargate を使いたいので [ネットワーキングのみ] を選択します。 次はクラスターの設定です。 新しく VPC を作成するよう選択し、VPC とサブネットの CIDR を設定していきます。 2-2. ECS タスク定義作成 クラスターの作成が完了するまでの間、タスク定義も作成していきます。 ECSの管理画面から[タスク定義]→[新しいタスク定義の作成]を選択します。 起動タイプは前述の通り Fargate を選択します。 EC2 管理までマネージドになるのは素敵ですね。 さらに実行ロールやタスク定義名を設定しつつ、、、 タスクサイズも適当に、とりあえず最小要件で設定しつつ、、、 [コンテナの定義]->[コンテナの追加] から、先ほど ECR にアップロードしたイメージを指定します。 ここでも待受ポートは Dockerfile で指定した通り、5000 と設定するのを忘れないようにしましょう。 App Runner は 1 手順のみでデプロイできたので、ECS は既に工程が多いようにみえてきました…。 2-3. ECS サービス作成 さて、そろそろ先ほどのクラスターが作成完了しているはずなので、ここからサービスを立ち上げます。 クラスターの画面から [デプロイ] を選択し、サービス名などを適当に設定して進みます。 デプロイが始まり、しばらく待つとデプロイ完了です。 ではデプロイした Flask アプリにアクセスしてみます。 作成したクラスターの [タスク]->[ネットワーキング]->[パブリックIP] から Flask コンテナの IP を確認できるので、これにブラウザでアクセスします。 ポートマッピングで指定した :5000 を付けるのを忘れないようにしましょう。 無事にアクセスできましたね。 おわりに さて、いかがでしたでしょうか。 App Runner を簡単に見せたいという気持ちは少なからずあったかもしれませんが、それでも手順の数でいうと以下のように差があることが分かっていただけたかと思います。 (ECR へのイメージプッシュは共通手順のため除く) App Runner の場合 サービス作成 ECS (Fargate) の場合 クラスター作成 タスク定義作成 サービス作成 最小構成のデプロイでこの差でしたが、Auto Scaling 等、もう少し設定を付加するとなればもっと違ってくるはずです。 (ECS だと CloudWatch アラーム + Auto Scaling の設定が必要です。) App Runner はサービス作成時に、一緒にぽちぽちっとするだけで Auto Scaling まで気軽に設定できるので楽ちんです。 (参考:サービス作成時 or 作成後に赤枠内で設定するだけ) また、ECR 上に新しいイメージがプッシュされた時にも、App Runner では CI/CD 構成を自分で用意せずとも設定項目一つで自動デプロイまで出来ちゃいます。 もちろん細かく要件に合わせた設定にするにはまだまだ ECS や k8s が適任かもしれませんが、少なくとも小〜中規模開発においては、まさに 「開発に集中」 を実現できるサービスだと実感しました。
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

API Gateway のアクセスログを取得してみた

はじめに 前回の記事では、API Gateway から直接 SQS に連携する方法を確認しました。Lambda を挟んでいない分シンプルになったメリットがありますが、Lambda 側でアクセスログを出すことが出来ません。そこで、API Gateway 側でアクセスログを出力することが出来ます。リクエストの Body などを含めた出力もできますので確認していきましょう。 API Gateway の IAM Role 設定 AWS アカウントの中で、リージョン単位で共有される CloudWatch Logs の出力に使う IAM Role の設定が必要です。 API Gateway 用の IAM Role を作成し、ARN を設定しておきます。 API Gateway でログ設定 API Gateway の Stage 上の設定で、[Logs/Tracing] のタブがあります。これで設定を有効にすることで、CloudWatch Logs にアクセスログを出力できます。 また、Method 単位でも有効化が可能です。 CloudWatch Logs の確認 上記の設定で CloudWatch Logs に出力する準備ができました。簡単ですね。実際に API Gateway にアクセスしてログを確認してみましょう。curl で API Gateway にアクセスします。 > curl -s -H 'Content-Type:application/json' \ -X POST \ https://uuy6eahto0.execute-api.ap-northeast-1.amazonaws.com/prod/sqs-queue \ -d '{"test1":"data1", "test2":"data2"}' | jq . { "SendMessageResponse": { "ResponseMetadata": { "RequestId": "73de415b-ace3-5f5d-9b2d-1b0eadf1aa21" }, "SendMessageResult": { "MD5OfMessageAttributes": null, "MD5OfMessageBody": "58fdfbfc48f868b6b9c50b3e8aa09894", "MD5OfMessageSystemAttributes": null, "MessageId": "8f194668-ad74-4207-b4c7-8b6bebdbf35b", "SequenceNumber": null } } } API Gateway の ID を調べます。 uuy6eahto0 CloudWatch Logs 上で ID を使って検索してみると、Log Group が引っかかるのでこれをクリックします。 適当に Log Stream を選択します。 API Gateway 上のアクセスログが出力されます。リソースのパスや、Request Body なども確認できます。 # この検証を通じてわかったこと API Gateway の CloudWatch Logs 用の Role は、リージョンで共有される Role となる。東京リージョンにある複数の API Gateway のうち、1個の API Gateway で設定すれば、他の API Gateway にも設定が反映される。 API Gateway の Request Body は、標準のアクセスログ出力機能で出力される。出力の仕方をカスタマイズしたい場合は、カスタムアクセスログの設定も可能
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

aws S3 互換ストレージ MinIO 入門 〜 mc.exe を試しに動かしてみる

S3 の aws コマンドの代わりとなる mc コマンドを試す MinIO は aws クラウドのストレージ S3 と互換性があるサービスですが aws のクラウドを使う必要はなく、自分のサーバーにインストールして簡易的な オブジェクト ストレージ(ファイル サーバー)を構築できます。 ここでは、S3 の aws コマンドの代わりとなる MinIO のクライアント mc を学習するための環境を Windows で簡単に作る方法を紹介します。たとえば、バケットを作成する aws mb コマンドに相当する mc mb コマンド を簡単に試すことができるようになります。ほかにも、mc ls コマンドで一覧することや mc cp コマンドでアップロード・ダウンロードをすることを試すことができます。こうして試すことで オブジェクト ストレージ が何なのかのイメージが付き、Docker やサーバーに配置された MinIO の詳細の学習もスムーズになります。 MinIO のサービスは、3台のサーバーに分散配置すると堅牢で高性能になりますが、ここでは簡単に導入するため Windows のローカル 1台に配置します。クライアントも同じ Windows のローカルで動かします。 なお、この記事は MinIO の公式 https://docs.min.io/docs/minio-client-quickstart-guide.html を参考にしています。 手順の構造化文章 あいまいな文章はいいから厳密な手順が知りたいという方のためにまずは typrm に対応した構造化文章(YAML)で示します。一般的な文章は後の章で示します。 設定: __FileName__: _a.txt __MinIO_Alias__: minioalias __BucketName__: bucket1 __MinIO_ConsolePort__: 60277 __MinIO_EndPoint__: http://localhost:9000 __MinIO_AccessKey__: minioadmin __MinIO_SecretKey__: minioadmin __MinIO_Folder__: ${env:USERPROFILE}\AppData\Roaming\MinIO #// USERPROFILE = C:\Users\____\ MinIO サーバーをインストールします: minio.exe をダウンロードします: #ref: https://dl.min.io/server/minio/release/windows-amd64/minio.exe ヘルプを表示します: (PowerShell): | & ${env:USERPROFILE}\Downloads\minio MinIO サーバーを起動します: (新しい PowerShell): | - mkdir ${env:USERPROFILE}\AppData\Roaming\MinIO #template: __MinIO_Folder__ - & ${env:USERPROFILE}\Downloads\minio server ${env:USERPROFILE}\AppData\Roaming\MinIO --console-address ":60277" #template: __MinIO_Folder__ --console-address ":__MinIO_ConsolePort__" ブラウザーで MinIO のコンソールを表示します: #keyword: MinIO console URL: http://localhost:60277 #template: __MinIO_ConsolePort__ Username: minioadmin #template: __MinIO_AccessKey__ Password: minioadmin #template: __MinIO_SecretKey__ ログを表示します: MinIO console >> Tools >> Logs MinIO クライアント mc.exe をインストールします: #keyword: install mc MinIO mc.exe をダウンロードします: #ref: https://dl.min.io/client/mc/release/windows-amd64/mc.exe ヘルプを表示します: (PowerShell): | & ${env:USERPROFILE}\Downloads\mc 公式: #ref: https://docs.min.io/minio/baremetal/reference/minio-cli/minio-mc.html エイリアスを新規作成します: (PowerShell): | & ${env:USERPROFILE}\Downloads\mc alias set minioalias http://localhost:9000 minioadmin minioadmin #template: mc alias set __MinIO_Alias__ __MinIO_EndPoint__ __MinIO_AccessKey__ __MinIO_SecretKey__ (書式): - mc alias set __Alias__ __EndPoint__ - mc alias set __MinIO_Alias__ __EndPoint__ __AccessKey__ __SecretKey__ --api __API_Signature__ __API_Signature__: --api オプションを省略した場合: S3v4 (パスワードなどを環境変数に設定する場合): export MC_HOST___Alias__=https://__AccessKey__:__SecretKey__@__EndPoint__ #ref: https://docs.min.io/docs/minio-client-complete-guide.html >> Specify temporary host configuration through environment variable 接続先の情報を表示します: (PowerShell): | & ${env:USERPROFILE}\Downloads\mc admin info minioalias #template: mc admin info __MinIO_Alias__ バケットを一覧します: #keyword: mc ls example (PowerShell): | & ${env:USERPROFILE}\Downloads\mc ls minioalias #template: mc ls __MinIO_Alias__ (参考)インターネットにあるお試しサイト https://play.min.io/ にアクセスする場合: | & ${env:USERPROFILE}\Downloads\mc ls play バケットを新規作成します: #keyword: mc mb example (PowerShell): | & ${env:USERPROFILE}\Downloads\mc mb minioalias/bucket1 & ${env:USERPROFILE}\Downloads\mc ls minioalias #template-at(-2): mc mb __MinIO_Alias__/__BucketName__ #template-at(-2): mc ls __MinIO_Alias__ ファイルをアップロードします: #keyword: mc cp example (PowerShell): | echo a > _a.txt #template: __FileName__ & ${env:USERPROFILE}\Downloads\mc cp _a.txt minioalias/bucket1 & ${env:USERPROFILE}\Downloads\mc ls minioalias/bucket1 #template-at(-2): mc cp __FileName__ __MinIO_Alias__/__BucketName__ #template-at(-2): mc ls __MinIO_Alias__/__BucketName__ rm _a.txt #template: __FileName__ 終了します: minio.exe が実行されているシェル >> Ctrl + C アンインストールします: minio.exe や mc.exe を削除します: (PowerShell): | rm ${env:USERPROFILE}\Downloads\minio.exe rm ${env:USERPROFILE}\Downloads\mc.exe minio.exe が使っていたフォルダーを削除します: (PowerShell): | rm -r -fo ${env:USERPROFILE}\mc rm -r -fo ${env:USERPROFILE}\AppData\Roaming\MinIO 手順 MinIO サーバーをインストールします https://dl.min.io/server/minio/release/windows-amd64/minio.exe をブラウザーのアドレスバーに入力して Enter を押し、minio.exe をダウンロードします。 なお、このアドレスは、MinIO の公式 https://docs.min.io/docs/minio-client-quickstart-guide.html の Windows 用の説明に書かれているアドレスです。安全のため、ダウンロードするときは、URL のドメインが .min.io であることを確認してください。 Windows のスタートを開き、PowerShell と入力して PowerShell を開き、下記のように入力します。 & ${env:USERPROFILE}\Downloads\minio 下記のようにヘルプが表示されればダウンロードは成功です。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\minio NAME: minio.exe - High Performance Object Storage DESCRIPTION: Build high performance data infrastructure for machine learning, analytics and application data workloads with MinIO USAGE: minio.exe [FLAGS] COMMAND [ARGS...] COMMANDS: server start object storage server gateway start object storage gateway FLAGS: --certs-dir value, -S value path to certs directory (default: "C:\\Users\\ts-ne\\.minio\\certs") --quiet disable startup information --anonymous hide sensitive information from logging --json output server logs and startup information in json format --help, -h show help --version, -v print the version VERSION: RELEASE.2022-01-08T03-11-54Z MinIO サーバーを起動します 新しい PowerShell を開き、下記のように入力します。Windows Defender によるセキュリティの確認が表示されたら、許可してください。 mkdir ${env:USERPROFILE}\AppData\Roaming\MinIO & ${env:USERPROFILE}\Downloads\minio server ${env:USERPROFILE}\AppData\Roaming\MinIO --console-address ":60277" 下記のように表示されればサーバーの起動は成功です。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\minio server ${env:USERPROFILE}\AppData\Roaming\MinIO --console-address ":60277" API: http://192.168.2.110:9000 http://127.0.0.1:9000 RootUser: minioadmin RootPass: minioadmin Console: http://192.168.2.110:60277 http://127.0.0.1:60277 RootUser: minioadmin RootPass: minioadmin Command-line: https://docs.min.io/docs/minio-client-quickstart-guide $ mc.exe alias set myminio http://192.168.2.110:9000 minioadmin minioadmin Documentation: https://docs.min.io WARNING: Detected default credentials 'minioadmin:minioadmin', we recommend that you change these values with 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD' environment variables ブラウザーで MinIO のコンソールを表示します ブラウザーで http://localhost:60277 を開きます。 Username にはサーバー起動時に表示される RootUser、つまり minioadmin を入力します。 Password にはサーバー起動時に表示される RootPass、つまり minioadmin を入力します。 ログインしたらダッシュボードが表示されます。 Tools メニューの Logs を選ぶと、ログが表示されます。 MinIO クライアント mc.exe をインストールします https://dl.min.io/client/mc/release/windows-amd64/mc.exe をブラウザーのアドレスバーに入力して Enter を押し、minio.exe をダウンロードします。なお、このアドレスは、MinIO の公式 https://docs.min.io/docs/minio-client-quickstart-guide.html の Windows 用の説明に書かれているアドレスです。安全のため、ダウンロードするときは、URL のドメインが .min.io であることを確認してください。 PowerShell で下記のように入力します。 & ${env:USERPROFILE}\Downloads\mc 下記のようにヘルプが表示されればダウンロードは成功です。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc mc.exe: Configuration written to `C:\Users\____\mc\config.json`. Please update your access credentials. mc.exe: Successfully created `C:\Users\____\mc\share`. mc.exe: Initialized share uploads `C:\Users\____\mc\share\uploads.json` file. mc.exe: Initialized share downloads `C:\Users\____\mc\share\downloads.json` file. NAME: mc - MinIO Client for cloud storage and filesystems. USAGE: mc [FLAGS] COMMAND [COMMAND FLAGS | -h] [ARGUMENTS...] COMMANDS: alias set, remove and list aliases in configuration file ls list buckets and objects mb make a bucket rb remove a bucket cp copy objects mirror synchronize object(s) to a remote site cat display object contents head display first 'n' lines of an object pipe stream STDIN to an object share generate URL for temporary access to an object find search for objects sql run sql queries on objects stat show object metadata mv move objects tree list buckets and objects in a tree format du summarize disk usage recursively retention set retention for object(s) legalhold manage legal hold for object(s) diff list differences in object name, size, and date between two buckets rm remove object(s) version manage bucket versioning ilm manage bucket lifecycle encrypt manage bucket encryption config event manage object notifications watch listen for object notification events undo undo PUT/DELETE operations anonymous manage anonymous access to buckets and objects tag manage tags for bucket and object(s) replicate configure server side bucket replication admin manage MinIO servers update update mc to latest release GLOBAL FLAGS: --autocompletion install auto-completion for your shell --config-dir value, -C value path to configuration folder (default: "C:\\Users\\____\\mc") --quiet, -q disable progress bar display --no-color disable color theme --json enable JSON lines formatted output --debug enable debug output --insecure disable SSL certificate verification --help, -h show help --version, -v print the version TIP: Use 'mc --autocompletion' to enable shell autocompletion VERSION: RELEASE.2022-01-07T06-01-38Z エイリアスを新規作成します エイリアスとは、特定の MinIO サーバーにログインするための情報と関連づけられた MinIO の変数です。MinIO サービスの名前に相当します。mc コマンドから操作対象の MinIO サービスを指定するときにエイリアスを指定します。 PowerShell で下記のように入力します。minioalias という名前でエイリアスを設定しています。 & ${env:USERPROFILE}\Downloads\mc alias set minioalias http://localhost:9000 minioadmin minioadmin パラメーターの意味は下記の通りです。 mc alias set __MinIO_Alias__ __MinIO_EndPoint__ __MinIO_AccessKey__ __MinIO_SecretKey__ 接続先の情報を表示します 接続先がどこにあるのか、接続先が生きているのかを確認します。 PowerShell で下記のように入力します。minioalias の部分は表示対象のエイリアスです。 & ${env:USERPROFILE}\Downloads\mc admin info minioalias たとえば下記のように表示されます。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc admin info minioalias ● localhost:9000 Uptime: 38 minutes Version: 2022-01-08T03:11:54Z Network: 1/1 OK バケットを新規作成して一覧します バケットを新規作成するには、PowerShell で下記のように入力します。 & ${env:USERPROFILE}\Downloads\mc mb minioalias/bucket1 バケットを一覧するには、PowerShell で下記のように入力します。 & ${env:USERPROFILE}\Downloads\mc ls minioalias たとえば下記のように表示されます。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc mb minioalias/bucket1 Bucket created successfully `minioalias/bucket1`. PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc ls minioalias [2022-01-09 22:43:56 JST] 0B bucket1/ ファイルをアップロードします PowerShell で下記のように入力します。 echo a > _a.txt #// アップロードするファイルを用意します & ${env:USERPROFILE}\Downloads\mc cp _a.txt minioalias/bucket1 rm _a.txt #// アップロードしたのでローカルのファイルを削除します & ${env:USERPROFILE}\Downloads\mc ls minioalias/bucket1 たとえば下記のように表示されます。 PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc mb minioalias/bucket1 Bucket created successfully `minioalias/bucket1`. PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc ls minioalias [2022-01-09 22:43:56 JST] 0B bucket1/ PS C:\Users\____> echo a > _a.txt #// アップロードするファイルを用意します PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc cp _a.txt minioalias/bucket1 _a.txt: 8 B / 8 B [==========================================================================] 843 B/s 0s PS C:\Users\____> rm _a.txt #// アップロードしたのでローカルのファイルを削除します PS C:\Users\____> & ${env:USERPROFILE}\Downloads\mc ls minioalias/bucket1 [2022-01-09 22:46:52 JST] 8B _a.txt MinIO コンソールには下記のように表示されます。 Browse ボタン(右上)を押すと、バケットの中のオブジェクト(ファイル)の一覧を表示できます。 コマンドのドキュメント コマンドの公式ドキュメントは下記にあります。下記のリンク先の 7. Commands に一覧があります。 終了とアンインストール MinIO サービスを終了します minio.exe が実行されているシェルで Ctrl + C を押します。 MinIO や mc をアンインストールします PowerShell で下記のように入力します。 rm ${env:USERPROFILE}\Downloads\minio.exe rm ${env:USERPROFILE}\Downloads\mc.exe minio.exe が使っていたフォルダーを削除します: PowerShell で下記のように入力します。 rm -r -fo ${env:USERPROFILE}\mc rm -r -fo ${env:USERPROFILE}\AppData\Roaming\MinIO
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む