ECS(Fargate) デプロイ
ECS(Fargate) デプロイする流れ
アプリ構成としては Go, PostgreSql,Nginx
全体の流れ
*当初はdocker composeで本番環境を構築しようとしていたが、開発環境と本番環境は別物であると気づいた。開発と全く同じ環境を本番へと適用するわけではないので(dbはコンテナを使わずrdsを使う等)、あとdocker composeでやると勝手に作成されてしまうため、何が作られているのかよく分からないと思う。
そのため本番環境はdocker composeで作成せず、aws内で一つずつ作成していく形にする。
#メモ
・ECRにimageを上げ直した場合サービスを更新してデプロイの強制することで変更を反映(サービスの更新しなくても時間差で反映されるのかは分からないけど、こっちの方が確実)
・サービス内のタスクのログが見たい場合、タスクのページに行ってコンテナのタブをクリックすると色々表示されてCloudWatch のログを表示ってのが出るのでそっちいくとcloud watchのログ見れる。タスクのページにもログはあるが、こっちの方が反映は遅いし、cloud watchのほうがいい。ちなみにこの時クラスター作成時にcloud watchをオンにはしてなかったんだけど(お金かかるため)cloud watch使えた。課金してたら何か違いがあるのかは分からない。
#
・ECRにimageを上げる。
まず、それぞれのコンテナで使うimageをbuildする必要がある。
このimageを開発環境とは違うので本番用のimageを作成する。
またdocker-composeで作成するのではなく、一つずつDockerfile(本番用)からimageをbuildすることにした。
!!!!!超重要。m1 mac使用している場合はECRにimageを上げる時のimageは--platform amd64を指定すること。!!!!!!
今回、docker-composeはあくまで開発用という扱い。本番用のdocker-composeは存在しない。
またdbに関してはコンテナ運用するよりdbだけはコンテナと切り離して使用した方がいいらしい。(Elastic File System(efs)でvolumeを作るのも考えたけど、efsはdbにはあまり向かない?まぁRDSを使った方がいいのは確実だと思う)dbはRDSを使用するため、コンテナ使用しないのでECRに必要ない。そのため今回この作業で必要なのはGoとNginxだけ。
コマンド(ECR行ってpushコマンドを確認。手順2はしなくていい。)
1 ログイン
この時ログインできないことある。
下のようなエラー出た場合(AWS ACCESS KEYとAWS ACCESS SECRET KEYが正しくない)は以下のurl参照。
when calling the GetAuthorizationToken operation: The security token included in the request is invalid.
Error: Cannot perform an interactive login from a non TTY device
(https://qiita.com/kaito_program/items/7b9ba489e44d2295cf6f)
*ターミナルを閉じると効果が切れるらしいのでその時はまた同じ設定する感じ。効果永続できるようにしたいが自分はわかってない。
*ECR以外でもこのエラーが出る可能性は高いと思うので、他のとこでも参考にしてほしい。
2 imageをbuild(最初に上でやった工程なので既にやっていればしなくていい)
3タグ付け
(例)docker tag *go-nginx-production*:latest XXXYYYZZZ.dkr.ecr.ap-northeast-1.amazonaws.com/go-nginx-ecr:latest
**で囲んだ場所に関してはbuildしたimageの名前に変更すること。
今回の場合はbuildしたimage(go-nginx-production)とecrのimage(go-nginx-ecr)が異なるので、commandを修正している。同じなら修正しなくていい。
4 push これはcommandそのまま打つだけ
以上でECRにimageを上げるのは終了
---------------------------------------------------------------------
以降使うセキュリティグループ
go ...カスタムTCP port3000
nginx ...HTTP, HTTPS (ALBで使用)
postgresql(RDS) ... PostgreSql
---------------------------------------------------------------------
* 以降使うvpcは全て一緒にすること。ない場合は作成しとく。
・ クラスター作成
・タスク定義作成(goとnginx用それぞれ作成)
それぞれにコンテナを記述。コンテナimageはECRのurlをクリックして貼り付ける。
・サービス作成(goとnginx用それぞれ作成)
・それぞれ先ほど作ったタスク定義を割り当てる。
・サービス間の連携を行う場合、サービスの検出をオンにする。(サービスディスカバリ)。名前空間を設定してサービスを共通グループで囲み。サービス名をそれぞれ設定。これでそれぞれのサービスが繋がることできた(nginxのnginx.confにてproxy_pathにサービス名(go).名前空間とすることでgoのurlにいってる)
nginx.confにまだサービス名.名前空間を反映してない場合は変更してimage(本番用)をbuildし直し、再度ECRへupする動作を行う。
・この段階では、ALB(Nginxだけ)とAuto Scalingの設定はしない。ALBの設定に関してはサービス作成時でないといけないので、nginxサービスに関しては後で作り直す。
-------------------------------------------------------------------
RDS(PostgreSql)
dbはコンテナじゃなくてRDS使う。値段高いのが痛い。
作成し終えたらrdsのurl生まれるのでgoのpostgres接続のhostにこのurlを当てる。
imageに反映されてなかったら再度build ecrにup
---------------------------------------------------------------
ALB(Application Load Balancer)
--------------------------------------
*設定前の準備
独自ドメイン取得。
ACM(Aws Certificate Manager)で証明書発行
-----------------------------------
・まずはターゲットグループ作成(EC2に行ったらある)。
Ip address選択
HTTP port 80
protocol version Http1
*healthy checkのpathはアクセスできるpath(postやログイン必要なパスはunhealthy返ってくるのでNG)自分の場合はそういうpathなかったので、goでjsonでmessageを返すだけのpathを作ることにしてそれをhealthy checkのpathとした。
IPv4 addressはいじらなくておk(最後の1桁を勝手に決めてくれる設定)
---------------------------------------------------------
・ロードバランサー作成
Application Load Balancer選択
vpc選択してmappingしとく。
セキュリティーグループは上のサービスのnginxと同じに(HTTP,HTTPS)
Listner and RoutingにはHTTPとHTTPSを設定する(それぞれ先ほど作ったターゲットグループ付与)
Default SSLCertificateはACMで発行した証明書設定
以上でALB作成完了。
---------------------------------------------
・サービスとALB紐付ける
ALB設定はサービス開始時じゃないと行えないため先ほど作成したnginxサービスを削除、再度作成することにする。
ロードバランサーの設定に行ったら、Application Load Balancer選択、先ほど作成したALB名選択。
ロードバランス用のコンテナでロードバランサーに追加ボタンを押す。
プロダクションリスナーポートはHTTPS
ターゲットグループに先ほどロードバランサー作成時に作ったターゲットグループを設定(この時プロダクションリスナーポートが自動でHTTPになるけど、先ほどHTTPSとした意味はあったのか不明、元からHTTPでもいいと思うが・・・動きはする)
・Auto Scaling
Auto scalingの設定は簡単。サービスの更新で最後にauto scaling設定してあげればいい。
・独自ドメインとALBを紐づける
Route53で独自ドメインのホストゾーンに。レコードの作成クリック。
レコード名はからで。
エイリアスをオンにしてそこでロードバランサーを選択してレコード作成すればおk
これにて終了