Screaming Loud

日々是精進

既存のEKSクラスタにFargate for EKS でAPI作成する際の導入でハマったところ

既存のEKSクラスタにterraformでFargateのPodを導入する際に、ハマったところを紹介します。

TL;DR

クラスタセキュリティグループ の設定を見直しましょう。

f:id:yuutookun:20210110003437p:plain
クラスタセキュリティグループ

mapRoleへの付与漏れ

Farage導入においては以下の記事がわかりやすいのですが、書いてあるとおりfargate profileを生成すると自動でmapRoleに pod execution roleが入ります。

tech.recruit-mp.co.jp

しかし、terraformで導入していてmapRoleもterraformで管理していると、

  1. terraformでfargate profileを作成
  2. aws側がmapRoleにpod execution roleの権限を追加
  3. terraformに記載されているmapRoleで上書き

となってしまい、mapRoleが消えてしまいます。

この事象が発生しているかは、 $ kubectl get eventUnauthorized 的な文言が出ているとmapRoleの付与漏れです。

fargate Podが起動しない

Podは作成されるけれど、以下のようなログを吐きfargateのノードが立ち上がらない問題が発生しました。 $ kubectl describe pod xxx のEventsで吐かれていました。

 Warning  FailedScheduling  55m   fargate-scheduler  Pod provisioning timed out (will retry) for pod

AWSのサポートに問い合わせてコントロールプレーン側のログを見てもらっても何も出ていませんでした。

結果としては、クラスタセキュリティグループのアウトバウンドがなぜか消えていたからでした。

fargateのノードはクラスタセキュリティグループがノードのセキュリティグループとして評価されるので、これのインバウンドとアウトバウンドはしっかり設定する必要があります。

EKS生成時に作られるクラスタセキュリティグループに対しては最低でも以下を許可する必要があります terraformで記載します

  ingress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    self        = true
  }
  egress {
    from_port   = 0
    to_port     = 0
    protocol    = "-1"
    cidr_blocks = ["0.0.0.0/0"]
  }

クラスタセキュリティグループ

上の節でも紹介しましたが、fargateはクラスタセキュリティグループがノード(Pod)のセキュリティグループとして評価されます。 なので、ALBなどからつなぐにはクラスタセキュリティグループに対してALBのセキュリティグループを許可する必要があります。

EKSのネットワーク設定にある追加のセキュリティグループに設定されていても、そこはfargateでは評価されないので注意が必要です。

他にもクラスタ上の別のノードと通信するためにはfargateのクラスタセキュリティグループを許可させるために付与する必要があります。

kube-systemなど各ノードに散らばりがちなpodに対して通信するためには、クラスタセキュリティグループは全ノードに付与しておいたほうがおすすめです。

またfargateのpodを運用する場合、色々なセキュリティグループを随時許可する必要が出ると思うので、 terraformで運用する場合はクラスタセキュリティグループを terraform import しておいたほうがいいでしょう。

まとめ

fargateでのハマりどころは、ほぼ クラスタセキュリティグループ と言っていいかもしれません。 そこさえ気をつければ、他のハマりどころは少ないと思います。

could not query provider registry for registry.terraform.io でterraformのproviderがダウンロードできない問題の対処

現象

localのMacでterraform initした際に以下の様なエラーが発生して providerがダウンロードできなくなりました。

Error: Failed to query available provider packages
Could not retrieve the list of available versions for provider hashicorp/aws:
could not query provider registry for registry.terraform.io/hashicorp/aws: the
request failed after 2 attempts, please try again later: Get
"https://registry.terraform.io/v1/providers/hashicorp/aws/versions": net/http:
request canceled while waiting for connection (Client.Timeout exceeded while
awaiting headers)

これ別にaws providerに限った話ではなく、 datadogとかrandomとか全てで発生します

initは通常 .terraform 配下のキャッシュを見ているので required_provider にマッチしていれば、ダウンロード自体が発生しないのでproviderアップデートのときですね

環境は以下です

  • macOS Catalina
  • tfenvによるterraform管理
  • terraform v0.13.2

providerの指定はこんな感じ

 required_providers {
    aws = {
      source  = "hashicorp/aws"
      version = ">= 3.0"
    }
    datadog = {
      source  = "datadog/datadog"
      version = "= 2.12.1"
    }
  }

原因

ここに書いてある通りです。

github.com

/etc/resolve.conf に存在しないnameserverを書いている場合、cgoを許可しないとDNS解決がGoでうまくいかないっぽいです。

解決法

以下のどちらかを実施すれば直ります

  • ネットワーク設定から存在しないDNSサーバのIPを消す
  • terraformをソースからビルドする。その際 $ CGO_ENABLED=1 go build -ldflags "-s -w" -o tf でcgoを許可してビルドする

でした。 変なところでハマってしまいました。

2020年読んだ本まとめ

