2022-03 blog 読み
- Spot Ocean: k8s Node の Autoscaling
- Karpenter も検討している
- EKS を AWS CDK で管理
- TypeScript なので dev にもとっつきやすい
- Polaris で manifest のテスト https://polaris.docs.fairwinds.com/
- GCP では Project を作成した entity に対し、デフォルトでその Project に対する Owner 権限が付与される。 GCP Project を作成したら、 GCP Project を作成する Service Account から、その Project に対する Owner 権限を剥奪する
- 危険な provider の利用を禁止する
- Cloud Build で使用する Docker image に予め plugin を install しておく。 terraform init で -plugin-dir を指定するようにし、 Docker image にインストールされていない plugin は使えないようにする
- CI の設定を変更するのを防ぐ
- Cloud Build の CI の設定ファイルは GCS で管理する。 Webhook の仕組みは Cloud Function を使い、自前で実装する
- Google Cloud Build から OIDC を使って AWS に対して Terraform を実行している
- 新しい AWS Account が作られたら CloudFormation Stack Set を実行
OU内にNewAccountが作られることをトリガーとして、同Account内のterraform-apply IAM Roleが自動的にそのOUを代表するAdmin accountのみを信頼するよう設定できるようになりました。
なお、あらかじめAdmin account は 対応するGCP ProjectをOIDCのIdPとして信頼しています
Go expvar
Go の Web アプリケーションのメトリックスを API で公開する
S3 Presigned URL
S3 ACL 無効化
Okta を用いたアカウント管理
Tagを変更するとこの制限を突破できてしまうので、別途SCP (Service Control Policy) などでTagの変更が確実にDenyされていることを保証する必要があります。
Private Subnetにデータストア接続用の踏み台は引き続き必要だったので、EC2より管理の楽なECS on Fargateで踏み台を再構築し、ここへもSession Managerで接続させている
- CloudWatch Log Insight
- Serverless Framework
- Lambda から RDS に接続するのに RDS Proxy が必要
- 202012 現在 RDS Proxy は Read/Write 構成を取ることができないので、いくら RDS Proxy があるとはいえ、参照系のクエリすらマスタを叩くことになります
- 同時実行数周りのケアについても今後はもしかしたら課題として上がってくるかもしれない
kubeval と似たツールだが、 kubeval よりいくつかの点で改良されている
- Pod 数が増えると不安定になっていた
- conntrack table が溢れてリクエストが drop されていた
- kube-proxy の設定で conntrackのmaxを増やした
- dns-autoscaler を導入
- DNS の Pod が入れ替わるタイミングで DNS のエラーが発生するので、 node-local-dns を導入
- GCS には組み込みキャッシュがあり、デフォルトで 1時間キャッシュされる
- パージできない・コストがかかる
GCSをオリジンとして使う場合のポイントは、いかにGCS側の組み込みキャッシュを抑制するか
カーネルパラメータ net.core.somaxconn
を増やす
速報などのプッシュ通知をメディアが送信すると一気にユーザはアプリを開くため、急激なスパイクが発生します。 そのスパイクは通常時の10倍以上のトラフィックが発生します
HPAとcluster autoscalerだけでこのスパイクは受け止められない
Push 通知を送る際に、 SNS => Lambda で HPA の minReplicas を増やしている
- istioctl ではなく、 Istio Operator でマニフェストとして管理
- istio-proxy のlifecycleの変更
- preStop, postStart の設定
- Autoscaling によってピーク時以外は Node 数を減らすことでコストを大幅に削減できる
- EKS への切り替えを DNS の切り替えによって段階的に行ったが、クライアントの DNS キャッシュによって古い環境へリクエストが流れていた
DNSはttlだけではなくクライアントのキャッシュなども影響があるので、 なるべくDNSでのルーティングは早めに終わらせ、ALBのWeighted Routingで検証することをオススメします
- application container のログは fluentd をサイドカーとして動かして収集している
- appのコンテナより先に死なないようにpreStopでapiの死活を監視し、appコンテナが死んでからfluentのコンテナが落ちるようにしている
割と普通なことしかしていないが、それでもこれだけのリクエストが捌けるらしい
- JobとJobにより生成されたPodが実行完了後もクラスター内に残り続け、不要なオブジェクトとしてControlPlaneのリソースを圧迫し、クラスターが不安定になった
- 事件発生の数日前に、従来より高頻度に定期実行されるデータ収集用のバッチ処理をデプロイしたことにより、自動削除が追いつかなくなった事が、本事象の顕在化の引き金
- Datadogで取得可能なTerminatedContaierをモニタリング
TTL-after-finished Controller
PagerDuty Incident Responseには、オンコールに全員参加するのはアンチパターンだと紹介されています。 kintone.comでもオンコールは全員ではなく、限られたメンバーのみを呼び出すようにしました
- ロールバック
- Feature Flag
ロールバックもするが、大きな変更では Feature Flag をよく使う
開発環境でしばらく寝かせるということはせず、開発環境の適用後に自動テストが通過すれば、本番環境に同じコンテナイメージを適用します。
開発環境では、本番同等のリクエストを再現するのは難しいことが経験的にわかっていました。
そのため入念な試験だけでなく、問題が発生したら即座に切り戻せる仕組みに注力
各環境でコンテナイメージを統一することで管理が容易になり、Gitのソースコードがそのまま今の本番環境を表します
ロールバックだと特定の機能だけリバートするのが難しい、 Feature Flag ならそれが出来る
Feature Flag の管理はとてもシンプルで、環境変数でやっているらしい。
# V1Strategyを利用する
kubectl set env deployment/my-component MYCOMPONENT_USEV2STRATEGY=false
# V2Strategyを利用する
kubectl set env deployment/my-component MYCOMPONENT_USEV2STRATEGY=true
開発と本番で同じイメージを使うのは個人的にとても良い。
Monorepo 用のツールではあるが、 JavaScript や TypeScript などを想定しているようで、
自分が考えている Terraform や Lambda の Monorepo とは違いそう。
YouTubeのvideoIDが不正です