SREとして入社し1年たつので振り返り

こんにちは。SREの栗原です。 この記事は10Xアドベントカレンダーの15日目の記事です。

私がSREとして2022年の10月に入社し1年が経ちました。 この1年間でやってきたことについて書いていきます。 現在SREチームは採用募集中です。この記事を見てスキルがマッチしていたり興味が湧いた方は是非カジュアル面談をしましょう!

SRE(Site Reliability Engineer) / 株式会社10X

入社初期の取り組み

弊社がGoogle Cloudを広範囲にわたって利用していることを踏まえ、前職でGoogle Cloudを最も積極的に使用し、深く理解していた経験を生かしました。具体的には、Quotaの確認や、個人的に見落としがちだと思われるアラートの設定に取り組みました。

例えば、Quotaの面ではBigqueryの Streaming insert quotaの確認を行いました。BigqueryのStreaming insertは、無限に利用できるわけではなく、リージョンごとに帯域の上限が存在します。これは特に、Cloud LoggingのLog Routerを用いてLogをBigqueryに保存したり、Stream Firestore to BigQueryを利用する際に問題になりやすいです。

アラート設定の面では、Cloud NATに関するアラートが不足していたため、port枯渇を検知できるアラートを追加しました。Cloud NATでは、一度portを閉じてしまうと、設定された一定の秒数、そのportは利用できなくなる仕組みがあります(TCP TIME_WAIT Timeout)。そのため、導入時にはスパイクなどで気付かずにportが枯渇する可能性があるため、ある程度の余裕をもったport数をInstanceに割り当てることが重要です。このアラートの具体的な設定は、以下のMQLを参考にしてください。

fetch gce_instance
| { metric 'compute.googleapis.com/nat/port_usage'
    | align next_older(1m)
    | group_by [metadata.system.name, metric.nat_gateway_name], max(value.port_usage)
  ; metric 'compute.googleapis.com/nat/allocated_ports'
    | align next_older(1m)
    | group_by [metadata.system.name, metric.nat_gateway_name], max(value.allocated_ports) }
| ratio
| every 1m
| condition val() > 0.5 '{Value}'

自動化と効率化への取り組み

Terraform moduleへのresource追加

私が入社した時点では、stailerの使用に必要なresourceが集約されたTerraform moduleが存在していました。
しかし、まだ自動化できる領域が残っていたため、積極的にresourceの追加に取り組みました。この取り組みにより、開発チームは作業負担が軽減され、より重要なタスクに集中できるようになりました。

Redashやめる

当時、Redashの運用者が誰であるかが不明瞭な状態でした。
DWHなどへの認証情報を持つserviceとして、その放置はセキュリティ上非常に危険であると判断しました。
そこで、利用状況を調査した結果Redashを削除することに決めました。解析チームが必要なクエリをTableauに移行してくれたおかげで、スムーズに削除することができました。本当にありがとうございました🙇

Kubernetes yamlのコピペ運用をやめる

cron jobのyamlがパートナーごとにコピペされる運用が行われていました。
これにより、cronの変更やパートナーの追加があるたびに cron jobの数×パートナーの数 を含む膨大な差分のプルリクエストが生じ、 実質的なレビューが困難な状態でした。
そこで、kustomizeのbaseを上手く活用し、必要な情報だけをyamlに記述する方法に切り替えました。 この改善により、約4000行近く削減され、変更があってもレビューが行いやすくなりました。

サービスアカウントキーの発行方法の見直し

サービスアカウントキーは可能な限り発行すべきものではないです。しかし、パートナーの基幹システムと我々が管理しているGoogle Cloudサービスを繋ぐ際には、どうしてもこれが必要になる場合があります。以前は、信頼された方が代理でwebコンソールからサービスアカウントキーを発行していましたが、現在ではTerraformを介してキーを発行し、Secret Managerに格納するようになりました。さらに、Secret Managerの閲覧者を必要最低限に絞りました。この取り組みによってサービスアカウントキーを発行できる権限を持つ人の権限剥奪が可能になり、権限昇格に対するリスクを減少させることができました。

育休の取得

2023年3月から7月にかけて、5ヶ月間育休を頂きました。
この育休の取得については、転職時の採用面接で話し合っていました。
この期間があったおかげで、娘の成長を間近で見守ることができ、また産後の妻をサポートし、彼女がゆっくり休めることができました。

その後の取り組み

Deny policiesの導入

Deny policies  |  IAM Documentation  |  Google Cloud

resource "google_iam_deny_policy" "all_principals_delete_operation" {
  provider = google-beta
  parent   = urlencode("cloudresourcemanager.googleapis.com/organizations/${var.org_id}")
  name     = "all-principals-delete-operation"
  rules {
    deny_rule {
      denied_principals  = ["principalSet://goog/public:all"]
      denied_permissions = ["cloudresourcemanager.googleapis.com/projects.delete"]
      exception_principals = [
        # NOTE: 例外プリンシパルを設定する場合はここに書く
      ]
    }
  }
}

意図しない事故を防ぐ為に導入しました。
上記に書かれているTerraformを適用するとサービスアカウント含め全てのユーザーがprojectを削除できなくなります。
間違ってprojectを消してしまう例としてfirebase経由で削除がありますが、それにも対応でき非常に満足している機能の一つです。

firebase経由でproject削除

Terraform Planの権限修正

私たちの環境では、terraform planの実行に必要な権限が過剰に付与されていました。
本来変更を加えないはずの操作ですが、変更可能な権限が付与されていました。

IAM Recommenderを活用することで作業負荷がかなり下がりました。
IAM Recommenderは、過剰な権限を特定し、必要最小限の権限セットを提案してくれます。 しかし、この機能では利用している権限を完璧に把握することはできないため、過信せずに全てのstateでplanが問題なく通るのか動作チェックを行ってください。一例ですが clientoauthconfig 周りの権限が検知できていないため下記のpermissionを含んだcustom roleを作成しterraform planで利用しているサービスアカウントに付与しました。

 "clientauthconfig.brands.get",
 "clientauthconfig.brands.list",
 "clientauthconfig.clients.get",
 "clientauthconfig.clients.getWithSecret",
 "clientauthconfig.clients.list",
 "clientauthconfig.clients.listWithSecrets"

これから

現在、様々なリポジトリに分散してしまったKubernetesのyamlファイルを一つのリポジトリに集約し、ガードレールを設ける作業を行っています。
また、一時的な権限付与ならSlackだけで承認・権限付与・権限剥奪まで行えるような仕組み作りも進めています。育休が明けた今、目の前にある課題を一つずつ確実にやっていき💪していきます。

明日はData ScientistのTaniguchiさんがデータ関連についての記事を公開する予定です。お楽しみに!