RailsアプリをEKS on Fargateで構築する際に調べた事まとめ
Railsアプリを公開するには
EKS on Fargate構築では、AWS Load Balancer Controllerを使用することでアプリを公開することができるが、以下のようなデメリットが存在する。
- クラスタの再構築時にコントローラー等の設定を再度する必要がある。
- Terraformを使ってAWS Load Balancer Controllerを構築することができない。
クラスタを再構築しないのであれば問題ないかもしれないですが、やや気になるポイントだと思います。
ノードグループを作成する
本来であればノードは全てFargateに任せたいところですが、今回はCoreDNSデプロイメントの設定変更を回避するために、一部ノードグループを作成しました。
CoreDNSとは、EKSクラスターのDNSサーバー(kubernetes推奨)。
coreDNSに問題があると、DNSが500エラーコードを返すこともある。
※ノードグループを用意したくない場合は、EKSクラスターを構築したあとに、以下のコマンドを打てばCoreDNSをFargateのみで使えます。
kubectl patch deployment coredns \
-n kube-system \
--type json \
-p='[{"op": "remove", "path": "/spec/template/metadata/annotations/eks.amazonaws.com~1compute-type"}]'
kubectl rollout restart -n kube-system deployments/coredns
RDSの設定
RDSの環境変数
apiVersion: v1
kind: ConfigMap
metadata:
name: rails-environent
data:
RAILS_ENV: production
APP_DATABASE_DATABASE: ✳︎✳︎✳︎_production
RAILS_SERVE_STATIC_FILES: "true"
APP_DATABASE_HOST: terraform-✳︎✳︎✳︎✳︎✳︎✳︎✳︎.ap-northeast-1.rds.amazonaws.com #毎回値が変わるのでAWSで確認
APP_DATABASE_USERNAME: admin
APP_DATABASE_PASSWORD: ✳︎✳︎✳︎✳︎✳︎✳︎✳︎✳︎
RAILS_SERVE_STATIC_FILESをtrueにすることで、rails assets:precompileでpublicフォルダから静的ファイルの提供が行われるようになります。
Railsアプリのconfig/environment/production.rb内に以下のようなコードがあり、RAILS_SERVE_STATIC_FILESの値を使用しています。
config.public_file_server.enabled = ENV["RAILS_SERVE_STATIC_FILES"].present?
OICDプロバイダー
EKSでは、pod単位でserviceaccountをIAMを割り当てることが出来る。
その際に、OICDプロバイダーが必要になるので設定が必要。
※OICDプロバイダー=なりすまし防止の認証機能のようなもの。
実際に生じたエラーと解決策まとめ
僕がRailsアプリをEKS on Fargate環境にデプロイする際に、実際に生じたエラーとその解決策を以下にまとめます。
RailsコンテナがCrashLoopBackOffのまま立ち上がらない
原因が不明なのでログを出力して探る。
kubectl describe pod <ポッド名>
kubectl logs <ポッド名>
クラッシュする前のpodのログをみるには、--previousオプションを指定する。
kubectl logs --previous <ポッド名>
webidentityerrエラーでALBが作成されない
Ingressのapply後に、本来ならALBが作成されるハズなので、下記コマンドで確認するけれどALBが作成されない問題。
kubectl get ingress
NAME/CLASS/HOSTは表示されるが、ADDRESSの部分が空欄になっているので、ALBが作成されていないことが分かる。
NAME CLASS HOSTS ADDRESS PORTS AGE
alb-lb alb-ingress-class eks.mydogfoodnavi.com 80 19s
原因がわからないので、とりあえずログを確認することに。
まずは、$ kubectl get podでAWSロードバランサーコントローラーのpod名を調べる。
続いて、$ kubectl logs でログを出力すると、以下のような怪しい文章を発見。
{"level":"error","ts":✳︎✳︎✳︎✳︎✳︎✳︎,"logger":"controller-runtime.manager.controller.ingress","msg":"Reconciler error","name":"alb-lb","namespace":"default","error":"WebIdentityErr: failed to retrieve credentials\ncaused by: AccessDenied: Not authorized to perform sts:AssumeRoleWithWebIdentity\n\tstatus code: 403, request id: ✳︎✳︎✳︎✳︎✳︎✳︎"}
WebIdentityErrが何なのか分からないのでググってみると、以下のような原因が考えられることが判明。
- サービスアカウントの設定ミス。
- IAMロールの信頼関係の設定ミス。
自分の場合は、terraformのコードが間違っていて、正しくIAMロールを設定できていなかったので修正したら治りました。