44smkn Bi-Week in Review - December 26, 2022
AWS Week in ReviewとSRE Weekly読んでて、自分の備忘録用のメモもこんな感じにまとまっていると良いだろうかと思い、試してみることにしました
44smkn Week in Review - November 14, 2022 - 1クール続けるブログ 1週間に1回こうやって振り返る機会を設けるのが理想なので、来週はちゃんと1週間に1回のペースに戻したいところ。
今週は、初めて奈良に行ってきたけど凄く良かった。お寺は仏教に関する解像度が上がると楽しくなる。
「法相宗の本尊は唯識曼荼羅もしくは弥勒菩薩のはずだった気がするけど、なんで興福寺は釈迦如来なんだろう?」みたいな疑問を持ちつつ見るのが良い。
天はインド(バラモン教?)の神様が仏教に帰依した姿と知って仏像を見るのが楽しくなった。仏じゃないから仏像とは言わないのかな。
天は六道で言うところの天道にいて、悟りを得たわけではないので輪廻転生するらしい。
2,3 冊しか仏教に関連する本は読んでないので、もうちょっと読んで知識を付けたい。
そういえば、なんであんなにカジュアルに鹿いたんだろう…。
鹿と鹿の糞を避けるのに必死で、あんまりちゃんと南大門を見れなかった気がする。
- Article
- Amazon EKS add-ons: Advanced configuration - AWS
- 見せてやるよ、EventBridge の本気ってやつをな / The art of EventBridge - speakerdeck
- Kubernetes v1.26: Electrifying - kubernetes.io
- ChatGPT: Smart, but Not Smart Enough - New Stack
- HashiCorp Consul Introduces New Sidecar Model for Kubernetes Deployments - InfoQ
- [レポート] Amazon EKS の最新情報とロードマップ #CON205 #reinvent - クラスメソッド
- Book
Article
Amazon EKS add-ons: Advanced configuration - AWS
CNIとかkube-proxyの管理ってArgoCDでやるべきなのか EKS Add-ons でやるべきなのか悩む部分があり、特にEKS Add-onsは公式サポートなので安心感があるものの、環境変数などの設定がterraformのコード等で管理できないのが微妙だなと思っていました。
このアップデートによりEKS Add-onsの詳細な設定がterraformで管理できるようになったようです 👏
terraformで詳細な設定を行うためのinput parameter:
https://registry.terraform.io/providers/hashicorp/aws/4.48.0/docs/resources/eks_addon#configuration_values
見せてやるよ、EventBridge の本気ってやつをな / The art of EventBridge - speakerdeck
EventBridgeの設計の方向性が網羅されていたのが良かったし、Schema周りのサポートにこんなに力を入れているのは知らなかった。
AWSのeventを拾って何かを処理を動かすというのはやったことがあり既に良さを感じている部分ではあるが、自前でスキーマを定義して各サービスの連携に利用するというのにも良いのではないかと思った。
EventBridgeでなにか困ったらここに戻ってこようと思える綺麗でまとまった資料。ありがたい…!
Kubernetes v1.26: Electrifying - kubernetes.io
Kubernetesのv1.26がリリースされましたね。
自分が気になるところで言うとこの辺ですかね。
- CEL in Admission Control graduates to alpha
- KEP-3488: CEL for Admission Control
- validating admissionでwebhookの大体手段をCELを利用して提供する
- Job tracking without lingering Pods
- KEP-2307: Job tracking without lingering Pods
- v1.23にBetaになったのでv1.23から使えるみたい(v1.24からBetaはデフォルトで有効化されてないので)
- podの存在に依存せずにJobの実行ステータスを更新するらしい
- 一瞬便利かもと思ったが大規模なジョブのときしか困らないかもしれない
- Dynamic Resource Allocation graduates to alpha
- cpu / memory 以外に必要とするリソースを要求できるのかな(例えばgpuとか)
ChatGPT: Smart, but Not Smart Enough - New Stack
Temporary policy: ChatGPT is banned にあるように、StackOverflowは、ChatGPTの正答率が低いことを理由に、ChatGPTで作成された回答の流入を減速させるため、一時的にChatGPTを禁止しているとのこと。
今のところは、プログラミングにおいてChatGPTに依存してはいけない。現実のコーディングや安全なプログラミングには十分ではないとのことだった。
HashiCorp Consul Introduces New Sidecar Model for Kubernetes Deployments - InfoQ
HashiCorpのConsulをkubernetes上にデプロイする際に、Consulクライアントエージェントをインストールするのではなくsidecarの injectになったみたい。
こちら調べたときに、 日本でも今年の11月くらいから、HCP Consulの提供が始まっていることを知りました。
control planeのお世話をしたくない人たちにとっては、Service Meshの一つの選択肢になりそう。
強みとしては、AppMeshと同じようにk8sクラスタ以外のECSやEC2に関しても統合できる点かなと思います。
(まあでも、k8sだけを考えたらIstioに乗っかるのが一番な気もする…)
[レポート] Amazon EKS の最新情報とロードマップ #CON205 #reinvent - クラスメソッド
動画: https://youtu.be/4TXZQg-WW4o
気になった今後のリリースで来るだろうもの
- IAM cluster access management
- status:
Coming Soom
- 現在のConfigMapによる管理はbrittle(脆い)であるため、EKS APIで認証認可の機能を代替する
- status:
- Simplified IAM Roles for Service Account
- Support for Amazon VPC Lattice
- status:
New at re:Invent
- なんとここでKubernetes Gateway APIが利用されているとは
- status:
- Managed Karpenter
- status:
Working on it
- EKSからより使いやすいようにしたい(karpenterをデプロイするためにはまずノードが必要という鶏卵問題が発生するので)
- status:
既に実装済のものではあったけど、2022年にclusterのscaleを強化したという話は凄く嬉しかった。 あと、 karpenterにnativeのnode termination handlingが追加されているとはね。
Book
再読 - 別冊NHK100分de名著 集中講義 大乗仏教 こうしてブッダの教えは変容した
真言宗の総本山である東寺と華厳経の世界観を表した奈良の東大寺に行くにあたり、初期仏教と般若経、法華経、華厳経の概要や違いを説明しているこの本を読み返さねばと思って再び手に取りました。
般若経の「前世にブッダと出会い誓願を立て既に菩薩となっている」という考えや、法華経の「初転法輪は方便ということにして、第2の初転法輪が実はあったことにする」というのはやはり興味深いなと思います。
読み返しても華厳経の世界観は難しくて良く分からないなと思います。浄土教もそうですが、昔からパラレルワールドという概念があったというのはびっくりですね。
本の最後の方に禅宗が載っているのですが、「坐禅だけではなく、掃除をしたり食事を作ったりという日常行為全てが修行」という価値観が、なんとなく「洗濯物干すのもHIPHOP」に通じるような(通じません)。
44smkn Bi-Week in Review - December 12, 2022
AWS Week in ReviewとSRE Weekly読んでて、自分の備忘録用のメモもこんな感じにまとまっていると良いだろうかと思い、試してみることにしました 44smkn Week in Review - November 14, 2022 - 1クール続けるブログ
先週書けなかったので、2週間分ということで Bi-Week
と銘打ってみた。英語的に正しいのかは怪しい。
ゆるくやっていくので1週飛んだって良い。続けるのが大事。
ブログに書いていると個人的に見返す回数が増えた気がして、記事読んで満足した気になってそのまま忘れていくより全然いいので、できれば続けていきたい。
すごく温かい気候が続いていますが、積雪の予報としては平年並みらしくチャンスがあればスノーボード行きたい。
今持っているボードより、もうちょいグラトリに向いているボードを買いたくなったが、調べると結構値段するので腰が引けてきた。
Article
How Service Tiers Can Help to Avoid Microservices Disasters - New Stack
service tierというラベルをサービスに付与することで、問題が起こった時の優先度付けや対応や投資を効率的に行うことができる。
記事の中でのラベル付の例が非常に分かりやすかった。規模が増せば増すほど効果が大きいのだろうと思う。
Monzoは大規模な移行作業を自動化する際に利用しているらしい(link)。
冒頭で書かれていることには共感できる。依存されているサービスがクリティカルだと思いがちだけど、そうでないケースもある。ノンクリティカルなサービスに余分な対障害性をもたせると複雑さやコストの増大につながる。
依存する側のサービスの方のtierが低いのであれば、依存される側のサービスの障害から保護する必要はないが、もし依存する側のサービスの方のtierが高いのであれば、依存される側のサービスに障害が起きても稼働を続けるような保護をする必要がある。
[レポート] Revitalize your security with the AWS Security Reference Architecture #SEC203 #reinvent - クラスメソッド
AWSのセキュリティはサービスが多いこともあり、どこから学べば良いのか?どう設計していけば良いのか?と頭を悩ますことが多い。
AWS SRA - Security Reference Architecture という模範的ガイダンスの存在をこのレポートで知ったが、ここからスタートしても良さそうという印象を持った。
どうOrganizaiton Unitを分けて、それぞれにどのような責務をもたせるかということを推奨としているかが分かるのが良い。
実装するコードもあるのも良い。
[セッションレポート] Feature Flagで機能別にローンチをコントロールする (BOA305-R) #reinvent - クラスメソッド
セッション動画 (公開される前だったので記事内にリンクなし)
Feature Toggle あるいは Feature Flag の機能を提供するサービスとしてAWSでは下記の2つがある
デプロイとリリースの分離 is 大事。
専用のSaaSだったりもあるが結構お値段が張る印象があるので、AWSはどうなんだろうと興味を持ちました。
CloudWatch Evidentlyは長い期間でA/Bテストとかするのに便利AppConfig Feature Flagは、自動ロールバックの機能があり、新しいバージョンの設定を安全にrolloutするのに適しているとのこと。
Cognitoを使ってflag取得の権限を与えている。
Company, team, self. - Will Larson
良かったので、自分なりのざっくりまとめ。
筆者は、「会社、チーム、自分自身」の順に優先させることで正しい結果にたどり着くというのをアドバイスしていたが、マネージャとしての経験を積むにつれ、そういったアドバイスをやめた。
そのアドバイスに忠実に従いすぎてburn outしてしまうリーダーたちがいた。
人は複雑な方法でエネルギーを得ている。
ソフトウェアを書くこと。既存のシステムを最適化すること。社内のWikiを綺麗にすること。会議をすること。
その仕事自体があまり重要でないとしても、エネルギーを与える仕事によって、人々はより多くのことを成し遂げられる。
自分自身とチームを活性化させるために、正しい優先順位を破ることはリーダーシップにおいて重要。
リーダーシップとは、正しい場所に素早くたどり着くことであり、必ずしもまっすぐ歩くことでない。
目的を持ってあるくより行き当たりばったりの道を嬉々としてスキップするほうが早い場合もある。
ただし、他のチームに問題を起こしてはいけない。
AWS Verified Access Preview — VPN-less Secure Network Access to Corporate Applications - AWS
ZTNA(Zero Trust Network Access) の サービスがAWSから出てきましたね。
他社の同様の製品は Cloudflare Access くらいしか知りませんが、そこと比べるとスマホのサポートが無いのが悩ましいところですかね。
AWSのサービスと統合されるのが強みなのかなと。
Cedarという言語も気になりますね。
関連するセッションのレポートも classmethod から上がっていた。
[レポート]AWS Verified Accessの詳細が分かる!re:Inventの最新セッションを紹介 #reinvent
Book
Web配信の技術―HTTPキャッシュ・リバースプロキシ・CDNを活用する
キャッシュあまりに難しすぎることが分かる。とにかく考慮することが多い。
例えば、下記の条件を満たせば、Cache-Controlヘッダの指定がなくてもキャッシュされたりとか…。しかも Date - LastModified / ブラウザ実装による定数(一般的に10)
がTTLとして設定される。
https://tex2e.github.io/rfc-translater/html/rfc7234.html#3--Storing-Responses-in-Caches
キャッシュさせなくてもCDN利用するだけでスループットがレイテンシが改善するという、(ネットワーク強くない人からすると)直感的でないことを知れたのも良かった。
ちなみにこの本は DMM booksの70%OFFセールのときに買ったのだが、マーカーがブラウザ及びPCのアプリから見れなくて絶望している。
44smkn Week in Review - November 28, 2022
AWS Week in ReviewとSRE Weekly読んでて、自分の備忘録用のメモもこんな感じにまとまっていると良いだろうかと思い、試してみることにしました
44smkn Week in Review - November 14, 2022 - 1クール続けるブログ
今週はre:Inventなのでそのへんを追いかけたいけど、そんなに時間がないような気もしてきた。
また現地のre:Inventに参加する機会があれば行きたいなあ。
- Article
- CEO Raj Dutt Interview: The Grafana Experience Will Change - New Stack
- Argo Rollouts at scale: Bringing Automated Rollbacks to 2,100+ services at Monzo - monzo
- Enabling Collaborative K8s Troubleshooting with ChatOps - New Stack
- 色々試して行き着いた読書方法 - iwashi
- The state of OpenTelemetry - cncf
- Strategies and Tools for Performing Migrations on Platform - spotify
- Podcast
Article
CEO Raj Dutt Interview: The Grafana Experience Will Change - New Stack
業務でGrafana使うことがなくなり、あまり追えてなかったので、Grafanaの過去/現在/未来の話を大雑把に知れて良かった。
Grafanaファミリーがまた増えていた。まさか Mimir というメトリクスのプロダクトも作っているとは。加えて、プロファイリングツールである Phlare というのもあるらしい。
Loki(ログ)Grafana(可視化)Tempo(トレース)Mimir(メトリクス)で LGTM
とのこと。
少しだけどどうやって収益あげているか?とかどの製品の売上がどのくらい占めるかとかの言及あって面白い。
OSSの企業ちゃんと儲かっていて欲しいけれど、難しい面が結構ありそうだなと思っている。
(Prometheusのメンテナの44%以上がGrafana Labs出身ってすごいな。Prometheusで集めたデータ可視化にGrafana使うことへの安心感がすごい。)
Argo Rollouts at scale: Bringing Automated Rollbacks to 2,100+ services at Monzo - monzo
Monzoというオンライン銀行のサービスがArgo Rolloutを使いPrometheusのクエリベースのRollbackを実装した記事。Monzoさんって結構名前聞く気がする。
Ephemeral Metadata という機能を使って、新旧のサービスに対応するメトリクスへのクエリを分けているらしい。
サービス数がめちゃくちゃ多いからだと思うけど、移行用にサービスを作ってしまうの凄い。
あと、めっちゃ良いなと思ったのは、各サービスに重要度を示す tier というのがあるらしい。これを使って移行する順番を自動的に決めることが出来たとのこと。
Enabling Collaborative K8s Troubleshooting with ChatOps - New Stack
botkube.io は良いぞという話だった。
あまりChatOpsに関して調べたことはないので知識なかったんですが、Chat上でのペアワークをするのに便利という点やモバイルからでも作業ができるというのは、確かに補助的にそういうツールがあると便利かもなあと思った。
色々試して行き着いた読書方法 - iwashi
「高速で読み流しながらマークし、後でまとめる。全部読まなくていい。」
めっちゃ良い読書法と思うし、凄い試したいのに、どうしてもじっくり読みがち。しかも全部読まなきゃという感覚に襲われてしまう。
今少しずつ練習している…。
The state of OpenTelemetry - cncf
OpenTelemetryの各言語の実装状況がまとまっていて良かった。
てっきりGoとかが成熟しているのかなと思いきや、一番成熟しているのはJavaだった。
記事内でも言及がありますが、experimental は、α / β / rc をカバーするらしく、更にstableに移行する時に既存のユーザをbreakするようなことはしないらしいので本格的に採用しても良いレベルなのかも知れない。
ついでにDatadogのOpentelemetryのサポート状況を見てみたけど、2つの方法でサポートしているらしい。
https://docs.datadoghq.com/tracing/trace_collection/open_standards/
1. app(otel sdk) -> opentelemetry-collector with datadog-exporter -> datadog-agent -> datadog backend 2. app(otel sdk) -> datadog-agent -> datadog backend
Strategies and Tools for Performing Migrations on Platform - spotify
Spotifyが大規模なmigrationを行った経験から、「症状(When), 避けるべきこと(Don't), 推奨すること(Do)」を各challengeでまとめている記事。
この記事内でのSpotifyの事例は、mobile appのビルドをbazelに移行することだったが、多くの大規模な移行に共通する学びだと思った。
好きなDoがいくつかあるので挙げておく。
Challenge 1: Do
- Address your audience. Understand their mental models so that you can talk about what’s relevant, connect where their needs are, and find proxies to expand your reach.
Challenge 2: Do
- Communicate. Keep your audience engaged by sharing the progress through newsletters and workplace posts.
- Look to automation. Simplify the migration process by investing in automation upfront.
- Make time for spike weeks. Partner with squads and tribes to jointly dedicate a week to work on the migration.
Challenge 4: Do
- Use dashboards. Metrics and dashboards will communicate the progress and impact, as well as help prioritize your work at scale over time.
Podcast
53. 時系列データベースエンジン w/ nakabonne - fukabori.fm
OpenTelemetryやらGrafanaやらの記事を読んでいたので、久しぶりに聞いた。
時系列データの特徴とそれを生かした時系列データベースの設計が分かりやすく語られててやっぱり良かった。
Prometheusがパーティション切り替わる時に、通信遅延や時間のズレによってデータを取り逃すことがあるかも(かつ後発のDBではそうならないようになっている)という話は興味深かった。
WEB+DB PRESSのRustで作るRDBMSの写経をやったからか、昔より解像度高めに聞けた気がする。
Rebuild: 348: Stop Digging Up The Past (higepon)
前半のTwitterの話は聞いてて胸が苦しくなった。
ソフトウェアの品質が高いからこそ、大量にソフトウェアエンジニアがいなくなっても動き続けるんだよね。
次のラピュタの放送で壊れるんじゃないか…?という話があって確かにと頷いた(これrebuildで聞いた話じゃないかな…?)
44smkn Week in Review - November 21, 2022
AWS Week in ReviewとSRE Weekly読んでて、自分の備忘録用のメモもこんな感じにまとまっていると良いだろうかと思い、試してみることにしました 44smkn Week in Review - November 14, 2022 - 1クール続けるブログ
これ始めて2週目で既に遅延している
まあでもゆるくやっていくのを目標としているのでそれでもヨシ
- Article
- メルカリShopsの注文システム安定化の歩み - mercari
- Kubecost Open Sources OpenCost: an Open Source Standard for Kubernetes Cost Monitoring
- All-in-One, Integrated Front-End Toolchain Rome Released V10, Dubbed First Stable Release - infoq
- Amazon EKS now supports Kubernetes version 1.24
- Composite availability: calculating the overall availability of cloud infrastructure
- Podcast / Radio
Article
メルカリShopsの注文システム安定化の歩み - mercari
マイクロサービス群のorchestrationをGCP Workflowsでやっているんですね。Workflows使ったことないですが、AWSで言うStepFunctionsという認識をしています。
冒頭読んで、もしかしてSagaの補償トランザクションの話かなと思ったんですが違ったようです。
「不整合の検知をできるようにする → 運用の中でカバーしきれなかったエラーのパターンやAPIが見つかる → 地道に改善を続けてほぼすべてのパターンがハンドリングできるようになる」という流れでした素敵。
Kubecost Open Sources OpenCost: an Open Source Standard for Kubernetes Cost Monitoring
kubecost自体はオープンソースではなくて、kubecostの中のコスト配分エンジンをオープンソース化したものがOpenCostみたいですね。
この記事に加えて OpenCost Product Comparison – Kubecost を見ると分かりやすいです。
OpenCostにはDashboardは含まれないそうです、prometheusのメトリクスを吐いてくれそうです。そう考えるとDatadogも使えそう。
それを踏まえて、AWS and Kubecost collaborate to deliver cost monitoring for EKS customersの記事でインストールされているのは kubecostの方であると。
tierを上げたかったらmarketplaceで買えますよってことですかね多分。
Freeだと15日間のretentionしかないのでちゃんと使うには課金が必要そうな雰囲気。ただ最初の30日間は無料とのこと。
https://www.kubecost.com/pricing/
All-in-One, Integrated Front-End Toolchain Rome Released V10, Dubbed First Stable Release - infoq
JaveScript周りのツールチェインは種類とその中での選択肢が多くてややこしいなと思っていました。
それを1つにまとめようとする壮大なツールとして、romeというのがあるんですね。
Rust書き換えて初めてのstable releaseということで、ここから盛り上がってくるんでしょうか?
Amazon EKS now supports Kubernetes version 1.24
v1.23 と v1.24 はほとんど期間開かなかったですね。確認したらおよそ3ヶ月間でした。
Topology Aware HintsでAZ跨ぎの通信量が減るのが期待できそうですね。
- dockershimとお別れ
- v1.24以降新しく追加される BetaAPI は今までと違いデフォルトで有効にはならない
- Topology Aware Hints
- more...
Composite availability: calculating the overall availability of cloud infrastructure
アプリケーションを構成する全ての異なるサービスを組み合わせた可用性 - composite availability
を計算する必要があるよね、という話。これを意識すると、よりresilientなシステムを設計することができて、その結果ユーザ体験が良くなるんではとのことでした。
自分たちで運用するサービスのSLOを決めるときも、この composite availability
以上には出来ないと思うので、プロダクトの要求する可用性がそれよりも高いのであれば、設計自体も見直す必要があるのだよなと思いました。
この記事の例だと、Google Cloudのサービスが説明に使われていたので、AWSでも例を一つ取って計算してみます。記事に書かれているSerialのパターンで。
SLAはここを参考: https://aws.amazon.com/legal/service-level-agreements/
.9999 * .9999 * .999 * .999 = 0.9978... ≒ 99.78%
Podcast / Radio
内山昂輝の1クール!#408
冒頭にあった休んだ時にストック使うべきかどうかという話。
内山さんが新型コロナウイルスに感染してしまったため、昔に収録したストックが放送された先週。「ピンチヒッターで人が来たほうが面白いんじゃないか」と話されていた。
それ聞いて思い出したのは、おぎやはぎのメガネびいきにて、おぎやはぎのお二人が欠席してゲスト予定のchelmicoとトンツカタン森本、アルピーでやってた回。
そう考えるとスリリングで面白いのかもしれないけど、ピンチヒッター側のプレッシャーがすごそう。
普段テレビでニュース観ないので、サッカーの情報はほぼ内山さんからしか入ってこない。
今回もワールドカップの話をしてくれていた。「いつもと時期違うんですよね」の一本槍で、この前美容師さんとの会話乗り切った。ありがとう。
ちょろいのリスナーも美容師さんから振られたうたプリの話を3枚くらいの手札で乗り切ってた気がする。
44smkn Week in Review - November 14, 2022
AWS Week in ReviewとSRE Weekly読んでて、自分の備忘録用のメモもこんな感じにまとまっていると良いだろうかと思い、試してみることにしました。
raindrop.io にブックマークが溜まっていくだけで見返す機会がないのは良くない。
ゆるくやっていこう。古い記事も今週読んだらここに載ります。
- Article
- GitHub Universe 2022における新発表のすべて - github
- GitHub Codespaces with JetBrains IDEs (Public Beta) - github
- Introducing GitHub Actions Importer - github
- Spotify’s Vulnerability Management Platform - spotify
- スキルマップを使ったSPOF可視化と改善について - mercari
- Introducing the Docker+Wasm Technical Preview - docker
- Introducing Amazon EventBridge Scheduler - AWS
Article
GitHub Universe 2022における新発表のすべて - github
TasklistsはGitHub Projectsと深く統合されており、”tracked by”や”tracks”といった新しいフィールドを用いて、親と子の課題を俯瞰的に確認できます。 RoadmapとTasklistは近日公開予定です。ウェイティングリストに登録し、準備が整いましたら、お試しください。
Issueの依存関係を表現関係を表現したいというのは仕事上でも需要があるし、OSSのIssueを眺めるときにも役に立ちそう。
Issues / About Tasklists に詳細あり。waitlistに登録しないと。
GitHub Codespaces with JetBrains IDEs (Public Beta) - github
GitHub now supports the use of GitHub Codespaces with JetBrains IDEs via the JetBrains Gateway. After downloading the JetBrains Gateway and installing the GitHub Codespaces plugin, users will be able to connect to their codespaces with the JetBrains IDE of their choice.
JetBrains Gatewayという「リモートサーバにSSH接続し、そこで動いているIDEバックエンドサービスにアクセスする仕組みを提供するクライアントのアプリケーション」を利用しているとのこと。
CodeSpacesでIntelliJとか動いたらすごいな。本格的にiPadで開発できそう。
Introducing GitHub Actions Importer - github
We’re excited to announce a public preview of GitHub Actions Importer, which helps you forecast, plan, and facilitate migrations from your current CI/CD tool to GitHub Actions. The user interface for GitHub Actions Importer is an extension to the official GitHub CLI, which delegates to a Docker container.
jenkins
の例が載っているが、 https://github.com/github/gh-actions-importer#supported-platforms を見ると、他にcircle-ciやgitlab等がサポートされている様子。
ジョブの移行って不確実性が高い上に関係者が多くなりがちなので、 gh actions-importer audit
でどのくらいの数のジョブが自動変換できるかとかが見れるのは嬉しいだろうなあという感じがする。
The GitHub Actions Importer IssueOps template repository provides the foundational functionality required to run GitHub Actions Importer commands through GitHub Actions and Issues.
GHA workflowでimporterが動かせるテンプレートリポジトリもあるらしい。
Spotify’s Vulnerability Management Platform - spotify
Spotifyの脆弱性管理プラットフォームの名前は Kitsune らしい。
脆弱性のライフサイクルを管理するバックエンドAPIサーバをそう名付けたのにはどういう理由があるんだろう。
backstage.io で可視化してユーザとの接点を作っているらしい。独自のpluginとかも作れるんだなあ知らなかった。New Stackのplatform engineeringの記事とかでも取り上げられているので結構気になる。
スキルマップを使ったSPOF可視化と改善について - mercari
スキルマップは具体的な項目かつシートに書いていくのが分かりやすそうだなと思いました。 この項目を作っていくのが結構大変だと思うんですが、どういうふうに作っていったのか気になりました。
やること
- チームとして特定のメンバーにスキルが偏っている項目(カバレッジが低いもの)を見つけ、ドキュメント作成や勉強会開催、ペアプログラミング等を通して偏りをなくす
- エンジニア個人のOKR設定やオンボーディングのために参照する
やらないこと
スキルマップ活用のポリシーをちゃんと定めているのが良いですね。なにか取り組むときには、どう使い、どう使わないのかを定義するべきだなと思いました。
Introducing the Docker+Wasm Technical Preview - docker
previewではありますが、dockerからwasmが扱えるようになったんですね。
wasm動かすときには、--runtime
と--platform
を指定するそう。
ここで使われているイメージは https://hub.docker.com/r/michaelirwin244/wasm-example/tags で、OS/ARCH
の表示がwasi/wasm32
になっていることが分かります。
docker run -dp 8080:8080 --name=wasm-example --runtime=io.containerd.wasmedge.v1 --platform=wasi/wasm32 michaelirwin244/wasm-example
wasm moduleのbuild/pushに関しての記載: https://docs.docker.com/desktop/wasm/#building-and-pushing-a-wasm-module
Introducing Amazon EventBridge Scheduler - AWS
class methodの方の解説記事も出ていた: [新機能] タイムゾーン指定でスケジュール起動できるAmazon EventBridge Schedulerがリリースされました
EventBridge Ruleのquotaにぶち当たったことは今のところないけど、1アカウント内1regionで300までとは中々しぶい。
quotaはまず嬉しいしタイムゾーン指定ができるのもありがたい。
targetが豊富になったのも気になり。この感じだとEKS Jobとか呼べそうである。定期実行しているterraform moduleをこっちに書き換えるのはあり。
terraform-provider-awsの方で既にissueは作られていて、PRは既にマージされていそうなので、あとはリリースを待つのみである。
https://github.com/hashicorp/terraform-provider-aws/issues/27760
Fluent BitのLua PluginとLuaの単体テスト含むCIを試してみた
記事一覧はこちら
今回使ったコードはここにまとめてあります。
背景・モチベーション
fluent-bitにはmodifyやrecord_modifierというFilterが用意されており、Record/Eventsの変更ができるようになっていますが、複雑なことをやらせようと思うとlua filterが必要になってくると思います。
例えば、kubernetes filterを利用し、metadataを付与した後に、namespace
やlabels
、container_name
などを組み合わせて文字列を作り更に条件分岐も組み合わせたい、となることがありました。
Fluent BitのLua Pluginを試す
実現したい処理
stackdriver pluginで送信するときに logNameフィールドとして抽出される値をLua pluginを利用しrecordに追加する
- logNameフィールドとして抽出されるときにデフォルトで参照されるkey名は
logging.googleapis.com/logName
である - valueとしては
<namespace>_<appラベル or pod_nameからrandom stringを除いたもの>_<container>
としたい - kubernetes filterで付与されたmetadataを利用する
今回はKuberntesクラスタで動かさずローカルで試すことを目標とします。
そのため、tail pluginやkubernetes filterは利用せず、dummy pluginを利用して、metadataが付与された状態のrecordを注入することとします。
{ "timestamp":"2022-05-09T23:56:33.044423373Z", "stream":"stderr", "log":"some messages", "kubernetes":{ "pod_name":"test-server-75675f5897-7ci7o", "namespace_name":"test-ns", "pod_id":"60578e5f-e5bb-4388-be57-9de01c8a4b79", "labels":{ "apps":"test" }, "annotations":{ "kubernetes.io/psp":"default" }, "host":"some.host", "container_name":"test-server", "docker_id":"1d79200d4e60bb7f58b2e464e22a82d5d3bf694ebf334b3757bbdb0ce25353aa", "container_hash":"container.registry/test-server/test-server@sha256:bfd1a73b6d342a9dd5325c88ebd5b61b7eaeb1c8a3327c3d7342028a33b89fe0", "container_image":"container.registry/test-server/test-server:0.0.82" } }
Luaで実装しFilterから呼び出す
https://docs.fluentbit.io/manual/pipeline/filters/lua#callback-prototype
引数として、tag
, timestamp
, record
の3つを取り、かならず3つの値をretrunする必要があります。それが code
, timestamp
, record
であり、code
の値によって後ろ2つの返却値の扱いが変わってきます。1
のときには2つとも利用されますが、それ以外のときは timestamp
は利用されませんし、record
も1
に加えて2
のときしか利用されません。
- -1: recordはdropされる
- 0: recordは変更されない
- 1: timestampとrecordが変更される
- 2: recordのみ変更される
それも踏まえて処理を実装したのが下記です。
function append_k8s_logname(tag, timestamp, record) local new_record = record local app = record["kubernetes"]["labels"]["app"] if app == nil then local pod_name = record["kubernetes"]["pod_name"] _, _, app = string.find(pod_name, "([%w-]+)%-%w+%-%w+") end local namespace = record["kubernetes"]["namespace_name"] local container_name = record["kubernetes"]["container_name"] local log_name = string.format("%s_%s_%s", namespace, app, container_name) new_record["logging.googleapis.com/logName"] = log_name return 2, 0, new_record end
Luaは初めて書いたのですが下記が参考になりました。
正規表現はPOSIX準拠ではないようでしたが、機能としては十分でハマることはほぼありませんでした。
- Lua 5.4 Reference Manual - contents
- Lua: demo
- https://github.com/fluent/fluent-bit/tree/master/scripts
では、Filterから呼び出してみたいと思います。最低限、必要なのはscriptへのパスと呼び出す関数名になります。パスはmainの設定ファイルからの相対パスもサポートされているようです。productionでは絶対パスで指定したほうが良いと思いますが、今回はテストなので相対パスで書いています。
stdoutをOUTPUTに指定し動作確認したところ、期待通りの出力を得ることができました。
[FILTER] Name lua Match * script ./append_k8s_logname.lua call append_k8s_logname [OUTPUT] Name stdout
$ fluent-bit -c fluent-bit.conf [0] kube.var.log.containers.test-server_test-ns_test-server-aeeccc7a9f00f6e4e066aeff0434cf80621215071f1b20a51e8340aa7c35eac6.log: [1653143473.074878000, {"kubernetes"=>{"labels"=>{"app"=>"test"}, "pod_name"=>"test-server-75675f5897-7ci7o", "annotations"=>{"kubernetes.io/psp"=>"default"}, "namespace_name"=>"test-ns", "container_name"=>"test-server", "docker_id"=>"1d79200d4e60bb7f58b2e464e22a82d5d3bf694ebf334b3757bbdb0ce25353aa", "container_hash"=>"container.registry/test-server/test-server@sha256:bfd1a73b6d342a9dd5325c88ebd5b61b7eaeb1c8a3327c3d7342028a33b89fe0", "host"=>"some.host", "container_image"=>"container.registry/test-server/test-server:0.0.82", "pod_id"=>"60578e5f-e5bb-4388-be57-9de01c8a4b79"}, "log"=>"some messages", "logging.googleapis.com/logName"=>"test-ns_test_test-server", "timestamp"=>"2022-05-09T23:56:33.044423373Z", "stream"=>"stderr"}]
Fluent Bitの設定に関するCIを作成する
Fluent Bitの運用を行っていく上で不安になる要素として2つあります。これらを解消するためのCIパイプラインを作成していきます。
Fluent Bitの設定をvalidate
上記のIssueで設定のvalidateが入ったようです。--dry-run
というoptionがあるようなのでそれを利用することで解決。
LuaのUnit Testを書く
Luaのunit testのツールに関しては、lua-users wiki: Unit Testing や What unit test frameworks are people using? : lua を参考にし、fluent-bit内で動くLuaJITで動きそう かつ 導入が簡単なものとして luaunit というツールを選定しました。これは、 luaunit.lua
というファイルを配置するだけで動くようになります。
Luaのdocやサンプルコードを見ている限り、関数や変数にはsnake_caseが用いられているように見えていたのですが、luaunit
ではcamelCaseやPascalCaseが使われていて、ちょっと違和感があります。
ざっと書いてみたのはこんな感じです。Luaっぽく書くにはどうすれば良いんだ…(頭抱え)。
local lu = require('luaunit') local akl = require('append_k8s_logname') TestAppendK8sLogname = {} function TestAppendK8sLogname:setUp() create_record = function(labels) return { kubernetes = { pod_name = "test-server-75675f5897-7ci7o", container_name = "envoy", namespace_name = "test-ns", labels = labels } } end self.create_record = create_record self.logname_key = "logging.googleapis.com/logName" end function TestAppendK8sLogname:testAppLabelExists() local record = self.create_record({ app = "app" }) local _, _, got = akl.append_k8s_logname(nil, nil, record) lu.assertEquals(got[self.logname_key], "test-ns_app_envoy") end function TestAppendK8sLogname:testAppLabelNotExists() local record = self.create_record({ dummy = "dummy" }) local _, _, got = akl.append_k8s_logname(nil, nil, record) lu.assertEquals(got[self.logname_key], "test-ns_test-server_envoy") end -- end of table TestAppendK8sLogname local runner = lu.LuaUnit.new() runner:setOutputType("text") os.exit( runner:runSuite() )
テスト対象の関数をテスト用のファイルから呼び出すためにexportする処理を追加してあげる必要がある。
local M = {} M.append_k8s_logname = append_k8s_logname return M
実行してみてテストが通ることを確認する。
$ luajit append_k8s_logname_test.lua .. Ran 2 tests in 0.001 seconds, 2 successes, 0 failures OK
GHAに実装する
Fluent Bitとluajitをもっといい感じにインストールしたい…と思いつつ下記のように実装。
後はrenovateを設定すればいい感じになるはず。
fluent-bit-lua-example/test-fluent-bit-config.yaml at main · 44smkn/fluent-bit-lua-example · GitHub
まとめ
Luaを触ったこと無かったこともあり、Lua Filterは食わず嫌いをしていたけれど触ってみると意外となんとかなるかもなという所感を持ちました。
karpenterのOD Fallbackを試してみた
記事一覧はこちら
こちらの記事は、2022/3/13に大幅に修正いたしました。
EC2 OnDemand Fallback at the Provisioner level · Issue #714 · aws/karpenter · GitHub のIssueから、OD Fallbackを行う方法は、nodeAffinityのprefferredを利用しか無いと思っていたのですが、v0.6.0からFAQs | Karpenterにて下記のように記載されるようになり、より良い方法があることがわかりました。
そのため書き直しました。
Karpenter will fallback to on-demand, if your provisioner specifies both spot and on-demand.
背景・モチベーション
karpenterのGAがアナウンスされて、クラスメソッドさんの記事やスタディサプリENGLISHのSREさんが書いた記事を読んで、とても良さそうだし業務にも活かせそうと思ったので触りたくなりました。
本番環境で運用する上では、スポットが起動しなくなったときにオンデマンドを起動する(OD Fallback)仕組みを考えておかねばと思っています。
多様なインスタンスタイプを起動する候補にしていれば、昨今の安定したスポットインスタンス供給でそのような自体はあんまり考えられませんが、備えあれば憂いなしとも言いますし。
Karpenterの概要
個人的には公式Docの Concept
のページにある Kubernetes cluster autoscaler
という項目に書いてある3つが非常にKarpenterの特徴がわかりやすい記述になっているのではないかと思っています。
- Designed to handle the full flexibility of the cloud
- Group-less node provisioning
- Scheduling enforcement
特によく言及されるスケジューリングの速さに関しては、下2つの項目が関わっていると思います。
AutoScalingGroupやManagedNodeGroupといったGroupのメカニズムを使用せず直接インスタンスを起動していること。EC2Fleetを利用して必要なcapasityを満たすようにEC2インスタンスを起動する仕組みになっているようです。
また、Podスケジューリングをkube-scheduler
に頼らず、karpenterが作成したノードにpodをbindするようです。そのためkubeletはノードの起動やkube-schedulerを待つ必要がなく、コンテナイメージのPullなどコンテナランタイムの準備をすぐに行うことが可能なようです。
Karpenterの環境構築
https://karpenter.sh/docs/getting-started-with-terraform/karpenter.sh
通常のEKSクラスタ構築に加えて行う必要があるのは下記かと思います。
- PrivateサブネットとSecurityGroupに
"karpenter.sh/discovery" = var.cluster_name
とタグ付与して、karpenterがdiscoveryできるようにする - Karpenterが起動するノードに紐付けるInstanceProfileの作成
- defaultのInstanceProfileをHelm経由で設定する or ProvisionerというCRD内で宣言する必要がある
- IRSAでkarpenterのcontrollerのpodが利用するIAMロール
ちなみにeksのmoduleをv1.18に設定したら、やたらとハマったのでこちらのIssueが役に立ちました:Error when creating provisioner - failed calling webhook · Issue #1165 · aws/karpenter · GitHub
EKSクラスタの構築が完了したら、下記のようにHelmを利用してインストールしていきました。
$ helm repo add karpenter https://charts.karpenter.sh $ helm repo update $ helm upgrade --install karpenter karpenter/karpenter --namespace karpenter \ --create-namespace --version 0.6.5 \ --set clusterName=${CLUSTER_NAME} \ --set clusterEndpoint=$(aws eks describe-cluster --name ${CLUSTER_NAME} --query "cluster.endpoint" --output json) \ --set serviceAccount.annotations."eks\.amazonaws\.com/role-arn"=${KARPENTER_IAM_ROLE_ARN} \ --set aws.defaultInstanceProfile=KarpenterNodeInstanceProfile-${CLUSTER_NAME} \ --wait
OD Fallbackを行うためのマニフェスト指定
Karpenter will fallback to on-demand, if your provisioner specifies both spot and on-demand.
More specifically, Karpenter maintains a concept of “offerings” for each instance type, which is a combination of zone and capacity type (equivalent in the AWS cloud provider to an EC2 purchase option).
Spot offerings are prioritized, if they’re available. Whenever the Fleet API returns an insufficient capacity error for Spot instances, those particular offerings are temporarily removed from consideration (across the entire provisioner) so that Karpenter can make forward progress through fallback. The retry will happen immediately within milliseconds.
冒頭で紹介したとおり、OD Fallbackする方法はProvisionerの .spec. requirements
内の karpenter.sh/capacity-type
keyに対して on-demand
とspot
の両方を指定すれば良いようです。
基本的にはspotを優先的に起動し、もし不足していたらon-demandをprovisionするようです。
ということで、default
という名称のproviderを用意します。default
という名称のproviderは faq#if-multiple-provisioners-are-defined-which-will-my-pod-use にあるように特別扱いされます。
ちなみに後続のテストのために、インスタンスタイプを c4.xlarge
絞っています。
apiVersion: karpenter.sh/v1alpha5 kind: Provisioner metadata: name: default namespace: karpenter spec: requirements: - key: "node.kubernetes.io/instance-type" operator: In values: ["c4.xlarge"] - key: karpenter.sh/capacity-type operator: In values: ["spot", "on-demand"] # ここで双方を指定する provider: subnetSelector: karpenter.sh/discovery/44smkn-test: "*" securityGroupSelector: karpenter.sh/discovery/44smkn-test: "*" ttlSecondsAfterEmpty: 30
OD Fallbackのテスト
この後のセクションで触れますが、karpneterはFallbackするときの条件としてEC2 Fleet作成リクエストのエラーコードが InsufficientInstanceCapacity
である必要があります。
これを自分で再現するのは難しいので、エラーコードが SpotMaxPriceTooLow
も同じような挙動を取るように変更してイメージを作り直します。
func (p *InstanceProvider) updateUnavailableOfferingsCache(ctx context.Context, errors []*ec2.CreateFleetError, capacityType string) { for _, err := range errors { if InsufficientCapacityErrorCode == aws.StringValue(err.ErrorCode) || "SpotMaxPriceTooLow" == aws.StringValue(err.ErrorCode) { p.instanceTypeProvider.CacheUnavailable(ctx, aws.StringValue(err.LaunchTemplateAndOverrides.Overrides.InstanceType), aws.StringValue(err.LaunchTemplateAndOverrides.Overrides.AvailabilityZone), capacityType) } } }
# karpenter's root dir $ GOFLAGS=-tags=aws ko build -L ./cmd/controller $ docker tag <loaded image> ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/karpenter/controller:latest $ docker push ${ACCOUNT_ID}.dkr.ecr.ap-northeast-1.amazonaws.com/karpenter/controller:latest $ kubectl edit deploy karpenter -n karpenter # update container image and imagePullPolicy
SpotMaxPriceTooLow
を起こすように、spotのmax-priceを下げてスポットインスタンスが起動できないというシチュエーションを作ります。
karpenterはLaunch Templateを生成し、それをインスタンス起動するためのEC2Fleet作成リクエスト時に渡しています。なので、作成されたLaunch Templateを直接マネジメントコンソールから編集してmax-priceを変更しちゃいます。直接Launch TemplateをProvisionerに指定することも出来るのですが、編集して対応することにしました。
というのも、karpenterはkarpenterが持ちうるLaunch Templateの設定値セットのHashを取って同一であれば、同じLaunch Templateを再利用します。そのため編集してしまったほうが手間が少なく済んだのです。
c4.xlarge
のスポット価格が 0.0634
くらいだったので 0.06
に設定して、ノードのprovisionを試みます。
すると、下記のようにInsufficientInstanceCapacity for offering
というログが発生して一度ERRORとなった後に、再試行し on-demand
のノードが起動することが分かりました。
秒単位でFallbackしていて非常に速いですね。次のセクションで仕組みについて見ていきたいと思います。
2022-03-13T13:02:18.067Z INFO controller.provisioning Waiting for unschedulable pods {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:35.367Z INFO controller.provisioning Batched 2 pods in 1.022647416s {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:35.374Z INFO controller.provisioning Computed packing of 1 node(s) for 2 pod(s) with instance type option(s) [c4.xlarge] {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:39.916Z DEBUG controller.provisioning InsufficientInstanceCapacity for offering { instanceType: c4.xlarge, zone: ap-northeast-1a, capacityType: spot }, avoiding for 45s {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:39.916Z DEBUG controller.provisioning InsufficientInstanceCapacity for offering { instanceType: c4.xlarge, zone: ap-northeast-1c, capacityType: spot }, avoiding for 45s {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:39.916Z DEBUG controller.provisioning InsufficientInstanceCapacity for offering { instanceType: c4.xlarge, zone: ap-northeast-1d, capacityType: spot }, avoiding for 45s {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:39.916Z ERROR controller.provisioning Could not launch node, launching instances, with fleet error(s), SpotMaxPriceTooLow: Your Spot request price of 0.06 is lower than the minimum required Spot request fulfillment price of 0.0634.; SpotMaxPriceTooLow: Your Spot request price of 0.06 is lower than the minimum required Spot request fulfillment price of 0.0647. {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:39.916Z INFO controller.provisioning Waiting for unschedulable pods {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:46.150Z DEBUG controller.provisioning Created launch template, Karpenter-44smkn-test-9056194203411996147 {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:48.361Z INFO controller.provisioning Launched instance: i-05c437e761fec9383, hostname: ip-10-0-1-223.ap-northeast-1.compute.internal, type: c4.xlarge, zone: ap-northeast-1a, capacityType: on-demand {"commit": "6180dc3", "provisioner": "default"} 2022-03-13T13:02:48.391Z INFO controller.provisioning Bound 2 pod(s) to node ip-10-0-1-223.ap-northeast-1.compute.internal {"commit": "6180dc3", "provisioner": "default"}
Fallbackの仕組み
一部コードを載せていますが、ここでの説明に不要な部分は省略させていただいております。またインライン展開している箇所もあります。
UnschdulableなPodをスケジューリングする際のエントリポイントから順を追ってみていきます。
インスタンス作成の失敗などでPodのスケジューリングに失敗した場合には、この関数の単位でループすると認識しています。
pkg/controllers/provisioning/provisioner.go#L85-L127
func (p *Provisioner) provision(ctx context.Context) error { logging.FromContext(ctx).Infof("Batched %d pods in %s", len(items), window) // Get instance type options vendorConstraints, err := v1alpha1.Deserialize(&v1alpha5.Constraints{Provider: p.Spec.Provider}) if err != nil { return nil, apis.ErrGeneric(err.Error()) } instanceTypes, err := p.cloudProvider.instanceTypeProvider.Get(ctx, vendorConstraints.AWS) // Launch capacity and bind pods workqueue.ParallelizeUntil(ctx, len(schedules), len(schedules), func(i int) { /* request ec2 fleet */ } }
instanceTypeProvider.Get(ctx, vendorConstraints.AWS)
での処理が重要です。以下の処理を呼び出しています。
Offeringとは、インスタンスタイプ毎のcapacityTypeとzoneの組み合わせのことを指します。
ちなみに、ここではProviderのrequimentsなどを考慮していないので、ほとんどのインスタンスタイプが返却されます。実際は、binpacking の処理にて考慮がされます。
pkg/cloudprovider/aws/instancetypes.go#L63-L110
// Get all instance type options (the constraints are only used for tag filtering on subnets, not for Requirements filtering) func (p *InstanceTypeProvider) Get(ctx context.Context, provider *v1alpha1.AWS) ([]cloudprovider.InstanceType, error) { for _, instanceType := range instanceTypes { offerings := []cloudprovider.Offering{} for zone := range subnetZones.Intersection(availableZones) { // while usage classes should be a distinct set, there's no guarantee of that for capacityType := range sets.NewString(aws.StringValueSlice(instanceType.SupportedUsageClasses)...) { // exclude any offerings that have recently seen an insufficient capacity error from EC2 → ここでInsufficientInstanceCapacityのエラーコードが返ってきたOfferingを候補から外す if _, isUnavailable := p.unavailableOfferings.Get(UnavailableOfferingsCacheKey(capacityType, instanceType.Name(), zone)); !isUnavailable { offerings = append(offerings, cloudprovider.Offering{Zone: zone, CapacityType: capacityType}) } } } }
p.unavailableOfferings.Get(UnavailableOfferingsCacheKey(capacityType, instanceType.Name(), zone))
で返ってくる値はどのように決定されるのでしょうか。
EC2 Fleet作成を試みた後にキャッシュに保持する処理があります。現状は45秒キャッシュするようです。
一回目の処理では失敗したOfferingをcacheし、エラーログを出力して処理を終了します。呼び出し元はループしているので、その後に再度この処理が行われます。
候補からspotは省かれています。候補のOfferingにspotが1つでもあれば、capacityTypeにはspot
となりますが、今回はないのでon-demand
になります。
capacityTypeはノードのlabelに付与されるため、userDataがspotのときと異なることになります。そのため、既存のLaunchTemplateを利用できず新しくLaunchTemplateを作成します。ログを見ると作成されていることが確認できます。
そしてCreateFleetInputにもon-demandのOptionが追加されることで on-demand
のノードが起動するようです。
pkg/cloudprovider/aws/instance.go#L147
func (p *InstanceProvider) launchInstances(ctx context.Context, constraints *v1alpha1.Constraints, instanceTypes []cloudprovider.InstanceType, quantity int) ([]*string, error) { capacityType := p.getCapacityType(constraints, instanceTypes) // Get Launch Template Configs, which may differ due to GPU or Architecture requirements launchTemplateConfigs, err := p.getLaunchTemplateConfigs(ctx, constraints, instanceTypes, capacityType) createFleetInput := &ec2.CreateFleetInput{ /* ... */ } if capacityType == v1alpha1.CapacityTypeSpot { createFleetInput.SpotOptions = &ec2.SpotOptionsRequest{AllocationStrategy: aws.String(ec2.SpotAllocationStrategyCapacityOptimizedPrioritized)} } else { createFleetInput.OnDemandOptions = &ec2.OnDemandOptionsRequest{AllocationStrategy: aws.String(ec2.FleetOnDemandAllocationStrategyLowestPrice)} } createFleetOutput, err := p.ec2api.CreateFleetWithContext(ctx, createFleetInput) // ここで InsufficientInstanceCapacity だったOfferingをcacheしています。現状は45秒キャッシュするようです。 for _, err := range errors { if InsufficientCapacityErrorCode == aws.StringValue(err.ErrorCode) { p.instanceTypeProvider.CacheUnavailable(ctx, aws.StringValue(err.LaunchTemplateAndOverrides.Overrides.InstanceType), aws.StringValue(err.LaunchTemplateAndOverrides.Overrides.AvailabilityZone), capacityType) } } }
まとめ
一度、2021年12月に書いた内容が間違っていたため書き直したのですが、当時のv0.5.1と細部が違っていて非常に学べることが多かったです。
eks moduleのv18でとてもハマったのは想定外でしたが…。
下記のようにBlockDeviceMappingのサポートが次回リリースのバージョンが入りそうなので、やっと20GiBのRoot volumeの制限から抜け出せそうですね。