dogwood008の開発メモ!

最近のマイブームは機械学習, Ruby on Rails。中でも機械学習を使った金融商品の自動取引に興味があります。

【EKS】502が出る原因の一つ:ACMの証明書のARNが間違い

要旨

AWS Load Balancer Controller で指定するACMのARNが誤っていると、構成によっては502が返る。

これは、ALBのホスト名に対し直接httpsで繋ぎに行くと、ブラウザのアドレスバーからたどれる証明書を見ることで確認できる。

背景

Route 53 + WAF + CloudFront + ALB + EKSという構成でアプリケーションをホストしていたところ、あらゆるPathで502が表示され、その原因がわからないということがあった。

AWS公式で、502の対処方法が書かれているが、今回の原因は該当するものが無く解決に苦戦したので、誰かの役に立てばと思いその記録をしておくものである。

aws.amazon.com

用語

  • Route 53 ... AWSのDNS
  • WAF ... Web Application Firewall
  • CloudFront , CF ... CloudFront AWSのCDN
  • ALB ... Application Load Balancer
  • EKS ... Amazon EKS (Elastic Kubernetes Service)
  • ACM ... AWS Certification Manager
  • ARN ... Amazon Resource Name

詳細

実際に502が出ていたのは、Route 53 でレコードが割り当てられているホスト名に対し、httpsで接続しに行った時である。例えば、test.example.com に対し、203.0.113.1 が割り振られているとき、 https://test.example.com にアクセスした際に502がレスポンスとして返る、という状況である。

なお、Route 53では test.example.com から CF に対して Alias A & AAAA レコードが張ってある。また、 CF からはオリジンとして ALB を参照するようになっていた。ALBの後ろにはEKSが居て、サブドメインを見ながら到達させるPodをKubernetesが判断する、という構成になっていた。

詳しくは覚えていないが、https://test.example.com にブラウザでアクセスした際に表示された502は、ALBではなくCFが返していたように記憶している。つまり、CFとオリジン(=ALB)間で、不都合な通信が行われていたということが推測できる。

ここから、動作確認のため、 CFではなくALBが発行するホスト名(下図, albname-012.AWS_REGION.elb.amazonaws.com)に対し、httpsで接続した。この時、ブラウザはGoogle Chromeを使用していたので、アドレスバーから割り当てられている証明書を確認することができた。表示された証明書は *.cloudfront.net ではなく、ACMで発行したものであった。ここで気付いたのが、*.example.com のものを期待していたのに、例えば *.debug.example.com のように、本来期待していたものと異なる証明書が表示されていた。

ALBに割り当てられたホスト名
ALBに割り当てられたホスト名

ここでAWS Load Balancer Controller の Ingress を確認してみると、 metadata.annotations の項目の、 alb.ingress.kubernetes.io/certificate-arn で指定するARNが本来設定しないといけないものと異なっていたことがわかった。

その後、正しいARNを設定したところ、期待動作をするようになった。つまり、Route 53からCFに割り当てたホスト名 test.example.com でhttpsでリクエストすると、正常系のレスポンスが返るようになった。