2020年に読んだ本は22冊でした。

f:id:yuutookun:20210103212517p:plain
読書メーターのstats

mocyutoさんの2020年読書まとめ - 読書メーター

今まで通勤中に結構読んでたのですが、2020年はリモートワークで読む時間が減って読む量が減った気がします。 ただ、実際カウントしてみると2019年と1冊差でしたね。

個別ピックアップ

以下は読んだ本のピックアップです。

これとかは意外に知らなかった歴史の背景などが知ることができたので面白かったですね。

bookmeter.com

あとは話題になった本です。 とりあえず読んだことがないのであれば、さらっと読んでみてもいいかもしれないですねー

bookmeter.com

こちらをきっかけに The Last of Us というゲームをやるに至りました。

bookmeter.com

去年のまとめ

yuutookun.hatenablog.com

GitHub Actionでtagを打った際にgit-pr-releaseみたいなリリースノートを作る

今年はコロナで出かけていないので、ちょっとGitHub Actionいじってます。

やりたいこと

タイトル通りですが、やりたいことは「GitHub Actionでタグを打ったときに、git-pr-releaseみたいな前のタグからのPRのリストをリリースノートに乗せたい」です。

f:id:yuutookun:20210102163926p:plain
実際の自動で生成したリリースノート

やりかた

これを実施するにあたり、git-pr-releaseと違ってメインブランチとサブブランチを決めてそのPRを取るという手法が使えないので以下のようにする必要があります

  • 前のタグからの今のタグへの全コミット取得
  • PRのコミット取得
  • 対象のPRを取得
  • リリースノートに反映

前のタグからの今のタグへの全コミット取得

これはGitHubAPIからは取れなかったので、Git操作で取得します。 git log を使えば、あるタグから別のタグまでのコミットログを取れます。 また通常のログだといろいろな情報が乗ってくるので、formatしてあげて必要な情報に絞る必要があります。 今回はコミットハッシュだけがほしいので %H だけを使います。 コマンドで示すと以下です。

$ git log v0.10.0...v0.10.1 --pretty=format:"%H"

それとは別にtag一覧を取って、最新と一つ前を取る必要があります。 sortを使うとタグのバージョンを考慮してsortしてくれるので使わない手はありません。 コマンドでは以下になります。

$ git tag  --sort=-v:refname

これのsortでは v0.1.0. v0.8.0, v0.10.0 をちゃんと並べてくれます

これをGitHubActionでやる必要があるので、実施には actions/github-script@v3 を使います. github-scriptを使うとjsで操作を記述できる上に、GitHub APIが簡単に叩けます。

では特定タグ間のコミットログのハッシュ取得部分です。 jsの simple-git というライブラリを使ってGit操作を行っています。

const simpleGit = require('simple-git');
const git = simpleGit(path); // pathは操作するリポジトリの絶対パス
const logs = await git.tags({ '--sort': '-v:refname' })
    .then((t) => {
        const tags = t.all.slice(0, 2);
        return git.log({ 'from': tags[0], 'to': tags[1] })
    });

slice(0,2) と指定しているのは、sortされているので最新とその次を取るためです。 (一番最初のタグのときは考慮してないので、もしやる場合は考慮させましょう)

PRのコミットを取得

ここに関してはGitHub APIを叩いて取得します。

    const { data } = await github.pulls.list({
        owner: 'mocyuto',
        repo: 'ec2-search',
        base: 'master',
        state: 'closed',
    })

これだけでmasterに向けたmege済みのPRを取得できます。

他にも操作する場合は、以下のoctokitのページを見るといろいろわかります。 localで試したい場合は、以下を参考に試してみるといいと思います。 localの場合は octokit を使い、github-scriptの中では github を使えば動きます。

octokit.github.io

あとはjsでfilterするだけです。

リリースノートに反映

自分は action-gh-release を使っていたので、これをベースに説明します。

ほぼREADMEに書いてあることを実施すればいいのですが、一点リリースノートを追記する際、 bodyを記載した際は追記になるので、matrixで複数リリースノートへ書き込みを行うと同じ文言がmatrix分だけ乗ってしまいます。

ですので、matrixを利用している場合はjobをわけたほうがよいです。

実際のソースコード

以下がワークフローの記述部分です simpe-git を使うためにnpm installしています。 あとactions/checkout@v2 はデフォルトでdepth=1なので0を指定して全部取ってきましょう。

https://github.com/mocyuto/ec2-search/blob/v0.10.1/.github/workflows/release.yml#L77-L99

そして、呼び出しているスクリプトは以下です。

https://github.com/mocyuto/ec2-search/blob/v0.10.1/.github/script/prs.js

まとめ

最初は割と面倒かなと思ったのですが、github-scriptとsimple-gitのおかげでラップしてくれたので、以外に簡単にできました。 tag打ちのときの面倒の手助けになれば。